diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..33ffaa404 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +po/exclude.pot binary diff --git a/.gitignore b/.gitignore index 819cd185d..524f2e6d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,237 +1,285 @@ -*~ -00_header -10_* -20_linux_xen -30_os-prober -40_custom -41_custom +# +# Ignore patterns in this directory and all subdirectories. +# *.1 *.8 -ABOUT-NLS -aclocal.m4 -ahci_test -ascii.bitmaps -ascii.h -autom4te.cache -build-aux -build-grub-gen-asciih -build-grub-gen-widthspec -build-grub-mkfont -cdboot_test -cmp_test -config.cache -config.guess -config.h -config-util.h -config-util.h.in -config.log -config.status -config.sub -configure -core_compress_test -DISTLIST -docs/*.info -docs/stamp-vti -docs/version.texi -ehci_test -example_grub_script_test -example_scripted_test -example_unit_test +*.a *.exec *.exec.exe -fddboot_test -genkernsyms.sh -gensymlist.sh -gentrigtables -gentrigtables.exe -gettext_strings_test -/gnulib -grub-bin2h -/grub-bios-setup -/grub-bios-setup.exe -grub_cmd_date -grub_cmd_echo -grub_cmd_regexp -grub_cmd_set_date -grub_cmd_sleep -/grub-editenv -/grub-editenv.exe -grub-emu -grub-emu-lite -grub-emu.exe -grub-emu-lite.exe -grub_emu_init.c -grub_emu_init.h -/grub-file -/grub-file.exe -grub-fstest -grub-fstest.exe -grub_fstest_init.c -grub_fstest_init.h -grub_func_test -grub-install -grub-install.exe -grub-kbdcomp -/grub-macbless -/grub-macbless.exe -grub-macho2img -/grub-menulst2cfg -/grub-menulst2cfg.exe -/grub-mk* -grub-mount -/grub-ofpathname -/grub-ofpathname.exe -grub-core/build-grub-pe2elf.exe -/grub-probe -/grub-probe.exe -grub_probe_init.c -grub_probe_init.h -/grub-reboot -grub_script_blanklines -grub_script_blockarg -grub_script_break -grub-script-check -grub-script-check.exe -grub_script_check_init.c -grub_script_check_init.h -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 -grub_script.tab.c -grub_script.tab.h -grub_script.yy.c -grub_script.yy.h -grub-set-default -grub_setup_init.c -grub_setup_init.h -grub-shell -grub-shell-tester -grub-sparc64-setup -grub-sparc64-setup.exe -/grub-syslinux2cfg -/grub-syslinux2cfg.exe -gzcompress_test -hddboot_test -help_test -*.img *.image *.image.exe -include/grub/cpu -include/grub/machine -INSTALL.grub -install-sh -lib/libgcrypt-grub -libgrub_a_init.c +*.img *.log *.lst -lzocompress_test *.marker -Makefile -/m4 *.mod -mod-*.c -missing -netboot_test *.o -*.a -ohci_test -partmap_test -pata_test *.pf2 *.pp -po/*.mo -po/grub.pot -po/Makefile.in.in -po/Makevars -po/Makevars.template -po/POTFILES -po/Rules-quot -po/stamp-po -printf_test -priority_queue_unit_test -pseries_test -stamp-h -stamp-h1 -stamp-h.in -symlist.c -symlist.h -trigtables.c +*.pyc *.trs -uhci_test -update-grub_lib -unidata.c -xzcompress_test -Makefile.in +*~ +.deps-core/ +.deps-util/ +.deps/ +.dirstamp +DISTLIST GPATH GRTAGS GSYMS GTAGS -compile -depcomp +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 -texinfo.tex -grub-core/lib/libgcrypt-grub -.deps -.deps-util -.deps-core -.dirstamp -Makefile.util.am -contrib -grub-core/bootinfo.txt -grub-core/Makefile.core.am -grub-core/Makefile.gcry.def -grub-core/contrib -grub-core/gdb_grub -grub-core/genmod.sh -grub-core/gensyminfo.sh -grub-core/gmodule.pl -grub-core/grub.chrp -grub-core/modinfo.sh -grub-core/*.module -grub-core/*.module.exe -grub-core/*.pp -grub-core/kernel.img.bin -util/bash-completion.d/grub -grub-core/lib/gnulib -grub-core/rs_decoder.h +mod-*.c +update-grub_lib widthspec.bin -widthspec.h -docs/stamp-1 -docs/version-dev.texi -Makefile.utilgcry.def -po/*.po -po/*.gmo -po/LINGUAS -po/remove-potcdate.sed -include/grub/gcrypt/gcrypt.h -include/grub/gcrypt/g10lib.h -po/POTFILES.in -po/POTFILES-shell.in -/grub-glue-efi -/grub-render-label -/grub-glue-efi.exe -/grub-render-label.exe + +# +# 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-core/build-grub-module-verifier +/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 index 81de20fa3..4bd05a30a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ language: c addons: apt: packages: + - autopoint - libsdl1.2-dev - lzop - ovmf @@ -35,7 +36,7 @@ before_script: script: # Comments must be outside the command strings below, or the Travis parser # will get confused. - - ./autogen.sh + - ./bootstrap # Build all selected GRUB targets. - for target in $GRUB_TARGETS; do diff --git a/ChangeLog-2015 b/ChangeLog-2015 deleted file mode 100644 index 869f6bfb8..000000000 --- a/ChangeLog-2015 +++ /dev/null @@ -1,55487 +0,0 @@ -2015-01-23 Vladimir Serbinenko - - * tests/file_filter/file: Really add missing file. - -2015-01-23 Andrei Borzenkov - - * grub-core/disk/xen/xendisk.c: Accept hdX as disk names on Xen to - allow legacy menu.lst processing. - -2015-01-22 Felix Janda - - Remove direct _llseek code and require long filesystem libc. - -2015-01-20 Vladimir Serbinenko - - Remove potential division by 0 in gfxmenu. - -2015-01-20 Vladimir Serbinenko - - * grub-core/normal/menu_text.c (grub_menu_init_page): Avoid - returning 0 geometry to avoid divisions by 0. - -2015-01-20 Vladimir Serbinenko - - * grub-core/osdep/unix/cputime.c (grub_util_get_cpu_time_ms): Cache - sc_clk_tck and check it for sanity. - -2015-01-20 Vladimir Serbinenko - - * grub-core/kern/efi/mm.c (grub_efi_get_memory_map): Never return a - descriptor_size==0 to avoid potential divisions by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/osdep/haiku/getroot.c (grub_util_find_partition_start_os): - Avoid division by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/kern/generic/rtc_get_time_ms.c (grub_rtc_get_time_ms): Avoid - division by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/loader/i386/xnu.c (guessfsb): Avoid division by 0. - -2015-01-20 Vladimir Serbinenko - - * grub-core/kern/i386/tsc.c (calibrate_tsc): Ensure that - no division by 0 occurs. - -2015-01-20 Vladimir Serbinenko - - * include/grub/misc.h (grub_div_roundup): Remove as it's unused. - -2015-01-20 Vladimir Serbinenko - - * grub-core/term/gfxterm.c: Avoid division by zero. - -2015-01-20 Vladimir Serbinenko - - Avoid division by zero in serial. - - * grub-core/term/serial.c (grub_cmd_serial): Ensure speed is not 0. - * grub-core/term/ns8250.c (serial_get_divisor): Exit if speed is 0. - -2015-01-20 Vladimir Serbinenko - - * grub-core/video/readers/jpeg.c: Avoid sivision by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c: Validate volumes to avoid division - by zero. - -2015-01-20 Vladimir Serbinenko - - * include/grub/term.h: Avoid returining 0-sized terminal - as it may lead to division by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/zfs.c: Avoid divisions by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/btrfs.c: Avoid divisions by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/lib/pbkdf2.c (grub_crypto_pbkdf2): Check that hash len is not 0. - -2015-01-20 Vladimir Serbinenko - - * grub-core/osdep/linux/blocklist.c (grub_install_get_blocklist): Check - blocksize validity. - -2015-01-20 Vladimir Serbinenko - - * grub-core/disk/i386/pc/biosdisk.c: Check disk size sanity. - -2015-01-20 Vladimir Serbinenko - - * grub-core/disk/ieee1275/nand.c (grub_nand_open): Check block size - validity. - -2015-01-20 Vladimir Serbinenko - - * grub-core/disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Do not - divide by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/hfs.c (grub_hfs_mount): Additional filesystem - sanity checks. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/minix.c: Additional filesystem - sanity checks. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/ext2.c (grub_ext2_mount): Additional - checks for superblock validity. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_mount): Check - that sblock.ino_per_group is not 0. - -2015-01-20 Vladimir Serbinenko - - Reject NILFS2 superblocks with over 1GiB blocks. - - * grub-core/fs/nilfs2.c (grub_nilfs2_valid_sb): Check that - block size is <= 1GiB. - -2015-01-20 Vladimir Serbinenko - - * grub-core/disk/ata.c (grub_ata_setaddress): Check that geometry - is sane when using CHS addressing. - -2015-01-20 Vladimir Serbinenko - - * grub-core/disk/AFSplitter.c (AF_merge): Check that mdlen is not 0. - -2015-01-20 Vladimir Serbinenko - - * grub-core/commands/i386/pc/play.c (grub_cmd_play): Avoid - division by zero. - -2015-01-20 Vladimir Serbinenko - - * grub-core/bus/usb/usbtrans.c (grub_usb_bulk_maxpacket): Avoid - potentially returning 0. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/minix.c (grub_minix_read_file): Avoid reading past - the end of file. - -2015-01-20 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (grub_fshelp_read_file): Don't attempt to read - past the end of file. - -2015-01-20 Vladimir Serbinenko - - * grub-core/script/lexer.c (grub_script_lexer_yywrap): Update len - synchronously with line. - -2015-01-20 Vladimir Serbinenko - - Replace explicit sizeof divisions by ARRAY_SIZE. - -2015-01-19 Kris Moore - - * grub-core/disk/geli.c: Support GELI v6 and v7. - -2014-12-09 Andrei Borzenkov - - * grub-core/term/serial.c (grub_cmd_serial): Fix --rtscts - option processing. - -2014-12-07 David Kozub - - * grub-core/kern/arm/misc.S: fix unaligned 64bit local variable - in __aeabi_uidivmod - Fixes Savannah bug #43632. - -2014-12-07 Peter Nelson - - * grub-core/fs/ext2.c (grub_ext2_read_block): Support large sparse - chunks. - -2014-12-07 Andrei Borzenkov - - * util/grub-mkconfig_lib.in (version_test_gt): Remove redundant - non-portable '-n' echo option. - * util/grub.d/10_kfreebsd.in: Change how list is built to avoid - non-portable 'echo -n. - * util/grub.d/10_linux.in: Likewise (closes 43668). - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Print spaces directly to avoid - non-portable 'echo -n'. - -2014-12-07 Curtis Larsen - - * grub-core/net/tcp.c (grub_net_recv_tcp_packet): Fix double - free when multiple empty segments were received (closes 42765). - -2014-12-05 Andrei Borzenkov - - * tests/util/grub-shell.in: Support --files also for netboot. - * tests/file_filter_test.in: New file with file filters tests. - * Makefile.util.def: Add file_filter_test. - * conf/Makefile.extra-dist: ... and here. - * tests/file_filter/file.gz: Test file for file_filter_test. - * tests/file_filter/file.gz.sig: Likewise. - * tests/file_filter/file.lzop: Likewise. - * tests/file_filter/file.lzop.sig: Likewise. - * tests/file_filter/file.xz: Likewise. - * tests/file_filter/file.xz.sig: Likewise. - * tests/file_filter/keys: Likewise. - * tests/file_filter/keys.pub: Likewise. - * tests/file_filter/test.cfg: Likewise. - * grub-core/commands/verify.c: Fix memory corruption doing - signature check for network files (closes 43601). - -2014-12-01 Andrei Borzenkov - - * grub-core/loader/i386/xen_fileXX.c (grub_xen_get_infoXX): Fix - memory leak (CID 73645, 73782). - * grub-core/fs/zfs/zfsinfo.c (print_vdev_info): Fix memory leak - (CID 73635). - -2014-11-30 Andrei Borzenkov - - * grub-core/lib/syslinux_parse.c (free_menu): Do not free - inline array (CID 73610). - -2014-11-28 Andrei Borzenkov - - * grub-core/io/lzopio.c (test_header): Fix double free (CID 73665) - * grub-core/disk/geli.c (configure_ciphers): Fix memory leaks - (Coverity CID 73813, 73710) - * grub-core/disk/luks.c (configure_ciphers): Fix memory leaks - and use after free (Coverity CID 73813, 73710, 73730) - * grub-core/disk/luks.c (luks_recover_key): Fix memory leak (Coverity - CID 73854) - * util/grub-install-common.c (grub_install_get_target): Check return - value of grub_util_fd_read (Coverity CID 73819). - * util/grub-mkstandalone.c (add_tar_file): Fix out of bound access - to hd.magic (Coverity CID 73587, 73888, bug 43690). - -2014-11-20 Andrei Borzenkov - - * tests/util/grub-fs-tester.in: Consistently print output - of grub ls if test fails. - -2014-11-07 Leif Lindholm - - * grub-core/kern/efi/init.c: check value of *path before - dereferencing. - -2014-11-03 Michael Chang - - * grub-core/net/icmp6.c (grub_net_recv_icmp6_packet): Fix size - of neighbor solicitation packet in grub_netbuff_pull. - -2014-10-14 Andrei Borzenkov - - * grub-core/loader/arm/linux.c: Use full initializer for initrd_ctx to - avoid fatal warnings with older gcc (probably before 4.7). - * grub-core/loader/arm64/linux.c: Likewise. - * grub-core/loader/i386/linux.c: Likewise. - * grub-core/loader/i386/pc/linux.c: Likewise. - * grub-core/loader/ia64/efi/linux.c: Likewise. - * grub-core/loader/mips/linux.c: Likewise. - * grub-core/loader/powerpc/ieee1275/linux.c: Likewise. - * grub-core/loader/sparc64/ieee1275/linux.c: Likewise. - -2014-09-25 Colin Watson - - Fix in-tree --platform=none - - * configure.ac: Only remove include/grub/cpu and - include/grub/machine in the --platform=none case, not all of - include/grub. - -2014-09-23 Colin Watson - - Add a new "none" platform that only builds utilities - - * configure.ac: Add "none" platform. Default to it for unsupported - CPUs rather than stopping with a fatal error. Don't downgrade - x86_64-none to i386. Define COND_real_platform Automake conditional - if the platform is anything other than "none". Don't do any include - directory linking for "none". - * Makefile.am: Skip building grub-core and all bootcheck targets if - !COND_real_platform. - * include/grub/time.h: Don't include if GRUB_UTIL - is defined. - -2014-09-22 Andrei Borzenkov - - Use grub_cpu_to_XXX_compile_time for constants. - -2014-09-21 Valentin Dornauer - - The AML parser implements only a small subset of possible AML - opcodes. On the Fujitsu Lifebook E744 this and another bug in - the parser (incorrect handling of TermArg data types) would lead - to the laptop not turning off (_S5 not found). - - * grub-core/commands/acpihalt.c: Support OpAlias in the AML parser; - in skip_ext_op(), handle some Type2Opcodes more correctly (TermArgs - aren't always simply strings!); Add function to skip TermArgs - * include/grub/acpi.h: Add new opcodes - -2014-09-21 Vladimir Serbinenko - - * grub-core/normal/main.c: Don't drop to rescue console in - case of password-protected prompt and no menu entries. - -2014-09-21 Vladimir Serbinenko - - * grub-core/commands/keylayouts.c: Ignore unknown keys. - -2014-09-21 Vladimir Serbinenko - - * grub-core/gmodule.pl.in: Accept newer binutils which output - empty column rather than 0x0. - -2014-09-21 Michael Chang - - * grub-core/osdep/unix/config.c: Remove extraneous comma. - -2014-09-21 Peter Jones - - * grub-core/loader/arm/linux.c: Initialized initrd_ctx so - we don't free a random pointer from the stack. - * grub-core/loader/arm64/linux.c: Likewise. - * grub-core/loader/i386/linux.c: Likewise. - * grub-core/loader/i386/pc/linux.c: Likewise. - * grub-core/loader/ia64/efi/linux.c: Likewise. - * grub-core/loader/mips/linux.c: Likewise. - * grub-core/loader/powerpc/ieee1275/linux.c: Likewise. - * grub-core/loader/sparc64/ieee1275/linux.c: Likewise. - -2014-09-15 Khem Raj - - * grub-core/kern/emu/hostfs.c: use _DEFAULT_SOURCE in addition to - _BSD_SOURCE to avoid warnings under glibc 2.20+. - -2014-09-08 Michael Chang - - * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Fix extent size - check; comparing &data->extent against addresses in the region it - points to is unpredictable. - -2014-09-07 Colin Watson - - Support grub-emu on x32 (ILP32 but with x86-64 instruction set) - - * configure.ac: Remove -m64 from checks for -mcmodel=large and - -mno-red-zone. These are always either unnecessary (x86_64-emu) or - already in TARGET_CFLAGS at this point, and they produce incorrect - results when building for x32. - * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Cast - pointers to Elf64_Xword via grub_addr_t, in order to work on x32. - * include/grub/x86_64/types.h (GRUB_TARGET_SIZEOF_VOID_P, - GRUB_TARGET_SIZEOF_LONG): Define to 4 on x32. - -2014-09-07 Colin Watson - - * configure.ac: Remove several unnecessary semicolons. - -2014-08-25 Colin Watson - - * grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation): - Initialise pend to pacify GCC. - -2014-08-14 Andrey Borzenkov - - * util/grub-mkconfig.in: Fix typo (gettext_print instead of - gettext_printf). - -2014-08-13 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c: Retry probing keyboard if - scancode setup failed. - -2014-08-10 Vladimir Serbinenko - - * grub-core/kern/disk_common.c: Clump disk size to 1EiB. - -2014-08-10 Vladimir Serbinenko - - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_rw): Add - safety to avoid triggerring VirtualBox bug. - -2014-08-10 Vladimir Serbinenko - - * grub-core/fs/cbfs.c: Don't probe disks of unknow size. - - Fixes hang on virtualbox. - -2014-07-08 Colin Watson - - * util/grub.d/10_hurd.in: Make kernel list progression not fail on - kernels whose paths contain regex metacharacters. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - - Reported by: Heimo Stranner. - -2014-06-26 Colin Watson - - * docs/grub-dev.texi (Finding your way around): The build system no - longer uses AutoGen directly. - -2014-06-21 Роман Пехов - - * grub-core/commands/loadenv.c (check_blocklists): Fix overlap check. - -2014-06-21 Glenn Washburn - - * util/grub-install.c: Fix handling of --disk-module. - -2014-06-21 Stephane Rochoy - - * grub-core/loader/i386/bsd.c (grub_netbsd_boot): Pass pointer to - EFI system table. - -2014-06-21 Stephane Rochoy - - * grub-core/commands/efi/lsefisystab.c (grub_cmd_lsefisystab): Show - EFI system table physical address. - -2014-06-21 Trevor Woerner - - * util/grub-gen-asciih.c (add_glyph): Fix uninitialised variable. - -2014-06-21 Vladimir Serbinenko - - * grub-core/commands/verify.c (grub_pubkey_open): Trust procfs. - -2014-06-21 Vladimir Serbinenko - - * grub-core/commands/verify.c (grub_pubkey_open): Fix memdisk - check. - -2014-04-20 Vladimir Serbinenko - - * grub-core/kern/misc.c (__bzero): Don't compile in GRUB_UTIL. - - Reported by: Yves Blusseau . - -2014-04-20 Piotr Krysiuk - - * grub-core/lib/i386/relocator.c: Allow loading old kernels by placing - GDT in conventional memory. - -2014-04-10 Colin Watson - - * util/grub.d/30_os-prober.in: Tolerate devices with no filesystem - UUID. Other parts of grub-mkconfig tolerate these, they were - previously allowed here up to commit - 55e706c918922def17f5012c23cfe88c4c645208, and they can arise in - practice when the system has active LVM snapshots. - Fixes Ubuntu bug #1287436. - -2014-04-10 Colin Watson - - * grub-core/disk/lvm.c (grub_lvm_detect): Search for - "logical_volumes" block a little more accurately. - -2014-04-06 Vladimir Serbinenko - - * grub-core/lib/syslinux_parse.c: Fix timeout quoting. - -2014-04-04 Vladimir Serbinenko - - * include/grub/libgcc.h: Remove ctzsi2 and ctzdi2. They're no longer - pulled from libgcc. - -2014-04-04 Vladimir Serbinenko - - Replace few instances of memcmp/memcpy in the code that should be - grub_memcmp/grub_memcpy. - -2014-04-03 Vladimir Serbinenko - - * grub-core/osdep/linux/getroot.c (grub_util_part_to_disk): Support NVMe - device names. - -2014-03-31 Thomas Falcon - - btrfs: fix get_root key comparison failures due to endianness - - * grub-core/fs/btrfs.c (get_root): Convert - GRUB_BTRFS_ROOT_VOL_OBJECTID to little-endian. - -2014-03-31 Colin Watson - - Fix partmap, cryptodisk, and abstraction handling in grub-mkconfig. - - Commit 588744d0dc655177d5883bdcb8f72ff5160109ed caused grub-mkconfig - no longer to be forgiving of trailing spaces on grub-probe output - lines, which among other things means that util/grub.d/10_linux.in - no longer detects LVM. To fix this, make grub-probe's output - delimiting more consistent. As a bonus, this improves the coverage - of the -0 option. - - Fixes Debian bug #735935. - - * grub-core/disk/cryptodisk.c - (grub_util_cryptodisk_get_abstraction): Add a user-data argument. - * grub-core/disk/diskfilter.c (grub_diskfilter_get_partmap): - Likewise. - * include/grub/cryptodisk.h (grub_util_cryptodisk_get_abstraction): - Update prototype. - * include/grub/diskfilter.h (grub_diskfilter_get_partmap): Likewise. - * util/grub-install.c (push_partmap_module, push_cryptodisk_module, - probe_mods): Adjust for extra user-data arguments. - * util/grub-probe.c (do_print, probe_partmap, probe_cryptodisk_uuid, - probe_abstraction): Use configured delimiter. Update callers. - -2014-03-31 Colin Watson - - * util/grub-probe,c (options): Make -0 work again (broken by - conversion to argp). - (main): Simplify logic. - -2014-03-26 Vladimir Serbinenko - - * grub-core/lib/relocator.c: Fix the case when end of leftover is used. - -2014-03-26 Fu Wei - - * grub-core/loader/arm64/linux.c: Remove redundant "0x". - -2014-02-28 Vladimir Serbinenko - - * include/grub/i386/openbsd_bootarg.h: Add addr and frequency fields. - * grub-core/loader/i386/bsd.c (grub_cmd_openbsd): Fill addr field. - - Suggested by: Markus Müller. - -2014-02-28 Vladimir Serbinenko - - * grub-core/kern/i386/pc/mmap.c: Fallback to EISA memory map - if E820 failed to return any regions. - -2014-02-28 Vladimir Serbinenko - - * grub-core/mmap/i386/uppermem.c (lower_hook) [COREBOOT]: Ignore low - tables for low memory calculations. - -2014-02-28 Vladimir Serbinenko - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): Limit - location to 640K. - -2014-02-28 Vladimir Serbinenko - - * grub-core/kern/i386/coreboot/mmap.c: Filter out 0xa0000-0x100000 - region. - -2014-02-20 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Ignore NPORTS field and rely on PI - exclusively. - -2014-02-04 Paulo Flabiano Smorigo - - Add bootpath parser for open firmware. - - It enables net boot even when there is no bootp/dhcp server. - - * grub-core/net/drivers/ieee1275/ofnet.c: Add grub_ieee1275_parse_bootpath - and call it at grub_ieee1275_net_config_real. - * grub-core/kern/ieee1275/init.c: Add bootpath to - grub_ieee1275_net_config. - * include/grub/ieee1275/ieee1275.h: Likewise. - - -2014-02-04 Paulo Flabiano Smorigo - - Add grub_env_set_net_property function. - - * grub-core/net/bootp.c: Remove set_env_limn_ro. - * grub-core/net/net.c: Add grub_env_set_net_property. - * include/grub/net.h: Likewise. - -2014-02-03 Vladimir Serbinenko - - * util/grub-mkrescue.c: Build fix for argp.h with older gcc. - -2014-02-03 Vladimir Serbinenko - - * util/grub-mkfont.c: Build fix for argp.h with older gcc. - -2014-01-29 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Increase timeout. Some SSDs take up to - 7 seconds to recover if last poweroff was bad. - -2014-01-29 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Properly handle transactions with no - transferred data. - -2014-01-29 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Add safety cleanups. - -2014-01-29 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Allocate and clean space for all possible 32 - slots to avoid pointing to uninited area. - -2014-01-29 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Do not enable I/O decoding and keep - enabling busmaster for the end. - -2014-01-29 Vladimir Serbinenko - - * util/grub-mkfont.c: Downgrade warnings about unhandled features - to debug. - -2014-01-29 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c: Tolerate missing keyboard. - -2014-01-29 Paulo Flabiano Smorigo - - * .gitignore: add missing files and .exe variants. - -2014-01-26 Mike Gilbert - - grub-install: support for partitioned partx loop devices. - - * grub-core/osdep/linux/getroot.c (grub_util_part_to_disk): Detect - /dev/loopX as being the parent of /dev/loopXpY. - -2014-01-26 Vladimir Serbinenko - - * grub-core/term/serial.c (grub_serial_register): Fix invalid free. - Ensure that pointers are inited to NULL and that pointers are not - accessed after free. - -2014-01-25 Andrey Borzenkov - - * include/grub/crypto.h: Replace __attribute__ ((format (printf)) with - __attribute__ ((format (__printf__)) to fix compilation under MinGW-w64. - * include/grub/emu/misc.h: ... and here. - * include/grub/err.h: ... and here. - * util/import_gcry.py: ... and here (in files g10lib.h). - -2014-01-25 Andrey Borzenkov - - * util/grub-mkimage.c: Make prefix argument mandatory. - -2014-01-24 Vladimir Serbinenko - - Fix several translatable strings. - - Suggested by: D. Prévot. - -2014-01-24 Vladimir Serbinenko - - * util/grub-install.c: List available targets. - -2014-01-23 Colin Watson - - * util/grub-install.c (write_to_disk): Add an info message. - -2014-01-21 Andrey Borzenkov - - * Makefile.am: Allow adding extra files to generated Windows ZIP - archive by setting GRUB_WINDOWS_EXTRA_DIST. - -2014-01-21 Andrey Borzenkov - - * configure.ac: Look for DejaVuSans also in /usr/share/fonts/truetype. - Show detected font path in summary. - -2014-01-21 Paulo Flabiano Smorigo - - * grub-core/net/arp.c (grub_net_arp_send_request): Increase network try - interval gradually. - * grub-core/net/icmp6.c (grub_net_icmp6_send_request): Likewise. - * grub-core/net/net.c (grub_net_fs_read_real): Likewise. - * grub-core/net/tftp.c (tftp_open): Likewise. - * include/grub/net.h (GRUB_NET_INTERVAL_ADDITION): New define. - -2014-01-21 Paulo Flabiano Smorigo - - * grub-core/net/net.c (receive_packets): Change stop condition to avoid - infinite loops. - - In net/net.c there is a while (1) that only exits if there is a stop - condition and more then 10 packages or if there is no package received. - - If GRUB is idle and enter in this loop, the only condition to leave is - if it doesn't have incoming packages. In a network with heavy traffic - this never happens. - -2014-01-19 Colin Watson - - * grub-core/osdep/freebsd/hostdisk.c (grub_util_fd_open): Ignore - EPERM when modifying kern.geom.debugflags. It is only a problem for - such things as installing GRUB to the MBR, in which case there'll be - an error later anyway, not for opening files during tests. - -2014-01-18 Andrey Borzenkov - - * grub-core/Makefile.am: Build grub_emu_init.[ch] from MODULE_FILES - instead of MOD_FILES. - * grub-core/genemuinit.sh: Simplify stripping of suffix so it works - both with and without .exe. - * grub-core/genemuinitheader.sh: Same. - -2014-01-18 Vladimir Serbinenko - - * util/grub-install.c: Fix a typo. - -2014-01-18 Vladimir Serbinenko - - * grub-core/normal/main.c (read_config_file): Buffer config file. - Reduces boot time. - -2014-01-18 Andrey Borzenkov - - * acinclude.m4 (grub_CHECK_LINK_DIR): Check that we can also remove - symbolic link to directory. It fails in Msys shell on Windows 2003. - -2014-01-18 Vladimir Serbinenko - - * Makefile.am (default_payload.elf): Add modules - multiboot cbmemc linux16 gzio echo help. - -2014-01-18 Mike Gilbert - - * Makefile.util.def: Link grub-ofpathname with zfs libs. - -2014-01-18 Vladimir Serbinenko - - * grub-core/commands/macbless.c: Rename FILE and DIR to avoid - conflicts. - - Reported by: Andrey Borzenkov. - -2014-01-18 Andrey Borzenkov - - * include/grub/misc.h: Move macros for compiler features to ... - * include/grub/compiler.h: ... new file. - * include/grub/list.h: Include instead of . - * grub-core/commands/fileXX.c: Include . - * grub-core/efiemu/prepare.c: Include . - * grub-core/loader/i386/xen_file.c: Include . - * grub-core/loader/i386/xen_fileXX.c: Include . - * grub-core/video/capture.c: Include . - * include/grub/command.h: Include . - * include/grub/dl.h: Include . - * include/grub/procfs.h: Include . - -2014-01-18 Andrey Borzenkov - - * configure.ac: Add support for BUILD_EXEEXT and use it ... - * Makefile.am: ... here. - * Makefile.util.def: ... and here. - * grub-core/Makefile.am: ... and here. - -2014-01-18 Andrey Borzenkov - - * include/grub/osdep/hostfile_windows.h: Use _W64 instead of - FILE_OFFSET_BITS to differentiate between native MinGW and Mingw W64. - -2014-01-18 Vladimir Serbinenko - - * grub-core/term/terminfo.c: Recognize keys F1-F12. - -2014-01-18 Andrey Borzenkov - - * configure.ac: Add support for BUILD_LDFLAGS. - * Makefile.am: Use BUILD_LDFLAGS for build time programs here ... - * grub-core/Makefile.am: ... and here. - * INSTALL: Mention BUILD_LDFLAGS. - -2014-01-18 Vladimir Serbinenko - - * util/grub-mount.c: Extend GCC warning workaround to grub-mount. - -2014-01-18 Vladimir Serbinenko - - * grub-core/kern/efi/efi.c: Ensure that the result starts with / - and has no //. - -2014-01-18 Vladimir Serbinenko - - * NEWS: Add few missing entries. - -2014-01-17 Colin Watson - - * util/grub.d/00_header.in (make_timeout): Use && rather than test - -a. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/10_netbsd.in (netbsd_load_fs_module): Use || rather - than test -o. - * util/grub.d/30_os-prober.in: Use && rather than test -a, and || - rather than test -o. - -2014-01-17 Colin Watson - - * grub-core/osdep/freebsd/hostdisk.c (grub_util_fd_open): Remove - redundant preprocessor conditional. - -2014-01-08 Colin Watson - - * Makefile.util.def (grub-macbless): Change mansection to 8. - -2014-01-07 Leif Lindholm - - * grub-core/loader/arm64/linux.c: correctly set device path end length. - -2014-01-07 Andrey Borzenkov - - * util/grub-install.c: Use bootaa64.efi instead of bootaarch64.efi on - arm64 to comply with EFI specification. Also use grubaa64.efi for - consistency. - * util/grub-mkrescue.c: Change to use bootaa64.efi too. - -2014-01-07 Andrey Borzenkov - - * include/grub/osdep/hostfile_windows.h: Do not redefine fseeko/ftello - on MinGW-64 when compiling for 32 bits. - -2013-12-30 Andrey Borzenkov - - * grub-core/Makefile.core.def: strip .eh_frame section for arm64-efi. - -2013-12-30 Vladimir Serbinenko - - * NEWS: Add few missing entries. Correct existing ones. - -2013-12-28 Vladimir Serbinenko - - Don't abort() on unavailable coreboot tables if not running on coreboot. - -2013-12-28 Andrey Borzenkov - - * grub-core/kern/emu/misc.c: Remove unused error.h; fixes compilation - on mingw. - -2013-12-28 Colin Watson - - * NEWS: The cmosclean command in fact dates back to 1.99. Remove - mention of it from 2.02. - -2013-12-27 Vladimir Serbinenko - - * grub-core/kern/arm/cache_armv6.S: Remove .arch directive. - - As these functions are used on pre-ARMv6 CPUs as well we don't want - to make assembler assume that architecture is higher than default one. - -2013-12-27 Colin Watson - - * NEWS: First draft of 2.02 entry. - -2013-12-27 Colin Watson - - * INSTALL (Cross-compiling the GRUB): Fix some spelling mistakes. - * docs/grub.texi (Getting the source code): Likewise. - -2013-12-25 Andrey Borzenkov - - * grub-core/osdep/windows/platform.c (get_platform): Fix EFI - detection. - -2013-12-24 Vladimir Serbinenko - - * configure.ac: Set version to 2.02~beta2. - -2013-12-24 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c (name_devices): Skip Apple ghosts. - -2013-12-24 Andrey Borzenkov - - * util/grub-probe.c: Improve help message and simplify list handling. - -2013-12-24 Vladimir Serbinenko - - Fix buffer overflow in grub_efi_print_device_path. - -2013-12-24 Vladimir Serbinenko - - Show SATA device path. - -2013-12-24 Vladimir Serbinenko - - Revert grub-file usage in grub-mkconfig. - -2013-12-24 Vladimir Serbinenko - - Make newly-created files other than grub.cfg world-readable. - -2013-12-24 Andrey Borzenkov - - * util/grub.d/00_header.in: Improve compatibility with old config. - -2013-12-24 Vladimir Serbinenko - - Make rijndael.c respect aliasing rules. - - Trivial backport of dfb4673da8ee52d95e0a62c9f49ca8599943f22e. - -2013-12-24 Vladimir Serbinenko - - Make grub_util_device_is_mapped_stat available in grub-emu core. - -2013-12-24 Vladimir Serbinenko - - Add -Qn to TARGET_CFLAGS if it's supported. - Fixes compilation on cygwin. - - Reported by: Andrey Borzenkov. - Suggested by: Andrey Borzenkov. - -2013-12-24 Vladimir Serbinenko - - Save TARGET_CC version in modinfo.sh. - - Suggested by: Andrey Borzenkov. - -2013-12-24 Vladimir Serbinenko - - Make grub_util_devmapper_part_to_disk and grub_util_find_partition_start - follow the same algorithm to avoid method mismatch. Don't assume - DMRAID- UUID to mean full disk but instead check that mapping is linear. - -2013-12-24 Vladimir Serbinenko - - Declare GRUB_EFI_VENDOR_APPLE_GUID. - -2013-12-24 Vladimir Serbinenko - - Dump type and vendor specific data when printing device path. - -2013-12-23 Colin Watson - - Update some documentation to refer to Git rather than Bazaar. - - * docs/grub.texi (Obtaining and Building GRUB): Refer to Git rather - than Bazaar. - * po/README: Likewise. Fix spelling mistake. - -2013-12-23 Colin Watson - - Don't distribute config.h. - - * Makefile.am (platform_HEADERS): Move to ... - (nodist_platform_HEADERS): ... here. Fixes gettext_strings_test - failure when building from a distributed tarball. - -2013-12-23 Colin Watson - - * configure.ac: Fix spelling. - * grub-core/commands/parttool.c: Fix grammar. - * grub-core/disk/ldm.c: Use consistent capitalisation for "LDM - Embedding Partition". - -2013-12-23 Vladimir Serbinenko - - ARM64 support for grub-mkrescue. - -2013-12-23 Vladimir Serbinenko - - Install modinfo.sh to keep build information around. - -2013-12-23 Vladimir Serbinenko - - * grub-core/modinfo.sh.in: Add build config information. - -2013-12-23 Vladimir Serbinenko - - ARM64 grub-file and grub-mkconfig support. - -2013-12-23 Vladimir Serbinenko - - Remove leftover options defines. - -2013-12-23 Vladimir Serbinenko - - * include/grub/arm64/linux.h: Remove leftovers. Add missing prefixes. - -2013-12-23 Vladimir Serbinenko - - * grub-core/loader/arm64/linux.c: Add missing bracket. - -2013-12-23 Vladimir Serbinenko - - Add arm64-efi recognition to grub-file. - -2013-12-23 Vladimir Serbinenko - - Fix ia64-efi recognition in grub-file. - -2013-12-23 Vladimir Serbinenko - - Recognize raspberry pi kernel in grub-file. - -2013-12-23 Vladimir Serbinenko - - Enable cache on ARM U-Boot port. - - Without it the port is reidiculously slow. - -2013-12-23 Vladimir Serbinenko - - Fix ARM cache maintainance. - - More code was converted from ASM to C for easier handling. - -2013-12-22 Vladimir Serbinenko - - * grub-core/kern/arm/cache.c (grub_arm_disable_caches_mmu): Use v6 - algorithm on v5. - - Suggested by: Leif Lindholm. - -2013-12-22 Andrey Borzenkov - - * util/grub-mkconfig.in: Fix Xen platform conditions. - -2013-12-22 Andrey Borzenkov - - * util/grub-mkrescue.c: Split single help message string in several - strings used in previous shell version. - -2013-12-22 Leif Lindholm - - Add arm64 Linux loader. - -2013-12-22 Leif Lindholm - - Add grub_fdt_create_empty_tree() and grub_fdt_set_prop64(). - -2013-12-22 Vladimir Serbinenko - - Add module loading and parsing boot time checkpoints. - -2013-12-22 Vladimir Serbinenko - - * grub-core/loader/arm/linux.c: Pass arguments through on ATAG - platforms. - -2013-12-22 Lars Wendler - - * util/grub-mkconfig.in: Skip non-executable files. - -2013-12-22 Vladimir Serbinenko - - Workaround buggy timer in raspberry pie by using our own timer - implementation. - -2013-12-22 Vladimir Serbinenko - - * include/grub/arm/uboot/kernel.h (GRUB_KERNEL_MACHINE_HEAP_SIZE): - Increase to 16 MiB to allow loading the whole memdisk. - -2013-12-22 Vladimir Serbinenko - - Fix ARM Linux Loader on non-FDT platforms. - -2013-12-21 Vladimir Serbinenko - - * configure.ac: Choose link format based on host_os on emu. - -2013-12-21 Vladimir Serbinenko - - * grub-core/osdep/unix/getroot.c: Non-unix build fix. - -2013-12-21 Vladimir Serbinenko - - * grub-core/kern/emu/main.c: Build fix for emu. - -2013-12-21 Vladimir Serbinenko - - Build fixes for argp.h with older gcc. - -2013-12-21 Vladimir Serbinenko - - * util/grub-glue-efi.c: Use "universal binary" rather "fat binary" - in strings. - - Suggested by: David Prévot. - -2013-12-21 Vladimir Serbinenko - - * include/grub/crypto.h (grub_crypto_xor): Fix cast-align warning. - -2013-12-21 Vladimir Serbinenko - - Enable -Wformat=2 if it's supported. - -2013-12-21 Vladimir Serbinenko - - * configure.ac: Add -Wmissing-include-dirs -Wmissing-prototypes - -Wmissing-declarations if supported. - -2013-12-21 Vladimir Serbinenko - - * grub-core/commands/macbless.c (grub_mac_bless_inode): Pass inode as - u32 as both HFS and HFS+ have 32-bit inodes. - -2013-12-21 Vladimir Serbinenko - - * include/grub/misc.h (grub_strtol): Fix overflow. - -2013-12-21 Vladimir Serbinenko - - * include/grub/term.h (grub_unicode_estimate_width): Use grub_size_t - as return type in both conditionals. - -2013-12-21 Vladimir Serbinenko - - * include/grub/video.h (grub_video_rgba_color_rgb): Fix prototype - to use uint8_t for color. - -2013-12-21 Vladimir Serbinenko - - * util/misc.c (grub_util_get_image_size): Check for overflow. - -2013-12-21 Vladimir Serbinenko - - * grub-core/disk/raid6_recover.c (grub_raid_block_mulx): Use grub_size_t - for size. - -2013-12-21 Vladimir Serbinenko - - * grub-core/disk/lvm.c: Use grub_size_t for sizes and grub_ssize_t - for pointer difference. - -2013-12-21 Vladimir Serbinenko - - * util/import_gcry.py: Skip sample keys. - -2013-12-21 Vladimir Serbinenko - - * util/misc.c (grub_qsort_strcmp): Don't discard const attribute. - -2013-12-21 Vladimir Serbinenko - - * configure.ac: Remove duplicate warning arguments. - -2013-12-21 Vladimir Serbinenko - - Add missing static qualifiers. - -2013-12-21 Vladimir Serbinenko - - Add missing includes. - -2013-12-21 Vladimir Serbinenko - - Inline printf templates when possible to enable format checking. - -2013-12-21 Vladimir Serbinenko - - * include/grub/crypto.h: Don't discard const attribute. - -2013-12-21 Vladimir Serbinenko - - * grub-core/net/bootp.c (grub_cmd_dhcpopt): Use snprintf where it - was intended. - -2013-12-21 Vladimir Serbinenko - - * grub-core/lib/crypto.c: Don't discard const attribute. - -2013-12-21 Vladimir Serbinenko - - * grub-core/lib/disk.c: Fix potential overflow. - -2013-12-21 Vladimir Serbinenko - - * grub-core/lib/arg.c: Don't discard const attribute. - -2013-12-21 Vladimir Serbinenko - - * grub-core/kern/dl.c: Don't discard const attribute. - -2013-12-21 Vladimir Serbinenko - - * grub-core/kern/disk.c: Fix potential overflow. - -2013-12-21 Vladimir Serbinenko - - * conf/Makefile.common: Don't include non-existing directory - grub-core/lib/libgcrypt-grub/include. - -2013-12-21 Vladimir Serbinenko - - Clarify several translatable messages. - -2013-12-21 David Prévot - - Correct some translatable strings. - -2013-12-21 Colin Watson - - * util/grub-mkrescue.c: Rephrase mkrescue description. - -2013-12-21 Vladimir Serbinenko -2013-12-21 Colin Watson - - Clarify several translatable messages. - -2013-12-20 Colin Watson - - Be more verbose about some configure failures. - -2013-12-20 Colin Watson - - Fix various build problems on GNU/Hurd. - - * grub-core/osdep/unix/getroot.c (strip_extra_slashes): Move inside - !defined (__GNU__). - (xgetcwd): Likewise. - * include/grub/emu/hostdisk.h (grub_util_hurd_get_disk_info) - [__GNU__]: Add prototype. - * util/getroot.c (grub_util_biosdisk_get_grub_dev) [__GNU__]: Format - long int using %ld rather than %d. - -2013-12-18 Vladimir Serbinenko - - * util/grub-install.c: Inform user about install platform. - -2013-12-18 Vladimir Serbinenko - - * configure.ac: Set version to 2.02~beta1. - -2013-12-18 Allen Pais -2013-12-18 Bob Picco - - * grub-core/boot/sparc64/ieee1275/boot.S: Fix order of fields. - -2013-12-18 Vladimir Serbinenko - - Make grub_zlib_decompress handle incomplete chunks. - - Fixes squash4. - -2013-12-18 Vladimir Serbinenko - - * grub-core/Makefile.am: Don't attempt to export grub_bios_interrupt - on i386-multiboot. - -2013-12-18 Aleš Nesrsta - - * grub-core/disk/usbms.c: Retry on unknown errors. - Reuse the same tag on retries. - -2013-12-18 Aleš Nesrsta - - * grub-core/bus/usb/ehci.c: Fix handling of newborn transfers. - - Avoid confusing them with already completed transfers. - -2013-12-18 Vladimir Serbinenko - - Remove xen VFB. - - Due to XEN bug it prevents Linux boot. Remove it at least, until - workaround is found. - -2013-12-18 Vladimir Serbinenko - - * po/exclude.pot: Add 2 missing excludes. - -2013-12-18 Vladimir Serbinenko - - Add missing license section in macbless.mod and macho.mod. - -2013-12-18 Vladimir Serbinenko - - Allow compilation without thumb-interwork as long as no thumb is - involved or only thumb2 is used. - -2013-12-18 Vladimir Serbinenko - - * INSTALL: Update comment as to why sparc64 clang isn't usable. - -2013-12-18 Vladimir Serbinenko - - Add __attribute__ ((sysv_abi)) only if it's really needed. - - Some compilers don't support it. - -2013-12-18 Vladimir Serbinenko - - * grub-core/lib/syslinux_parse.c: Declare timeout unsigned. - -2013-12-18 Vladimir Serbinenko - - Remove -Wold-style-definition. - - Not very useful and interaction of it with regexp depends on GCC - version. - -2013-12-18 Vladimir Serbinenko - - Make grub_util_get_windows_path_real static. - -2013-12-18 Vladimir Serbinenko - - * grub-core/commands/fileXX.c: Silence cast-align. - * grub-core/loader/i386/xen_fileXX.c: Likewise. - -2013-12-18 Vladimir Serbinenko - - * include/grub/efi/api.h (GRUB_EFI_ERROR_CODE): Use explicit cast - rather than LL suffix. - -2013-12-18 Vladimir Serbinenko - - * include/grub/efi/api.h (PRIxGRUB_EFI_UINTN_T): Remove leftover. - -2013-12-18 Vladimir Serbinenko - - * grub-core/loader/arm/linux.c: Use common initrd functions. - -2013-12-18 Vladimir Serbinenko - - Decrease number of strings to translate. - -2013-12-18 Vladimir Serbinenko - - * grub-core/kern/arm/dl.c: Remove unnecessarry execution mode check. - -2013-12-18 Vladimir Serbinenko - - Mark strings for translation and add remaining ones to exclude list. - -2013-12-18 Vladimir Serbinenko - - * util/grub-file.c (main): Fix sizeof usage. - -2013-12-18 Vladimir Serbinenko - - Silence spurious warning. - -2013-12-18 Vladimir Serbinenko - - Remove check_nt_hiberfil as it's been superseeded by file command. - -2013-12-17 Vladimir Serbinenko - - * docs/osdetect.cfg: Add isolinux config to detected OSes. - -2013-12-17 Vladimir Serbinenko - - Implement syslinux parser. - -2013-12-17 Vladimir Serbinenko - - * grub-core/commands/legacycfg.c: Use 32-bit Linux protocol on non-BIOS. - -2013-12-17 Vladimir Serbinenko - - Support cpuid --pae. - -2013-12-17 Vladimir Serbinenko - - Use AT keyboard on Yeeloong 3A. - -2013-12-17 Vladimir Serbinenko - - Add Yeeloong 3A reboot and halt. - -2013-12-17 Vladimir Serbinenko - - Add Radeon Yeeloong 3A support. - -2013-12-17 Vladimir Serbinenko - - Add bonito 3A support. - -2013-12-17 Vladimir Serbinenko - - * grub-core/loader/machoXX.c: Fix compilation on non-i386. - -2013-12-17 Vladimir Serbinenko - - * grub-core/loader/i386/xen_fileXX.c: Silence cast-align. - -2013-12-17 Vladimir Serbinenko - - * grub-core/loader/macho.c: Fix compilation on non-i386. - -2013-12-17 Vladimir Serbinenko - - Add missing format_arg attribute to check that printf with translated - messages has proper arguments. - -2013-12-17 Vladimir Serbinenko - - Use grub_xasprintf to format translated error messages containing - 64-bit quantity. - -2013-12-17 Jon McCune - - Fix double-free introduced by commit 33d02a42d64cf06cada1c389 - -2013-12-17 Vladimir Serbinenko - - Unify message for unsupported relocation. - -2013-12-17 Vladimir Serbinenko - - Mark miscompile error for translation. - -2013-12-17 Vladimir Serbinenko - - Use %I64 and not %ll when using OS printf if compiling for windows. - -2013-12-17 Vladimir Serbinenko - - Update Mac code to match new register_efi prototype. - -2013-12-17 Vladimir Serbinenko - - Implement better integration with Mac firmware. - -2013-12-17 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c: Implement special value for - load_addr. - -2013-12-17 Vladimir Serbinenko - - Include serial module in default_payload.elf. - -2013-12-17 Vladimir Serbinenko - - Add explicit thumb interwork bx in asm files. - - Shouldn't matter for armv >= 5 but let's be safe. - -2013-12-17 Vladimir Serbinenko - - Implement Truecrypt ISO loader. - -2013-12-17 Vladimir Serbinenko - - * grub-core/lib/arg.c: Ensure at least a single space between commands. - -2013-12-17 Vladimir Serbinenko - - Implement grub_file tool and use it to implement generating of config - in separate root. - -2013-12-17 Vladimir Serbinenko - - Change to v1 xen grants. - -2013-12-17 Vladimir Serbinenko - - * grub-core/lib/i386/xen/relocator.S: Fix hypercall ABI violation. - - GRUB relied on %ebx being preserved across hypercall which isn't true. - -2013-12-17 Vladimir Serbinenko - - * grub-core/lib/x86_64/xen/relocator.S: Fix hypercall ABI violation. - - GRUB relied on %rdi being preserved across hypercall which isn't true. - -2013-12-17 Vladimir Serbinenko - - Implement XEN VFB support. - -2013-12-17 Vladimir Serbinenko - - Remove grub_bios_interrupt on coreboot. - - It's not used currently and cannot be used safely currently. - -2013-12-16 Vladimir Serbinenko - - Update exclude.pot and mark few strings for translation. - -2013-12-16 Vladimir Serbinenko - - * util/grub-mkrescue.c: Fix incorrect file usage in fallback code. - - Reported by: Jon McCune - -2013-12-16 Andrey Borzenkov - - * grub-core/osdep/linux/platform.c (grub_install_get_default_x86_platform): - Add verbose information which firmware directories were tried. - -2013-12-16 Andrey Borzenkov - - * grub-core/osdep/unix/exec.c (grub_util_exec_redirect_all): New - function to optionally redirect all three standard descriptors. - Redefine grub_util_exec, grub_util_exec_redirect and - grub_util_exec_redirect_null to use it. - * include/grub/emu/exec.h: Define it. - * include/grub/osdep/exec_unix.h: Delete, it is unused. - * grub-core/osdep/linux/platform.c (grub_install_get_default_x86_platform): - Use grub_util_exec_redirect_all to redirect error to NULL. - -2013-12-16 Vladimir Serbinenko - - * grub-core/tests/sleep_test.c: Silence spurious warning. - -2013-12-16 Vladimir Serbinenko - - Make grub_xen_hypercall on i386 cdecl rather than stdcall to avoid - linker trying to "fixup" the code. - -2013-12-16 Vladimir Serbinenko - - * grub-core/kern/x86_64/xen/startup.S: Align stack. - -2013-12-16 Vladimir Serbinenko - - Add support for converting PE+ to Elf64. - -2013-12-16 Vladimir Serbinenko - - * grub-core/commands/minicmd.c (grub_mini_cmd_dump): Handle LLP case. - -2013-12-16 Vladimir Serbinenko - - Remove practice of assigning random const pointers to device id. - - This is not required as cache code already checks driver id as well. - -2013-12-16 Vladimir Serbinenko - - * include/grub/x86_64/types.h: Define sizeof (long) as 4 when compiling - with mingw. - -2013-12-16 Vladimir Serbinenko - - * include/grub/efi/api.h: Don't use call wrappers when compiled with - mingw or cygwin as API already matches. - -2013-12-16 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/errno.h: Undefine errno before redefining. - -2013-12-16 Vladimir Serbinenko - - * include/grub/efi/api.h: Define (u)intn_t based on pointer size and - not on long. - -2013-12-16 Vladimir Serbinenko - - Handle X86_64_PC64 relocation. - - Those are generated by some cygwin compilers. - -2013-12-16 Vladimir Serbinenko - - Determine the need for mingw-related stubs at compile time rather than - using not very significant $target_os. - -2013-12-16 Vladimir Serbinenko - - * grub-core/genmod.sh.in: Strip before converting to ELF as strip - may not work with ELF. - -2013-12-16 Vladimir Serbinenko - - Use unix functions for temporary files and special files on cygwin. - -2013-12-16 Vladimir Serbinenko - - Define functions explicitly rather than using --defsym in tests - whenever possible. Respect locality in remaining cases. - -2013-12-16 Vladimir Serbinenko - - * grub-core/genmoddep.awk: Remove explicit getline < /dev/stdin. - -2013-12-15 Andrey Borzenkov - - * grub-core/osdep/windows/platform.c (grub_install_register_efi): Handle - unlikely errors when getting EFI variables and make exhaustive search - for all BootNNNN variables to find matching one. - -2013-12-15 Ian Campbell - - * grub-core/kern/uboot/init.c: Fix units of uboot timer. - -2013-12-15 Vladimir Serbinenko - - New functional test for sleep function. - - This test allows to check sleep without qemu. Keep qemu version as - well as functional test won't notice if all clocks are going too fast - or too slow. - -2013-12-15 Vladimir Serbinenko - - Add explicit sysv_abi on amd64 asm routines. - -2013-12-15 Vladimir Serbinenko - - * grub-core/commands/efi/lsefisystab.c: Use %lld to show - num_table_entries. - -2013-12-15 Vladimir Serbinenko - - * include/grub/test.h: Use gnu_printf rather than printf on GRUB - functions. - -2013-12-15 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c: Use grub_addr_t rather than long when - appropriate. - -2013-12-15 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c: Use %p rather than %lx for pointers. - -2013-12-15 Vladimir Serbinenko - - * grub-core/kern/elfXX.c: Use grub_addr_t rather than long when - appropriate. - -2013-12-15 Vladimir Serbinenko - - * grub-core/disk/loopback.c: Use sequential IDs rather than pointer. - - In case of quick removal of loopback and adding another one it may - get same ID, confusing the cache system. - -2013-12-15 Vladimir Serbinenko - - * grub-core/commands/acpi.c: Use grub_addr_t rather than long when - appropriate. - -2013-12-15 Vladimir Serbinenko - - * grub-core/kern/i386/coreboot/cbtable.c: Use char * arithmetic rather - than converting to long. - -2013-12-15 Vladimir Serbinenko - - * grub-core/disk/cryptodisk.c: Rename "n" to "last_cryptodisk_id". - -2013-12-15 Vladimir Serbinenko - - * util/grub-mkimagexx.c (relocate_addresses): Display offset rather - than almost useless pointer. - -2013-12-15 Vladimir Serbinenko - - Add gcc_struct to all packed structures when compiling with mingw. - - Just "packed" doesn't always pack the way we expect. - -2013-12-14 Vladimir Serbinenko - - * include/grub/i386/coreboot/lbio.h: Add missing attribute (packed). - -2013-12-14 Vladimir Serbinenko - - * util/grub-pe2elf.c: Fix handling of .bss. - -2013-12-14 Vladimir Serbinenko - - Implement windows flavour of EFI install routines. - -2013-12-14 Vladimir Serbinenko - - * conf/Makefile.extra-dist: Adjust path to conf/i386-cygwin-img-ld.sc. - -2013-12-14 Vladimir Serbinenko - - Change grub_install_register_efi interface to pass GRUB device. - - This allows grub_install_register_efi to request partition info - directly. - -2013-12-14 Vladimir Serbinenko - - Workaround cygwin bug when using \\?\Volume{GUID} syntax. - -2013-12-14 Vladimir Serbinenko - - Do not use TCHAR string functions as they are not available on cygwin. - -2013-12-14 Vladimir Serbinenko - - Workaround windows bug when querying EFI system partition parameters. - -2013-12-14 Vladimir Serbinenko - - * grub-core/kern/i386/qemu/init.c (resource): Decrease struct size - by using bitfields. - -2013-12-14 Vladimir Serbinenko - - * grub-core/boot/i386/qemu/boot.S: Add missing EXT_C. - -2013-12-14 Vladimir Serbinenko - - Make i386-* other than i386-pc compileable under cygwin. - -2013-12-14 Vladimir Serbinenko - - Fix definition of grub_efi_hard_drive_device_path. Take care that - existing code would work even if by some reason bogus definition is - used by EFI implementations. - -2013-12-14 Vladimir Serbinenko - - * grub-core/osdep/windows/hostdisk.c: Fix cygwin compilation. - -2013-12-14 Vladimir Serbinenko - - * grub-core/osdep/windows/blocklist.c: Add missing cast in printf - invocation. - -2013-12-14 Vladimir Serbinenko - - * util/config.c: Remove trailing newline from distributor in simple - parsing. - -2013-12-14 Vladimir Serbinenko - - * include/grub/efi/api.h: Rename protocol and interface to avoid - conflict. - -2013-12-14 Vladimir Serbinenko - - * .gitignore: add .exe variants. add missing files. remove few outdated - entries. - -2013-12-14 Vladimir Serbinenko - - * grub-core/osdep/exec.c: Use unix version on cygwin. - -2013-12-13 Vladimir Serbinenko - - Implement multiboot2 EFI BS specification. - -2013-12-11 Vladimir Serbinenko - - * grub-core/normal/charset.c: Fix premature line wrap and crash. - Crash happened only in some cases like a string starting at the - half of the screen of same length. - -2013-12-11 Vladimir Serbinenko - - * include/grub/efiemu/efiemu.h: Sync configuration table declaration - with EFI counterpart. - -2013-12-11 Vladimir Serbinenko - - Propagate the EFI commits to x86-efi specific parts. - -2013-12-11 Vladimir Serbinenko - - * grub-core/commands/efi/lssal.c: Fix terminating condition. - -2013-12-11 Vladimir Serbinenko - - Introduce grub_efi_packed_guid and use it where alignment is not - guaranteed. - -2013-12-11 Vladimir Serbinenko - - * include/grub/efi/api.h (grub_efi_device_path): Define length as - unaligned u16 rather than u8[2]. - -2013-12-11 Vladimir Serbinenko - - * grub-core/kern/ia64/dl.c (grub_arch_dl_relocate_symbols): Add checks - for relocation range. - -2013-12-11 Vladimir Serbinenko - - * grub-core/kern/ia64/dl.c (grub_arch_dl_relocate_symbols): Handle - non-function pcrel21b relocation. It happens with .text.unlikely - section. - -2013-12-10 Leif Lindholm - - * make MAX_USABLE_ADDRESS platform-specific - * grub-core/kern/efi/mm.c: add Vladimir's new BYTES_TO_PAGES_DOWN macro. - -2013-12-10 Leif Lindholm - - * grub-core/lib/fdt.c: change memcpy => grub_memcpy - -2013-12-09 Jon McCune - - * Add --no-rs-codes flag to optionally disable reed-solomon codes - in grub-install and grub-bios-setup for x86 BIOS targets. - -2013-12-09 Vladimir Serbinenko - - Add missing compile and link options for sparc64-emu. - -2013-12-09 Vladimir Serbinenko - - Implement sparc64 trampolines (needed for sparc64-emu). - -2013-12-09 Vladimir Serbinenko - - * grub-core/kern/sparc64/dl.c (grub_arch_dl_relocate_symbols): Check - range of R_SPARC_HI22. - Implement R_SPARC_LM22. - -2013-12-09 Vladimir Serbinenko - - * grub-core/kern/powerpc/dl_helper.c (grub_arch_dl_get_tramp_got_size): - Do not explicitly check for symbol table as it's already checked in - platform-independent layer. - -2013-12-09 Vladimir Serbinenko - - * grub-core/kern/emu/cache.c [__ia64__]: Use our cache cleaning routine - on ia64 as __clear_cache is a dummy on ia64. - -2013-12-09 Vladimir Serbinenko - - * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): - Do not explicitly check for symbol table as it's already checked in - platform-independent layer. - -2013-12-09 Colin Watson - - * util/grub-mkconfig.in: Add missing newline to output. - -2013-12-08 Vladimir Serbinenko - - * grub-core/kern/ia64/efi/init.c (grub_arch_sync_caches): Move to ... - * grub-core/kern/ia64/cache.c (grub_arch_sync_caches): ... here. - -2013-12-08 Vladimir Serbinenko - - * grub-core/kern/emu/main.c: Silence missing prototypes to allow emu - compilation with GCC <= 4.2. - * grub-core/kern/emu/argp_common.c: Likewise. - -2013-12-08 Vladimir Serbinenko - - * include/grub/kernel.h [__sparc__]: Restrict sparc64-ieee1275 to - right platform rather than leaking to sparc64-emu. - -2013-12-08 Vladimir Serbinenko - - * grub-core/osdep/windows/emuconsole.c: Remove unsigned comparison >= 0. - But ensure that the variables in question are indeed unsigned. - -2013-12-08 Vladimir Serbinenko - - * grub-core/kern/emu/lite.c: Add missing include of ../ia64/dl_helper.c. - -2013-12-08 Vladimir Serbinenko - - Remove grub_memalign on emu. - -2013-12-08 Vladimir Serbinenko - - * grub-core/kern/ia64/efi/init.c: Fix alignment code so it doesn't - truncate incomplete lines but instead flushes them. - -2013-12-08 Vladimir Serbinenko - - Move OS-dependent mprotect for module loading to grub-core/osdep/*/dl.c - and implement windows variant. - -2013-12-08 Vladimir Serbinenko - - Fix mips-emu compilation. - -2013-12-08 Vladimir Serbinenko - - * configure.ac: Check for freetype library usability. - -2013-12-08 Vladimir Serbinenko - - Make arm-emu work. - -2013-12-07 Vladimir Serbinenko - - * util/grub-mkfont.c: Replace stpcpy with grub_stpcpy. - -2013-12-07 Andrey Borzenkov - - * docs/grub.texi (Environment): Update color_normal and color_highlight - defaults (light-gray instead of white). - -2013-12-07 Andrey Borzenkov - - * grub-core/normal/main.c (INIT): Set default color to light-gray - to match GRUB_TERM_DEFAULT_NORMAL_COLOR (i.e. rescue mode), Linux - and apparently BIOS defaults. - -2013-12-07 Vladimir Serbinenko - - Transform -C option to grub-mkstandalone to --core-compress available - in all grub-install flavours. - -2013-12-07 Vladimir Serbinenko - - Merge GRUBFS and GRUB_FS variables. - -2013-12-07 Andrey Borzenkov - - Revert commit 69ca97c820, it caused failures when using OS device name - in grub-install. Instead just strip off parenthesis in grub-install - if (hdX) was passed. - -2013-12-07 Andrey Borzenkov - - * util/grub-install.c (push_partmap_module): Add helper to convert - partmap names to module names and use it in probe_mods(). Fixes - failure to find partmap modules in diskfilter case. - -2013-12-07 Vladimir Serbinenko - - * configure.ac: Make unifont mandatory on coreboot. - -2013-12-07 Vladimir Serbinenko - - * configure.ac: Skip unifont 6.3 pcf and bdf. - -2013-12-07 Vladimir Serbinenko - - * Makefile.am: Remove partial font files if generation failed. - -2013-12-07 Andrey Borzenkov - - * util/misc.c (grub_qsort_strcmp): Add qsort helper function to sort - strings. - * include/grub/util/misc.h: Define it ... - * util/grub-install.c (device_map_check_duplicates): ... and use it. - -2013-12-07 Andrey Borzenkov - - * util/grub.d/30_os-prober.in: Fix use of grub-probe instead of - ${grub_probe}. - -2013-12-06 Vladimir Serbinenko - - Don't add -mlong-calls when compiling with clang. - -2013-12-06 Vladimir Serbinenko - - * configure.ac: Fix a typo. - -2013-12-06 Vladimir Serbinenko - - Revamp relocation handling. - - Move more code to common dl.c. Add missing veneers for arm and arm64. - Decreases kernel size by 70 bytes on i386-pc (40-50 compressed) - -2013-12-05 Vladimir Serbinenko - - * util/grub-mkimagexx.c: Fix reloc section generation for ia64. - -2013-12-05 Mike Gilbert - - * INSTALL: Raise minimum python version to 2.6. - * gentpl.py: Use python3-style print function. - -2013-12-05 Vladimir Serbinenko - - * util/grub-install.c: Mention Boot* variable. - -2013-12-05 Colin Watson - - * grub-core/osdep/linux/hostdisk.c - (grub_util_find_partition_start_os): Initialise start to avoid - spurious compiler warning. - -2013-12-05 Colin Watson - - On Linux, read partition start offsets from sysfs if possible, to - cope with block device drivers that don't implement HDIO_GETGEO. - Fixes Ubuntu bug #1237519. - - * grub-core/osdep/linux/hostdisk.c (sysfs_partition_path): New - function. - (sysfs_partition_start): Likewise. - (grub_util_find_partition_start_os): Try sysfs_partition_start - before HDIO_GETGEO. - -2013-12-05 Leif Lindholm - - * grub-core/kern/fdt.c: Update struct size when adding node. - -2013-12-05 Vladimir Serbinenko - - Handle unaligned .bss on sparc64. - - Current code improperly assumes that both __bss_start and _end are - aligned to 8-bytes. Eliminating this assumption and explicitly align - modules. - -2013-12-04 Vladimir Serbinenko - - * grub-core/boot/sparc64/ieee1275/boot.S [CDBOOT]: Move scratchpad - so it doesn't land in the middle of loaded image. - -2013-12-04 Vladimir Serbinenko - - * configure.ac: Move all warning options that may be absent in - gcc >= 3.1 to optional. - - Note: while this allows to compile with older GCC, official requirements - remain the same and no support for older GCC. - -2013-12-04 Colin Watson - - Copying the themes directory in grub-shell isn't - parallel-test-friendly and breaks on the second test when the source - directory is read-only (as in "make distcheck"). Instead, add a - hidden --themes-directory option to grub-mkrescue et al, and use it - in grub-shell. - -2013-12-04 Vladimir Serbinenko - - * conf/Makefile.common (CFLAGS_GNULIB): Remove -Wno-old-style-definition - as it's no longer necessarry. - -2013-12-04 Vladimir Serbinenko - - * configure.ac: Allow compilation with older GCC for ARM. - -2013-12-04 Vladimir Serbinenko - - * configure.ac: Add -no-integrated-as if {addme|ame} isn't supported. - * INSTALL: Note that GRUBwas successfully compiled with clang 3.2 for - ppc. - -2013-12-04 Vladimir Serbinenko - - * grub-core/kern/emu/main.c: Ignore missing prototype for main. - -2013-12-04 Vladimir Serbinenko - - Pass font config to config.h and not by TARGET_CFLAGS as adding - arguments doesn't work if TARGET_CFLAGS is specified on command - line. - -2013-12-04 Vladimir Serbinenko - - * configure.ac: Add -Wvla if compiler supports it. - -2013-12-04 Vladimir Serbinenko - - * grub-core/osdep/windows/emuconsole.c (grub_console_putchar): - Remove variable length arrays. - * grub-core/term/efi/console.c (grub_console_putchar): Likewise. - -2013-12-04 Vladimir Serbinenko - - * grub-core/kern/i386/qemu/init.c: Remove variable length arrays. - -2013-12-04 Vladimir Serbinenko - - * include/grub/types.h: Declare all byteswaps as inline functions - except compile-time ones. - - Solves variable shadowing in constructions like - cpu_to_le (le_to_cpu(x) + 1). - -2013-12-04 Vladimir Serbinenko - - * grub-core/kern/efi/efi.c: Remove variable length arrays. - -2013-12-04 Vladimir Serbinenko - - * grub-core/kern/uboot/init.c (uboot_timer_ms): Fix overflow after 71 - minutes. - -2013-12-04 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c: Remove variable length arrays. - * grub-core/net/drivers/ieee1275/ofnet.c: Likewise. - -2013-12-03 Colin Watson - - * grub-core/Makefile.core.def (setjmp): Distribute - lib/arm64/setjmp.S. - -2013-12-03 Colin Watson - - Add a new timeout_style environment variable and a corresponding - GRUB_TIMEOUT_STYLE configuration key for grub-mkconfig. This - controls hidden-timeout handling more simply than the previous - arrangements, and pressing any hotkeys associated with menu entries - during the hidden timeout will now boot the corresponding menu entry - immediately. - - GRUB_HIDDEN_TIMEOUT= + GRUB_TIMEOUT= now - generates a warning, and if it shows the menu it will do so as if - the second timeout were not present. Other combinations are - translated into reasonable equivalents. - - Based loosely on work by Franz Hsieh. Fixes Ubuntu bug #1178618. - -2013-12-02 Vladimir Serbinenko - - * util/config.c: Add missing pointer adjustment. - Reported by: qwertial - -2013-11-30 Andrey Borzenkov - - * grub-core/kern/arm64/dl_helper.c: Include grub/arm64/reloc.h - directly, not via `cpu' link, to fix libgrub.pp generation. - -2013-11-30 Leif Lindholm - - New port arm64-efi. - -2013-11-30 Andrey Borzenkov - - * docs/grub.texi (sleep): Document exit codes. - -2013-11-30 Vladimir Serbinenko - - Ensure that -mno-unaligned-access or some equivalent option is used. - -2013-11-30 Vladimir Serbinenko - - * grub-core/lib/libgcrypt/mpi/longlong.h: Fix compilation error with - -march=armv3. - -2013-11-30 Vladimir Serbinenko - - Remove leftover GRUB_IA64_DL_TRAMP_SIZE. - -2013-11-29 Colin Watson - - * docs/grub-dev.texi (Font Metrics): Exclude @image command from DVI - builds, since we don't have an EPS version of font_char_metrics.png. - Add leading dot to image extension per the Texinfo documentation. - -2013-11-29 Colin Watson - - * util/grub-gen-asciih.c: Include FT_SYNTHESIS_H rather than - , fixing build with FreeType 2.5.1. - * util/grub-gen-widthspec.c: Likewise. - * util/grub-mkfont.c: Likewise. - -2013-11-29 Andrey Borzenkov - - * util/grub-setup.c (main): Move parsing of (hdX) syntax to ... - * util/setup.c (SETUP): ... here. Fixes regression: grub-install - failed to install on (hdX). - * util/grub-setup.c (get_device_name): Remove, not needed after - above change. - -2013-11-29 Vladimir Serbinenko - - * grub-core/kern/emu/hostfs.c (is_dir): Remove variable length arrays. - -2013-11-29 Vladimir Serbinenko - - * util/grub-fstest.c: Remove variable length arrays. - -2013-11-29 Vladimir Serbinenko - - * grub-core/osdep/linux/ofpath.c: Check return value of read. - -2013-11-29 Vladimir Serbinenko - - * util/mkimage.c (grub_install_generate_image): Use grub_crypto_hash for - computing crc32 rather than handling with md fundtions directly. - -2013-11-29 Vladimir Serbinenko - - * util/mkimage.c (grub_install_generate_image): Use grub_crypto_hash for - checking fwstart.img rather than md fundtions directly. - -2013-11-29 Vladimir Serbinenko - - * util/grub-mkrescue.c (main): Check that fread succeeded. - -2013-11-29 Vladimir Serbinenko - - * conf/Makefile.common: Remove -mexplicit-relocs and - -DUSE_ASCII_FALLBACK on yeeloong. - - -DUSE_ASCII_FALLBACK is already added by font snippets. - -mexplicit-relocs isn't needed is compiler/assemblera are - configured properly. - If they're not we shouldn't attempt to fix it by ourselves. - Binary compare between before and after shows no difference. - -2013-11-29 Vladimir Serbinenko - - * grub-core/Makefile.core.def: Remove libgnulib.a and use its - sources in dependencies directly. - - This was the only instance of "library" in core config. A bug was - reported that -fno-stack-protector wasn't passed to it. Instead of - figuring out why it failed just remove this construction used - needlessly. - -2013-11-29 Vladimir Serbinenko - - * grub-core/osdep/unix/password.c (grub_password_get): Check that - fgets succeeded. - -2013-11-27 Francesco Lavra - - * docs/grub.texi (ls): Fix command description in case of a device name - passed as argument. - -2013-11-27 Vladimir Serbinenko - - Eliminate variable length arrays in grub_vsnprintf_real. - - A bit tricky because this function has to continue to work without - heap for short strings. Fixing prealloc to 32 arguments is reasonable - but make all stack references use 32-bit offset rather than 8-bit one. - So split va_args preparsing to separate function and put the prealloc - into the caller. - -2013-11-27 Vladimir Serbinenko - - Introduce grub_util_file_sync and use it instead of fsync(fileno(f)). - Fixes build for windows. - -2013-11-27 Vladimir Serbinenko - - * gentpl.py: Don't generate platform-dependent conditionals for - platform-independent targets. - -2013-11-27 Colin Watson - - * grub-core/osdep/unix/exec.c (grub_util_exec_redirect): Remove - references to mdadm from otherwise generic code. - (grub_util_exec_pipe): Likewise. - (grub_util_exec_pipe_stderr): Likewise. - * grub-core/osdep/unix/getroot.c (grub_util_pull_lvm_by_command): - This function calls vgs, not mdadm; adjust variable names - accordingly. - -2013-11-27 Colin Watson - - Generate Makefile.*.am directly from gentpl.py, eliminating the use - of Autogen. The Autogen definitions files remain intact as they - offer a useful abstraction. - -2013-11-27 Colin Watson - - Add grub_util_disable_fd_syncs call to turn grub_util_fd_sync calls - into no-ops, and use it in programs that copy files but do not need - to take special care to sync writes (grub-mknetdir, grub-rescue, - grub-mkstandalone). - -2013-11-26 Colin Watson - - * tests/util/grub-fs-tester.in: Execute xorriso from $PATH rather - than hardcoding /usr/local/bin/xorriso. - -2013-11-26 Vladimir Serbinenko - - Add PCI command activation to all PCI drivers as required for coreboot - and maybe some other firmwares. - -2013-11-26 Vladimir Serbinenko - - * grub-core/Makefile.am: Reduce gratuituous differences between Apple - and non-Apple variants of efiemu compile. - -2013-11-25 Andrey Borzenkov - - * configure.ac: Add explicit check for linking format of - efiemu64; save it as EFIEMU64_LINK_FORMAT. - * grub-core/Makefile.am: Use EFIEMU64_LINK_FORMAT instead of - hardcoding linking format. - -2013-11-25 Vladimir Serbinenko - - * util/grub-mknetdir.c: Look for platform directories under pkglibdir - and not pkgdatadir. - -2013-11-25 Colin Watson -2013-11-25 Vladimir Serbinenko - - Add a --locale-directory option to grub-install and related tools. - - * include/grub/util/install.h (GRUB_INSTALL_OPTIONS): Add - --locale-directory option. - (enum grub_install_options): Add - GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY. - * util/grub-install-common.c (grub_install_help_filter): Handle - GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY. - (grub_install_parse): Likewise. - (get_localedir): New function to check for a user-provided option - before trying grub_util_get_localedir. - (copy_locales): Use get_localedir rather than - grub_util_get_localedir. Handle differing locale directory layouts. - (grub_install_copy_files): Likewise. - -2013-11-25 Vladimir Serbinenko - - * grub-core/osdep/unix/platform.c (get_ofpathname): Trim ending newline. - Don't rely on PATH_MAX. - -2013-11-25 Vladimir Serbinenko - - * grub-core/genmoddep.awk: Use more portable && rather than and. - -2013-11-24 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S [__APPLE__]: Create _edata by placing - an object after data. While it doesn't seem right solution, it - works well enough and OSX isn't main compilation platform. - -2013-11-24 Vladimir Serbinenko - - * gentpl.py: Add -ed2016 in order to make objconv accept our binary. - While it doesn't seem right solution, it works well enough and - OSX isn't main compilation platform. - -2013-11-24 Vladimir Serbinenko - - * configure.ac: Add -static to LDFLAGS when using apple linker to - prevent it from pulling in dynamic linker. - -2013-11-24 Vladimir Serbinenko - - Apple assembly doesn't handle symbol arithmetic well. So define an - offset symbol in boot.S and use it. - -2013-11-24 Vladimir Serbinenko - - Apple assembly doesn't handle symbol arithmetic well. So instead - of getting addres of kernel_sector + 4 define kernel_sector_high. - It also makes code more readable. - -2013-11-24 Vladimir Serbinenko - - With Apple assembly in .macro environvemnt you have to use $$ instead - of $. So introduce new preprocessor macro MACRO_DOLLAR(x) which expands - to $$x on Apple and to $x on everything else. - -2013-11-24 Vladimir Serbinenko - - * grub-core/Makefile.am: Use correct TARGET_OBJCONV rather than - OBJCONV. - -2013-11-24 Vladimir Serbinenko - - * grub-core/gdb/i386/machdep.S: Use xorl %eax, %eax on both Apple - and non-Apple. This instruction is shorter and faster, - so no reason not to use it on both. - -2013-11-24 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c: Use section _text, _text rather than - .text when compiling for Apple. - -2013-11-24 Vladimir Serbinenko - - * grub-core/term/arc/console.c: Add missing cast to silence warning. - -2013-11-24 Vladimir Serbinenko - - * grub-core/boot/i386/pc/boot.S: Fix floppy probe. Due to missing - %dx restore the probe worked on non-existant drive. Reorganize the - code a little bit to free 2 bytes necessary for push/pop. - -2013-11-23 Vladimir Serbinenko - - * grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation): - Add missing cast to silence warning. - -2013-11-23 Keshav Padram Amburay - - * util/grub-install.c (update_nvram): Support --no-nvram flag - for EFI targets. - -2013-11-23 Vladimir Serbinenko - - * INSTALL: Add note about sparc64/ia64 with clang (unsupported). - -2013-11-23 Vladimir Serbinenko - - * util/garbage-gen.c: Add missing include of sys/time.h. - -2013-11-23 Vladimir Serbinenko - - Don't add -mflush-func if it's not supported by compiler. - -2013-11-23 Vladimir Serbinenko - - Move common BIOS/coreboot memory map declarations to - include/grub/i386/memory_raw.h and eliminate duplicate declarations. - -2013-11-22 Andrey Borzenkov - - * Makefile.am: Add util/garbage-gen.c to EXTRA_DIST. - -2013-11-22 Vladimir Serbinenko - - * INSTALL: Document why older clang versions aren't appropriate. - -2013-11-22 Vladimir Serbinenko - - * INSTALL: Document about clang for mips. - -2013-11-22 Vladimir Serbinenko - - * grub-core/lib/libgcrypt/mpi/longlong.h: Use C version with mips - clang. - -2013-11-22 Vladimir Serbinenko - - Add *-xen to the list of grub-install-common platforms. - -2013-11-22 Vladimir Serbinenko - - * configure.ac: Do not enforce -mcmodel=large. It's not necessarry with - 3 last commits. - -2013-11-22 Vladimir Serbinenko - - * grub-core/kern/xen/init.c: Do not map more pages than we can address. - -2013-11-22 Vladimir Serbinenko - - * grub-core/kern/efi/mm.c: Limit allocations to 2GiB when not compiling - with -mcmodel=large. - -2013-11-22 Vladimir Serbinenko - - * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Add - range-checking for 32-bit quantities. - -2013-11-22 Vladimir Serbinenko - - * configure.ac: Compile with -fPIC when compiling with clang on - mips. - -2013-11-22 Vladimir Serbinenko - - * configure.ac: Add -no-integrated-as on mips(el) to TARGET_CCASFLAGS - when compiling with clang. - -2013-11-22 Vladimir Serbinenko - - clang emits calls to abort () under some unknown conditions. - Export abort () when compiling with clang. - -2013-11-22 Vladimir Serbinenko - - * docs/grub-dev.texi: Document stack and heap sizes. - -2013-11-22 Vladimir Serbinenko - - * include/grub/i386/pc/memory.h: Decrease - GRUB_MEMORY_MACHINE_SCRATCH_SIZE and increase - GRUB_MEMORY_MACHINE_PROT_STACK_SIZE. - The binary doesn't change (checked). It's more to better reflect actual - usage. - -2013-11-22 Vladimir Serbinenko - - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_open): Ensure - at compile time that enough of scratch size is available. - -2013-11-22 Vladimir Serbinenko - - * grub-core/kern/x86_64/efi/callwrap.S: Fix stack alignment. - Previously we misaligned stack by 8 in startup.S and compensated - for it in callwrap.S. According to ABI docs (EFI and sysv amd64) - right behaviour is to align stack in startup.S and keep it aligned - in callwrap.S. startup.S part was committed few commits before. This - takes care of callwrap.S. - Reported by: Gary Lin. - -2013-11-22 Vladimir Serbinenko - - * grub-core/boot/mips/startup_raw.S: Handle the case of gap between - .data and .bss. May happen if compiler and assembly use different - alignment. - -2013-11-22 Vladimir Serbinenko - - On MIPS handle got16 relocations to local symbols in an ABI-compliant - way. - -2013-11-22 Vladimir Serbinenko - - Add support for a new magic symbol _gp_disp on mips to handle PIC - binaries. - -2013-11-22 Vladimir Serbinenko - - Use $t9 for indirect calls from asm to C as PIC ABI requires. - -2013-11-22 Vladimir Serbinenko - - Remove -march=mips3 from TARGET_CCASFLAGS as it creates linking problem - when rest of GRUB is compiled for hisher stepping. Instead use - .set mips3/.set mips1 around cache and sync opcodes. - -2013-11-21 Vladimir Serbinenko - - Unify GOT/trampoline handling between PPC, MIPS and IA64 as they - do essentially the same thing, do it in similar way. - -2013-11-21 Colin Watson - - * util/grub-mkrescue.c (main): If a source directory is not - specified, read platform-specific files from subdirectories of - pkglibdir, not pkgdatadir. - -2013-11-21 Colin Watson - - * grub-core/normal/progress.c: Remove unused file. - -2013-11-20 Vladimir Serbinenko - - * grub-core/lib/crypto.c (grub_crypto_hash): Remove variable length - array. - -2013-11-20 Vladimir Serbinenko - - * util/grub-mkconfig.in: Say explicit "grub configuration" rather - than grub.cfg. - -2013-11-20 Vladimir Serbinenko - - * coreboot.cfg: Add missing file. - -2013-11-19 Vladimir Serbinenko - - * Makefile.am: Allow STRIP to be empty when creating windowszip. - -2013-11-19 Axel Kellermann - - * util/grub.d/30_os-prober.in: Add GRUB_OS_PROBER_SKIP_LIST to - selectively skipping systems. - -2013-11-19 Colin Watson - - * Makefile.util.def (grub-mkimage): Add - grub-core/osdep/aros/config.c to extra_dist. - * conf/Makefile.extra-dist (EXTRA_DIST): Add docs/autoiso.cfg, - docs/osdetect.cfg, grub-core/gnulib-fix-null-deref.diff, - grub-core/gnulib-fix-width.diff, grub-core/gnulib-no-abort.diff, and - grub-core/gnulib-no-gets.diff. - -2013-11-19 Vladimir Serbinenko - - Add automated filesystem checking based on scripts I've used now for - quite some time locally. Most of the test require root so they are - skipped when run without necessarry privelegies. - -2013-11-19 Colin Watson - - * util/grub-install.c (main): Adjust info messages to match - installed paths of grub-bios-setup and grub-sparc64-setup. - -2013-11-19 Colin Watson - - * util/grub-install-common.c (copy_locales): Consistently use - grub_util_get_localedir () rather than LOCALEDIR. - (grub_install_copy_files): Likewise. - -2013-11-19 Josh Triplett - - * grub-core/kern/x86_64/efi/startup.S (_start): Align the stack to a - 16-byte boundary, as required by the x86-64 ABI, before calling - grub_main. In some cases, GCC emits code that assumes this - alignment, which crashes if not aligned. The EFI firmware is also - entitled to assume that stack alignment without checking. - -2013-11-18 Josh Triplett - - * grub-core/mmap/efi/mmap.c (grub_mmap_register): Round up/down to - 4k page boundaries as expected by firmware rather than 1k - boundaries. - (grub_mmap_malign_and_register): Likewise. - -2013-11-18 Vladimir Serbinenko - - * tests/grub_func_test.in: Decrease RAM size to 512M. With less - fragmentation 512M is enough. - -2013-11-18 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_real_malloc): Decrease cut-off of moving the - pointer to 32K. This is the size of cache element which is the most - common allocation >1K. This way the pointer is always around blocks - of 32K and so we keep performance while decreasing fragmentation. - -2013-11-18 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_real_malloc): Don't update the pointer to - current memory when allocating large chunks. This significantly - decreases memory fragmentation. - -2013-11-18 Colin Watson - - * tests/gzcompress_test.in: Skip if gzip is not installed (unlikely, - but for symmetry). - * tests/lzocompress_test.in: Skip if lzop is not installed. - * tests/xzcompress_test.in: Skip if xz is not installed. - -2013-11-18 Colin Watson - - * util/grub-mkrescue.c (main): Fix typo. - -2013-11-18 Vladimir Serbinenko - - * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Update - clock frequency to 200 MHz, - -2013-11-18 Vladimir Serbinenko - - * tests/util/grub-shell.in: Increase console size to 1024x1024. - -2013-11-18 Vladimir Serbinenko - - * Makefile.am (default_payload.elf): Add pata to loaded modules. - Load config file from (cbfsdisk)/etc/grub.cfg. - -2013-11-18 Vladimir Serbinenko - - * util/grub-install-common.c (grub_install_copy_files): Fix module - destination directory. - -2013-11-18 Colin Watson - - * tests/util/grub-shell.in: Don't fail on emu platform if po/*.gmo - files have not been built. - -2013-11-18 Colin Watson - - * grub-core/osdep/unix/hostdisk.c (grub_util_make_temporary_file): - Handle errors from mkstemp. - (grub_util_make_temporary_dir): Handle errors from mkdtemp. - -2013-11-18 Vladimir Serbinenko - - * tests/util/grub-shell.in: Use -cdrom and don't force cdrom - on primary master on pseries. - -2013-11-18 Vladimir Serbinenko - - * grub-core/tests/videotest_checksum.c: Don't reload unifont if it's - already loaded. This saves memory needed for tests, - -2013-11-18 Vladimir Serbinenko - - * util/grub-mkrescue.c (main): Fix a typo to make yeeloong part - work again. - -2013-11-18 Vladimir Serbinenko - - * grub-core/term/terminfo.c (grub_cmd_terminfo): Fix a typo to make -g - work again. - -2013-11-18 Vladimir Serbinenko - - * tests/util/grub-shell.in: For powerpc tests put the CD-ROM as primary - master since with some combinations of qemu and firmware only primary - IDE channel is available. - -2013-11-18 Vladimir Serbinenko - - * grub-core/tests/gfxterm_menu.c: Skip high-resolution tests on - low-memory platforms where we don't have enough memory for them. - * grub-core/tests/videotest_checksum.c: Likewise. - -2013-11-18 Vladimir Serbinenko - - * grub-core/tests/cmdline_cat_test.c: Don't reload unifont if it's - already loaded. This saves memory needed for tests, - -2013-11-18 Vladimir Serbinenko - - Fix handling of install lists. - -2013-11-18 Vladimir Serbinenko - - * grub-core/lib/sparc64/setjmp.S: Force spilling of current window. - -2013-11-18 Vladimir Serbinenko - - On i386-ieee1275 we run in paged mode. So we need to explicitly map - the devices before accessing them. - -2013-11-18 Vladimir Serbinenko - - * grub-core/lib/relocator.c (grub_mm_check_real): Accept const char * - as file argument. - -2013-11-18 Vladimir Serbinenko - - * grub-core/normal/cmdline.c (grub_cmdline_get): Plug memory leak. - -2013-11-18 Vladimir Serbinenko - - * grub-core/kern/file.c (grub_file_open): Free file->name on failure. - (grub_file_close): Free file->name. - -2013-11-18 Vladimir Serbinenko - - * grub-core/commands/verify.c (free_pk): Plug memory leak. - (grub_load_public_key): Likewise. - (grub_verify_signature_real): Likewise. - (grub_cmd_verify_signature): Likewise. - -2013-11-18 Vladimir Serbinenko - - * grub-core/commands/legacycfg.c (grub_legacy_check_md5_password): Plug - memory leak. - -2013-11-18 Vladimir Serbinenko - - * grub-core/lib/powerpc/setjmp.S (grub_setjmp): Save r31. - (grub_longjmp): Restore r31. - * include/grub/powerpc/setjmp.h (grub_jmp_buf): Reserve space for r31. - -2013-11-18 Vladimir Serbinenko - - * util/grub-mkrescue.c (make_image_fwdisk_abs): Insert all partmap - modules to be in line with make_image_abs. - -2013-11-18 Vladimir Serbinenko - - * include/grub/mips/setjmp.h (grub_jmp_buf): Fix buffer size. - - setjmp.S uses 12 entries but buffer is declared with only 11 entries. - -2013-11-17 Ian Campbell - - * grub-core/disk/uboot/ubootdisk.c: Include SCSI disks. - -2013-11-17 Vladimir Serbinenko - - * tests/grub_func_test.in: Increase memory reservation as on EFI we need - to leave some memory to firmware. - -2013-11-17 Vladimir Serbinenko - - * grub-core/tests/cmdline_cat_test.c (cmdline_cat_test): Ignore errors - of loading gfxterm as gfxterm is embed in kernel on some platforms. - * grub-core/tests/gfxterm_menu.c (gfxterm_menu): Likewise. - Load gfxmenu. - -2013-11-17 Vladimir Serbinenko - - * tests/core_compress_test.in: Use full arguments as grub-mkimage-extra - now needs full arguments. - -2013-11-17 Vladimir Serbinenko - - * util/grub-mkrescue.c (main): Add trailing \n in - .disk_label.contentDetails to be in line with previous shell script. - -2013-11-17 Vladimir Serbinenko - - * util/grub-mkrescue.c (main): Use right source file for bootinfo.txt. - -2013-11-17 Vladimir Serbinenko - - * util/grub-install-common.c (grub_install_parse): Recognize - --compress=none like shell script did. - -2013-11-17 Vladimir Serbinenko - - * include/grub/misc.h: Replace check for __sparc64__ with one for - __sparc__ as __sparc64__ isn't actually defined. - -2013-11-17 Vladimir Serbinenko - - * tests/util/grub-shell.in: Use escc-ch-b on powerpc. This is missing - counterpart of fixing the naming of escc ports. - -2013-11-17 Vladimir Serbinenko - - * util/grub-install-common.c (platforms): Fix the order of entries and - remove useless field val. - -2013-11-16 Vladimir Serbinenko - - * util/grub-install.c: Add new option --no-bootsector to skip - installing of bootsector. Accept --grub-setup=/bin/true as - backwards-compatible synonym. - -2013-11-16 Andrey Borzenkov - - * util/grub-install.c (device_map_check_duplicates): Fix incorrect - order of qsort arguments (number of elements vs. element size). - -2013-11-16 Vladimir Serbinenko - - Rewrite grub-install, grub-mkrescue, grub-mkstandalone and grub-mknetdir - the function of these files exceeds what can be sanely handled in shell - in posix-comaptible way. Also writing it in C extends the functionality - to non-UNIX-like OS and minimal environments. - -2013-11-16 Vladimir Serbinenko - - * grub-core/kern/arm/cache.S: Don't switch back to ARM mode when - compiling to thumb2. - * grub-core/kern/arm/cache_armv7.S: Likewise. - * grub-core/lib/arm/setjmp.S: Likewise. - -2013-11-16 Leif Lindholm - - * grub-core/kern/arm/uboot/startup.S: delete superflouous save of r8 - in grub_uboot_syscall - -2013-11-16 Vladimir Serbinenko - - Decrease stack usage in lexer. - - We have only 92K of stack and using over 4K per frame is wasteful - - * grub-core/script/yylex.l (yyalloc), (yyfree), (yyrealloc): Declare - as macros so that compiler would remove useless structure on stack. - Better solution would be to fix flex not to put this structure on - the stack but flex is external program. - -2013-11-16 Vladimir Serbinenko - - Decrease stack usage in signature verification. - - We have only 92K of stack and using over 4K per frame is wasteful - - * grub-core/commands/verify.c (grub_load_public_key): Allocate on heap - rather than stack. - (grub_verify_signature_real): Likewise. - -2013-11-16 Vladimir Serbinenko - - Decrease stack usage in mdraid 0.9x. - - We have only 92K of stack and using over 4K per frame is wasteful - - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Allocate on heap - rather than stack. - -2013-11-16 Vladimir Serbinenko - - Decrease stack usage in BtrFS. - - We have only 92K of stack and using over 4K per frame is wasteful - - * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Allocate on heap - rather than stack. - -2013-11-16 Vladimir Serbinenko - - Decrease stack usage in JFS. - - We have only 92K of stack and using over 4K per frame is wasteful - - * grub-core/fs/jfs.c (getblk): Allocate on heap rather than on - stack. Note: this function is recursive. - (grub_jfs_read_inode): Read only part we care about. - -2013-11-16 Leif Lindholm - - * grub-core/kern/arm/uboot/startup.S: fix grub_uboot_syscall va_arg - handling - -2013-11-16 Andrey Borzenkov - - * configure.ac: Restore -nostdlib for libgcc symbols tests. - -2013-11-16 Andrey Borzenkov - - * docs/grub.texi (Environment): Document cmdpath. - -2013-11-16 Andrey Borzenkov - - * grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation): - Remove "unused" attribute from arguments, they are used. - -2013-11-15 Colin Watson - - * .gitignore: Only ignore grub-mk* at the top level. - -2013-11-15 Colin Watson - - * util/grub-reboot.in (usage): Fix a typo. - -2013-11-15 Vladimir Serbinenko - - Replace libgcc version of ctz with our own. - - On upcoming arm64 port libgcc ctz* are not usable in standalone - environment. Since we need ctz* for this case and implementation is - in C we may as well use it on all concerned platforms. - -2013-11-14 Vladimir Serbinenko - - * configure.ac: Probe for linking format rather than guessing it based - on target_os. - -2013-11-14 Vladimir Serbinenko - - * grub-core/disk/xen/xendisk.c (grub_xendisk_fini): Set state to - "1" prior to handoff. - - Reported by: M A Young. - -2013-11-14 Vladimir Serbinenko - - * grub-core/kern/xen/init.c (grub_xenstore_write_file): Don't add - \0 to all files. - - Reported by: M A Young. - -2013-11-14 Vladimir Serbinenko - - * grub-core/osdep/bsd/hostdisk.c (grub_util_get_fd_size_os): Fix - compilation on NetBSD. - -2013-11-14 Vladimir Serbinenko - - * acinclude.m4: Don't add -P on initial nm test. - - Note: even though this patch postdates Andrey's it bears 14 Nov as - date due to timezone difference. - -2013-11-15 Andrey Borzenkov - - * grub-core/Makefile.core.def (signature_test): Add missing - tests/signatures.h. - -2013-11-14 Colin Watson - - * util/grub-install_header: Set localedir here, since this file is - where it's used. - * util/grub-install.in: Remove setting of localedir. - * util/grub-mkrescue.in: Likewise. - -2013-11-14 Vladimir Serbinenko - - * Makefile.am (default_payload.elf): Add uhci, ohci and usb_keyboard. - -2013-11-14 Vladimir Serbinenko - - * configure.ac: Move nm checks to the end. - Call grub_PROG_NM_WORKS. - * acinclude.m4: New check grub_PROG_NM_WORKS. - Use $TARGET_CFLAGS -c when compiling test binary. - -2013-11-14 Colin Watson - - * util/getroot.c (grub_util_biosdisk_get_grub_dev) [__GNU__]: Remove - unused variables. - -2013-11-14 Matthew Garrett - - * grub-core/kern/main.c (grub_set_prefix_and_root): Set variable - cmdpath to firmware directory. - -2013-11-14 Vladimir Serbinenko - - * grub-core/kern/efi/efi.c (grub_efi_get_filename): Reset the pointer - at the start of second iteration. - -2013-11-14 Vladimir Serbinenko - - * grub-core/Makefile.am (efiemu64.o): Explicitly set link format. - -2013-11-14 Vladimir Serbinenko - - * Makefile.am (default_payload.elf): New target for easier coreboot - build. - -2013-11-14 Vladimir Serbinenko - - * grub-core/kern/arm/cache_armv6.S: Remove special handling for - clang (not necessarry with -no-integrated-as). - * include/grub/symbol.h [__arm__]: Likewise. - -2013-11-14 Vladimir Serbinenko - - * configure.ac: Use -no-integrated-as on arm with clang. - * INSTALL: Mention ARM compilation with clang. - -2013-11-14 Vladimir Serbinenko - - * conf/Makefile.common (CCASFLAGS_PLATFORM) [COND_arm]: Add - -mthumb-interwork. - -2013-11-14 Colin Watson - - * grub-core/fs/ext2.c (grub_ext2_read_block): Factor out common - code for indirect block handling. - - Saves 185 bytes on compressed image. - -2013-11-13 Paulo Flabiano Smorigo - - Fix make clean. - - * Makefile.am: Remove build-grub-* in make clean. - -2013-11-13 Paulo Flabiano Smorigo - - New files to gitignore. - - * .gitignore: Add build-grub-gen-asciih, build-grub-gen-widthspec, - build-grub-mkfont, and grub-emu-lite. Remove .bzrignore. - -2013-11-13 Leif Lindholm - - * grub-core/kern/arm/misc.S: Make thumb2-compatible. - -2013-11-13 Leif Lindholm - - * .gitignore: fix rules for .dep* and add *.a post git migration - -2013-11-13 Colin Watson - - * configure.ac (AM_INIT_AUTOMAKE): Require at least version 1.10.1, - to match INSTALL. - -2013-11-13 Colin Watson - - * grub-core/kern/misc.c: Don't redirect divisions in the - GRUB_UTIL case. - * include/grub/misc.h: Likewise. - -2013-11-13 Colin Watson - - * grub-core/osdep/unix/emuconsole.c (put): Pacify the compiler on - systems that require checking the return value of write. - -2013-11-13 Colin Watson - - * util/grub-install.in (efi_quiet): Fix inverted logic: make - efibootmgr quiet when --debug is not used, rather than when it is. - -2013-11-13 Colin Watson - - * gentpl.py (define_macro_for_platform_dependencies): Remove - first (and thus unused) of two definitions for this function. - (platform_dependencies): Likewise. - -2013-11-13 Colin Watson - - * acinclude.m4 (grub_apple_cc): Remove; since the removal of nested - functions, we only need to check this for the target, not the host. - * configure.ac (grub_apple_cc): Likewise. - -2013-11-13 Vladimir Serbinenko - - * grub-core/kern/arm/cache.c (probe_caches): Move asm part to ... - * grub-core/kern/arm/cache_armv6.S: ... here. This allows this - asm to stay in arm even if surrounding is thumb. - -2013-11-13 Vladimir Serbinenko - - * grub-core/kern/arm/misc.S: Add __muldi3 and __aeabi_lmul. Those - helper functions are needed for thumb. - -2013-11-13 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_make_raid): Make - level / 3 division explicitly unsigned. Saves few bytes. - -2013-11-13 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (ZAP_LEAF_NUMCHUNKS): Use unsigned arithmetics. - -2013-11-13 Vladimir Serbinenko - - * grub-core/normal/datetime.c (grub_get_weekday): Use if rather than - division. - -2013-11-13 Vladimir Serbinenko - - * grub-core/kern/uboot/init.c: Move grub_uboot_machine_type and - grub_uboot_boot_data to asm part. - -2013-11-13 Vladimir Serbinenko - - * grub-core/kern/arm/uboot/startup.S: Remove = by replacing with - literal load. - (grub_uboot_syscall): Save/restore r9 and align stack. - -2013-11-13 Vladimir Serbinenko - - * grub-core/kern/arm/cache.S: Replace = with explicit litteral load. - -2013-11-13 Vladimir Serbinenko - - * include/grub/symbol.h (END) [__arm__]: New macros. Replace all .end - occurencies with END. - -2013-11-13 Colin Watson - - * util/grub-editenv.c (help_filter, argp): Document how to delete - the whole environment block. - Reported by Dan Jacobson. Fixes Debian bug #726265. - -2013-11-13 Colin Watson - - * docs/grub.texi (Internationalisation, Supported kernels): Fix - sectioning. - -2013-11-13 Josh Triplett - - * grub-core/normal/term.c (grub_set_more): Use bool logic rather than - increment/decrement. - -2013-11-13 Vladimir Serbinenko - - * grub-core/kern/arm/cache_armv6.S [__clang__]: Don't add .armv6 when - compiling with clang. - -2013-11-13 Vladimir Serbinenko - - * grub-core/kern/arm/uboot/startup.S: Use .org rather than assigning - ".". - -2013-11-13 Vladimir Serbinenko - - Redirect all divisions to grub_divmod64. - -2013-11-12 Vladimir Serbinenko - - * grub-core/term/tparm.c (tparam_internal): Use unsigned divisions. - -2013-11-12 Vladimir Serbinenko - - Add missing includes of loader.h. - -2013-11-12 Vladimir Serbinenko - - * configure.ac: Allow disabling themes. - -2013-11-12 Lukas Schwaighofer - - * util/grub.d/20_linux_xen.in: Don't decompress initrd. - -2013-11-12 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c: Don't poll non-functional AT controller - until it becomes operational. - -2013-11-12 Vladimir Serbinenko - - * grub-core/Makefile.core.def (legacy_password_test): Disable - on platforms where no legacycfg is compiled. - * grub-core/tests/lib/functional_test.c: Tolerate failure to - load legacy_password_test. - -2013-11-12 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/efiemu/prepare.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/osdep/windows/hostdisk.c (grub_util_fd_strerror): Silence - strict-aliasing warning. - (fsync): Silence cast warning. - -2013-11-12 Vladimir Serbinenko - - * grub-core/commands/verify.c: Remove variable length arrays. - Load gcry_dsa/gcry_rsa automatically. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/signature_test.c: New test. - -2013-11-12 Vladimir Serbinenko - - * grub-core/disk/cryptodisk.c (luks_script_get): Adapt to new procfs - API. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/legacy_password_test.c (vectors): Make static. - * grub-core/tests/pbkdf2_test.c (vectors): Likewise. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/setjmp_test.c: Reset counter to 0 before starting. - -2013-11-12 Vladimir Serbinenko - - * grub-core/fs/proc.c: Allow \0 in proc files. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/xnu_uuid_test.c: Fix assert message. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/xnu_uuid_test.c: Fix copyright year. - -2013-11-12 Vladimir Serbinenko - - * grub-core/fs/ext2.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/lib/crypto.c (grub_crypto_cbc_decrypt): Remove variable - length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/disk/AFSplitter.c: Remove variable length arrays. - * grub-core/disk/cryptodisk.c: Likewise. - * grub-core/disk/geli.c: Likewise. - * grub-core/disk/luks.c: Likewise. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/legacy_password_test.c: New test. - * grub-core/commands/legacycfg.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/lib/pbkdf2.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/pbkdf2_test.c: New test. - -2013-11-12 Vladimir Serbinenko - - * grub-core/lib/xzembed/xz_dec_stream.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/io/lzopio.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * include/grub/crypto.h: Add maximums on hash size and cipher block - size. - -2013-11-12 Vladimir Serbinenko - - * grub-core/commands/xnu_uuid.c: Remove variable length arrays. - -2013-11-12 Vladimir Serbinenko - - * grub-core/tests/xnu_uuid_test.c: New test. - -2013-11-12 Vladimir Serbinenko - - * grub-core/commands/hashsum.c: Remove unneeded memset (zalloc already - covers it). - -2013-11-12 Vladimir Serbinenko - - * grub-core/commands/hashsum.c: Remove variable length arrays. - -2013-11-11 Vladimir Serbinenko - - * grub-core/tests/gfxterm_menu.c (gfxterm_menu): Handle out-of-memory - condition. - * tests/grub_func_test.in: Increase memory allocation. - -2013-11-11 Vladimir Serbinenko - - * grub-core/osdep/unix/getroot.c [HAVE_STRUCT_STATFS_F_FSTYPENAME - && HAVE_STRUCT_STATFS_F_MNTFROMNAME]: Include sys/param.h and - sys/mount.h. - -2013-11-11 Vladimir Serbinenko - - * grub-core/osdep/apple/hostdisk.c (grub_util_get_fd_size): Rename to .. - (grub_util_get_fd_size_os): ...this. - (grub_hostdisk_flush_initial_buffer): New empty function. - -2013-11-11 Vladimir Serbinenko - - * grub-core/gensyminfo.sh.in: Handle the case of portable output - without --defined-only. - -2013-11-11 Vladimir Serbinenko - - * grub-core/lib/i386/relocator_common.S [__APPLE__ && __x86_64__]: Use - rip-relative addressing in prologue. - -2013-11-11 Vladimir Serbinenko - - * include/grub/misc.h [__APPLE__]: Do not add regparm(0) on x86_64. - * grub-core/kern/misc.c (__bzero) [__APPLE__]: New function. - -2013-11-11 Vladimir Serbinenko - - * util/getroot.c (grub_util_biosdisk_get_grub_dev) [__APPLE__]: - Add missing semicolon. - -2013-11-11 Vladimir Serbinenko - - * util/grub-macho2img.c: Use plain fopen rather than grub_util_fopen. - -2013-11-11 Vladimir Serbinenko - - * configure.ac: Check for lzma.h for enabling liblzma and allow - manual disabling. - -2013-11-11 Vladimir Serbinenko - - Add missing includes of loader.h. - -2013-11-11 Fam Zheng - - * util/grub.d/30_os-prober.in: Add minix entry. - -2013-11-10 Vladimir Serbinenko - - * grub-core/loader/i386/coreboot/chainloader.c (load_segment): Use - right buffer for temporary load. - -2013-11-10 Vladimir Serbinenko - - * grub-core/loader/i386/coreboot/chainloader.c: Support tianocore. - -2013-11-10 Vladimir Serbinenko - - * grub-core/loader/i386/coreboot/chainloader.c: Support lzma-compressed - payload. - -2013-11-10 Vladimir Serbinenko - - * include/grub/lib/LzmaDec.h: Fix to include LzmaTypes.h and - not Types.h. - * grub-core/lib/LzmaDec.c: Fix prologue to make it compileable in GRUB - environment. - (LzmaDec_InitDicAndState): Make static. - -2013-11-10 Vladimir Serbinenko - - * util/grub-mkimagexx.c (generate_elf): Fix module address on coreboot. - -2013-11-10 Vladimir Serbinenko - - * grub-core/term/ieee1275/escc.c (GRUB_MOD_INIT): Fix order of channels. - - Reported by: Aaro Koskinen - -2013-11-10 Vladimir Serbinenko - - * docs/grub-dev.texi: Replace bzr references with git ones. - -2013-11-10 Andrey Borzenkov - - * docs/grub.texi (Simple configuration): Remove reference to - grub-reboot from saved default entry description - grub-default - does not use it anymore. - -2013-11-10 Vladimir Serbinenko - - * configure.ac: Make efiemu test cflags match the cflags efiemu is - compiled with. - -2013-11-10 Andrey Borzenkov - - * docs/grub.texi (Simple configuration): Document GRUB_DISABLE_SUBMENU. - -2013-11-10 Vladimir Serbinenko - - Fix grub_machine_fini bitrot. - - Reported by: Glenn Washburn. - -2013-11-10 Vladimir Serbinenko - - * configure.ac: Remove leftover -fnested-funcions -Wl,-allow_execute. - -2013-11-10 Vladimir Serbinenko - - * grub-core/Makefile.am (efiemu): Remove leftover -DAPPLE_CC and - -DELF. - * grub-core/efiemu/runtime/config.h: Use __i386__ and __x86_64__ - instead of ELF*. - -2013-11-10 Vladimir Serbinenko - - * configure.ac: Restore CFLAGS to TARGET_CFLAGS before external tests. - Add -march=core2 when testing compile of efiemu64. - - Thanks Andrey Borzenkov for spotting this. - -2013-11-09 Vladimir Serbinenko - - Add new ports: i386-xen and x86_64-xen. This allows running GRUB in - XEN PV environment and load kernels. - -2013-11-09 Vladimir Serbinenko - - * grub-core/loader/i386/multiboot_mbi.c: Handle space in command line. - * grub-core/loader/multiboot_mbi2.c: Likewise. - -2013-11-09 Vladimir Serbinenko - - * grub-core/lib/cmdline.c (grub_loader_cmdline_size): Fix empty cmdline - handling. - -2013-11-09 Vladimir Serbinenko - - * grub-core/commands/i386/cmostest.c: Add new command "cmosset". - - Tested by: Denis 'GNUtoo' Carikli. - -2013-11-08 Vladimir Serbinenko - - * grub-core/normal/datetime.c (grub_get_weekday): Use unsigned types. - -2013-11-08 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_circular_progress.c (parse_angle): - Use to get rounded angle rather than truncated. - -2013-11-08 Vladimir Serbinenko - - * grub-core/term/serial.c: Add option for enabling/disabling - RTS/CTS flow control. - -2013-11-08 Vladimir Serbinenko - - * grub-core/lib/libgcrypt/cipher/idea.c (mul_inv): Remove signed - divisions. - -2013-11-08 Vladimir Serbinenko - - * grub-core/lib/libgcrypt/mpi/mpih-div.c (_gcry_mpih_divrem): - Use grub_fatal rather than divide by zero. - * grub-core/lib/libgcrypt/mpi/mpi-pow.c (gcry_mpi_powm): Likewise. - -2013-11-08 Vladimir Serbinenko - - * include/grub/gui.h (grub_fixed_sfs_divide): Round rather than - truncate. - (grub_fixed_fsf_divide): Likewise. - -2013-11-08 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_list.c (draw_scrollbar): Avoid - division by-zero and senseless negative divisions. - -2013-11-08 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_circular_progress.c (circprog_paint): Avoid - division by-zero and senseless negative divisions. - (circprog_set_property): Don't accept negative num_ticks. - -2013-11-08 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_progress_bar.c (draw_pixmap_bar): Avoid - division by-zero and senseless negative divisions. - -2013-11-08 Vladimir Serbinenko - - * configure.ac: Use elf_*_fbsd on kfreebsd. - -2013-11-08 Vladimir Serbinenko - - * grub-core/tests/div_test.c: New test. - -2013-11-08 Vladimir Testov - - * grub-core/gfxmenu/gui_box.c: Updated to work with area status. - * grub-core/gfxmenu/gui_canvas.c: Likewise. - * grub-core/gfxmenu/view.c: Likewise. - * grub-core/video/fb/video_fb.c: Introduce new functions: - grub_video_set_area_status, grub_video_get_area_status, - grub_video_set_region, grub_video_get_region. - * grub-core/video/bochs.c: Likewise. - * grub-core/video/capture.c: Likewise. - * grub-core/video/video.c: Likewise. - * grub-core/video/cirrus.c: Likewise. - * grub-core/video/efi_gop.c: Likewise. - * grub-core/video/efi_uga.c: Likewise. - * grub-core/video/emu/sdl.c: Likewise. - * grub-core/video/radeon_fuloong2e.c: Likewise. - * grub-core/video/sis315pro.c: Likewise. - * grub-core/video/sm712.c: Likewise. - * grub-core/video/i386/pc/vbe.c: Likewise. - * grub-core/video/i386/pc/vga.c: Likewise. - * grub-core/video/ieee1275.c: Likewise. - * grub-core/video/i386/coreboot/cbfb.c: Likewise. - * include/grub/video.h: Likewise. - * include/grub/video_fb.h: Likewise. - * include/grub/fbfill.h: Updated render_target structure. - grub_video_rect_t viewport, region, area - int area_offset_x, area_offset_y, area_enabled - * include/grub/gui.h: New helper function - grub_video_bounds_inside_region. - * docs/grub-dev.texi: Added information about new functions. - -2013-11-08 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_real_malloc): Use AND rather than MOD - for alignment. - -2013-11-08 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (grub_reed_solomon_recover): Add - missing attribute. - * grub-core/gdb/cstub.c (grub_gdb_trap): Likewise. - -2013-11-08 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_divmod64): Don't fallback to - simple division on arm and ia64. - -2013-11-08 Vladimir Serbinenko - - * grub-core/kern/arm/misc.S (__aeabi_unwind_cpp_pr0): Add dummy to - link with libgcc. - -2013-11-08 Vladimir Serbinenko - - * include/grub/symbol.h (FUNCTION), (VARIABLE): Fix precedence logic. - -2013-11-08 Vladimir Serbinenko - - * include/grub/symbol.h (FUNCTION), (VARIABLE) [__arm__]: Use % as - prefix symbol, not @. - -2013-11-08 Vladimir Serbinenko - - * INSTALL: Add note about older gcc and clang. - -2013-11-08 Vladimir Serbinenko - - * tests/util/grub-shell.in: Boot as hdd on ppc by default. - -2013-11-08 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_add_module): Fix - NULL pointer dereference. - -2013-11-07 Vladimir Serbinenko - - * grub-core/Makefile.am: Do not include libgcc.h when compiling with - clang. - -2013-11-07 Vladimir Serbinenko - - * grub-core/kern/powerpc/dl.c: Add missing pragma to silence cast-align - warnings. - -2013-11-07 Vladimir Serbinenko - - * grub-core/net/net.c (grub_net_route_unregister): Remove unused - function. - * grub-core/loader/i386/xnu.c (hextoval): Likewise. - * grub-core/disk/geli.c (ascii2hex): Likewise. - -2013-11-07 Vladimir Serbinenko - - * configure.ac: Run linker tests without -Werror. - Define TARGET_LDFLAGS_STATIC_LIBGCC and TARGET_LIBGCC. - Change all occurences of -static-libgcc resp -lgcc to - TARGET_LDFLAGS_STATIC_LIBGCC resp TARGET_LIBGCC. - -2013-11-07 Vladimir Serbinenko - - * configure.ac: Don't add -no-itegrated-as on clang on non-x86. - -2013-11-07 Vladimir Serbinenko - - Allow compiling with clang (not really supported though). - - * conf/Makefile.common (CFLAGS_PLATFORM): Don't add -mrtd -mregparm=3 - unconditionally. - * configure.ac: Add -no-integrated-as when using clangfor asm files. - Add -mrtd -mregparm=3 on i386 when not using clang. - * grub-core/kern/misc.c (grub_memset): Add volatile when on clang. - -2013-11-07 Vladimir Serbinenko - - * grub-core/kern/ieee1275/cmain.c: Add explicit attribute on asm - bindings. - * grub-core/lib/reed_solomon.c: Likewise. - * include/grub/i386/gdb.h: Likewise. - * include/grub/i386/pc/int.h: Likewise. - * include/grub/i386/pc/pxe.h: Likewise. - * include/grub/ieee1275/ieee1275.h: Likewise. - -2013-11-07 Vladimir Serbinenko - - Import libgcrypt 1.5.3. - -2013-11-07 Vladimir Serbinenko - - * configure.ac: Don't add -Wcast-align on x86. - -2013-11-07 Vladimir Serbinenko - - * configure.ac: Add -freg-struct-return on all platforms that - support it. - -2013-11-07 Vladimir Serbinenko - - * acinclude.m4: Use -Werror on parameter tests. - * configure.ac: Likewise. - -2013-11-07 Vladimir Serbinenko - - * acinclude.m4: Add missing TARGET_CCASFLAGS on asm tests. - -2013-11-07 Vladimir Serbinenko - - * configure.ac: Check that -malign-loops works rather than assuming that - either -falign-loops or -malign-loops work. - -2013-11-07 Vladimir Serbinenko - - * configure.ac: Remove -fnested-functions. We don't need it anymore. - -2013-11-07 Vladimir Serbinenko - - * configure.ac: Prevent cflags leaking to subsequent tests by always - resetting cflags to target_cflags in target tests. - -2013-11-07 Vladimir Serbinenko - - * grub-core/kern/parser.c (grub_parser_split_cmdline): Remove nested - function. - -2013-11-07 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Remove nested functions. - -2013-11-07 Vladimir Serbinenko - - * grub-core/lib/arg.c (grub_arg_parse): Remove nested function. - -2013-11-07 Vladimir Serbinenko - - * grub-core/normal/cmdline.c (grub_cmdline_get): - Remove nested functions. - -2013-11-07 Vladimir Serbinenko - - * tests/test_sha512sum.in: Make it work on emu. - -2013-11-07 Vladimir Serbinenko - - * grub-core/normal/charset.c (bidi_line_wrap): Eliminate nested - functions. - (grub_bidi_line_logical_to_visual): Likewise. - -2013-11-07 Vladimir Serbinenko - - Remove vestiges of -Wunsafe-loop-optimisations. - - * conf/Makefile.common (CFLAGS_GNULIB): Remove - -Wno-unsafe-loop-optimisations. - * grub-core/commands/legacycfg.c: Remove -Wunsafe-loop-optimisations - pragma. - * grub-core/io/gzio.c: Likewise. - * grub-core/script/parser.y: Likewise. - * grub-core/script/yylex.l: Likewise. - * util/grub-mkfont.c: Likewise. - -2013-11-07 Vladimir Serbinenko - - * util/grub-mkfont.c (process_cursive): Remove nested function. - -2013-11-07 Vladimir Serbinenko - - * include/grub/misc.h (grub_dprintf): Use unnamed vararg. - (grub_boot_time): Likewise. - -2013-11-07 Vladimir Serbinenko - - * include/grub/symbol.h (FUNCTION): Use @function rather than - "function". - (VARIABLE): Likewise. - -2013-11-07 Vladimir Serbinenko - - * grub-core/net/bootp.c (OFFSET_OF): Explicitly cast to grub_size_t. - -2013-11-07 Vladimir Serbinenko - - * grub-core/net/bootp.c (set_env_limn_ro): Make pointer const. - (parse_dhcp_vendor): Likewise. - -2013-11-07 Vladimir Serbinenko - - * util/grub-mkimagexx.c (relocate_symbols): Remove unneeded brackets. - -2013-11-07 Vladimir Serbinenko - - * grub-core/gettext/gettext.c (main_context), (secondary_context): - Define after defining type and not before. - -2013-11-07 Vladimir Serbinenko - - * grub-core/fs/zfs/zfscrypt.c (grub_ccm_decrypt): Return right error - type. - (grub_gcm_decrypt): Likewise. - (algo_decrypt): Likewise. - (grub_zfs_decrypt_real): Transform error type. - -2013-11-07 Vladimir Serbinenko - - * grub-core/disk/geli.c (geli_rekey): Fix error return type. - -2013-11-07 Vladimir Serbinenko - - * grub-core/disk/usbms.c (grub_usbms_cbi_cmd): Fix error type. - (grub_usbms_cbi_reset): Likewise. - (grub_usbms_bo_reset): Likewise. - (grub_usbms_reset): Likewise. - (grub_usbms_attach): Likewise. - (grub_usbms_transfer_cbi): Likewise. - -2013-11-07 Vladimir Serbinenko - - * grub-core/io/lzopio.c (test_header): Simplify code and remove useless - "checksum = checksum;". - -2013-11-07 Vladimir Serbinenko - - * grub-core/fs/reiserfs.c (grub_reiserfs_iterate_dir): Fix type of - entry_type. - -2013-11-07 Vladimir Serbinenko - - * grub-core/commands/legacycfg.c (grub_cmd_legacy_kernel): Fix - BIOS disk check. - -2013-11-07 Vladimir Serbinenko - - * grub-core/bus/usb/ehci.c (grub_ehci_restore_hw): Return right enum - type. - (grub_ehci_fini_hw): Likewise. - * grub-core/bus/usb/usbhub.c (grub_usb_add_hub): Likewise. - -2013-11-07 Vladimir Serbinenko - - * include/grub/usb.h (grub_usb_controller_dev): Make portstatus - return grub_usb_err_t for cosistency. All users updated. - -2013-11-07 Vladimir Serbinenko - - * util/mkimage.c (SzAlloc): Use attribute unused rather than dubious - assigning to itself. - -2013-11-05 Gustavo Luiz Duarte -2013-11-05 Paulo Flabiano Smorigo - - Issue separate DNS queries for ipv4 and ipv6 - - Adding multiple questions on a single DNS query is not supportted by - most DNS servers. This patch issues two separate DNS queries - sequentially for ipv4 and then for ipv6. - - Fixes: https://savannah.gnu.org/bugs/?39710 - - * grub-core/net/bootp.c (parse_dhcp_vendor): Add DNS option. - * grub-core/net/dns.c (grub_dns_qtype_id): New enum. - * (grub_net_dns_lookup): Now using separated dns packages. - * (grub_cmd_nslookup): Add error condition. - * (grub_cmd_list_dns): Print DNS option. - * (grub_cmd_add_dns): Add four parameters: --only-ipv4, --only-ipv6, - --prefer-ipv4, and --prefer-ipv6. - * include/grub/net.h (grub_dns_option_t): New enum. - * (grub_net_network_level_address): option added. - -2013-11-05 Vladimir Testov - - * grub-core/video/fb/video_fb.c: Merge two blit functions - into one. - -2013-11-05 Vladimir Serbinenko - - * grub-core/term/terminfo.c: Add sequences for home and end. - -2013-11-05 Vladimir Serbinenko - - * grub-core/lib/legacy_parse.c: Fix handling of hercules and add - graphics console. - -2013-11-05 Vladimir Serbinenko - - * grub-core/video/i386/pc/vga.c: Fix double bufferring and - add mode 0x12. - -2013-11-04 Vladimir Serbinenko - - * docs/grub.texi (Vendor power-on keys): Add XPS M1330M based on old - e-mail by Per Öberg. - -2013-11-04 Vladimir Serbinenko - - * grub-core/commands/i386/nthibr.c (GRUB_MOD_INIT): Fix typo in command - name. - -2013-11-04 Andrey Borzenkov - - * configure.ac: Explicitly disable emusdl, emuusb and emupci on non- - emu platforms. - * grub-core/Makefile.core.def: Enable emupci and emuucb only for emu. - -2013-11-04 Vladimir Serbinenko - - * docs/grub.texi: Document usage of menuentry id. - -2013-11-04 Vladimir Serbinenko - - * docs/grub.texi: Add few mentions about EFI, debug and videoinfo. - -2013-11-04 Peter Lustig - - * grub-core/commands/i386/nthibr.c: New command. - -2013-11-04 Vladimir Serbinenko - - * grub-core/tests/video_checksum.c: Add 2560x1440 mode to testing. - -2013-11-04 Vladimir Serbinenko - - * include/grub/term.h (grub_term_coordinate): Extend to 16-bit per - coordinate. - -2013-11-04 Vladimir Serbinenko - - Support GRUB_DISABLE_SUBMENU config. - - Inspired by patch from Prarit Bhargava. - -2013-11-03 Vladimir Serbinenko - - * docs/grub.texi: Mention RSA support. - -2013-11-03 Vladimir Serbinenko - - * grub-core/commands/verify.c: Add RSA support. - -2013-11-03 Vladimir Serbinenko - - * grub-core/disk/ahci.c (grub_ahci_pciinit): Detect ATAPI devices. - * grub-core/disk/ata.c (grub_ata_identify): Use atapi_identify if - device is known to be ATAPI. - -2013-11-03 Mike Frysinger - - * configure.ac: Don't add target-prefix. - -2013-11-03 Vladimir Serbinenko - - * grub-core/commands/loadenv.c (grub_cmd_save_env): Remove unset - variables. - -2013-11-03 Vladimir Serbinenko - - * grub-core/gettext/gettext.c (grub_gettext_init_ext): Ignore errors - if language is English. - -2013-11-03 Vladimir Serbinenko - - * grub-core/osdep/linux/getroot.c: Fix cast-align problems. - -2013-11-02 Vladimir Serbinenko - - * configure.ac: Don't add -m32/-m64 on emu. - -2013-11-02 neil - - * grub-core/osdep/linux/blocklist.c: Include linux/types.h for some - broken linux headers. - -2013-11-02 Vladimir Serbinenko - - * util/grub.d/30_os-prober.in: Add unhiding of partition if on msdos. - -2013-11-02 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (grub_reed_solomon_recover): Don't do - Reed-Solomon recovery if more than half of redundancy info is 0. - -2013-11-02 Vladimir Serbinenko - - * util/grub-mount.c: Handle symlinks to directories. - -2013-11-02 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (find_file): Save ctx->next when calling - find_file recursively for symlink. - -2013-11-02 Vladimir Serbinenko - - * tests/util/grub-shell.in: Copy themes. - -2013-11-02 Vladimir Serbinenko - - * util/grub-mkimagexx.c (locate_sections): Reject mislinked images. - -2013-11-02 Vladimir Serbinenko - - * configure.ac: Use 0x8000 for address instead of 8000. - -2013-11-02 Vladimir Serbinenko - - * grub-core/loader/sparc64/ieee1275/linux.c (get_physbase): Fix - signature. - -2013-11-02 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c (grub_efidisk_readwrite): Remove unused - variable. - -2013-11-02 Vladimir Serbinenko - - * configure.ac (TARGET_CFLAGS): Add -march=i386 on i386. - -2013-11-02 Vladimir Serbinenko - - * grub-core/fs/hfspluscomp.c (hfsplus_read_compressed_real): Call - file_progress_read_hook. - * grub-core/fs/ntfscomp.c (hfsplus_read_compressed_real): Likewise. - -2013-11-02 Vladimir Serbinenko - - * conf/Makefile.common (CFLAGS_PLATFORM): Remove poisoning of float - and double. - -2013-11-01 Vladimir Serbinenko - - * grub-core/fs/tar.c (grub_cpio_read): Add read_hook. - -2013-11-01 Vladimir Serbinenko - - Rewrite blocklist functions in order to get progress when - reading large extents and decrease amount of blocklist hook calls. - -2013-11-01 Vladimir Serbinenko - - * grub-core/term/serial.c (options), (grub_cmd_serial): Fix handling - of SI suffixes. - -2013-11-01 Vladimir Serbinenko - - Support --base-clock for serial command to handle weird cards with - non-standard base clock. - -2013-11-01 Vladimir Serbinenko - - * grub-core/fs/ext2.c (grub_ext2_read_symlink): Use memcpy rather - strncpy. - * grub-core/fs/jfs.c (grub_jfs_lookup_symlink): Likewise. - * grub-core/kern/misc.c (grub_strncpy): Move from here ... - * include/grub/misc.h (grub_strncpy): ... to here. Make inline. - * grub-core/net/net.c (grub_net_addr_to_str): Use COMPILE_TIME_ASSERT - + strcpy rather than strncpy. - -2013-11-01 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (nvpair_name): Use correct type for size. - (check_pool_label): Likewise. Fixes overflow. - (nvlist_find_value): Fix comparison. - -2013-11-01 Vladimir Serbinenko - - * include/grub/misc.h (grub_strcat): Removed. All users changed to - more appropriate functions. - -2013-11-01 Vladimir Serbinenko - - * grub-core/kern/efi/efi.c (grub_efi_get_filename): Avoid inefficient - realloc. - -2013-11-01 Vladimir Serbinenko - - * util/grub-mkrescue.in: Do not use UUID search on EFI. - -2013-11-01 Vladimir Serbinenko - - * grub-core/kern/dl.c: Unify section-finding algorithm. Saves 30 bytes - on core size. - -2013-10-30 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_realloc): Don't copy more data than we have. - -2013-10-30 Vladimir Serbinenko - - * grub-core/io/gzio.c (huft_build): Use zalloc for safety. - (initialize_tables): reset tl and td to NULL after freeing. - -2013-10-28 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c: Implement network tag. - -2013-10-28 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c: Add EFI memory map to the list - of supported tags. - -2013-10-28 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c: Implement EFI memory map. - -2013-10-28 Vladimir Serbinenko - - * grub-core/loader/multiboot.c: Add support for multiboot kernels - quirks. - -2013-10-28 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (allocate_pages): Allocate at least - a page in protected space. - -2013-10-28 Vladimir Serbinenko - - * grub-core/loader/multiboot.c (grub_cmd_module): Don't attempt to - allocate space for zero-sized modules. - -2013-10-28 Vladimir Serbinenko - - * grub-core/loader/xnu_resume.c (grub_xnu_resume): Reject empty images. - -2013-10-28 Francesco Lavra - - * grub-core/lib/fdt.c: Fix miscellaneous bugs. - -2013-10-28 Vladimir Serbinenko - - * grub-core/lib/progress.c (grub_file_progress_hook_real): Add missing - safeguards. Fixes a crash with i386/pc/console.c. - -2013-10-28 Vladimir Serbinenko - - * include/grub/emu/hostdisk.h: Add proper declaration for grub_host_init - and grub_hostfs_init. - -2013-10-28 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_check_file_presence): Use - windows method on other platforms without good stat as well. - -2013-10-28 Vladimir Serbinenko - - * grub-core/osdep/linux/getroot.c: Add new btrfs defines. - -2013-10-28 Vladimir Serbinenko - - Make / in btrfs refer to real root, not the default volume. - Modify mkrelpath to work even if device is mounted with subvolid option. - -2013-10-28 Andrey Borzenkov - - * Makefile.util.def: Add grub-core/kern/disk_common.c to library - extra_dist. - * grub-core/Makefile.core.def: Add kern/disk_common.c to disk module - extra_dist. - -2013-10-27 Vladimir Serbinenko - - * util/grub-mkfont.c (main): Show error message when FT_Set_Pixel_Sizes - fails. - -2013-10-27 BVK Chaitanya - - * docs/autoiso.cfg: New file. - -2013-10-27 Vladimir Serbinenko - - * configure.ac: Remove leftover COND_BUILD_GRUB_MKFONT and - COND_GRUB_PE2ELF conditions. - -2013-10-27 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c (grub_cmd_openbsd): Accept "sd", "cd", - "vnd", "rd" and "fd" disks. - -2013-10-27 Vladimir Serbinenko - - Move grub_disk_write out of kernel into disk.mod. - -2013-10-27 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Unify int and wchar - handling. - -2013-10-27 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_abort): Make static - -2013-10-27 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Don't attempt to - transform invalid unicode codepoints. - -2013-10-27 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Remove needless explicit - \0 checking. - -2013-10-27 Vladimir Serbinenko - - * grub-core/lib/legacy_parse.c: Add support for "nd" disk. - -2013-10-26 Vladimir Serbinenko - - Consolidate cpuid code. - -2013-10-26 Vladimir Serbinenko - - Move cpuid code to cpuid.h and TSC code to tsc.c. - -2013-10-26 Grégoire Sutre - - * util/grub.d/00_header.in: Don't use LANG if it's not set. - -2013-10-26 Grégoire Sutre - - * util/grub-mkconfig.in: Replace $0 with $self. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - -2013-10-26 BVK Chaitanya - - * docs/osdetect.cfg: New file. - -2013-10-26 BVK Chaitanya - - * tests/util/grub-shell.in: Add new --debug option. - -2013-10-26 BVK Chaitanya - - * tests/test_unset.in: New test. - -2013-10-26 BVK Chaitanya - - * tests/test_sha512sum.in: New test. - -2013-10-26 Vladimir Serbinenko - - * grub-core/fs/iso9660.c: Replace strncat with memcpy. - * include/grub/misc.h: Remove strncat. - * grub-core/lib/posix_wrap/string.h: Likewise. - -2013-10-26 Vladimir Serbinenko - - * grub-core/net/tftp.c: Retransmit ack when rereceiving old packet. - Try to handle more than 0xFFFF packets. - Reported by: Bernhard Übelacker . - He also spotted few overflows in first version of this patch. - -2013-10-26 Vladimir Serbinenko - - * tests/date_unit_test.c: New test. - -2013-10-26 Vladimir Serbinenko - - * grub-core/normal/datetime.c (grub_unixtime2datetime): Fix mishandling - of first three years after start of validity of unixtime. - -2013-10-26 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (get_logical_num_lines): Use unsigned - division as the one making more sense. - (update_screen): Likewise. - (complete): Likewise. - -2013-10-25 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (complete): Make sure that width is >0. - -2013-10-25 Vladimir Serbinenko - - Make char and string width grub_size_t rather than grub_ssize_t. - -2013-10-25 Vladimir Serbinenko - - * grub-core/normal/cmdline.c (grub_history_get): Make argument into - unsigned. - (grub_history_replace): Likewise. - -2013-10-25 Vladimir Serbinenko - - * grub-core/disk/raid6_recover.c: Use unsigned arithmetics when - appropriate. - -2013-10-25 Vladimir Serbinenko - - * grub-core/video/bitmap_scale.c: Use unsigned arithmetics when - appropriate. - -2013-10-25 Vladimir Serbinenko - - * grub-core/video/fb/fbblit.c: Use (255 ^ x) rather than (255 - x). - Use unsigned divisions rather than signed variants. - -2013-10-25 Vladimir Serbinenko - - * grub-core/video/readers/png.c (grub_png_convert_image): Use - unsigned arithmetics. - Add missing break. - -2013-10-25 Vladimir Serbinenko - - * grub-core/video/readers/jpeg.c: Use unsigned where appropriate. - -2013-10-25 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (xor_out): Use unsigned modular arithmetics - rather than signed one. - (recovery): Likewise. - -2013-10-25 Vladimir Serbinenko - - * grub-core/net/dns.c (hash): Use unsigned arithmetic. - -2013-10-25 Vladimir Serbinenko - - * grub-core/io/gzio.c (test_zlib_header): Use undigned modulo rather - than signed. - -2013-10-25 Jon McCune - - * docs/grub.texi: Cleanup security documentation around signatures. - -2013-10-25 Vladimir Serbinenko - - * grub-core/fs/ext2.c (EXT2_BLOCK_SIZE): Make unsigned. - -2013-10-25 Vladimir Serbinenko - - * grub-core/commands/gptsync.c (lba_to_chs): Use proper types rather - than int. - -2013-10-25 Vladimir Serbinenko - - * conf/Makefile.common (CPPFLAGS_KERNEL): Add -DGRUB_KERNEL=1. - * include/grub/dl.h (GRUB_MOD_INIT), (GRUB_MOD_FINI): Define - functions when compiling for kernel. - -2013-10-25 Vladimir Serbinenko - - * grub-core/lib/progress.c (grub_file_progress_hook_real): Cast to - unsigned long long when using %llu. - -2013-10-25 Vladimir Serbinenko - - * grub-core/lib/progress.c (grub_file_progress_hook_real): Refresh - terminal after updating progress. - -2013-10-25 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S (grub_gate_a20): Remove - argument. We don't disable Gate A20 in this code. - -2013-10-25 Vladimir Serbinenko - - * grub-core/boot/i386/qemu/boot.S: Ensure that A20 is enabled. - Conceptually based on change in branch "vbe-on-coreboot". - -2013-10-24 Robert Millan - - * grub-core/video/i386/pc/vbe.c (grub_video_vbe_setup): Replace - numeric constants with their symbolic equivalent. - Taken from branch "vbe-on-coreboot". - -2013-10-22 Vladimir Serbinenko - - * docs/grub.texi: Fix ordering and use pxref rather than xref. - -2013-10-22 Vladimir Serbinenko - - * grub-core/lib/progress.c (grub_file_progress_hook_real): Use - divmod64 for offset division. - -2013-10-22 Paulo Flabiano Smorigo - - Rename .bzrignore to .gitignore. Add "*.o" rule. - - * .bzrignore: Renamed to... - * .gitignore: ...this. - -2013-10-22 Paulo Flabiano Smorigo - - Add new progress module that displays the load progress of files. - - * grub-core/lib/progress.c: New file. - * grub-core/Makefile.core.def (progress): New module. - * grub-core/kern/file.c (grub_file_open): File name added. - * (grub_file_read): Progress hook added. - * grub-core/fs/cbfs.c (grub_cbfs_read): Likewise. - * grub-core/fs/cpio_common.c (grub_cpio_read): Likewise. - * grub-core/net/net.c (grub_net_fs_read_real): Likewise. - * include/grub/file.h (struct grub_file): Add progress module members. - * include/grub/term.h (struct grub_term_output): Likewise. - * grub-core/osdep/unix/emuconsole.c (grub_console_term_output): - Terminal velocity added. - * grub-core/osdep/windows/emuconsole.c (grub_console_term_output): Likewise. - * grub-core/term/arc/console.c (grub_console_term_output): Likewise. - * grub-core/term/efi/console.c (grub_console_term_output): Likewise. - * grub-core/term/gfxterm.c (grub_video_term): Likewise. - * grub-core/term/i386/coreboot/cbmemc.c (grub_cbmemc_term_output): Likewise. - * grub-core/term/i386/pc/console.c (grub_console_term_output): Likewise. - * grub-core/term/i386/pc/vga_text.c (grub_vga_text_term): Likewise. - * grub-core/term/ieee1275/console.c (grub_console_term_output): Likewise. - * grub-core/term/morse.c (grub_audio_term_output): Likewise. - * grub-core/term/serial.c (grub_serial_term_output): Likewise. - * grub-core/term/spkmodem.c (grub_spkmodem_term_output): Likewise. - * grub-core/term/uboot/console.c (uboot_console_term_output): Likewise. - -2013-10-22 Vladimir Serbinenko - - Verify signatures of signatures unless --skip-sig is specified. - -2013-10-21 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Remove needless explicit - \0 checking. - - Saves 70 bytes on compressed image. - -2013-10-21 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_strtoull): Remove needless *ptr != 0 - check. - - Saves 10 bytes on compressed image. - -2013-10-21 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_isprint): Move to ... - * include/grub/misc.h (grub_isprint): ... here. Make inline. - - Saves 20 bytes on compressed image due to remving exporting. - -2013-10-21 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (grub_ntfs_mount): Remove redundant check. - - Saves 5 bytes on compressed image. - -2013-10-21 Vladimir Serbinenko - - * grub-core/fs/ntfs.c: Move common UTF-16 handling to a separate - function get_utf8. - - Saves 379 bytes on compressed image. - -2013-10-21 Vladimir Serbinenko - - * grub-core/fs/ntfs.c: Handle 48-bit MFT no. - -2013-10-21 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (read_run_data): Rewrite using bitfields. - - Saves 40 bytes on compressed image. - -2013-10-21 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (grub_ntfs_iterate_dir): Use grub_uint8_t for - mask rather than 64-bit type. - - Saves 20 bytes on compressed image. - -2013-10-21 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (read_data): Move code for compressed data to ... - * grub-core/fs/ntfscomp.c (ntfscomp): ... here. - - Saves 273 bytes on compressed image. - -2013-10-20 Vladimir Serbinenko - - * grub-core/kern/disk.c (grub_disk_write): Use malloc/free instead of - variable length arrays. - - Saves 50 bytes on compressed image. - -2013-10-20 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c: Remove variable length arrays. - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/ufs.c: Remove variable length arrays. - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/ntfs.c: Add comment about fixed allocation size. - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/zfs.c: Remove variable length arrays. - Reduces zfs.mod by 160 bytes (208 compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (check_pool_label): Fix memory leak. - -2013-10-20 Vladimir Serbinenko - - * grub-core/net/arp.c: Remove variable length arrays. - * grub-core/net/bootp.c: Likewise. - * grub-core/net/dns.c: Likewise. - * grub-core/net/icmp6.c: Likewise. - * grub-core/net/net.c: Likewise. - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/ntfs.c: Remove variable length arrays. - Increases ntfs.mod by 64 bytes (but decreases by 3 when - compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/hfs.c: Remove variable length arrays. - Reduces hfs.mod by 8 bytes (52 compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/udf.c: Remove variable length arrays. - Increases udf.mod by 128 bytes (but decreases by 13 when - compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/iso9660.c: Remove variable length arrays. - Increases iso9660.mod by 200 bytes (but decreases by 79 when - compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c: Remove variable length arrays. - Increases nilfs2.mod by 24 bytes (but decreases by 115 when - compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/xfs.c: Remove variable length arrays. - Reduces xfs.mod by 40 bytes (43 compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/fshelp.c: Remove variable length arrays. - Reduces fshelp.mod by 116 bytes (23 compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/normal/completion.c: Remove variable length arrays. - * grub-core/normal/menu_entry.c: Likewise. - - Reduces normal.mod by 496 bytes. - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/minix.c: Remove variable length arrays. Reduces jfs.mod - by 356 bytes (158 compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/jfs.c: Remove variable length arrays. Reduces jfs.mod - by 364 bytes (169 compressed). - -2013-10-20 Vladimir Serbinenko - - * grub-core/fs/bfs.c: Remove variable length arrays. Reduces afs.mod and - bfs.mod size by 556 resp 740 bytes (288 resp 334 compressed). - * include/grub/types.h (grub_unaligned_uint64_t): New type. - -2013-10-19 Vladimir Serbinenko - - Lift 255x255 erminal sie restriction to 65535x65535. Also change from - bitmasks to small structures of size chosen to fit in registers. - -2013-10-19 Vladimir Serbinenko - - * conf/Makefile.common: Use -freg-struct-return on i386. This - decreases code size and improves performance. - -2013-10-19 Vladimir Serbinenko - - * grub-core/osdep/unix/exec.c: Fix compilation error on emu. - -2013-10-19 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Fix formatting of - "(null)" string. - Simplify expressions to save around 256 bytes in kernel.img. - * tests/printf_unit_test.c (printf_test): Add "(null)" tests. - -2013-10-19 Vladimir Serbinenko - - * grub-core/tests/video_checksum.c (grub_video_capture_write_bmp): - Use GRUB_UTIL_FD_O_* rather than O_*. - -2013-10-19 Vladimir Serbinenko - - Add haiku-specific functions. - -2013-10-19 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c: Remove few leftover includes. - -2013-10-19 Vladimir Serbinenko - - Move stat () and device mode checking into OS-dependent files as - long as performance doesn't suffer. - -2013-10-19 Vladimir Serbinenko - - Split make_system_path_relative_to_its_root into separate file - relpath.c from getroot.c as it's common between unix and haiku - but otherwise haiku doesn't use any functions from unix getroot.c. - -2013-10-19 Vladimir Serbinenko - - * grub-core/osdep/aros/hostdisk.c (grub_util_is_directory): - New function. - (grub_util_is_special_file): Likewise. - -2013-10-19 Vladimir Serbinenko - - * grub-core/osdep/unix/getroot.c: Move exec functions to ... - * osdep/unix/exec.c: ... here. Add few additional exec_* variants. - -2013-10-19 Vladimir Serbinenko - - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Define size_t to - grub_size_t. This fixes the case when size_t mismatches grub_size_t. - -2013-10-19 Vladimir Serbinenko - - * util/grub-mkimagexx.c (make_reloc_section): Fix memory leak. - (load_image): Likewise. - -2013-10-19 Vladimir Serbinenko - - * util/grub-render-label.c: Move backend part to ... - * util/render-label.c: ... here. - -2013-10-18 Vladimir Serbinenko - - * grub-core/osdep/random.c: Use unix/random.c on haiku. Haiku uses - yarrow (by B. Schneier et al) for its /dev/urandom (similar to FreeBSD). - -2013-10-18 Vladimir Serbinenko - - * grub-core/osdep/generic/blocklist.c: Add missing include to string.h. - -2013-10-18 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Handle - CD-ROM in case when it's declared as having subpartitions. - -2013-10-18 Vladimir Serbinenko - - Don't add -lm on haiku. - - * configure.ac: Define BUILD_LIBM to -lm on most platforms - and empty on haiku. - * grub-core/Makefile.am (gentrigtables): Use $(BUILD_LIBM) rather than - -lm. - -2013-10-18 Vladimir Serbinenko - - * configure.ac: Use -melf_*_haiku as target on haiku. - -2013-10-18 Vladimir Serbinenko - - * Makefile.util.def: Add util/setup.c to extra_dist. - -2013-10-18 Vladimir Serbinenko - - * grub-core/kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Pass - unknown types through. - -2013-10-18 Vladimir Serbinenko - - * grub-core/osdep/unix/getroot.c (grub_util_check_block_device): Remove. - (grub_util_check_char_device): Likewise. - * include/grub/emu/getroot.h: Likewise. - -2013-10-18 Vladimir Serbinenko - - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Use define for defining - memset rather than inline static function. - -2013-10-18 Vladimir Serbinenko - - * grub-core/lib/xzembed/xz_config.h: Enable all bcj filters when - not doing embedded decompressor. - -2013-10-18 Vladimir Serbinenko - - * grub-core/disk/ldm.c: Rename variables and arguments to prevent - shadowing. - * grub-core/kern/disk.c: Likewise. - * grub-core/kern/misc.c: Likewise. - * include/grub/parser.h: Likewise. - * include/grub/script_sh.h: Likewise. - * include/grub/zfs/zfs.h: Likewise. - -2013-10-18 Vladimir Serbinenko - - * grub-core/disk/luks.c (configure_ciphers): Fix spurious warning. - -2013-10-18 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs_lz4.c: Check that __INTEL_COMPILER is - defined before trying to use it. - -2013-10-18 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_create_node): Fix uninited value - warning. - -2013-10-18 Vladimir Serbinenko - - * include/grub/dl.h: Remove double declaration of GRUB_MOD_DEP. - Use __unused__ rather than __used__ on gcc < 3.2. - -2013-10-18 Vladimir Serbinenko - - * include/grub/setjmp.h: Define RETURNS_TWICE. Keep it empty for - gcc < 4.0. - * include/grub/*/setjmp.h: USe RETURNS_TWICE. - -2013-10-18 Vladimir Serbinenko - - * grub-core/disk/dmraid_nvidia.c: Fix potentially uninited "layout". - -2013-10-18 Vladimir Serbinenko - - * include/grub/misc.h: Don't use warn_unused_result on gcc < 3.4. - * include/grub/emu/misc.h: Likewise. - -2013-10-18 Vladimir Serbinenko - - * grub-core/term/i386/pc/vga_text.c: Remove extra declaration of - cur_color. - -2013-10-18 Vladimir Testov - - * grub-core/tests/checksums.h: Regenerated due to progress bar - get_minimal_size changes. - -2013-10-17 BVK Chaitanya - - Added `tr' command support. - - * grub-core/commands/tr.c: New file. - * grub-core/Makefile.core.def: Build rules for new module. - - * tests/grub_cmd_tr.in: New test. - * Makefile.util.def: Build rules for new test. - -2013-10-17 Vladimir Testov - - * grub-core/gfxmenu/gui_progress_bar.c: Sanity checks added. - -2013-10-17 Vladimir Testov - - * grub-core/gfxmenu/gui_progress_bar.c: New option ``highlight_overlay`` - * docs/gurb.texi: Likewise. - -2013-10-17 Vladimir Testov - - * grub-core/gfxmenu/gui_progress_bar.c (draw_pixmap_bar): Fixed bug. - Pixmap highlighted section with east and west slices was displayed - incorrectly due to negative width of the central slice. - -2013-10-17 Vladimir Testov - - * docs/grub.texi: Graphical options information update. - Removed outdated. Updated current. Inserted missed. - -2013-10-17 Vladimir Serbinenko - - * docs/grub.texi: Mention few new platform-specific commands. - -2013-10-17 Vladimir Serbinenko - - * grub-core/script/yylex.l: Fix LSQBR2 and RSQBR2. It's not - currently used so this doesn't really have any effect. - Reported by: Douglas Ray - -2013-10-17 Vladimir Serbinenko - - * autogen.sh: Don't set LC_CTYPE as it doesn't create problem for - compilation but prevents gcc from displaying messages in non-Latin - alphabets. - * conf/Makefile.common: Likewise. - -2013-10-16 Hiroyuki YAMAMORI - - Handle Japanese special keys. - Reported by: Hiroyuki YAMAMORI. - Codes supplied by: Hiroyuki YAMAMORI. - -2013-10-16 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: Scrollbar sanity checks added. - -2013-10-16 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: New option `item_pixmap_style`. - * docs/grub.texi: Likewise. - -2013-10-16 Vladimir Serbinenko - - * grub-core/osdep/unix/hostdisk.c (grub_util_fd_read): Return correct - value in case of incomplete read. - (grub_util_fd_write): Likewise. - -2013-10-15 Vladimir Serbinenko - - * util/editenv.c (grub_util_create_envblk_file): Use grub_util_rename. - -2013-10-15 Vladimir Serbinenko - - * util/grub-editenv.c (create_envblk_file): More from here ... - * util/editenv.c (grub_util_create_envblk_file): ... to here. - -2013-10-15 Vladimir Serbinenko - - * grub-core/osdep/unix/getroot.c (grub_guess_root_devices): - canonicalize file name before doing the rest. - -2013-10-15 Vladimir Serbinenko - - * include/grub/osdep/hostfile_windows.h: Add missing ftello for - mingw32. - -2013-10-15 Vladimir Serbinenko - - Define grub_util_is_directory/regular/special_file and - use OS-dependent versions rather than to rely on stat(). - -2013-10-15 Vladimir Serbinenko - - * util/grub-mkimage.c: Move backend part to ... - * util/mkimage.c: ... here. - -2013-10-15 Vladimir Serbinenko - - Allow compilation with mingw64 albeit with warnings due to lack of - %llx/%llu. - - * grub-core/gnulib/msvc-inval.c: Use __cdecl rather than cdecl. - * grub-core/lib/posix_wrap/wchar.h: Define wint_t. - * grub-core/lib/posix_wrap/wctype.h: Define wctype_t. - * include/grub/osdep/hostfile_windows.h: Don't define fseeko/ftello - on mingw64. - * include/grub/types.h: Allow sizeof (long) != sizeof (void *). - -2013-10-15 Vladimir Serbinenko - - Remove leftover references to some of the system headers. - -2013-10-15 Vladimir Serbinenko - - * grub-core/disk/geli.c (grub_util_get_geli_uuid): Close handle after - read. - -2013-10-15 Vladimir Serbinenko - - * grub-core/disk/cryptodisk.c: Use grub_util_fd_strerror instead - of strerror. - -2013-10-15 Vladimir Serbinenko - - Split out blocklist retrieving from setup.c to - grub-core/osdep/blocklist.c and add windows implementation since - generic version doesn't work on NTFS on Windows due to aggressive - unflushable cache. - -2013-10-15 Vladimir Serbinenko - - Split grub-setup.c into frontend (grub-setup.c) and backend (setup.c) - files. - -2013-10-15 Vladimir Serbinenko - - * grub-core/osdep/windows/hostdisk.c (grub_util_fd_strerror): - Cut tailing newline. Remove arbitrary limitation. Always use - grub_util_tchar_to_utf8. - -2013-10-15 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Handle %% properly. - * tests/printf_unit_test.c (printf_test): Add %% tests. - Reported by: Paulo Flabiano Smorigo. - -2013-10-15 Vladimir Serbinenko - - * grub-core/osdep/windows/hostdisk.c (fsync) [__MINGW32__]: Really - implement fsync. - -2013-10-15 Vladimir Serbinenko - - * configure.ac: Check for nvlist_lookup_string in nvpair since we - use nvlist_lookup_string and don't use nvlist_print. - -2013-10-15 Vladimir Serbinenko - - Add wrappers around rename, unlink, mkdir, opendir, readdir and - closedir to handle filename charset translation. - -2013-10-15 Vladimir Serbinenko - - * include/grub/emu/hostdisk.h: Move file operations to - * include/grub/emu/hostfile.h: ... here. - -2013-10-15 Vladimir Serbinenko - - * grub-core/osdep/windows/hostdisk.c (canonicalize_file_name): Handle - unicode path. - -2013-10-15 Vladimir Serbinenko - - * grub-core/tests/checksums.h: Regenerate due to swiss.sed change. - -2013-10-15 Vladimir Serbinenko - - Move cpu time retrieval to separate grub_util_get_cpu_time_ms - and remove export.h. - -2013-10-15 Vladimir Serbinenko - - * grub-core/kern/emu/error.c: Removed. - * grub-core/Makefile.core.def (kernel): Don't add error.c and progname.c - explicitly as it's already in libgnu.a. - -2013-10-15 Vladimir Serbinenko - - * grub-core/osdep/windows/emuconsole.c: Add missing config.h and - config-util.h include. - -2013-10-15 Vladimir Serbinenko - - Split emunet into platform-dependent and GRUB-binding parts. Keep - platform-dependent part in kernel for easy access to OS functions. - -2013-10-15 Vladimir Serbinenko - - * grub-core/tests/video_checksum.c: Use grub_util_fd_* rather than - open/read/write. - -2013-10-14 Vladimir Serbinenko - - * grub-core/osdep/windows/emuconsole.c: New file. - -2013-10-14 Andrey Borzenkov - - * conf/Makefile.extra-dist: Add osdep/*/init.c - -2013-10-14 Vladimir Serbinenko - - * Makefile.am: Use TARGET_OBJCOPY when doing objcopy for target. - -2013-10-14 Vladimir Serbinenko - - * util/grub-probe.c (probe): Separate different drives in hint-str - by spaces and not newlines. - * util/grub-mkconfig_lib.in: Handle multidevice filesystem. - -2013-10-14 Andrey Borzenkov - - * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): - Handle CD-ROMs. - -2013-10-14 Vladimir Serbinenko - - Pass-through unknown E820 types. It required reorganisation of mmap - module. - -2013-10-14 Andrey Borzenkov - - * Makefile.util.def: Add osdep/init.c to grub-mount files. - -2013-10-14 Vladimir Serbinenko - - Make grub_util_fd_seek match behaviour of other grub_util_fd_* and - fseeko. - -2013-10-14 qwertial - - * grub-core/gdb_grub.in: Fix overflow and wrong field. - -2013-10-14 Jon McCune - - * docs/grub.texi: Document new signatures possibility. - -2013-10-14 Vladimir Serbinenko - - Define GRUB_UTIL_FD_O_* and always use them with grub_util_fd_open. - -2013-10-14 Vladimir Serbinenko - - * include/grub/osdep/hostfile_windows.h (grub_util_utf8_to_tchar): Add - missing prototype. - (grub_util_tchar_to_utf8): Likewise. - -2013-10-14 Vladimir Serbinenko - - * grub-core/Makefile.core.def: Add osdep/init.c on emu. - * grub-core/kern/emu/main.c: Add missing include. - * grub-core/osdep/basic/init.c (grub_util_host_init) [!GRUB_UTIL]: - Don't call grub_util_init_nls. - * grub-core/osdep/windows/init.c (grub_util_host_init) [!GRUB_UTIL]: - Likewise. - -2013-10-13 Vladimir Serbinenko - - * util/misc.c (grub_util_get_image_size): Use FILE functions rather than - stat. - -2013-10-13 Vladimir Serbinenko - - * util/grub-editenv.c: Remove leftover set_program_name and init_nls. - -2013-10-13 Vladimir Serbinenko - - * include/grub/misc.h: Use gnu_printf only on gcc 4.4 or later. - -2013-10-13 Vladimir Serbinenko - - Add a wrapper for fopen. On unix-like systems just pass-through. On - windows use unicode version. - -2013-10-13 Vladimir Serbinenko - - Move set_program_name and init_nls to host_init. On windows - fix in this fuction console and argument charset as well. - -2013-10-12 Andrey Borzenkov - - Fix inconsistent use of GRUB_CRYPTODISK_ENABLE and - GRUB_ENABLE_CRYPTODISK. - - * util/grub-install.in: Rename all GRUB_CRYPTODISK_ENABLE to - GRUB_ENABLE_CRYPTODISK. - * util/grub-mkconfig_lib.in: Likewise. - -2013-10-12 Christian Cier-Zniewski - - * docs/grub.texi (Vendor power-on keys): Add Dell Latitude E4300. - -2013-10-12 Melki Christian - - * grub-core/term/at_keyboard.c [DEBUG_AT_KEYBOARD]: Fix compilation - error when enabling debug. - -2013-10-12 Ilya Bakulin - - * configure.ac: Use -melf_*_obsd on openbsd. - -2013-10-12 Vladimir Serbinenko - - * grub-core/kern/arm/dl_helper.c: Use more proper %p for pointer. - -2013-10-12 Vladimir Serbinenko - - * include/grub/misc.h: Use gnu_printf rather than printf as format - template since our functions are independent of libc. - -2013-10-11 Vladimir Serbinenko - - * util/grub-setup.c (setup): Move copying of partition table as - futher up as possible to avoid possible overwrite by floppy routines. - -2013-10-11 Vladimir Serbinenko - - * grub-core/fs/fat.c: Fix handling of exfat contiguous files. - -2013-10-10 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: New option `scrollbar_thumb_overlay`. - * docs/grub.texi: Likewise. - -2013-10-10 Vladimir Serbinenko - - * util/getroot.c (make_device_name): Remove dos_part and bsd_part as - it's mostly unused. Move vestiges to the callers. - -2013-10-10 Vladimir Serbinenko - - * util/grub-mkpasswd-pbkdf2.c: Remove temporary buffers for hex - version of salt and hash. Use grub_snprintf rather than snprintf. - -2013-10-10 Vladimir Serbinenko - - * docs/grub.texi: Fix problem with braces. - -2013-10-10 Vladimir Serbinenko - - * conf/Makefile.extra-dist: Fix extra-dist list. - * grub-core/Makefile.core.def: Likewise. - -2013-10-10 Vladimir Serbinenko - - * docs/grub.texi: Document disk names used on Windows and AROS. - -2013-10-10 Vladimir Serbinenko - - * grub-core/osdep/aros/getroot.c: Change to //: prefix as discussed - with AROS devs. - * grub-core/osdep/aros/hostdisk.c: Likewise. - -2013-10-10 Vladimir Serbinenko - - Avoid including hostfile.h when not necessarry as it pulls - in OS-specific headers which may redefine generic names - like "far". - -2013-10-09 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: New options for scrollbar padding: - scrollbar_left_pad, scrollbar_right_pad, scrollbar_top_pad, - scrollbar_bottom_pad - * docs/grub.texi: Likewise. - -2013-10-09 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c (list_destroy): Fixed memory leak. - -2013-10-09 Vladimir Serbinenko - - Move OS-dependent file definitions to include/grub/osdep/hostfile*.h. - -2013-10-09 Vladimir Serbinenko - - * include/grub/emu/hostdisk.h (grub_hostdisk_linux_find_partition): - Removed. - * grub-core/osdep/linux/hostdisk.c (grub_hostdisk_linux_find_partition): - Made static. - -2013-10-09 Vladimir Serbinenko - - * include/grub/emu/getroot.h (grub_util_find_hurd_root_device): Remove - leftover. - -2013-10-09 Vladimir Serbinenko - - Move OS-specific driver configuration to grub_util_fd_open. This - moves OS-dependent parts from kern/emu/hostdisk.c to - grub-core/osdep/*/hostdisk.c. - -2013-10-09 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Use size_t instead of - grub_size_t. - * util/grub-mkimagexx.c (locate_sections): Likewise. - (load_image): Likewise. - -2013-10-09 Vladimir Serbinenko - - * util/misc.c (grub_util_write_image_at): Don't use PRIxGRUB_SIZE for - size_t. - (grub_util_write_image): Likewise. - -2013-10-08 Vladimir Serbinenko - - * grub-core/osdep/basic/random.c: New file. Abort on an attempt to - get random when no RNG is available. - * grub-core/osdep/random.c: Use basic/random.c on OS out of whitelist. - -2013-10-08 Vladimir Serbinenko - - * include/grub/util/lvm.h: Removed. - -2013-10-08 Vladimir Serbinenko - - * grub-core/kern/emu/misc.c (fsync) [__MINGW32__]: Move to ... - * grub-core/osdep/windows/hostdisk.c (fsync) [__MINGW32__]: ... here. - -2013-10-08 Vladimir Serbinenko - - * grub-core/osdep/windows/sleep.c: Add missing config.h. - -2013-10-08 Vladimir Serbinenko - - * grub-core/kern/emu/misc.c (grub_get_rtc): Remove (it's a leftover). - -2013-10-08 Vladimir Serbinenko - - * grub-core/net/drivers/emu/emunet.c: Move to .. - * grub-core/osdep/linux/emunet.c: ..here. - -2013-10-08 Vladimir Serbinenko - - * util/ieee1275/ofpath.c: Move to ... - * grub-core/osdep/linux/ofpath.c: ..here, split stub into ... - * grub-core/osdep/basic/ofpath.c: ..here. - -2013-10-08 Vladimir Serbinenko - - Move password-querying (util-version) routines to grub-core/osdep. - -2013-10-08 Vladimir Serbinenko - - Move sleep routines to grub-core/osdep. - -2013-10-08 Vladimir Serbinenko - - Move OS-dependent files to grub-core/osdep and document it. - -2013-10-08 Vladimir Serbinenko - - * grub-core/kern/emu/misc.c (canonicalize_file_name): Move to ... - * grub-core/kern/emu/hostdisk_*.c (canonicalize_file_name): ... here. - -2013-10-08 Vladimir Serbinenko - - * grub-core/kern/arm/misc.S: Remove leftover ARM and THUMB. - -2013-10-08 Vladimir Serbinenko - - * util/misc.c: Remove leftover inclusion of malloc.h. - -2013-10-08 Vladimir Serbinenko - - * include/grub/setjmp.h: Remove leftover GRUBOF. - -2013-10-08 Vladimir Serbinenko - - * util/raid.c: Fold into ... - * util/getroot_linux.c: ... here. Make all functions static. - -2013-10-08 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs_lz4.c: Switch from ad-hoc endiannes and width - macros to GRUB ones. - -2013-10-08 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c (draw_scrollbar): Fixed rare - occasional bug. If there are too many boot entries or too low - scrollbar height then we need to use another formula to calculate - the position and size of the scrollbar thumb. - -2013-10-08 Vladimir Serbinenko - - * util/random_unix.c: Add NetBSD, Solaris and Mac OS X to verified list. - -2013-10-08 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: New option `scrollbar-slice`. - * docs/grub.texi: Likewise. - -2013-10-08 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: Draw the scrollbar in a separate - viewport. - -2013-10-08 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c (list_get_minimal_size): Corrected - minimal width calculations. - -2013-10-07 Vladimir Serbinenko - - * docs/grub.texi: Update note on colors on emu console. - -2013-10-07 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_get_file_block): Give GRUB_ERR_BAD_FS - for quadruple indirect rather than GRUB_ERR_NOT_IMPLEMENTED_YET as - it's FS and not GRUB limitation. - -2013-10-07 Vladimir Serbinenko - - * grub-core/kern/arm/efi/startup.S: Remove thumb leftover. - -2013-10-07 Vladimir Serbinenko - - * grub-core/kern/arm/efi/init.c: Rewrite timer fucntion. - -2013-10-04 Samuel Thibault - - * util/grub.d/10_hurd.in: Use `version_find_latest` to sort gnumach - kernels by version order. - -2013-10-04 Vladimir Serbinenko - - * util/random_unix.c: Add kFreeBSD to the list of secure RNG. - -2013-10-04 Vladimir Serbinenko - - Add AROS hostdisk and getroot routines. - -2013-10-04 Vladimir Serbinenko - - Make cryptodisk and diskfilter probe data retrievable programmatically - and not just printable. - -2013-10-04 Vladimir Serbinenko - - Split random retrieving code into separate files. - -2013-10-03 Vladimir Serbinenko - - * grub-core/kern/arm/dl.c (do_relocations): Accept and ignore - R_ARM_V4BX. - -2013-10-03 Vladimir Serbinenko - - * grub-core/tests/video_checksum.c: Increase robustness to out of memory - condition. - * grub-core/tests/fake_input.c: Likewise. - * grub-core/tests/cmdline_cat_test.c: Likewise. - -2013-10-03 Vladimir Serbinenko - - * grub-core/video/capture.c: Do not do finalization when .fini - is called as there is explicit capture_end. - -2013-10-03 Vladimir Serbinenko - - * grub-core/term/gfxterm.c: Add flag "functional" to skip input when - changing windows to avoid crash. - -2013-10-03 Vladimir Serbinenko - - * grub-core/kern/arm/cache.c: Add v5 write-through cache support. - -2013-10-03 Vladimir Serbinenko - - * po/exclude.pot: Add several strings to exclude. - -2013-10-03 Vladimir Serbinenko - - * tests/gettext_strings_test.in: Add getroot_*.c to exclude list. - -2013-10-03 Vladimir Serbinenko - - * autogen.sh: Add ./util/grub-gen-widthspec.c and - ./util/grub-gen-asciih.c to exclude list. - -2013-10-03 Vladimir Serbinenko - - * grub-core/gfxmenu/theme_loader.c (theme_set_string): Fix memory leak - and don't mark error strings for translation. - -2013-10-03 Vladimir Serbinenko - - * grub-core/disk/uboot/ubootdisk.c (uboot_disk_open): Use grub_error - properly in case of missing block size. - -2013-10-03 Vladimir Serbinenko - - * grub-core/lib/arm/setjmp.S: Add missing license section. - -2013-10-03 Vladimir Serbinenko - - * po/swiss.sed: Add replacement for key names and for term computer. - -2013-10-02 Vladimir Testov - - * grub-core/gfxmenu/theme_loader.c: New global options for the - theme background image handling. desktop-image-scale-method, - desktop-image-h-align, desktop-image-v-align. - * grub-core/gfxmenu/view.c: Likewise. - * include/gfxmenu_view.h: Likewise. - * include/bitmap_scale.h: Proportional scale functions introduced. - * grub-core/video/bitmap_scale.c: Likewise. Verification checks are - put in a separate functions. GRUB_ERR_BUG is set for grub_error in - cases of unexpected input variables for scale functions. - * docs/grub.texi: Updated documentation for new options. - -2013-10-02 Vladimir Serbinenko - - * grub-core/video/readers/png.c: Support narrow (4-/2-/1-bpp) PNG. - -2013-10-01 Vladimir Testov - - * grub-core/tests/checksums.h: Corrected due to changes in - bilinear interpolation function. - -2013-10-01 Vladimir Testov - - * grub-core/video/bitmap_scale.c (scale_bilinear): Increased precision - to eliminate artefacts in bilinear interpolation. - -2013-09-28 Vladimir Serbinenko - - * grub-core/video/readers/tga.c: Support paletted tga. - -2013-09-28 Vladimir Serbinenko - - * grub-core/video/readers/jpeg.c (grub_jpeg_decode_data): Remove - incorrect cbcr setting when in color mode. - -2013-09-28 Vladimir Serbinenko - - * grub-core/video/readers/png.c: Support paletted images and clean up - greyscale support. - -2013-09-28 Vladimir Serbinenko - - * grub-core/term/terminfo.c (grub_terminfo_readkey): Fix - usage of wrong table which resulted in mishandling of 4-byte - sequences. - -2013-09-28 Vladimir Serbinenko - - * grub-core/term/terminfo.c: Add Home and End key sequences. - -2013-09-27 Vladimir Serbinenko - - * grub-core/video/readers/png.c (grub_png_decode_image_header): - Fix formula for computing total number of bytes. - -2013-09-27 Vladimir Serbinenko - - * grub-core/video/readers/tga.c: Reorganize to separate RLE and - image processing, fix big-endian and support grayscale. - -2013-09-27 Vladimir Serbinenko - - * grub-core/video/fb/video_fb.c (grub_video_fb_create_render_target): - Correctly will with maximum transparency when using index color. - -2013-09-27 Vladimir Serbinenko - - * grub-core/video/readers/png.c: Support grayscale - -2013-09-27 Vladimir Serbinenko - - * grub-core/video/readers/jpeg.c: Support grayscale. - -2013-09-26 Jon McCune - - * grub-core/commands/loadenv.c: Support skipping signature check - and variable names filtering. - -2013-09-24 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk_unix.c: Declare AROS as non-unix. - * grub-core/kern/emu/hostfs.c: Likewise. - * util/getroot_unix.c: Likewise. - -2013-09-24 Vladimir Serbinenko - - * include/grub/emu/hostdisk.h (GRUB_FD_STAT_IS_FUNTIONAL): New define. - Migrate all explicit defines to this new one. - -2013-09-24 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_open): Use - grub_util_fd_strerror when using grub_util_fd_*. - (grub_util_fd_open_device): Likewise. - (grub_util_biosdisk_read): Likewise. - (grub_util_biosdisk_write): Likewise. - * grub-core/kern/emu/hostdisk_unix.c (grub_util_fd_open): New function. - (grub_util_fd_strerror): Likewise. - (grub_util_fd_sync): Likewise. - (grub_util_fd_close): Likewise. - * grub-core/kern/emu/hostdisk_windows.c (grub_util_fd_sync): Likewise. - (grub_util_fd_close): Likewise. - (grub_util_fd_strerror): Likewise. - * include/grub/emu/hostdisk.h (grub_util_fd_close): Make into real - function proto rather than macro. - (grub_util_fd_sync): Likewise. - (grub_util_fd_open): Likewise. - (grub_util_fd_strerror): New proto. - -2013-09-24 Vladimir Serbinenko - - * util/getroot.c (grub_util_biosdisk_is_present): Don't do stat on - platforms on which it doesn't work. - -2013-09-24 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_open): Move struct - stat immediately to where it's used. - -2013-09-24 Vladimir Serbinenko - - * util/getroot.c (grub_util_check_block_device): Move to ... - * util/getroot_unix.c (grub_util_check_block_device): ... here. - * util/getroot.c (grub_util_check_char_device): Move to ... - * util/getroot_unix.c (grub_util_check_char_device): ... here. - -2013-09-24 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_close): Fix - disk closing logic. - -2013-09-24 Andrey Borzenkov - - * docs/grub.texi (Simple configuration): Document GRUB_ENABLE_CRYPTODISK. - -2013-09-24 Andrey Borzenkov - - * docs/grub.texi (File name syntax): Document ZFS filenames - (/volume@snapshot/...). - -2013-09-23 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk_windows.c (grub_util_get_windows_path): - Always return full path. Fixes a problem with mkrelpath. - -2013-09-23 Paulo Flabiano Smorigo - - * util/grub-install.in: Add GPT PReP support. - * util/grub-probe.c (probe): Support GPT partition type. - (main): Support -t gpt_parttype. - -2013-09-23 Aleš Nesrsta - - * grub-core/bus/usb/ehci.c: SMI disabled in all cases - -2013-09-23 Massimo Maggi - - * grub-core/fs/zfs/zfs.c (check_pool_label): Check nvlist. - -2013-09-23 Tim Hardeck - - * util/grub.d/10_hurd.in: Filter out character for the class. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - -2013-09-23 Melki Christian - - * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Fix the type of - "changed". - -2013-09-23 Josh Triplett - - * grub-core/boot/i386/pc/lnxboot.S: Re-add support for recording the - boot partition. - -2013-09-23 Vladimir Serbinenko - - * Makefile.util.def (libgrubmods.a): Remove CFLAGS_POSIX as this lib - doesn't use posix_wrap. Keep literal -fno-builtin however. - -2013-09-23 Vladimir Serbinenko - - * conf/Makefile.common (CPPFLAGS_LIBFDT): Remove leftover. - -2013-09-23 Vladimir Serbinenko -2013-09-23 neil - - * configure.ac: Do not enable -Wmissing-noreturn as its - usefulness is limited and creates problems on some OS notably with - code generated by bison. - -2013-09-23 Vladimir Serbinenko -2013-09-23 neil - - * configure.ac: Do not explicitly enable -Waddress as it's not - supported by all gcc and when it is, it's already enabled by -Wall. - -2013-09-23 Vladimir Serbinenko - - * grub-core/video/efi_gop.c (grub_video_gop_setup): Fix a typo which - desactivated use of EDID at all. - -2013-09-23 Vladimir Serbinenko -2013-09-23 neil - - * grub-core/loader/multiboot.c (grub_multiboot_set_console): Always use - video if no text is available. - -2013-09-23 Vladimir Serbinenko -2013-09-23 neil - - * configure.ac: Substitute TARGET_RANLIB. - -2013-09-23 Vladimir Serbinenko -2013-09-23 neil - - * grub-core/genmod.sh.in: Remove ./ from TARGET_OBJ2ELF. Add quotes. - - Based on patches from AROS. - -2013-09-23 Vladimir Serbinenko -2013-09-23 neil - - * grub-core/Makefile.am: Override STRIP and RANLIB. - * configure.ac: compute TARGET_RANLIB. - * INSTALL: Document TARGET_RANLIB - - Based on patches from AROS. - -2013-09-23 Vladimir Serbinenko - - * util/getroot.c (grub_util_biosdisk_get_grub_dev): Do not assume - that floppies are unpartitioned. - -2013-09-23 Vladimir Serbinenko - - * util/getroot_unix.c [__MINGW32__ || __CYGWIN__]: - Define dummy grub_util_pull_lvm_by_command to decrease number of #if's. - -2013-09-23 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/sys/types.h: Use OpenBSD approach: it's - less nice but more portable. - * grub-core/lib/posix_wrap/wchar.h: Likewise. - -2013-09-23 Vladimir Serbinenko - - * include/grub/cryptodisk.h (grub_cryptodisk): Use grub_util_fd_t - for cheat_fd. - * grub-core/disk/cryptodisk.c (grub_cryptodisk_open): Use grub_util_* - functions. - (grub_cryptodisk_cheat_insert): Likewise. - (grub_cryptodisk_close): Likewise. - -2013-09-23 Vladimir Serbinenko - - * include/grub/emu/misc.h: Remove leftover cygwin definitions. - Use windows path for DEFAULT_DIRECTORY. - -2013-09-23 Vladimir Serbinenko - - * include/grub/i386/setjmp.h: Remove useless #if MINGW where original - difference was likely just gcc version, not anything mingw-related. - -2013-09-23 Vladimir Serbinenko - - Use Winapi on both cygwin and mingw32 to share more code between both. - -2013-09-22 Andrey Borzenkov - - * util/grub-install.in: Add --grub-editenv option. - * util/grub-install_header (grub_compress_file): Explicitly check for - plain file to avoid cp error. - -2013-09-22 Andrey Borzenkov - - * docs/grub.texi (Device syntax): Document new LVM UUID based device - names; fix LVM driver name (lvm, not lv). - * util/grub-probe.c (probe_abstraction): Support lvmid/xxx device - names. - -2013-09-22 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c: Disentagle into a series of OS-specific - files rather than one file with loads of #if's. - * util/getroot.c: Likewise. - -2013-09-22 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/sys/types.h: Use stddef on *BSD. - -2013-09-22 Vladimir Serbinenko - - * util/grub-mkpasswd-pbkdf2.c (grub_get_random): Add windows and - GNU/Hurd to the list of checked PRNG. - -2013-09-22 Vladimir Serbinenko - - * configure.ac: On FreeBSD use -melf_*_fbsd format. - -2013-09-21 Ales Nesrsta - - * grub-core/bus/usb/ehci.c: Corrected EHCI QH handling (async./sync.) - -2013-09-20 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c: Handle non-md UUIDs. - * grub-core/disk/lvm.c: Add LVM UUIDs. - * util/getroot.c: Use LVM UUIDs whenever possible. - -2013-09-19 Andrey Borzenkov - - * docs/grub.texi (Networking commands): Add documentation for - network related commands. - -2013-09-19 Vladimir Serbinenko - - * util/getroot.c (grub_util_open_dm): Check major rather than the name - to determine if device is handled by devmapper. - (convert_system_partition_to_system_disk): Likewise. - (get_dm_uuid): Don't check explicitly if device is mapped, it's - already done in grub_util_open_dm. - -2013-09-19 Leif Lindholm - - * kern/arm/cache.S: Correct access to ilinesz/dlinesz variables. - Clean up stack manipulation (sync_caches_armv*) - -2013-09-19 Vladimir Serbinenko - - * util/lvm.c: Remove since unused. Remove remaining references. - -2013-09-19 Vladimir Serbinenko - - Handle the case of partitioned LVM properly. - - * grub-core/kern/emu/hostdisk.c (grub_util_get_dm_node_linear_info): - Stop on meeting LVM, mpath or DMRAID. - (grub_hostdisk_os_dev_to_grub_drive): Canonicalize os device. - (read_device_map): Likewise. - * util/getroot.c (convert_system_partition_to_system_disk): Assume that - device is full disk rather than erroring out on LVM and similar cases. - -2013-09-18 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in: Keep supplied pkgdatadir if any. - -2013-09-18 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_mm_init_region): Skip regions less than - 4K before the end. - Reported by: Leif Lindholm - -2013-09-18 Pawel Wojtalczyk -2013-09-18 Vladimir Serbinenko - - * grub-core/term/efi/console.c (grub_console_getkey): Accept VT100-style - codes. - -2013-09-18 Colin Watson - - * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name_iter): - Remove no-longer-true __attribute__ ((unused)) on disk parameter. - -2013-09-18 Douglas Ray - - * util/grub-mkpasswd-pbkdf2.c (grub_get_random): Declare OpenBSD PRNG - as secure. - -2013-09-18 Aleš Nesrsta - - * docs/grub.texi: Fix broken link. - -2013-09-18 Melki Christian - - * grub-core/bus/usb/usb.c (grub_usb_device_initialize): Add condition - to break endless loop. - -2013-08-23 Vladimir Serbinenko - - * util/grub-fstest.c: Fix several printf formats. - * util/grub-mkimage.c: Likewise. - * util/grub-mkimagexx.c: Likewise. - * util/grub-script-check.c: Likewise. - -2013-08-23 Vladimir Serbinenko - - * grub-core/lib/xzembed/xz_dec_lzma2.c: Make -Wattributes not cause - error. - -2013-08-23 Vladimir Serbinenko - - * config.h.in [GRUB_BUILD]: Explicitly undefine ENABLE_NLS. - -2013-08-23 Vladimir Serbinenko - - * util/getroot.c (grub_find_device): Use cygwin_conv_path ratherthan - removed in current versions cygwin_conv_*. - -2013-08-23 Vladimir Serbinenko - - * configure.ac: Disable efiemu runtime on cygwin. - -2013-08-23 Vladimir Serbinenko - - * conf/Makefile.extra-dist: Add missing util/grub-gen-asciih.c, - util/grub-gen-widthspec.c and util/grub-pe2elf.c. - -2013-08-22 Vladimir Serbinenko - - * util/grub-mkpasswd-pbkdf2.c (grub_password_get): Remove extraneous - error message. - -2013-08-22 Vladimir Serbinenko - - * grub-core/lib/crypto.c (grub_password_get) [GRUB_UTIL]: Add - windows variant. - * util/grub-mkpasswd-pbkdf2.c: Add windows flavour for retrieving random - data. - -2013-08-22 Vladimir Serbinenko - - * configure.ac: Add -Wl,-melf_i386 and -Wl,-melf_x86_64 systematically - when on x86 and not cygwin. - * conf/Makefile.common: Remove unsystematic -Wl,-melf_i386 and - -Wl,-melf_x86_64. - -2013-08-22 Vladimir Serbinenko - - * configure.ac: Set CPP to build one when checkoing for freetype for - build. - -2013-08-22 Vladimir Serbinenko - - * util/grub-mkfont.c [!GRUB_BUILD]: Define my_argp_state. - [!GRUB_BUILD]: Remove has_argument. - -2013-08-22 Vladimir Serbinenko - - * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath) [_WIN32]: - Replace with a dummy. - -2013-08-22 Vladimir Serbinenko - - * configure.ac: Don't change host_os from mingw to cygwin. - -2013-08-22 Vladimir Serbinenko - - * configure.ac: Change target_os from windows to cygwin. - -2013-08-22 Vladimir Serbinenko - - Handle grub-pe2elf and grub-mkfont for cases when build != host. - - * Makefile.am (build-grub-mkfont): Don't include gnulib. - (build-grub-gen-asciih): Likewise. - (build-grub-gen-widthspec): Likewise. - * Makefile.util.def (grub-pe2elf): Remove. - * config.h.in [GRUB_BUILD]: Use build rather than host constants. - * configure.ac: Separate tests for build. - Move ./build-grub-pe2elf to grub-core. - Fix typo. - * grub-core/Makefile.am (build-grub-pe2elf): New target. - * grub-core/kern/emu/misc.c (xasprintf): Don't compile if GRUB_BUILD is - defined. - * include/grub/types.h [GRUB_BUILD]: Use build rather than host - constants. - * util/grub-mkfont.c [GRUB_BUILD]: Simplify not to rely on argp. - * util/grub-pe2elf.c: Simplify not to rely on getopt. - * util/misc.c (program_name) [GRUB_BUILD]: Define to static string. - -2013-08-22 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_size): Adapt for - mingw32 as well based on grub_util_get_disk_size. - * util/misc.c (grub_util_get_disk_size): Removed. all users switched to - grub_util_get_fd_size. - (sync): Removed. - (fsync): Moved to ... - * grub-core/kern/emu/misc.c (fsync): ... here. - -2013-08-22 Vladimir Serbinenko - - * include/grub/mm.h (grub_extend_alloc): Remove. - * grub-core/loader/i386/pc/plan9.c: Use own version of - grub_extend_alloc with appropriate types. - -2013-08-22 Vladimir Serbinenko - - * conf/Makefile.common (CFLAGS_GCRY): Add -Wno-redundant-decls. - -2013-08-22 Vladimir Serbinenko - - * util/getroot.c: Include sys/wait.h only when we need waitpid. - -2013-08-22 Vladimir Serbinenko - - Fix dependencies on cygwin. - - * gentpl.py: Support variable dependencies. Add $TARGET_OBJ2ELF to - dependencies when used and defined. - * grub-core/Makefile.core.def (regexp): Add dependency on libgnulib.a. - -2013-08-22 Vladimir Serbinenko - - * include/grub/zfs/spa.h (zio_cksum): Add explicit members for mac. - * grub-core/fs/zfs/zfs.c (zio_read): Don't use casts to retrieve mac. - -2013-08-22 Vladimir Serbinenko - - * grub-core/kern/emu/mm.c (grub_memalign): Don't define if there is no - implementation available to cause compile-time rather than runtime - error. - -2013-08-22 Vladimir Serbinenko - - * util/grub-fstest.c: Don't check for symlinks on windows. - -2013-08-22 Vladimir Serbinenko - - * INSTALL: Mention unavailability of man pages when cross-compiling. - -2013-08-22 Vladimir Serbinenko - - * include/grub/crypto.h: Don't declare gcry_log_bug, gcry_log_printf - and gcry_log_bug. - * grub-core/lib/libgcrypt_wrap/mem.c: Include g10lib.h - -2013-08-21 Vladimir Serbinenko - - * INSTALL: Document cross-compilation. - * acinclude.m4: Determine whether nm support -P and --defined-only. - * configure.ac: Add TARGET_ to all variables pertaining to target - that don't have it yet. - * gentpl.py: Likewise. - * grub-core/Makefile.am: Likewise. - * grub-core/genmod.sh.in: Likewise. - * grub-core/gensyminfo.sh.in: Handle OpenBSD and other non-GNU nm - as well. - -2013-08-21 Ilya Bakulin - - * configure.ac: Remove -Wempty-body. It's not essential and needs - recent gcc. - -2013-08-21 Ilya Bakulin - - * grub-core/kern/emu/hostdisk.c: Add conditionals for OpenBSD. - * util/getroot.c: Likewise. - -2013-08-21 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Add needed explicit cast. - * grub-core/lib/backtrace.c: Likewise. - * grub-core/net/ip.c: Likewise. - * grub-core/net/tcp.c: Likewise. - * grub-core/net/udp.c: Likewise. - -2013-08-21 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/wchar.h: Fix typo. - -2013-08-21 Vladimir Serbinenko - - * util/import_gcry.py: Add final newline in visibility.h. - -2013-08-21 Vladimir Serbinenko - - * conf/Makefile.common: Fix typo. - -2013-08-21 Vladimir Serbinenko - - * Makefile.util.def (grub-mkfont): Add missing libgnu.a. - -2013-08-21 Vladimir Serbinenko - - * Makefile.am (widthspec.h): Fix typo. - * util/grub-gen-widthspec.c: Likewise. - -2013-08-21 Vladimir Serbinenko - - Move ascii.h and widthspec.h generation to a separate build-time-only - tool. - -2013-08-16 Grégoire Sutre - - * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): - Always fill bootdisk info and improve check for NetBSD disklabel. - -2013-08-16 Vladimir Serbinenko - - * conf/Makefile.extra-dist: Add util/bin2h.c. - Reported by: floppym. - -2013-08-16 Vladimir Serbinenko - - * configure.ac: Make unifont mandatory for powerpc-ieee1275. - -2013-08-16 Vladimir Serbinenko - - * configure.ac: Disable unifont and starfield if no freetype was found. - -2013-08-16 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/wchar.h: Fix wchar_t and mbstate_t conflict - on NetBSD and OpenBSD. - -2013-08-15 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: Baseline misplacement fixed. - -2013-08-15 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: The number of color mappings is - reduced. Inheritant options are processed during the theme loading. - -2013-08-15 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: Minimal width fixed. - -2013-08-14 Avik Sil - - * grub-core/net/tftp.c: Send tftp ack packet before closing the socket. - -2013-08-14 Avik Sil - - * grub-core/net/drivers/ieee1275/ofnet.c: Get proper mac address when - using qemu. - -2013-08-14 Paulo Flabiano Smorigo - - * .bzrignore: Add bootinfo.txt, grub.chrp, gnulib/float.h, and - remove-potcdate.sed. - -2013-08-14 Andrey Borzenkov - - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_iterate): Remove - unused attribute from pull argument. - -2013-08-14 Andrey Borzenkov - - * util/getroot.c (grub_util_is_imsm): Fix descriptor and - memory leak. - -2013-08-14 Andrey Borzenkov - - * util/getroot.c (pull_lvm_by_command): add --separator option - to vgs call to disable padding of output to 10 characters. - -2013-08-14 Vladimir Serbinenko - - * grub-core/kern/emu/misc.c (grub_device_mapper_supported): Move from - here ... - * grub-core/kern/emu/hostdisk.c (grub_device_mapper_supported): ... to - here. - -2013-08-14 Vladimir Serbinenko - - * include/grub/i386/pc/biosdisk.h (grub_biosdisk_drp): Fix device_path - length. - -2013-08-14 Vladimir Serbinenko - - Fix handling of build-time grub-bin2h and grub-mkfont when doing - full Canadian cross. Tested with build=x86_64, host=arm, - target=ppc-ieee1275. - -2013-08-14 Vladimir Serbinenko - - * configure.ac: Error if no $BUILD_CC could be found. - Reported by: DevHC. - -2013-08-14 Vladimir Serbinenko - - * grub-core/kern/i386/coreboot/init.c: Fix compilation on - i386-multiboot. - -2013-08-14 Vladimir Serbinenko - - * grub-core/kern/vga_init.c: Fix compilation on qemu-mips. - * grub-core/kern/mips/qemu_mips/init.c: Likewise. - -2013-08-13 Colin Watson - - * util/getroot.c (grub_util_biosdisk_get_grub_dev): Zero out - grub_errno in the case where we handle GRUB_ERR_UNKNOWN_DEVICE by - falling back to the partition device, otherwise a later call to this - function may fail spuriously. - Reported by Axel Beckert. Fixes Debian bug #708614. - -2013-08-12 Grégoire Sutre - - * autogen.sh: Replace find -not by the POSIX-compliant find !. - -2013-08-12 Grégoire Sutre - - Prevent shadowing of stdlib's devname(3) on BSD. - - * grub-core/disk/cryptodisk.c (grub_cmd_cryptomount): Rename devname - and devlast to diskname and disklast, respectively. - -2013-08-11 Colin Watson - - * util/grub-mkconfig.in: Fix detection of Emacs autosave files. - -2013-08-08 Vladimir Testov - - * docs/grub.texi: Introduce terminal window position options: - terminal-left: terminal window's left position - terminal-top: terminal window's top position - terminal-width: terminal window's width - terminal-height: terminal window's height - terminal-border: terminal window's border width - * grub-core/gfxmenu/theme-loader.c: Likewise. - * include/grub/gfxmenu_view.h: Likewise. - * po/exlude.pot: Likewise. - * grub-core/gfxmenu/view.c: Likewise. - Also updated minimal window size. - Also terminal_sanity_check function has been introduced. - * grub-core/tests/checksums.h: Update (terminal window height - is adjusted now for low resolution screen) - -2013-08-02 Vladimir Serbinenko - - * grub-core/tests/checksums.h: Update (1-pixel difference in marker - position). - -2013-08-02 Vladimir Serbinenko - - * po/exclude.pot: Add few recent exceptions. - -2013-08-02 Vladimir Serbinenko - - * tests/grub_func_test.in: Add unicode.pf2. - -2013-08-02 Vladimir Serbinenko - - * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Start with - standard rather than noral color, in line with other terminals. - -2013-08-02 Vladimir Serbinenko - - * grub-core/partmap/dfly.c: Simplify dprintfs for easier gettext - analysis. - -2013-08-02 Vladimir Serbinenko - - * grub-core/loader/arm/linux.c: Change printf to dprintf. - -2013-08-02 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (check_feature): Cleanup and remove - inappropriate printf. - -2013-07-25 Andrey Borzenkov - - * .bzrignore: Remove grub-core/lib/dtc-grub, - grub-core/Makefile.libfdt.def - * conf/Makefile.extra-dist: Remove grub-core/Makefile.libfdt.def. - -2013-07-25 Vladimir Serbinenko - - * include/grub/video.h (grub_video_register): Keep double-linked as - well as single-linked invariants. - Reported by: qwertial. - -2013-07-25 Vladimir Serbinenko - - * grub-core/commands/nativedisk.c (get_uuid): Handle - GRUB_DISK_DEVICE_UBOOTDISK_ID. - -2013-07-25 Vladimir Testov - - * grub-core/gfxmenu/widget-box.c: Fixed draw function. Now it takes - maximum of NW, N, NE heights instead of N's height and maximum of - NW, W, SW widths instead of W's width. (So the box will be always - correctly drawn) - -2013-07-20 Grégoire Sutre - - * grub-core/partmap/bsdlabel.c (netopenbsdlabel_partition_map_iterate): - Fix misuse of variable count. - -2013-07-18 Leif Lindholm -2013-07-18 Francesco Lavra -2013-07-18 Vladimir Serbinenko - - New ports to arm-uboot and arm-efi. - Mostly by Leif Lindholm with some additions from - Francesco Lavra and cleanup by Vladimir Serbinenko. - -2013-07-16 Vladimir Serbinenko - - * grub-core/loader/multiboot_elfxx.c: Check eip after v2p translation - and not before. - Reported by: Leon Drugi. - -2013-07-16 Vladimir Serbinenko - - * grub-core/kern/powerpc/ieee1275/startup.S: Handle unaligned bss. - Reported by: Paulo Flabiano Smorigo. - -2013-07-14 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: USe viewport when drawing strings. - -2013-07-14 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: Fix height calculation. - -2013-07-14 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c: Stylistic fixes. - -2013-07-14 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c: Run emacs indent on file. - -2013-07-14 Andrey Borzenkov - - * grub-core/net/bootp.c: Export net_* variables. - * grub-core/net/net.c: Likewise. - -2013-07-14 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c: Remove brackets around return value. - -2013-07-14 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs_lz4.c: Add missing packed attribute. - -2013-07-14 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (nvlist_next_nvpair): Fix improper cast. - -2013-07-14 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs_lz4.c: Remove restrict keyword. - -2013-07-14 Massimo Maggi - - * grub-core/fs/zfs/zfs.c (nvlist_next_nvpair): Error is encode_size - <= 0. - -2013-07-14 Massimo Maggi - - * grub-core/fs/zfs/zfs.c: Split nvpair iterators into separate - functions. - -2013-07-14 Massimo Maggi - - * grub-core/fs/zfs/zfs_lz4.c: New file. - * grub-core/fs/zfs/zfs.c: Tie up lz4 decompression. - -2013-07-14 Massimo Maggi - - * grub-core/fs/zfs/zfs.c: Check for feature compatibility. - -2013-07-14 Massimo Maggi - - * grub-core/fs/zfs/zfs.c (uberblock_verify): Accept version 5000. - (check_pool_label): Likewise. - * include/grub/zfs/zfs.h: Rewrite SPA_VERSION_* macros. - -2013-07-14 Massimo Maggi - - * grub-core/fs/zfs/zfsinfo.c (print_vdev_info): Fix RAIDZ reporting. - -2013-07-13 Andrey Borzenkov - - * docs/grub.texi (Commands): Document postition parameters - for menuentry command. - -2013-07-13 Andrey Borzenkov - - * util/grub-mknetdir.in: Remove stray line from help output. - -2013-07-11 Vladimir Serbinenko - - Remove early sm712 init as there is no reason for it (the "watchdog" - effect was due to wrong GPIO map). - -2013-07-11 Vladimir Serbinenko - - * grub-core/commands/pcidump.c: Remove static variables. - -2013-07-11 Vladimir Serbinenko - - * grub-core/commands/sleep.c: Refresh screen before sleeping. - -2013-07-11 Vladimir Serbinenko - - * configure.ac: Move delimiter after the infos. - -2013-07-11 Vladimir Serbinenko - - * grub-core/bus/usb/usbhub.c: Fix recheck logic. - -2013-07-11 Vladimir Serbinenko - - * util/grub-mkfont.c (write_font_ascii_bitmap): Fix handling of glyphs - not filling whole 8x16 space. - -2013-07-11 Vladimir Serbinenko - - * grub-core/normal/charset.c (bidi_line_wrap): Fix spurios warning. - -2013-07-11 Vladimir Serbinenko - - * configure.ac: Indicate which liblzma is used if any. - -2013-06-21 Paul Wise -2013-06-21 Craig Sanders - - * util/grub-reboot.in: Document submenu usage. - -2013-06-25 Colin Watson - - * .bzrignore: Update with a number of new test-related files. - -2013-06-25 Colin Watson - - * util/grub-script-check.c: Fail on scripts containing no - commands, to guard against corrupted grub-mkconfig setups that - produce no useful output. - * tests/grub_script_no_commands.in: New test. - * Makefile.util.def (grub_script_no_commands): Add. - Reported by Hans Putter. Fixes Debian bug #713886. - -2013-06-16 Andrey Borzenkov - - * grub-core/disk/diskfilter.c: Forgot to remove comment - from previous commit. - -2013-06-16 Andrey Borzenkov - - * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use - grub_term_normal_color, do not hardcode GRUB_TERM_DEFAULT_NORMAL_COLOR. - -2013-06-16 Andrey Borzenkov - - * conf/Makefile.extra-dist: Add grub-core/fs/cpio_common.c. - -2013-06-16 Andrey Borzenkov - - * grub-core/disk/diskfilter.c (scan_devices): Iteratively - rescan diskfilter devices until nothing new is found. - -2013-06-16 Vladimir Serbinenko - - Fix casts when compiling coreboot-specific code for 64-bit EFI. - -2013-06-16 Vladimir Serbinenko - - Don't try to detect cbfs on *-emu. - -2013-06-16 Vladimir Serbinenko - - * grub-core/term/gfxterm.c: USe right background color when scrolling. - -2013-06-16 Vladimir Serbinenko - - Add support for processed coreboot payload chainloading. - -2013-06-16 Vladimir Serbinenko - - Enable coreboot information commands even when not loaded as - coreboot payload (e.g. when loaded from SeaBIOS-as-payload). - -2013-06-15 Vladimir Serbinenko - - Support for cbfs. Also factor out the part which is common - for all archives to a separate module. This splits tar from cpio - as they are very different but keeps cpio, cpio_be, odc and newc - together since they're very similar. - -2013-06-15 David Michael - - * configure.ac (FREETYPE): Change AC_CHECK_PROGS to AC_CHECK_TOOLS. - (freetype_cflags,freetype_libs): Change freetype-config to $FREETYPE. - -2013-06-15 Vladimir Serbinenko - - * tests/grub_script_eval.in: Really add the eval test. - -2013-06-14 Vladimir Serbinenko - - Move flavour-specific parts out of common cpio.c file and - rename remaining to cpio_common.c - -2013-06-07 Andrey Borzenkov - - * grub-core/script/execute.c (grub_script_execute_sourcecode): Split - off new function grub_script_execute_new_scope. Change callers to use - either of them as appropriate. - * grub-core/commands/eval.c: New command eval. - * docs/grub.texi (Commands): Document it. - -2013-06-07 Andrey Borzenkov - - * grub-core/kern/corecmd.c (grub_core_cmd_set): Use grub_env_get - to fetch values when listing. - -2013-06-07 Andrey Borzenkov - - Fix make dist on non-pc. - -2013-06-07 Francesco Lavra - - * grub-core/kern/corecmd.c (grub_core_cmd_ls): Fix handling of paths - without a device name. - -2013-06-07 Vladimir Serbinenko - - Remove enable_executable_check as it's not needed anymore. - Reported by: dougray. - -2013-06-07 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (insert_array): Fix order to discover - ambigouos RAID before discovering RAIDs on top of it. - Reported by: bodom. - -2013-06-07 Vladimir Serbinenko - - Fix typo (failback vs fallback). - -2013-05-31 Andrey Borzenkov - - * util/grub.d/30_os-prober.in: Add support for probing EFI - System Partition (as of os-prober 1.58). - -2013-05-31 Vladimir Serbinenko - - * configure.ac: Add yet another path to unifont. For parabola. - -2013-05-30 Josh Triplett - - * grub-core/normal/cmdline.c (grub_cmdline_get): Fix Ctrl-u - handling to copy the killed characters to the kill buffer as - UCS4 stored as grub_uint32_t rather than as 8-bit characters - stored as char. Eliminates UCS4 truncation and corruption - observed when killing characters with Ctrl-u and yanking them - back with Ctrl-y. - -2013-05-30 Vladimir Serbinenko - - Detach optional parts of gfxterm and integrate in with coreboot init. - -2013-05-30 Vladimir Serbinenko - - Move blit and fill dispatcher to appropriate files to decrease export - and relocation overhead. - -2013-05-30 Vladimir Serbinenko - - * grub-core/font/font.c, include/grub/font.h: Inline simple font - functions. - -2013-05-30 Vladimir Serbinenko - - * grub-core/Makefile.am: Fix compilation problem with some - automake versions. - -2013-05-30 Vladimir Serbinenko - - * configure.ac: Add Ubuntu path to unifont and report unifont path used. - -2013-05-30 Vladimir Serbinenko - - * Makefile.am, conf/Makefile.common: Fix compilation problem with some - automake versions. - -2013-05-30 Vladimir Serbinenko - - * grub-core/commands/acpihalt.c: Fix handling of DSDT in presence of - SSDT. - -2013-05-15 Radosław Szymczyszyn - - * grub-core/partmap/dfly.c: New partition map. - -2013-05-15 Vladimir Serbinenko - - * grub-core/kern/corecmd.c (grub_core_cmd_ls): Fix empty path - checking. - Reported by: Francesco Lavra. - -2013-05-14 Andrey Borzenkov - - * gentpl.py: Replace EXTRA_DIST with dist_noinst_DATA or - dist__DATA. EXTRA_DIST is ignored by automake inside - false conditions. - * conf/Makefile.common: define dist_grubconf_DATA - -2013-05-14 Vladimir Serbinenko - - Progressively skip menu elements on small terminals rather - than crashing. - -2013-05-14 Vladimir Serbinenko - - * grub-core/normal/cmdline.c (grub_cmdline_get): Fix off-by-one error - to avoid losing last column. - -2013-05-14 Vladimir Serbinenko - - * po/exclude.pot: Add missing string "%C". - -2013-05-14 Vladimir Serbinenko - - * tests/util/grub-shell.in: Remove the temporary directory on grub-emu - after the test. - -2013-05-11 Vladimir Serbinenko - - * util/grub-install.in: Gettextize "Not found" message. - -2013-05-11 Vladimir Serbinenko - - Fix distfiles list. - Reported by: Andrey Borzenkov - -2013-05-11 Paulo Flabiano Smorigo - - * grub-core/net/bootp.c (grub_cmd_bootp): Check if there is any card - present. - * include/grub/err.h (grub_err_t): New enum value GRUB_ERR_NET_NO_CARD. - -2013-05-11 Vladimir Serbinenko - - * grub-core/tests/setjmp_test.c: Ignore missing noreturn. - -2013-05-11 Vladimir Serbinenko - - * grub-core/fs/hfspluscomp.c (grub_hfsplus_compress_attr): Add packed - attribute since structure is not necessarily aligned. - -2013-05-11 Andrey Borzenkov - - * docs/grub.texi (Device syntax): Clarify description of network - drives. - -2013-05-10 Vladimir Serbinenko - - Redirect xasprintf to grub_xvasprintf rather than having #ifdef's - for vasprintf presence. - -2013-05-10 Vladimir Serbinenko - - * util/grub-install.in: Handle efibootmgr presence check. - Reported by: Leif Lindholm. - -2013-05-10 Vladimir Serbinenko - - * grub-core/commands/testspeed.c: Reuse formatting string to decrease - new strings to translate. - -2013-05-10 Vladimir Serbinenko - - * util/grub-mkrescue.in: Replace `STR' with `STRING' to avoid adding - yet another string (pun intended) to translate. - -2013-05-10 Vladimir Serbinenko - - * po/POTFILES-shell.in: Autogenerate it. - -2013-05-10 Vladimir Serbinenko - - * grub-core/net/net.c (grub_net_open_real): Autoload network modules. - -2013-05-10 Vladimir Serbinenko - - * grub-core/term/terminfo.c: Rename ANSI_C0 to ANSI_CSI to avoid - misnomer. - -2013-05-08 Andrey Borzenkov - - * docs/grub.texi (Network): Add description of net_default_interface, - net_default_ip and net_default_mac. Rewrite variables description - to emphasize that they are per-interface. - -2013-05-08 Vladimir Serbinenko - - New test: cmdline and cat. - -2013-05-08 Vladimir Serbinenko - - * grub-core/commands/cat.c: Show UTF-8 characters. - -2013-05-08 Vladimir Serbinenko - - * conf/Makefile.common: Poison float and double on non-emu. - -2013-05-08 Vladimir Serbinenko - - * configure.ac: Don't disable extended registers on emu. - -2013-05-07 Vladimir Serbinenko - - * configure.ac: Don't use extended registers on x86_64. - Reported by: Peter Jones. - -2013-05-07 Vladimir Serbinenko - - * grub-core/term/efi/console.c: Fix compile error. - -2013-05-07 Vladimir Serbinenko - - Compressed HFS+ support. - -2013-05-07 Vladimir Serbinenko - - * grub-core/commands/videoinfo.c: Use "paletted" rather than "packed - pixel". - -2013-05-07 Vladimir Serbinenko - - Menu color test. - -2013-05-07 Vladimir Serbinenko - - * grub-core/tests/setjmp_test.c: New test. - -2013-05-07 Vladimir Serbinenko - - New variables 'net_default_*' to determine MAC/IP of default interface. - -2013-05-07 Vladimir Serbinenko - - * tests/gettext_strings_test.in: A test to check for strings not - marked for translation. - -2013-05-07 Vladimir Serbinenko - - * autogen.sh: Exclude unused libgcrypt files from translation. - -2013-05-07 Vladimir Serbinenko - - Simplify few strings. - -2013-05-07 Vladimir Serbinenko - - Mark few forgotten strings for translation. - -2013-05-07 Vladimir Serbinenko - - * grub-core/loader/linux.c: Use grub_dprintf for debug statements - rather than printf. - -2013-05-07 Vladimir Serbinenko - - * grub-core/video/readers/jpeg.c: Use grub_dprintf for debug statements - rather than printf. - * grub-core/video/readers/tga.c: Likewise. - -2013-05-07 Vladimir Serbinenko - - * tests/priority_queue_unit_test.cc: New test. - -2013-05-07 Vladimir Serbinenko - - * grub-core/font/font.c: Use grub_dprintf for debug statements rather - than printf. - -2013-05-06 Andrey Borzenkov - - Reimplement grub-reboot to not depend on saved_entry. Use next_entry - variable for one time boot menu entry. - -2013-05-05 Bean - - * grub-core/commands/testspeed.c: New command testspeed. - -2013-05-05 Vladimir Serbinenko - - Factor-out human-size printing. - -2013-05-04 Vladimir Serbinenko - - Agglomerate more mallocs to speed-up gfxterm. - -2013-05-04 Vladimir Serbinenko - - Speed-up gfxterm by slightly agglomerating mallocs. - -2013-05-04 Vladimir Serbinenko - - More video checks. - -2013-05-04 Vladimir Serbinenko - - Speed-up gfxterm by saving intermediate results in index+alpha - format. - -2013-05-04 Vladimir Serbinenko - - * grub-core/tests/lib/functional_test.c: Don't stop on first failed - test. - -2013-05-04 Vladimir Serbinenko - - * grub-core/normal/menu_text.c (menu_clear_timeout): Clear second - line of timeout as it may contain the rest of long line. - -2013-05-04 Vladimir Serbinenko - - * grub-core/normal/main.c: Fix freed memory dereference. - -2013-05-04 Vladimir Serbinenko - - Fix several memory leaks. - -2013-05-04 Vladimir Serbinenko - - * grub-core/normal/menu.c (run_menu): Fix timeout reference point. - -2013-05-04 Vladimir Serbinenko - - * grub-core/gettext/gettext.c: Try $lang.gmo as well. - -2013-05-04 Vladimir Serbinenko - - Fix test -a and -o precedence. - Reported by: adrian15. - -2013-05-04 Vladimir Serbinenko - - * grub-core/font/font.c (grub_font_construct_glyph): Fix memory leak. - -2013-05-03 Andrey Borzenkov - - Rename grub-core/tests/checksums.c into grub-core/tests/checksums.h - and add it as source to functional_test module. - -2013-05-03 Vladimir Serbinenko - - * grub-core/tests/video_checksum.c: Don't set GENERATE_MODE. - -2013-05-03 Vladimir Serbinenko - - New series of tests for gfxterm and gfxmenu. - -2013-05-03 Vladimir Serbinenko - - * grub-core/gfxmenu/gfxmenu.c (grub_gfxmenu_try): Allow specifying - the theme path relative to $prefix/themes. - -2013-05-03 Vladimir Serbinenko - - * grub-core/video/fb/fbblit.c (grub_video_fbblit_blend_BGR888_RGBA8888): - Fix order bug. - (grub_video_fbblit_blend_RGB888_RGBA8888): Likewise. - -2013-05-03 Vladimir Serbinenko - - * include/grub/gui.h (grub_gfxmenu_timeout_unregister): Free cb - descriptor. - -2013-05-03 Vladimir Serbinenko - - * grub-core/gfxmenu/view.c (grub_gfxmenu_view_new): Clear - grub_gfxmenu_timeout_notifications. - (grub_gfxmenu_view_destroy): Likewise. - -2013-05-03 Vladimir Serbinenko - - * grub-core/normal/term.c (print_ucs4_real): Fix startwidth in dry run. - -2013-05-02 Vladimir Serbinenko - - Several fixes to ieee1275 and big-endian video. - -2013-05-02 Vladimir Serbinenko - - Add missing exports on mips. - -2013-05-02 Vladimir Serbinenko - - * grub-core/tests/videotest_checksum.c (videotest_checksum): Error out - if no unifont is found. - Restore original keyboard. - -2013-05-02 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_linux_setup_video): Add - GRUB_VIDEO_ADAPTER_CAPTURE: to handled drived ids. - -2013-05-02 Vladimir Serbinenko - - First automated video test (running videotest and comparing results) - -2013-05-02 Vladimir Serbinenko - - * grub-core/commands/videotest.c: Reduce flickering and draw 6 squares - instead of 2 to have full RGB/CMY test pattern. - -2013-04-30 Vladimir Serbinenko - - Add few more tests. - -2013-04-30 Vladimir Serbinenko - - * include/grub/arc/arc.h: Account for missing "other" peripheral on - ARCS. All users updated. - -2013-04-30 Vladimir Serbinenko - - * grub-core/kern/mips/loongson/init.c: Support halt for loongson 2E. - -2013-04-30 Vladimir Serbinenko - - * grub-core/partmap/amiga.c: Fix size of checksummed block. - -2013-04-29 Vladimir Serbinenko - - * configure.ac: Use -mcmodel=large on x86_64-emu as well. - Reported by: qwertial. - -2013-04-29 Vladimir Testov - - * grub-core/gfxmenu/circular_progress.c: Set start_angle in degrees - with syntax "XXX deg"/"XXX °". - -2013-04-29 Vladimir Serbinenko - - Make PCI init in i386-qemu port more robust. - -2013-04-29 Vladimir Testov - - * grub-core/gfxmenu/gui_list.c: Refresh first_shown_entry value when - cached view is reused. - * grub-core/gfxmenu/view.c: Call the refresh procedure for all - open boot menus. - -2013-04-29 Vladimir Serbinenko - - Unify more code in grub-install_header. - -2013-04-29 Vladimir Serbinenko - - Add few new tests. - -2013-04-29 Vladimir Serbinenko - - Enforce disabling of firmware disk drivers when native drivers kick in. - -2013-04-29 Vladimir Serbinenko - - * grub-core/commands/nativedisk.c: Customize the list of modules on - platform. Don't try to search for disks already using native drivers. - -2013-04-29 Vladimir Serbinenko - - * grub-core/bus/usb/uhci.c: Fix DMA handling and enable on all PCI - platforms. - -2013-04-29 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_arglist_to_argv): Fix - handling of variables containing backslash. - -2013-04-29 Vladimir Serbinenko - - * include/grub/list.h (FOR_LIST_ELEMENTS_SAFE):Fix a NULL pointer - dereference. - Reported by: qwertial. - -2013-04-29 Vladimir Serbinenko - - * grub-core/kern/mips/arc/init.c: Fix prefix detection. - -2013-04-29 Vladimir Serbinenko - - * grub-core/lib/arg.c (grub_arg_show_help): Fix a NULL pointer - dereference. - Reported by: qwertial. - -2013-04-28 Vladimir Serbinenko - - * docs/grub.texi: Add a comment about usefullness of nativedisk. - -2013-04-28 Vladimir Serbinenko - - * grub-core/commands/nativedisk.c: Ignore unknown filesystem error. - -2013-04-28 Vladimir Serbinenko - - New command `nativedisk'. - -2013-04-28 Vladimir Serbinenko - - * grub-core/io/lzopio.c: Use GRUB_PROPERLY_ALIGNED_ARRAY. - * grub-core/loader/i386/bsd.c: Likewise. - -2013-04-28 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Fix compilation for amd64 (format warnings). - -2013-04-28 Vladimir Serbinenko - - * include/grub/efi/api.h (GRUB_EFI_DEVICE_PATH_LENGTH): Use - grub_get_unaligned16 rather than shifts. - -2013-04-28 Vladimir Serbinenko - - * grub-core/kern/file.c: Use const char * rather than casting to - non-const. - -2013-04-28 Vladimir Serbinenko - - * grub-core/commands/probe.c: Add missing grub_device_close. - -2013-04-28 Vladimir Serbinenko - - * INSTALL: Document linguas.sh. - -2013-04-28 Vladimir Serbinenko - - Remove POTFILES.in and regenerate it in autogen.sh. - -2013-04-28 Vladimir Serbinenko - - Move --directory/--override-directorry to grub-install_header and unify. - -2013-04-28 Vladimir Serbinenko - - * grub-core/term/morse.c: Macroify dih and dah. - -2013-04-27 Paulo Flabiano Smorigo - - * include/grub/macho.h: Set GRUB_MACHO_FAT_EFI_MAGIC as unsigned. - -2013-04-27 Vladimir Serbinenko - - * grub-core/term/ns8250.c: Systematically probe ports by writing - to SR before using them. - -2013-04-27 Paulo Flabiano Smorigo - - * util/ieee1275/ofpath.c (of_path_of_scsi): Fix path output for sas - disks. - (check_sas): Get sas_adress info. - -2013-04-27 Vladimir Serbinenko - - * grub-core/disk/ahci.c (grub_ahci_pciinit): Fix handling of empty - ports. - -2013-04-27 Leon Drugi - - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_load): Fix cast in - BSS clearing. - -2013-04-27 Vladimir Serbinenko - - Core compression test. - -2013-04-27 Vladimir Serbinenko - - Implement grub_machine_get_bootlocation for ARC. - -2013-04-27 Vladimir Serbinenko - - Improve AHCI detection and command issuing. - -2013-04-26 Vladimir Serbinenko - - Fix pseries test. - -2013-04-26 Vladimir Serbinenko - - Make 'make check' work on emu. - -2013-04-26 Vladimir Serbinenko - - Replace libcurses with our own vt100 handling for the ease of testing - and decreasing prerequisites. - -2013-04-26 Vladimir Serbinenko - - * grub-core/Makefile.core.def: Fix grub-emu and grub-emu-lite sources. - -2013-04-26 Vladimir Serbinenko - - * util/getroot.c (exec_pipe): Put proper #if's so that its users don't - compile when not needed. - -2013-04-26 Vladimir Serbinenko - - * tests/pseries_test.in: New test. - -2013-04-26 Vladimir Serbinenko - - Add test to check that different boot mediums work. - -2013-04-26 Vladimir Serbinenko - - * util/grub-mkrescue.in: Rename i386-ieee1275 core image due to - ofw limited ISO support. - -2013-04-26 Vladimir Serbinenko - - * configure.ac: Fix loongson conditional. - -2013-04-25 Vladimir Serbinenko - - Enable mipsel-arc. - -2013-04-25 Vladimir Serbinenko - - Add serial on ARC platform. - -2013-04-25 Vladimir Serbinenko - - * grub-core/boot/powerpc/bootinfo.txt.in: Missing update from previous - commit. - -2013-04-25 Vladimir Serbinenko - - * tests/partmap_test.in: Add missing double semicolon. - -2013-04-25 Vladimir Serbinenko - - * util/grub-mkrescue.in: Fix loongson filename. - -2013-04-25 Vladimir Serbinenko - - * util/grub-mkrescue.in: Move all files that don't have a location - set in stone under /boot/grub. Use ISO hard links rather than copies - to save some space. - -2013-04-24 Vladimir Serbinenko - - * grub-core/term/ieee1275/console.c (grub_console_dimensions): Ignore - bogus SLOF values. - -2013-04-24 Vladimir Serbinenko - - Make check work on mips-arc. - -2013-04-24 Vladimir Serbinenko - - * util/grub-mkrescue.in: Alias sashARCS as sash. - -2013-04-24 Vladimir Serbinenko - - * grub-core/term/arc/console.c: Assume that console is 80x24 vt100 if - it's serial. - -2013-04-24 Vladimir Serbinenko - - * util/grub-install.in: Fix target fo qemu_mips. - Fix extension on EFI. - -2013-04-24 Vladimir Serbinenko - - * grub-core/normal/menu_text.c (print_entry): Put an asterisk - in front of chosen entry to mark it even if highlighting is lost. - -2013-04-24 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_linux_boot): Default to - gfxpayload=keep if cbfb is active. - -2013-04-24 Vladimir Serbinenko - - * grub-core/disk/ata.c (grub_ata_real_open): Use grub_error properly. - -2013-04-24 Vladimir Serbinenko - - Add missing video ids to coreboot and ieee1275 video. - -2013-04-24 Vladimir Serbinenko - - * util/grub-mkrescue.in: Add mips-arc support. - -2013-04-24 Vladimir Serbinenko - - * grub-core/kern/dl.c (grub_dl_resolve_symbols): Handle malloc failure. - -2013-04-24 Vladimir Serbinenko - - Move mips-arc link address. Previous link address was chosen - in belief that RAM on SGI platforms grows down while in fact it - grows up from an unusual base. - -2013-04-21 Vladimir Serbinenko - - * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate_iter): - Fix a type which prevented CD-ROM and floppy boot. - -2013-04-21 Vladimir Serbinenko - - Support coreboot framebuffer. - - * grub-core/video/i386/coreboot/cbfb.c: New file. - -2013-04-20 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_mm_init_region): Fix condition for - detecting too small regions. - -2013-04-20 Vladimir Serbinenko - - * grub-core/Makefile.core.def (legacycfg): Enable on EFI. - -2013-04-20 Vladimir Serbinenko - - * grub-core/lib/efi/relocator.c (grub_relocator_firmware_alloc_region): - Remove dprintf. - * grub-core/lib/relocator.c (malloc_in_range): Likewise. - -2013-04-19 Vladimir Serbinenko - - * grub-core/kern/ieee1275/init.c (grub_claim_heap): Improve handling - of GRUB_IEEE1275_FLAG_FORCE_CLAIM. - * grub-core/loader/powerpc/ieee1275/linux.c - (grub_linux_claimmap_iterate): Handle GRUB_IEEE1275_FLAG_FORCE_CLAIM. - -2013-04-19 Vladimir Serbinenko - - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): - Look for /boot-rom as well as /rom/boot-rom. - -2013-04-19 Vladimir Serbinenko - - * grub-core/commands/videotest.c (grub_cmd_videotest): Fix error - handling when creating text_layer failed. - * grub-core/video/video.c (grub_video_create_render_target): - Set result to 0 on error. - (grub_video_delete_render_target): Do not dereference NULL. - -2013-04-19 Vladimir Serbinenko - - * grub-core/kern/elfXX.c (grub_elfXX_load): Handle - GRUB_ELF_LOAD_FLAGS_30BITS and GRUB_ELF_LOAD_FLAGS_62BITS. - * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32), - (grub_linux_load64): Mask out 2 high bits. - -2013-04-19 Andrey Borzenkov - - * util/grub.d/30_os-prober.in: Add onstr to linux entries in one - more place. - -2013-04-19 Vladimir Serbinenko - - Add support for pseries and other bootinfo machines to grub-mkrescue. - - Tested by: Paulo Flabiano Smorigo. - -2013-04-17 Vladimir Serbinenko - - * util/grub-mkrescue.in: Add GPT for EFI boot. - -2013-04-17 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c: Detect floppies by ACPI ID. - It improves performance in qemu. - -2013-04-17 Vladimir Serbinenko - - * build-aux/snippet: Add missing gnulib files. - -2013-04-16 Andrey Borzenkov - - * grub-core/disk/efi/efidisk.c: Really limit transfer chunk size. - -2013-04-16 Andrey Borzenkov - - * autogen.sh: Use "-f" in addition for "-h" when checking file presence. - -2013-04-15 Vladimir Serbinenko -2013-04-15 Peter Jones - - * grub-core/disk/efi/efidisk.c: Limit disk read or write chunk to 0x500 - sectors. - Based on patch by Peter Jones. - -2013-04-15 Vladimir Serbinenko - - Fix DMRAID partition handling. - -2013-04-15 Vladimir Serbinenko - - * tests/grub_cmd_date.in: Skip on sparc64. - -2013-04-15 Vladimir Serbinenko - - * tests/grub_script_expansion.in: Use fixed-string grep to skip over - firmware error messages. - -2013-04-15 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_devalias_next): Make - source and destination differ. - -2013-04-15 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c: Fix CD-ROM and boot device - detection. - -2013-04-14 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/sys/types.h: Make WORDS_BIGENDIAN definition - match config-util.h to avoid warnings and increase compatibility. - -2013-04-14 Szymon Janc -2013-04-14 Vladimir Serbinenko - - Add option to compress files on install/image creation. - -2013-04-14 Vladimir Serbinenko - - * docs/grub-dev.texi: Rearrange menu to match the section order. - Reported by: Bryan Hundven. - -2013-04-14 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c: Remove useless leftover pointer. - -2013-04-14 Vladimir Serbinenko - - Move GRUB out of system area when using xorriso 1.2.9 or later. - -2013-04-14 Vladimir Serbinenko - - * tests/grub_cmd_date.in: Add missing exit 1. - -2013-04-14 Vladimir Serbinenko - - * tests/partmap_test.in: Skip on sparc64. - -2013-04-14 Vladimir Serbinenko - - Support grub-shell on sparc64. - -2013-04-14 Vladimir Serbinenko - - Support mkrescue on sparc64. - -2013-04-14 Vladimir Serbinenko - - Allow IEEE1275 ports on path even if it wasn't detected automatically. - Needed on OpenBIOS due to incomplete device tree. - -2013-04-14 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c: Iterate over bootpath even if it - would be otherwise excluded. - -2013-04-14 Vladimir Serbinenko - - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): - Inline name defines used only once. - -2013-04-13 Vladimir Serbinenko - - Fix memory leaks in ofnet. - Reported by: Francesco Lavra. - -2013-04-12 Vladimir Serbinenko - - * docs/man/grub-glue-efi.h2m: Add missing file. - -2013-04-12 Vladimir Serbinenko - - * util/grub-mkrescue.in: Fix wrong architecture for ppc dir. - -2013-04-12 Vladimir Serbinenko - - Better support Apple Intel Macs on CD. - -2013-04-12 Vladimir Serbinenko - - Replace stpcpy with grub_stpcpy in tools. - -2013-04-12 Vladimir Serbinenko - - Handle Japanese special keys. - Reported by: Hiroyuki YAMAMORI. - Codes supplied by: Hiroyuki YAMAMORI. - -2013-04-12 Vladimir Serbinenko - - * util/grub-mkimage.c: Document memdisk implying --prefix. - -2013-04-12 Vladimir Serbinenko - - * grub-core/bus/usb/ehci.c (grub_ehci_fini_hw): Ignore errors, not - much we can do about it anyway. - -2013-04-12 Aleš Nesrsta - - Fix handling of split transfers. - -2013-04-12 Vladimir Serbinenko - - * grub-core/net/http.c: Fix bad free. - -2013-04-12 Vladimir Serbinenko - - * grub-core/net/drivers/ieee1275/ofnet.c: Don't attempt to send more - than buffer size. - -2013-04-12 Vladimir Serbinenko - - Disable partmap check on i386-ieee1275 due to openfirmware issues. - -2013-04-12 Vladimir Serbinenko - - * tests/util/grub-shell.in: Fix it on powerpc. - -2013-04-12 Vladimir Serbinenko - - Turn off QEMU ACPI-way since new releases don't have shutdown port - anymore. - -2013-04-12 Vladimir Serbinenko - - * docs/grub.texi: Update coreboot status info. - -2013-04-12 Vladimir Serbinenko - - * tests/grub_cmd_date.in: New test for datetime. - -2013-04-12 Vladimir Serbinenko - - * tests/partmap_test.in: Fix missing qemudisk setting. - -2013-04-11 Vladimir Serbinenko - - Support i386-ieee1275 grub-mkrescue and make check on it. - -2013-04-11 Vladimir Serbinenko - - Merge powerpc grub-mkrescue flavour with common. Use xorriso HFS+ - feature for it. - -2013-04-11 Vladimir Serbinenko - - * docs/grub.texi: Fix description of GRUB_CMDLINE_XEN and - GRUB_CMDLINE_XEN_DEFAULT. - Reported by: Marc Warne (GigaTux) - -2013-04-11 Vladimir Serbinenko - - Import new gnulib. - -2013-04-11 Vladimir Serbinenko - - Use ACPI shutdown intests as traditional port was removed. - -2013-04-11 Andrey Borzenkov - - * util/grub.d/30_os-prober.in: Add onstr to entries for visual - distinction. - -2013-04-11 Vladimir Serbinenko - - Fix missing PVs if they don't contain "interesting" LV. Closes #38677. - Fix few warining messages and leaks while on it. - -2013-04-09 Andrey Borzenkov - - * autogen.sh: Use "-h", not "-f", to test for existence of symbolic - links under grub-core/lib/libgcrypt-grub/mpi. - -2013-04-08 Vladimir Serbinenko - - Fix ia64-efi image generation on big-endian machines. Deduplicate - some code while on it. - Reported by: Leif Lindholm. - -2013-04-08 Andrey Borzenkov - - * grub-core/Makefile.core.def: Add kern/elfXX.c to elf module - as extra_dist. - -2013-04-08 Andrey Borzenkov - - * grub-core/term/i386/pc/console.c: Fix cursor moving algorithm. - -2013-04-08 Bryan Hundven - - * docs/grub-dev.texi: Move @itemize after @subsection to satisfy - texinfo-5.1. - -2013-04-08 Vladimir Serbinenko - - * grub-core/normal/term.c: Few more fixes for menu entry editor - rendering. - Reported by: Andrey Borzenkov - -2013-04-07 Vladimir Serbinenko - - * grub-core/normal/term.c: Few more fixes for menu entry editor - rendering. - Reported by: Andrey Borzenkov - -2013-04-06 Andrey Borzenkov - - * conf/Makefile.extra-dist (EXTRA_DIST): Add - grub-core/lib/libgcrypt/src/gcrypt.h.in and util/import_gcrypth.sed. - -2013-04-06 Andrey Borzenkov - - * util/grub-install_header: Use @PACKAGE@.mo in message catalog name - instead of hardcoding grub.mo. - -2013-04-05 Fedora Ninjas - - * util/grub.d/30_os-prober.in: Support btrrfs linux-prober extensions. - -2013-04-05 Vladimir Serbinenko - - Use GRUB_PROPERLY_ALIGNED_ARRAY in grub-core/disk/cryptodisk.c and - grub-core/disk/geli.c. - -2013-04-05 Vladimir Serbinenko - - * util/grub-mkfont.c: Prefer enum to #define. - -2013-04-05 Vladimir Serbinenko - - * grub-core/commands/acpi.c: Use sizeof rather than hardcoding the size. - -2013-04-05 Vladimir Serbinenko - - Replace 8 with GRUB_CHAR_BIT in several places when appropriate. - -2013-04-05 Vladimir Serbinenko - - Add new defines GRUB_RSDP_SIGNATURE_SIZE and GRUB_RSDP_SIGNATURE. - -2013-04-05 Vladimir Serbinenko - - * grub-core/commands/verify.c: Use GRUB_CHAR_BIT. - -2013-04-05 Vladimir Serbinenko - - * include/grub/bsdlabel.h: Use enums. - -2013-04-05 Vladimir Serbinenko - - Move GRUB_CHAR_BIT to types.h. - -2013-04-04 Andrey Borzenkov - - * docs/grub.texi: Document more user commands. - -2013-04-04 Andrey Borzenkov - - * docs/grub.texi: Document menuentry --id option. - -2013-04-04 Francesco Lavra - - * util/grub-mkimage.c: Introduce new define EFI32_HEADER_SIZE. - -2013-04-04 Vladimir Serbinenko - - Unify file copying setup across different install scripts. Add - options for performing partial install. - -2013-04-04 Vladimir Serbinenko -2013-04-04 Peter Jones - - * grub-core/disk/efi/efidisk.c: Handle partitions on non-512B disks. - -2013-04-04 Vladimir Serbinenko - - Use TSC as a possible time source on i386-ieee1275. - -2013-04-04 Vladimir Serbinenko - - * grub-core/bus/usb/usbtrans.c (grub_usb_bulk_readwrite_packetize): - Init err. - -2013-04-04 Vladimir Serbinenko - - * util/grub-setup.c (setup): Handle some corner cases. - -2013-04-04 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/locale.h [GRUB_UTIL]: Include host locale.h. - -2013-04-03 Vladimir Serbinenko - - * grub-core/commands/verify.c: Save verified file to avoid it being - tampered with after verification was done. - -2013-04-03 Vladimir Serbinenko - - * grub-core/term/i386/pc/console.c (grub_console_getwh): Decrease - reported width by one to compensate for curesor algorithm problem. - -2013-04-03 Vladimir Serbinenko - - Fix screen corruption in menu entry editor and simplify the code - flow while on it. - -2013-04-03 Andrey Borzenkov - - * util/grub-mount.c (fuse_init): Return error if fuse_main - failed. - -2013-04-03 Francesco Lavra - - * include/grub/elf.h: Add missing ARM relocation codes and fix - existing ones. - -2013-04-03 Vladimir Testov - - * grub-core/gfxmenu/gui_progress_bar.c: Handle padding sizes. - -2013-04-03 Vladimir Testov -2013-04-03 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_circular_progress.c: Take both width and height - into account when calculating radius. - -2013-04-03 Vladimir Testov - - * grub-core/gfxmenu/view.c: Fix off-by-one error. - -2013-04-03 Vladimir Testov - - * grub-core/gfxmenu/gui_circular_progress.c: Fix off-by-one error. - -2013-04-01 Radosław Szymczyszyn - - * grub-core/partmap/apple.c (apple_partition_map_iterate): Add - missing closing bracket. - -2013-04-01 Radosław Szymczyszyn - - * INSTALL: Mention xorriso requirement. - -2013-03-31 Andrey Borzenkov - - * grub-core/commands/verify.c: Fix hash algorithms values for - the first three hashes - they start with 1, not with 0. - -2013-03-26 Vladimir Serbinenko - - * grub-core/kern/efi/mm.c (grub_efi_finish_boot_services): - Try terminating EFI services several times due to quirks in some - implementations. - -2013-03-26 Colin Watson - - * grub-core/commands/acpihalt.c (skip_ext_op): Add support for - skipping Event, Device, Processor, PowerRes, ThermalZone, and - BankField extended opcodes. - (get_sleep_type): Add minimal scope handling (just enough to - handle setting the scope to the root path). - (grub_acpi_halt): Parse any SSDTs as well as the DSDT. - * include/grub/acpi.h: Add enumeration values for Event, Device, - Processor, PowerRes, ThermalZone, and BankField extended opcodes. - -2013-03-26 Vladimir Testov - - * grub-core/gfxmenu/font.c (grub_font_get_string_width): Fix - memory leak. - -2013-03-25 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Give more time for AHCI request. - -2013-03-25 Vladimir Serbinenko - - * grub-core/normal/menu.c: Wait if there were errors shown at "boot" - command. - -2013-03-25 Vladimir Serbinenko - - Replace the region at 0 from coreboot tables to available in BSD - memory map. - -2013-03-24 Vladimir Serbinenko - - * util/grub.d/20_linux_xen.in: Automatically add no-real-mode edd=off on - non-BIOS platforms. - -2013-03-24 Vladimir Serbinenko - - * grub-core/Makefile.core.def (vga): Disable on coreboot and multiboot - platforms. - -2013-03-24 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Fix - handling of multi-device filesystems. - -2013-03-24 Vladimir Serbinenko - - * grub-core/Makefile.core.def (vbe): Disable on coreboot and multiboot - platforms. - -2013-03-24 Vladimir Serbinenko - - Add new 'proc' filesystem framework and put luks_script into it. - -2013-03-23 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c: Increase robustness on coreboot - and qemu. - -2013-03-22 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c: Fix incorrect handling of special volumes. - -2013-03-22 Vladimir Serbinenko - - Add ability to generate newc additions on runtime. - -2013-03-22 Vladimir Serbinenko - - * grub-core/commands/i386/coreboot/cbls.c: Fix typos and wrong - description. - -2013-03-21 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. - -2013-03-20 Vladimir Serbinenko - - * grub-core/commands/verify.c (hashes): Add several hashes - from the spec. - -2013-03-20 Vladimir Serbinenko - - Slight improve in USB-related boot-time checkpoints. - -2013-03-20 Vladimir Serbinenko - - * grub-core/commands/boottime.c: Fix copyright header. - -2013-03-20 Vladimir Serbinenko - - New commands cbmemc, lscoreboot, coreboot_boottime to inspect - coreboot tables content. Support for cbmemc. - -2013-03-20 Vladimir Serbinenko - - Fix a conflict between ports structures with 2 controllers of - same kind. - -2013-03-20 Vladimir Serbinenko - - * include/grub/boottime.h: Add missing file. - -2013-03-19 Vladimir Serbinenko - - Initialize USB ports in parallel to speed-up boot. - -2013-03-19 Vladimir Serbinenko - - Fix USB devices not being detected when requested - due to delayed attach. - -2013-03-19 Vladimir Serbinenko - - Implement boot time analysis framework. - -2013-03-19 Vladimir Serbinenko - - Remove get_endpoint_descriptor and change all functions needing - descriptor to just receive it as argument rather than endpoint - address. - -2013-03-19 Aleš Nesrsta - - Better estimate the maximum USB transfer size. - -2013-03-17 Vladimir Serbinenko - - Resend a packet if we got the wrong buffer in status. - -2013-03-10 Vladimir Serbinenko - - * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Use - multiplication rather than division. - -2013-03-10 Vladimir Serbinenko - - * grub-core/lib/arg.c (grub_arg_list_alloc): Use shifts rather - than divisions. - -2013-03-10 Vladimir Serbinenko - - * grub-core/commands/verify.c (grub_verify_signature): Use unsigned - operations to have intended shifts and not divisions. - -2013-03-10 Vladimir Serbinenko - - * grub-core/loader/i386/pc/plan9.c (fill_disk): Fix types to use - intended shifts rather than division. - -2013-03-10 Vladimir Serbinenko - - * include/grub/datetime.h (grub_datetime2unixtime): Fix unixtime - computation for some years before epoch. Avode confusing division - while on it. - -2013-03-10 Vladimir Serbinenko - - * grub-core/video/i386/pc/vbe.c - (grub_video_vbe_print_adapter_specific_info): Replace division by - shifts. - -2013-03-10 Vladimir Serbinenko - - Adjust types in gdb module to have intended unsigned shifts rather than - signed divisions. - -2013-03-10 Vladimir Serbinenko - - * grub-core/fs/hfs.c (grub_hfs_read_file): Avoid divmod64 since the - maximum size is 4G - 1 on hfs - -2013-03-10 Vladimir Serbinenko - - Avoid costly 64-bit division in grub_get_time_ms on most platforms. - -2013-03-10 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (grub_fshelp_log2blksize): Remove now unused - function. - -2013-03-07 Andrey Borzenkov - - * grub-core/fs/iso9660.c (add_part): Remove always_inline attribute - causing gcc error with gcc 4.7.1. - -2013-03-07 Nickolai Zeldovich - - * grub-core/commands/acpi.c (grub_acpi_create_ebda): Don't - dereference null pointer. While the code is technically correct, gcc - may eliminate a null check if pointer is already dereferenced. - -2013-03-07 Nickolai Zeldovich - - * grub-core/normal/crypto.c (read_crypto_list): Fix incorrect - OOM check. - * grub-core/normal/term.c (read_terminal_list): Likewise. - -2013-03-07 Vladimir Serbinenko - - Lift up core size limits on some platforms. Fix potential memory - corruption with big core on small memory systems. Document remaining - limits. - -2013-03-05 Vladimir Serbinenko - - * grub-core/term/terminfo.c (grub_terminfo_cls): Issue an explicit - gotoxy to 0,0. - -2013-03-03 Vladimir Serbinenko - - Remove all trampoline support. Add -Wtrampolines when - present. Remove symbols used for trampolines to make - link fail if trampolines are present. - -2013-03-03 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_arglist_to_argv): Move - append out of its parent. - -2013-03-03 Vladimir Serbinenko - - * grub-core/commands/regexp.c (set_matches): Move setvar out of its - parent. - -2013-03-03 Vladimir Serbinenko - - * grub-core/kern/env.c, include/grub/env.h: Change iterator through - all vars to a macro. All users updated. - -2013-03-03 Vladimir Serbinenko - - * grub-core/disk/ieee1275/nand.c: Fix compilation on - i386-ieee1275. - -2013-03-02 Vladimir Serbinenko - - * include/grub/cmos.h: Handle high CMOS addresses on sparc64. - -2013-03-02 Vladimir Serbinenko - - * include/grub/mips/loongson/cmos.h: Fix high CMOS addresses. - -2013-03-02 Vladimir Serbinenko - - Move to more hookless approach in IEEE1275 devices handling. - -2013-03-02 Vladimir Serbinenko - - * grub-core/kern/term.c (grub_term_normal_color), - (grub_term_highlight_color): Add back lost defaults. - -2013-03-02 Vladimir Serbinenko - - Make elfload not use hooks. Opt for flags and iterators instead. - -2013-03-02 Vladimir Serbinenko - - * grub-core/lib/ia64/longjmp.S: Fix the name of longjmp function. - * grub-core/lib/ia64/setjmp.S: Fix the name of setjmp function. - -2013-03-02 Vladimir Serbinenko - - * grub-core/script/execute.c (gettext_append): Remove nested functions. - -2013-03-02 Vladimir Serbinenko - - * grub-core/normal/charset.c (grub_bidi_logical_to_visual): Add - hook pass-through parameter. All users updated and unnested. - -2013-03-02 Vladimir Serbinenko - - * grub-core/commands/loadenv.c (grub_cmd_list_env): Move print_var - out of its parent. - -2013-03-02 Vladimir Serbinenko - - * grub-core/fs/hfs.c: Remove nested functions. - -2013-03-01 Vladimir Serbinenko - - * grub-core/fs/hfsplus.c (grub_hfsplus_btree_iterate_node): Pass - the context through. - (grub_hfsplus_iterate_dir): Move nested function out of its parent. - -2013-03-01 Vladimir Serbinenko - - * util/grub-editenv.c (list_variables): Move print_var out of its - parent. - -2013-03-01 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (read_device_map): Remove nested - function. - -2013-03-01 Vladimir Serbinenko - - * grub-core/gentrigtables.c: Make tables const. - -2013-03-01 Vladimir Serbinenko - - Remove nested functions from videoinfo iterators. - -2013-03-01 Vladimir Serbinenko - - * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Fix compilation - for 64-bit platforms. - -2013-03-01 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c: Transform iterate_child_devices into - a FOR_CHILDREN macro. - -2013-03-01 Vladimir Serbinenko - - * grub-core/kern/main.c (grub_set_prefix_and_root): Strip trailing - platform from firmware path. - -2013-02-28 Vladimir Serbinenko - - Enable linux16 on non-BIOS systems for i.a. memtest. - - * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Handle hole at 0 - correctly. - * grub-core/Makefile.core.def (linux16): Enable on all x86 flavours. - -2013-02-28 Vladimir Serbinenko - - * grub-core/kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate): - Fix end of table condition. - -2013-02-28 Vladimir Serbinenko - - * grub-core/lib/arg.c (grub_arg_show_help): Move showargs - out of its parent. - -2013-02-28 Vladimir Serbinenko - - * grub-core/fs/jfs.c: Remove nested functions. - -2013-02-28 Vladimir Serbinenko - - * grub-core/fs/minix.c: Remove nested functions. - -2013-02-28 Vladimir Serbinenko - - * grub-core/fs/iso9660.c: Remove nested functions. - -2013-02-28 Vladimir Serbinenko - - * grub-core/commands/parttool.c (grub_cmd_parttool): Move show_help out - of parent function. - -2013-02-28 Vladimir Serbinenko - - * util/grub-fstest.c: Remove nested functions. - -2013-02-27 Vladimir Serbinenko - - * grub-core/loader/machoXX.c: Remove nested functions. - -2013-02-27 Colin Watson - - Remove nested functions from disk and file read hooks. - - * include/grub/disk.h (grub_disk_read_hook_t): New type. - (struct grub_disk): Add read_hook_data member. - * include/grub/file.h (struct grub_file): Likewise. - * include/grub/fshelp.h (grub_fshelp_read_file): Add read_hook_data - argument. - - Update all callers. - -2012-02-27 Andrey Borzenkov - - * grub-core/partmap/msdos.c (grub_partition_msdos_iterate): - Fix off by one error in enumerating extended partitions. - -2013-02-26 Andrey Borzenkov - - * grub-core/disk/efi/efidisk.c(grub_efidisk_get_device_name): Fix - memory leak if device name is not found. - -2013-02-25 Andrey Borzenkov - - * grub-core/normal/menu_entry.c (update_screen): remove - unused variable `off' which caused scroll down arrow to be always shown. - -2013-02-25 Andrey Borzenkov - - * grub-core/normal/menu_entry.c (insert_string): fix off by one - access to unallocated memory. - -2013-02-25 Andrey Borzenkov - - * Makefile.util.def: Add partmap/msdos.c to common library. - * include/grub/msdos_partition.h: Add GRUB_PC_PARTITION_TYPE_LDM - * grub-core/disk/ldm.c: Check for existence of - GRUB_PC_PARTITION_TYPE_LDM. - -2013-02-25 Vladimir Serbinenko - - * grub-core/normal/misc.c (grub_normal_print_device_info): Use KiB to display - sizes and display sector size. - -2013-02-24 Vladimir Serbinenko - - Implement new command cmosdump. - -2013-02-19 Paulo Flabiano Smorigo - - Support Openfirmware disks with non-512B sectors. - - * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Get the block - size of the disk. - * (grub_ofdisk_get_block_size): New function. - * (grub_ofdisk_prepare): Use the correct block size. - * (grub_ofdisk_read): Likewise. - * (grub_ofdisk_write): Likewise. - * include/grub/ieee1275/ofdisk.h (grub_ofdisk_get_block_size): - New proto. - -2013-02-06 Vladimir Serbinenko - - * grub-core/commands/lsacpi.c: Fix types on 64-bit platform. - -2013-02-04 Vladimir Serbinenko - - * grub-core/disk/cryptodisk.c (grub_cryptodisk_scan_device): Don't stop - on first error. - -2013-02-01 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (find_file): Set oldnode to zero after - freeing it. - -2013-02-01 Vladimir Serbinenko - - Implement USBDebug (full USB stack variant). - -2013-02-01 Vladimir Serbinenko - - * grub-core/commands/lsacpi.c: Show more info. Hide some boring parts - unless they have unexpected values. - -2013-02-01 Vladimir Serbinenko - - * grub-core/bus/usb/usb.c (grub_usb_device_attach): Add missing - grub_print_error. - -2013-02-01 Vladimir Serbinenko - - * grub-core/bus/usb/serial/common.c (grub_usbserial_attach): Fix missing - zero-out of port structure. - -2013-01-30 Vladimir Serbinenko - - * grub-core/fs/xfs.c (grub_xfs_read_block): Fix computation in presence - of extended attributes. - -2013-01-27 Andrey Borzenkov - - * util/grub-install.in: change misleading comment about - device.map creation - -2013-01-27 Vladimir Serbinenko - - * grub-core/normal/menu_text.c (grub_menu_init_page): Fix behaviour - when menu highlight color isn't set. - -2013-01-27 C. Masloch - - Improve FreeDOS direct loading support compatibility. - - * include/grub/i386/relocator.h (grub_relocator16_state): - New member ebp. - * grub-core/lib/i386/relocator.c (grub_relocator16_ebp): New extern - variable. - (grub_relocator16_boot): Handle %ebp. - * grub-core/lib/i386/relocator16.S: Likewise. - * grub-core/loader/i386/pc/freedos.c: - Load BPB to pass kernel which partition to load from. - Check that kernel file is not too large. - Set register dl to BIOS unit number as well. - -2013-01-22 Colin Watson - - * util/grub-reboot.in (usage): Document the need for - GRUB_DEFAULT=saved. - * util/grub-set-default.in (usage): Likewise. - Reported by: Brian Candler. Fixes Ubuntu bug #1102925. - -2013-01-21 Vladimir Serbinenko - - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Include sys/types.h rather - than defining WORDS_BIGENDIAN manually. - -2013-01-21 Vladimir Serbinenko - - * include/grub/kernel.h (FOR_MODULES): Adjust to preserve alignment - invariants. - -2013-01-21 Colin Watson - - * grub-core/font/font.c (blit_comb: do_blit): Make static instead of - nested. - (blit_comb: add_device_width): Likewise. - -2013-01-21 Colin Watson - - Remove nested functions from USB iterators. - - * include/grub/usb.h (grub_usb_iterate_hook_t): New type. - (grub_usb_controller_iterate_hook_t): Likewise. - (grub_usb_iterate): Add hook_data argument. - (grub_usb_controller_iterate): Likewise. - (struct grub_usb_controller_dev.iterate): Likewise. - - Update all implementations and callers. - -2013-01-21 Vladimir Serbinenko - - * grub-core/normal/term.c (print_ucs4_terminal): Don't output right - margin when not needed. - -2013-01-21 Vladimir Serbinenko - - Make color variables global instead of it being per-terminal. - -2013-01-21 Vladimir Serbinenko - - * grub-core/commands/ls.c (grub_ls_print_devices): Add missing - asterisk. - -2013-01-21 Colin Watson - - Fix powerpc and sparc64 build failures caused by un-nesting memory - map iterators. - -2013-01-21 Colin Watson - - * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate): Fix - parameter declarations. - -2013-01-21 Vladimir Serbinenko - - * grub-core/commands/lsmmap.c: Fix unused variable on emu. - -2013-01-21 Vladimir Serbinenko - - Improve spkmomdem reliability by adding a separator between bytes. - -2013-01-21 Colin Watson - - * grub-core/partmap/msdos.c (embed_signatures): Add the signature of - an Acer registration utility with several sightings in the wild. - Reported by: Rickard Westman. Fixes Ubuntu bug #987022. - -2013-01-21 Colin Watson - - Remove nested functions from filesystem directory iterators. - - * include/grub/fs.h (grub_fs_dir_hook_t): New type. - (struct grub_fs.dir): Add hook_data argument. - - Update all implementations and callers. - -2013-01-21 Colin Watson - - * docs/grub.texi (Multi-boot manual config): Fix typo for - "recommended". - -2013-01-20 Leif Lindholm - - * util/grub-mkimage.c (main): Postpone freeing arguments.output - until after its use in generate_image. - -2013-01-20 Colin Watson - - * grub-core/loader/i386/linux.c (grub_cmd_initrd): Don't add the - initrd size to addr_min, since the initrd will be allocated after - this address. - -2013-01-20 Andrey Borzenkov - - * conf/Makefile.common: Fix autogen rules to pass definition - files on stdin; Makefile.util.am needs Makefile.utilgcry.def - -2013-01-20 Leif Lindholm - - * include/grub/elf.h: Update ARM definitions based on binutils. - -2013-01-20 Aleš Nesrsta - - Split long USB transfers into short ones. - -2013-01-20 Andrey Borzenkov - - * docs/grub.texi (Simple configuration): Clarify GRUB_HIDDEN_TIMEOUT - is interrupted by ESC. - -2013-01-20 Vladimir Serbinenko - - * util/grub-script-check.c (main): Uniform the error message. - -2013-01-20 Colin Watson - - Remove nested functions from ELF iterators. - -2013-01-20 Colin Watson - - Remove nested functions from device iterators. - - * include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type. - (grub_arc_iterate_devs): Add hook_data argument. - * include/grub/ata.h (grub_ata_dev_iterate_hook_t): New type. - (struct grub_ata_dev.iterate): Add hook_data argument. - * include/grub/device.h (grub_device_iterate_hook_t): New type. - (grub_device_iterate): Add hook_data argument. - * include/grub/disk.h (grub_disk_dev_iterate_hook_t): New type. - (struct grub_disk_dev.iterate): Add hook_data argument. - (grub_disk_dev_iterate): Likewise. - * include/grub/gpt_partition.h (grub_gpt_partition_map_iterate): - Likewise. - * include/grub/msdos_partition.h (grub_partition_msdos_iterate): - Likewise. - * include/grub/partition.h (grub_partition_iterate_hook_t): New - type. - (struct grub_partition_map.iterate): Add hook_data argument. - (grub_partition_iterate): Likewise. - * include/grub/scsi.h (grub_scsi_dev_iterate_hook_t): New type. - (struct grub_scsi_dev.iterate): Add hook_data argument. - - Update all callers. - -2013-01-20 Colin Watson - - Fix typos for "developer" and "development". - -2013-01-18 Vladimir Serbinenko - - Add license header to spkmodem-recv.c. - -2013-01-17 Vladimir Serbinenko - - Rewrite spkmodem to use PIT for timing. Double the speed. - -2013-01-16 Vladimir Serbinenko - - Add new command pcidump. - -2013-01-16 Vladimir Serbinenko - - New terminal outputs using serial: morse and spkmodem. - -2013-01-16 Vladimir Serbinenko - - Improve bidi handling in entry editor. - -2013-01-16 Vladimir Serbinenko - - * grub-core/script/lexer.c (grub_script_lexer_init): Rename getline - argument to prevent name collision. - -2013-01-15 Colin Watson - - Remove nested functions from script reading and parsing. - - * grub-core/kern/parser.c (grub_parser_split_cmdline): Add - getline_data argument, passed to getline. - * grub-core/kern/rescue_parser.c (grub_rescue_parse_line): Add - getline_data argument, passed to grub_parser_split_cmdline. - * grub-core/script/lexer.c (grub_script_lexer_yywrap): Pass - lexerstate->getline_data to lexerstate->getline. - (grub_script_lexer_init): Add getline_data argument, saved in - lexerstate->getline_data. - * grub-core/script/main.c (grub_normal_parse_line): Add getline_data - argument, passed to grub_script_parse. - * grub-core/script/script.c (grub_script_parse): Add getline_data - argument, passed to grub_script_lexer_init. - * include/grub/parser.h (grub_parser_split_cmdline): Update - prototype. Update all callers to pass appropriate getline data. - (struct grub_parser.parse_line): Likewise. - (grub_rescue_parse_line): Likewise. - * include/grub/reader.h (grub_reader_getline_t): Add void * - argument. - * include/grub/script_sh.h (struct grub_lexer_param): Add - getline_data member. - (grub_script_parse): Update prototype. Update all callers to pass - appropriate getline data. - (grub_script_lexer_init): Likewise. - (grub_normal_parse_line): Likewise. - - * grub-core/commands/legacycfg.c (legacy_file_getline): Add unused - data argument. - * grub-core/kern/parser.c (grub_parser_execute: getline): Make - static instead of nested. Rename to ... - (grub_parser_execute_getline): ... this. - * grub-core/kern/rescue_reader.c (grub_rescue_read_line): Add unused - data argument. - * grub-core/normal/main.c (read_config_file: getline): Make static - instead of nested. Rename to ... - (read_config_file_getline): ... this. - (grub_normal_read_line): Add unused data argument. - * grub-core/script/execute.c (grub_script_execute_sourcecode: - getline): Make static instead of nested. Rename to ... - (grub_script_execute_sourcecode_getline): ... this. - * util/grub-script-check.c (main: get_config_line): Make static - instead of nested. - -2013-01-15 Colin Watson - - Remove nested functions from memory map iterators. - - * grub-core/efiemu/mm.c (grub_efiemu_mmap_iterate): Add hook_data - argument, passed to hook. - * grub-core/kern/i386/coreboot/mmap.c - (grub_linuxbios_table_iterate): Likewise. - (grub_machine_mmap_iterate: iterate_linuxbios_table): Make static - instead of nested. - (grub_machine_mmap_iterate): Add hook_data argument. - * grub-core/kern/i386/multiboot_mmap.c (grub_machine_mmap_iterate): - Add hook_data argument, passed to hook. - * grub-core/kern/i386/pc/mmap.c (grub_machine_mmap_iterate): - Likewise. - * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_iterate): - Likewise. - * grub-core/kern/ieee1275/mmap.c (grub_machine_mmap_iterate): - Likewise. - * grub-core/kern/mips/arc/init.c (grub_machine_mmap_iterate): - Likewise. - * grub-core/kern/mips/loongson/init.c (grub_machine_mmap_iterate): - Likewise. - * grub-core/kern/mips/qemu_mips/init.c (grub_machine_mmap_iterate): - Likewise. - * grub-core/mmap/efi/mmap.c (grub_efi_mmap_iterate): Likewise. - (grub_machine_mmap_iterate): Likewise. - * grub-core/mmap/mmap.c (grub_mmap_iterate): Likewise. - * include/grub/efiemu/efiemu.h (grub_efiemu_mmap_iterate): Update - prototype. - * include/grub/memory.h (grub_memory_hook_t): Add data argument. - Remove NESTED_FUNC_ATTR from here and from all users. - (grub_mmap_iterate): Update prototype. - (grub_efi_mmap_iterate): Update prototype. Update all callers to - pass appropriate hook data. - (grub_machine_mmap_iterate): Likewise. - - * grub-core/commands/acpi.c (grub_acpi_create_ebda: find_hook): Make - static instead of nested. - * grub-core/commands/lsmmap.c (grub_cmd_lsmmap: hook): Likewise. - Rename to ... - (lsmmap_hook): ... this. - * grub-core/efiemu/mm.c (grub_efiemu_mmap_init: bounds_hook): - Likewise. - (grub_efiemu_mmap_fill: fill_hook): Likewise. - * grub-core/kern/i386/coreboot/init.c (grub_machine_init: - heap_init): Likewise. - * grub-core/kern/i386/pc/init.c (grub_machine_init: hook): Likewise. - Rename to ... - (mmap_iterate_hook): ... this. - * grub-core/kern/ieee1275/init.c (grub_claim_heap: heap_init): - Likewise. - * grub-core/lib/ieee1275/relocator.c - (grub_relocator_firmware_get_max_events: count): Likewise. - (grub_relocator_firmware_fill_events: fill): Likewise. Rename - to ... - (grub_relocator_firmware_fill_events_iter): ... this. - * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align: - hook): Likewise. Rename to ... - (grub_relocator_alloc_chunk_align_iter): ... this. - * grub-core/loader/i386/bsd.c (generate_e820_mmap: hook): Likewise. - Rename to ... - (generate_e820_mmap_iter): ... this. - * grub-core/loader/i386/linux.c (find_mmap_size: hook): Likewise. - Rename to ... - (count_hook): ... this. - (grub_linux_boot: hook): Likewise. Rename to ... - (grub_linux_boot_mmap_find): ... this. - (grub_linux_boot: hook_fill): Likewise. Rename to ... - (grub_linux_boot_mmap_fill): ... this. - * grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap: - hook): Likewise. Rename to ... - (grub_fill_multiboot_mmap_iter): ... this. - * grub-core/loader/multiboot.c (grub_get_multiboot_mmap_count: - hook): Likewise. Rename to ... - (count_hook): ... this. - * grub-core/loader/multiboot_mbi2.c (grub_fill_multiboot_mmap: - hook): Likewise. Rename to ... - (grub_fill_multiboot_mmap_iter): ... this. - * grub-core/loader/powerpc/ieee1275/linux.c - (grub_linux_claimmap_iterate: alloc_mem): Likewise. - * grub-core/loader/sparc64/ieee1275/linux.c (alloc_phys: choose): - Likewise. Rename to ... - (alloc_phys_choose): ... this. - (determine_phys_base: get_physbase): Likewise. - * grub-core/mmap/i386/mmap.c (grub_mmap_malign_and_register: - find_hook): Likewise. - * grub-core/mmap/i386/pc/mmap.c (preboot: fill_hook): Likewise. - (malloc_hook: count_hook): Likewise. - * grub-core/mmap/i386/uppermem.c (grub_mmap_get_lower: hook): - Likewise. Rename to ... - (lower_hook): ... this. - (grub_mmap_get_upper: hook): Likewise. Rename to ... - (upper_hook): ... this. - (grub_mmap_get_post64: hook): Likewise. Rename to ... - (post64_hook): ... this. - * grub-core/mmap/mips/uppermem.c (grub_mmap_get_lower: hook): - Likewise. Rename to ... - (lower_hook): ... this. - (grub_mmap_get_upper: hook): Likewise. Rename to ... - (upper_hook): ... this. - * grub-core/mmap/mmap.c (grub_mmap_iterate: count_hook): Likewise. - (grub_mmap_iterate: fill_hook): Likewise. - (fill_mask): Pass addr and mask within a single struct. - (grub_cmd_badram: hook): Make static instead of nested. Rename - to ... - (badram_iter): ... this. - (grub_cmd_cutmem: hook): Likewise. Rename to ... - (cutmem_iter): ... this. - -2013-01-13 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (read_device_map): Explicitly - delimit path in strings using quotes. - * util/getroot.c (grub_guess_root_devices): Likewise. - (grub_make_system_path_relative_to_its_root): Likewise. - * util/grub-probe.c (probe): Likewise. - * util/ieee1275/ofpath.c (find_obppath): Likewise. - (xrealpath): Likewise. - -2013-01-13 Vladimir Serbinenko - - Fix compilation with older compilers. - - * grub-core/Makefile.core.def (mpi): Add mpi-inline.c. - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Remove redundant - declarations. - * grub-core/lib/posix_wrap/string.h: Include sys/types.h. - * grub-core/lib/posix_wrap/sys/types.h: Add common types. - * grub-core/lib/xzembed/xz_dec_lzma2.c (dict_put): Replace byte - identifier with b. - * grub-core/lib/xzembed/xz_dec_stream.c (dec_vli): Likewise. - * include/grub/crypto.h: Add type defines. - * util/import_gcrypth.sed: Remove duplicate type defines. - -2013-01-13 Vladimir Serbinenko - - New command list_trusted. - - * grub-core/commands/verify.c (grub_cmd_list): New function. - -2013-01-13 Colin Watson - - * util/grub-mkimage.c (generate_image): Fix "size of public key" - info message. - -2013-01-13 Colin Watson - - Remove nested functions from PCI iterators. - - * grub-core/bus/pci.c (grub_pci_iterate): Add hook_data argument, - passed to hook. Update all callers to pass appropriate hook data. - * grub-core/bus/emu/pci.c (grub_pci_iterate): Likewise. - * include/grub/pci.h (grub_pci_iteratefunc_t): Add data argument. - Remove NESTED_FUNC_ATTR from here and from all users. - (grub_pci_iterate): Update prototype. - * grub-core/bus/cs5536.c (grub_cs5536_find: hook): Make static - instead of nested. Rename to ... - (grub_cs5536_find_iter): ... this. - * grub-core/kern/efi/mm.c (stop_broadcom: find_card): Likewise. - * grub-core/kern/mips/loongson/init.c (init_pci: set_card): - Likewise. - * grub-core/kern/vga_init.c (grub_qemu_init_cirrus: find_card): - Likewise. - * grub-core/video/bochs.c (grub_video_bochs_setup: find_card): - Likewise. - * grub-core/video/cirrus.c (grub_video_cirrus_setup: find_card): - Likewise. - * grub-core/video/efi_uga.c (find_framebuf: find_card): Likewise. - * grub-core/video/radeon_fuloong2e.c - (grub_video_radeon_fuloong2e_setup: find_card): Likewise. - * grub-core/video/sis315pro.c (grub_video_sis315pro_setup: - find_card): Likewise. - * grub-core/video/sm712.c (grub_video_sm712_setup: find_card): - Likewise. - -2013-01-12 Vladimir Serbinenko - - * grub-core/commands/verify.c: Mark messages for translating. - -2013-01-12 Vladimir Serbinenko - - * grub-core/lib/libgcrypt_wrap/mem.c (gcry_x*alloc): Make out of memory - fatal. - -2013-01-12 Vladimir Serbinenko - - * grub-core/lib/libgcrypt_wrap/mem.c (_gcry_log_bug): Make gcrypt bugs - fatal. - -2013-01-12 Vladimir Serbinenko - - * autogen.sh: Do not try to delete nonexistant files. - * util/import_gcrypth.sed: Add some missing header removals. - -2013-01-12 Colin Watson - - Clean up dangling references to grub-setup. - Fixes Ubuntu bug #1082045. - - * docs/grub.texi (Images): Refer generally to grub-install rather - than directly to grub-setup. - (Installing GRUB using grub-install): Remove direct reference to - grub-setup. - (Device map) Likewise. - (Invoking grub-install): Likewise. - * docs/man/grub-install.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkimage.h2m (SEE ALSO): Likewise. - * util/grub-install.in (usage): Likewise. - - * util/bash-completion.d/grub-completion.bash.in (_grub_setup): - Apply to grub-bios-setup and grub-sparc64-setup rather than to - grub-setup. - * configure.ac: Remove grub_setup output variable. - - * docs/man/grub-bios-setup.h2m (NAME): Change name from grub-setup - to grub-bios-setup. - * docs/man/grub-sparc64-setup.h2m (NAME): Change name from - grub-setup to grub-sparc64-setup. - -2013-01-11 Vladimir Serbinenko - - Import gcrypt public-key cryptography and implement signature checking. - -2013-01-10 Vladimir Serbinenko - - * grub-core/fs/ntfs.c: Ue more appropriate types. - * grub-core/fs/ntfscomp.c: Likewise. - * include/grub/ntfs.h: Likewise. - -2013-01-10 Vladimir Serbinenko - - Support Apple FAT binaries on non-Apple platforms. - - * include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define. - * include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT): - Likewise. - * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse - Apple FAT binaries. - -2013-01-10 Vladimir Serbinenko - - * grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K - sector devices. - -2013-01-07 Colin Watson - - * grub-core/io/bufio.c (grub_bufio_open): Use grub_zalloc instead of - explicitly zeroing elements. - * grub-core/io/gzio.c (grub_gzio_open): Likewise. - * grub-core/io/lzopio.c (grub_lzopio_open): Remove explicit zeroing - of elements in a structure already allocated using grub_zalloc. - * grub-core/io/xzio.c (grub_xzio_open): Likewise. - -2013-01-07 Colin Watson - - * docs/grub.texi (grub_cpu): New subsection. - (grub_platform): Likewise. - -2013-01-07 Vladimir Serbinenko - - * grub-core/fs/minix.c (grub_minix_read_file): Simplify arithmetics. - -2013-01-05 Vladimir Serbinenko - - * grub-core/fs/ext2.c (grub_ext2_read_block): Use shifts rather than - divisions. - -2013-01-05 Vladimir Serbinenko - - * grub-core/fs/ntfs.c: Eliminate useless divisions in favor of shifts. - * grub-core/fs/ntfscomp.c: Likewise. - * include/grub/ntfs.h (grub_ntfs_data): Replace spc with log_spc. - (grub_ntfs_comp): Likewise. - -2013-01-05 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (-grub_nilfs2_palloc_groups_per_desc_block): - Rename to ... - (grub_nilfs2_palloc_log_groups_per_desc_block): ... this. Return log - of groups_per_block. All users updated. - -2013-01-05 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_write): Call - grub_error properly. - * grub-core/disk/ieee1275/nand.c (grub_nand_write): Likewise. - * grub-core/disk/loopback.c (grub_loopback_write): Likewise. - -2013-01-03 Vladimir Serbinenko - - * util/grub.d/10_kfreebsd.in: Correct the patch to zpool.cache as it's - always in /boot/zfs. - Reported by: Yuta Satoh. - -2013-01-03 Yuta Satoh - - * util/grub.d/10_kfreebsd.in: Fix improper references to grub-probe by - ${grub_probe} - -2013-01-03 Vladimir Serbinenko - - * configure.ac: Extend -Wno-trampolines to host. - -2013-01-03 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_susp_iterate): Avoid hang if - entry->len = 0. - -2013-01-03 Colin Watson - - * docs/grub.texi (Invoking grub-mkrelpath): New section. - (Invoking grub-script-check): Likewise. - -2013-01-03 Colin Watson - - * docs/grub.texi (Invoking grub-mount): New section. - Reported by: Filipus Klutiero. Fixes Debian bug #666427. - -2013-01-02 Colin Watson - - * grub-core/tests/lib/test.c (grub_test_run): Return non-zero on - test failures, so that a failing unit test correctly causes 'make - check' to fail. - -2013-01-02 Colin Watson - - Fix failing printf test. - - * grub-core/kern/misc.c (grub_vsnprintf_real): Parse '-', '.', and - '$' in the correct order when collecting type information. - -2013-01-02 Colin Watson - - * docs/grub.texi (configfile): Explain environment variable - handling. - (source): New section. - Reported by: Arbiel Perlacremaz. Fixes Savannah bug #35564. - -2012-12-31 Colin Watson - - Remove several trivially-unnecessary uses of nested functions. - - * grub-core/commands/i386/pc/sendkey.c - (grub_cmd_sendkey: find_key_code, find_ascii_code): Make static - instead of nested. - * grub-core/commands/legacycfg.c (legacy_file: getline): Likewise. - Rename to ... - (legacy_file_getline): ... this. - * grub-core/commands/loadenv.c (grub_cmd_load_env: set_var): - Likewise. - * grub-core/kern/corecmd.c (grub_core_cmd_set: print_env): Likewise. - * grub-core/kern/fs.c (grub_fs_probe: dummy_func): Likewise. Rename - to ... - (probe_dummy_iter): ... this. - * grub-core/kern/i386/coreboot/mmap.c - (grub_linuxbios_table_iterate: check_signature): Likewise. - * grub-core/kern/parser.c (grub_parser_split_cmdline: - check_varstate): Likewise. Mark inline. - * grub-core/lib/arg.c (find_short: fnd_short): Likewise. Pass - an additional parameter. - (find_long: fnd_long): Likewise. Pass two additional parameters. - * grub-core/lib/crc.c (init_crc32c_table: reflect): Likewise. - * grub-core/lib/crc64.c (init_crc64_table: reflect): Likewise. - * grub-core/lib/ieee1275/cmos.c (grub_cmos_find_port: hook): - Likewise. Rename to ... - (grub_cmos_find_port_iter): ... this. - * grub-core/lib/ieee1275/datetime.c (find_rtc: hook): Likewise. - Rename to ... - (find_rtc_iter): ... this. - - * grub-core/normal/menu_entry.c (run): Fold nested editor_getsource - function directly into the function body, since it is only called - once. - -2012-12-30 Colin Watson - - * grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): Remove incorrect - __attribute__ ((unused)). - * grub-core/video/bochs.c (find_card): Likewise. - * grub-core/video/cirrus.c (find_card): Likewise. - * grub-core/video/radeon_fuloong2e.c (find_card): Likewise. - * grub-core/video/sis315pro.c (find_card): Likewise. - * grub-core/video/sm712.c (find_card): Likewise. - -2012-12-28 Colin Watson - - * util/grub-mkconfig.in: Accept GRUB_TERMINAL_OUTPUT=vga_text. - Fixes Savannah bug #37821. - -2012-12-28 Colin Watson - - Apply program name transformations at build-time rather than at - run-time. Fixes Debian bug #696465. - - * acinclude.m4 (grub_TRANSFORM): New macro. - * configure.ac: Create output variables with transformed names for - most programs. - * util/bash-completion.d/grub-completion.bash.in: Use - pre-transformed variables for program names. - * util/grub-install.in: Likewise. - * util/grub-kbdcomp.in: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mkconfig_lib.in: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - * tests/util/grub-shell-tester.in: Remove unused assignment. - * tests/util/grub-shell.in: Likewise. - * util/grub.d/00_header.in: Likewise. - -2012-12-28 Colin Watson - - Backport gnulib fixes for C11. Fixes Savannah bug #37738. - - * grub-core/gnulib/stdio.in.h (gets): Warn on use only if - HAVE_RAW_DECL_GETS. - * m4/stdio_h.m4 (gl_STDIO_H): Check for gets. - -2012-12-11 Vladimir Serbinenko - - * util/grub.d/20_linux_xen.in: Addmissing assignment to machine. - Reported by: Eriks Latosheks . - -2012-12-10 Vladimir Serbinenko - - * docs/grub.texi (Network): Update instructions on generating netboot - image. - -2012-12-10 Vladimir Serbinenko - - * grub-core/disk/cryptodisk.c (grub_cmd_cryptomount): Strip brackets - around device name if necessarry. - -2012-12-10 Paulo Flabiano Smorigo - - * util/grub-install.in: Follow the symbolic link parameter added - to the file command. - -2012-12-10 Andrey Borzenkov - - * util/grub-install.in: Remove stale TODO. - -2012-12-10 Paulo Flabiano Smorigo - - * grub-core/kern/ieee1275/init.c (grub_machine_get_bootlocation): Use - dynamic allocation for the bootpath buffer. - -2012-12-10 Dr. Tilmann Bubeck - - * grub-core/gfxmenu/view.c (init_terminal): Avoid making terminal - window too small. - -2012-12-10 Vladimir Serbinenko - - * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Get font as - argument rather than font name. All users updated. - (grub_gfxterm_set_window): Likewise. - -2012-12-10 Vladimir Testov - - * util/grub-mkfont.c (argp_parser): Fix a typo which prevented --asce - from working. - -2012-12-10 Vladimir Serbinenko - - * util/getroot.c (convert_system_partition_to_system_disk): Support - nbd disks. - -2012-12-10 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_dir): Stop if direntlen is 0 to avoid - infinite loop on corrupted FS. - -2012-12-08 Vladimir Serbinenko - - Fix big-endian mtime. - - * grub-core/fs/ufs.c (grub_ufs_inode): Split improperly attached - together sec and usec. - (grub_ufs_dir): Use correct byteswapping for UFS time. - -2012-12-08 Vladimir Serbinenko - - Support big-endian UFS1. - - * Makefile.util.def (libgrubmods): Add ufs_be.c - * grub-core/Makefile.core.def (ufs1_be): New module. - * grub-core/fs/ufs_be.c: New file. - * grub-core/fs/ufs.c: Declare grub_ufs_to_le* and use them throughout - the file. - -2012-11-28 Leif Lindholm - - * include/grub/types.h: Fix functionality unaffecting typo in - GRUB_TARGET_WORDSIZE conditional macro. - -2012-11-28 Paulo Flabiano Smorigo - - * grub-core/net/bootp.c (parse_dhcp_vendor): Fix double increment. - -2012-10-28 Grégoire Sutre - - * util/grub.d/10_netbsd.in: Fix tab indentation and make sure - that /netbsd appears first (when it exists). - -2012-10-12 Christoph Junghans - - * grub-core/Makefile.am (moddep.lst): Use $(AWK) rather than awk. - Fixes Savannah bug #37558. - -2012-10-12 Colin Watson - - * grub-core/commands/configfile.c (GRUB_MOD_INIT): Correct - description of extract_entries_configfile. - -2012-10-05 Colin Watson - - * grub-core/loader/i386/linux.c (allocate_pages): Fix spelling of - preferred_address. - (grub_cmd_linux): Likewise. - * grub-core/net/icmp6.c (struct prefix_option): Fix spelling of - preferred_lifetime. Update all users. - -2012-09-26 Colin Watson - - * Makefile.util.def (grub-mknetdir): Move to $prefix/bin. - Reported by: Daniel Kahn Gillmor. Fixes Debian bug #688799. - -2012-09-26 Colin Watson - - * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Redirect - errors from grub-probe to /dev/null, not stdout. - -2012-09-26 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_mount): Support AFFS bootblock in - sector 1. - -2012-09-24 Colin Watson - - * util/grub-install.in: Make the error message if $source_dir - doesn't exist more useful. - -2012-09-22 Colin Watson - - Fix grub-emu build on FreeBSD. - - * Makefile.util.def (grub-mount): Add LIBGEOM to ldadd. - * grub-core/net/drivers/emu/emunet.c: Only include Linux-specific - headers on Linux. - (GRUB_MOD_INIT): Return immediately on non-Linux platforms; this - implementation is currently Linux-specific. - * util/getroot.c (exec_pipe): Define only on Linux or when either - libzfs or libnvpair is unavailable. - (find_root_devices_from_poolname): Remove unused path variable. - -2012-09-19 Colin Watson - - * grub-core/partmap/msdos.c (pc_partition_map_embed): Revert - incorrect off-by-one fix from 2011-02-12. A 62-sector core image - should fit before end == 63. - -2012-09-19 Colin Watson - - * util/grub-setup.c (write_rootdev): Remove unused core_img - parameter. Update all callers. - (setup): Define core_sectors only if GRUB_SETUP_BIOS, to appease - 'gcc -Wunused-but-set-variable'. Remove unnecessary nested #ifdef - GRUB_SETUP_BIOS. - -2012-09-18 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (grub_tab): New variable. - (grub_add_tab): New function. - * util/grub.d/10_hurd.in: Replace \t with $grub_tab orgrub_add_tab. - * util/grub.d/10_illumos.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/10_xnu.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - -2012-09-18 Vladimir Serbinenko - - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set - GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN on mac. - * grub-core/term/ieee1275/console.c (grub_console_init_lately): Use - ieee1275-nocursor if GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN is set. - * grub-core/term/terminfo.c (grub_terminfo_set_current): Add new type - ieee1275-nocursor. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New value - GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN. - -2012-09-18 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_cmd_linux): Fix incorrect - le-conversion. - Reported by: BURETTE, Bernard. - -2012-09-17 Colin Watson - - * util/grub-mkconfig_lib.in (grub_quote): Remove outdated sentence - from comment. - -2012-09-14 Colin Watson - - * grub-core/term/terminfo.c: Only fix up powerpc key repeat on - IEEE1275 machines. Fixes powerpc-emu compilation. - * include/grub/terminfo.h: Likewise. - -2012-09-12 Vladimir Serbinenko - - * include/grub/efi/api.h (grub_efi_runtime_services): Make vendor_guid - a const pointer. - * grub-core/efiemu/runtime/efiemu.c (efiemu_memcpy): Make from a - const pointer. - (efiemu_set_variable): Make vendor_guid a const pointer. - -2012-09-12 Vladimir Serbinenko - - Don't require grub-mkconfig_lib to generate manpages for programs. - - * gentpl.py (manpage): Additional argument adddeps. Add adddeps to - dependencies, don't add grub-mkconfig_lib. - (program): Pass empty adddeps. - (script): Pass grub-mkconfig_lib as adddeps. - -2012-09-11 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (free_array) [GRUB_UTIL]: Fix memory leak. - * util/getroot.c (grub_find_device): Likewise. - (get_mdadm_uuid): Likewise. - (grub_util_is_imsm): Likewise. - (grub_util_pull_device): Likewise. - * util/grub-probe.c (probe): Likewise. - -2012-09-10 Benoit Gschwind - - * grub-core/loader/efi/appleloader.c (devpath_8): New var. - (devs): Add devpath_8. - -2012-09-08 Peter Jones - - * grub-core/Makefile.core.def (efifwsetup): New module. - * grub-core/commands/efi/efifwsetup.c: New file. - * grub-core/kern/efi/efi.c (grub_efi_set_variable): New function - * include/grub/efi/api.h (GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI): - New define. - * include/grub/efi/efi.h (grub_efi_set_variable): New proto. - -2012-09-05 Jiri Slaby - - * configure.ac: Add SuSe path. - -2012-09-05 Colin Watson - - * NEWS: Fix typo. - -2012-09-05 Colin Watson - - * util/import_gcry.py: Sort cipher_files, to make build system - generation more deterministic. - -2012-09-05 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (scan): Check function return value. - * grub-core/lib/ieee1275/datetime.c (grub_get_datetime): Likewise. - (grub_set_datetime): Likewise. - -2012-09-05 Vladimir Serbinenko - - * grub-core/script/yylex.l: Ignore unused-function and sign-compare - warnings. - -2012-09-05 Vladimir Serbinenko - - * grub-core/partmap/dvh.c (grub_dvh_is_valid): Add missing byteswap. - -2012-09-05 Vladimir Serbinenko - - * grub-core/fs/xfs.c (grub_xfs_read_block): Make keys a const pointer. - -2012-09-04 Colin Watson - - * Makefile.am (EXTRA_DIST): Add linguas.sh. It's only strictly - required for checkouts from bzr, but it may be useful for users or - distributors wishing to update translations against a tarball - distribution, and it can be helpful for the tarball to be a superset - of what's in bzr. - -2012-09-04 Colin Watson - - * Makefile.am (EXTRA_DIST): Add - grub-core/tests/boot/linux.init-mips.S, - grub-core/tests/boot/linux.init-ppc.S, and - grub-core/tests/boot/linux-ppc.cfg. - -2012-09-04 Colin Watson - - * grub-core/mmap/mips/loongson: Remove empty directory. - -2012-09-04 Colin Watson - - * docs/man/grub-mkdevicemap.h2m: Remove, since grub-mkdevicemap is - gone. - -2012-09-04 Colin Watson - - * .bzrignore: Add grub-bios-setup, grub-ofpathname, and - grub-sparc64-setup. - -2012-08-05 Grégoire Sutre - - * configure.ac: Strengthen the test for working -nostdinc -isystem. - -2012-07-31 Grégoire Sutre - - * po/POTFILES.in: Regenerated. - -2012-07-31 Grégoire Sutre - - * docs/grub.texi: Note that NetBSD/i386 is Multiboot-compliant. - (NetBSD): New subsection. - -2012-07-22 Ales Nesrsta - - * grub-core/bus/usb/ehci.c: PCI iter. - added PCI bus master setting. - * grub-core/bus/usb/ohci.c: PCI iter. - added PCI bus master setting. - -2012-07-22 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (grub_quote): Remove extra layer of escape. - * util/grub.d/10_hurd.in: Add missing quoting. - * util/grub.d/10_illumos.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - -2012-07-22 Vladimir Serbinenko - - New command `lsefi'. - - * grub-core/Makefile.core.def (lsefi): New module. - * grub-core/commands/efi/lsefi.c: New file. - * include/grub/efi/api.h: Add more GUIDs. - -2012-07-22 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c (grub_bsd_elf32_size_hook): Fix mask. - (grub_bsd_elf32_hook): Likewise. - (grub_bsd_elf64_size_hook): Likewise. - (grub_bsd_elf64_hook): Likewise. - (grub_bsd_load_elf): Likewise. - -2012-07-22 Vladimir Serbinenko - - * grub-core/lib/xzembed/xz_dec_stream.c (hash_validate): Fix behaviour - if hash function is unavailable. - (dec_stream_header): Likewise. - -2012-07-22 Vladimir Serbinenko - - * grub-core/normal/autofs.c (autoload_fs_module): Save and restore - filter state. - -2012-07-22 Vladimir Serbinenko - - Fix coreboot compilation. - - * grub-core/term/i386/pc/vga_text.c (grub_vga_text_init): Rename to ... - (grub_vga_text_init_real): ... this. - (grub_vga_text_fini): Rename to ... - (grub_vga_text_fini_real): ... this. - -2012-07-07 Vladimir Serbinenko - - * grub-core/Makefile.am: Fix path to boot/i386/pc/startup_raw.S. - -2012-07-02 Vladimir Serbinenko - - * grub-core/lib/legacy_parse.c: Support clear and testload. - -2012-07-02 Vladimir Serbinenko - - * grub-core/term/efi/serial.c: Support 1.5 stop bits. - -2012-07-02 Vladimir Serbinenko - - * grub-core/fs/ext2.c: Experimental support for 64-bit. - -2012-07-02 Vladimir Serbinenko - - * grub-core/net/tftp.c (ack): Fix endianness problem. - (tftp_receive): Likewise. - Reported by: Michael Davidsaver. - -2012-07-02 Vladimir Serbinenko - - * gentpl.py: Make mans depend on grub-mkconfig_lib. - -2012-07-02 Vladimir Serbinenko - - * include/grub/list.h (FOR_LIST_ELEMENTS_SAFE): New macro. - * include/grub/command.h (FOR_COMMANDS_SAFE): Likewise. - * grub-core/commands/help.c (grub_cmd_help): Use FOR_COMMANDS_SAFE. - -2012-07-02 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (find_efi_mmap_size): Don't decrease - efi_mmap_size. - Reported by: Stuart Hayes. - -2012-06-28 Vladimir Serbinenko - - Add monochrome text support (mda_text, aka `hercules' in grub-legacy). - - * grub-core/Makefile.core.def (mda_text): New module. - * grub-core/lib/legacy_parse.c (grub_legacy_parse): Support `hercules'. - * grub-core/term/i386/vga_common.c (grub_console_cur_color): Moved to .. - * grub-core/term/i386/pc/vga_text.c (cur_color): ... here - * grub-core/term/i386/pc/console.c (grub_console_cur_color): ... and - here. - * grub-core/term/i386/vga_common.c (grub_console_getwh): Moved to .. - * grub-core/term/i386/pc/vga_text.c (grub_console_getwh): ... here - * grub-core/term/i386/pc/console.c (grub_console_getwh): ... and - here. - * grub-core/term/i386/vga_common.c (grub_console_setcolorstate): Moved - to .. - * grub-core/term/i386/pc/vga_text.c (grub_console_setcolorstate): - ... here - * grub-core/term/i386/pc/console.c (grub_console_setcolorstate): ... and - here. - * grub-core/term/i386/vga_common.c: Removed. - * include/grub/i386/vga_common.h: Likewise. - * include/grub/vga.h (grub_vga_cr_bw_write): New function. - (grub_vga_cr_bw_read): Likewise. - * include/grub/vgaregs.h (GRUB_VGA_IO_CR_BW_INDEX): New enum value. - (GRUB_VGA_IO_CR_BW_DATA): Likewise. - * grub-core/term/i386/pc/vga_text.c [MODE_MDA]: Call - grub_vga_cr_bw_read/grub_vga_cr_bw_write instead of - grub_vga_cr_read/grub_vga_cr_write. - (grub_vga_text_setcolorstate) [MODE_MDA]: Ignore color. - -2012-06-27 Vladimir Serbinenko - - * configure.ac: Bump version to 2.00. - * grub-core/normal/main.c (features): Add feature_200_final. - -2012-06-27 Vladimir Serbinenko -2012-06-27 Jordan Uggla - - * NEWS: Fix unclarity and language mistakes. - -2012-06-27 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (find_efi_mmap_size): Increase - additional size to 3 pages. - Reported by: Stuart Hayes. - -2012-06-27 Vladimir Serbinenko - - * NEWS: Add 2.00 entry. - -2012-06-27 Vladimir Serbinenko - - * grub-core/commands/wildcard.c (check_file): Fix bad logic. - put explicit "/" for empty path. - (wildcard_expand): Improve dprintf. - -2012-06-27 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (grub_fshelp_find_file): Don't free oldnode if - it's equal to currnode. This can happen with "" symlink. - -2012-06-27 Yves Blusseau - - * util/grub-mkconfig_lib.in: Fix print messages replacing builtin - echo shell command by printf command. - -2012-06-26 Vladimir Serbinenko - - * grub-core/term/arc/console.c (grub_console_init_output): Add one since - the value returned by firmware is the maximal position, not diumension. - (grub_terminfo_output_state): Use a more sane fallback. - -2012-06-26 Vladimir Serbinenko - - * grub-core/term/terminfo.c (print_terminfo): Print terminal dimensions. - -2012-06-26 Vladimir Serbinenko - - * grub-core/kern/mips/arc/init.c (grub_machine_init): Set clock - frequency to 150 MHz. - -2012-06-26 Vladimir Serbinenko - - Apple fixes. - - * grub-core/lib/i386/relocator16.S: Use correct __APPLE__ and not - __APPLE_ - * grub-core/lib/i386/relocator_common.S [__APPLE__]: Fix gdtdesc - definition. - * grub-core/lib/i386/relocator64.S [__APPLE__]: Assemble jmp manually. - -2012-06-26 Vladimir Serbinenko - - Handle slash in HFS label. - - * grub-core/fs/hfs.c (macroman_to_utf8): New argument slash_translate. - (grub_hfs_dir): Tanslate slash. - (grub_hfs_label): Don't translate slash. - -2012-06-26 Vladimir Serbinenko - - * grub-core/commands/ls.c (grub_ls_list_devices): Disable - network protocol listing since it introduces problematic dependency on - net module. - -2012-06-26 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Add Yeeloong verified hash. - -2012-06-26 Vladimir Serbinenko - - Init video early on yeeloong to avoid being rebooted by watchdog. - - * grub-core/Makefile.am (gensm712): New target. - (sm712_start.S): Likewise. - (boot/mips/loongson/fwstart.S): Depend on sm712_start.S - * grub-core/boot/mips/loongson/fwstart.S [!FULOONG2F]: Init SM712. - * grub-core/video/sm712.c [GENINIT]: Generate compact init procedure - description. - * include/grub/vga.h: Move registry definitions to... - * include/grub/vgaregs.h: ... here. - -2012-06-26 Vladimir Serbinenko - - * grub-core/boot/decompressor/minilib.c (grub_memcmp): Fix the compare - signedness. - -2012-06-25 Vladimir Serbinenko - - * util/grub-install.in: Fix dvhtool invocation. Add arc to the list of - platforms with firmware disk drivers in the core. - -2012-06-25 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (scan_disk) [GRUB_UTIL]: Put more - informative verbose message. - (read_lv): Handle 64-bit segment size. - -2012-06-25 Vladimir Serbinenko - - * grub-core/disk/lvm.c (grub_lvm_getvalue): Handle 64-bit values. - -2012-06-25 Vladimir Serbinenko - - * grub-core/fs/fat.c (grub_fat_iterate_dir_next): Don't stop on a space - character but still remove trainling spaces. - (grub_fat_label): Ignore archive flag. - -2012-06-25 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_cmd_initrd): Avoid unnecessarry - cast between linux_kernel_header and linux_kernel_params. - -2012-06-25 Vladimir Serbinenko - - * include/grub/diskfilter.h (grub_raid5_recover_func_t): Use proper - type for size. - (grub_raid6_recover_func_t): Likewise. - * grub-core/disk/raid5_recover.c (grub_raid5_recover): Likewise. - * grub-core/disk/raid6_recover.c (grub_raid6_recover): Likewise. - -2012-06-25 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Add Fuloong2F verified hash. - -2012-06-25 Grégoire Sutre - - Fix overflow. - - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_size) - [__NetBSD__]: Add explicit cast before bitshift. - -2012-06-23 Vladimir Serbinenko - - * configure.ac: Bump to 2.00~rc1. - -2012-06-23 Vladimir Serbinenko - - * grub-core/boot/mips/loongson/fwstart.S: Add missing setting of high - half of $a0. - -2012-06-23 Vladimir Serbinenko -2012-06-23 Jordan Uggla - - * docs/grub.texi: Fix search syntax. - (Multi-boot manual config): Put msdos rather than GPT example. - Grammar corrections. - -2012-06-23 Vladimir Serbinenko - - * docs/grub.texi (Multi-boot manual config): Use --set. Improve remark. - -2012-06-22 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_free): Fix agglomerating of free regions. - -2012-06-22 Vladimir Serbinenko - - * grub-core/kern/mm.c (get_header_from_pointer): Put a more informative - message on double free. Put the value of magic in case of mismatch. - -2012-06-22 Vladimir Serbinenko - - Speed-up video on yeeloong. - - * grub-core/video/sm712.c (framebuffer): Remove render_target and - add cached_ptr. - (grub_video_sm712_video_fini): Unmap cached_ptr. - (grub_video_sm712_setup): Use cache address and grub_video_fb_setup. - (grub_video_sm712_set_active_render_target): Removed. - (grub_video_adapter): Use grub_video_fb_set_active_render_target. - (grub_video_sm712_swap_buffers): Call grub_video_fb_swap_buffers and - sync caches. - -2012-06-22 Vladimir Serbinenko - - Avoid flushing the same line multiple times on loongson. - - * grub-core/kern/mips/cache.S [GRUB_MACHINE_MIPS_LOONGSON]: - Step in 32 bytes and not 1 byte. - * grub-core/kern/mips/cache_flush.S [GRUB_MACHINE_MIPS_LOONGSON]: - Likewise. - -2012-06-22 Vladimir Serbinenko - - * util/getroot.c (grub_find_root_devices_from_mountinfo): Handle btrfs - subvolumes. - -2012-06-22 Vladimir Serbinenko - - Implement flow control for http. - - * grub-core/net/http.c (parse_line): Handle response 206. - (http_receive): Stall if too many packets are in the queue. - (http_establish): Fix range header. - (http_seek): Fix double free. - (http_close): Likewise. - (http_packets_pulled): New function. - (grub_http_protocol): Set http_seek - * grub-core/net/tcp.c (grub_net_tcp_socket): New field `i_stall'. - (ack_real): Set window depending on i_stall. - (grub_net_send_tcp_packet): Likewise. - (grub_net_tcp_stall): New function. - (grub_net_tcp_unstall): Likewise. - * include/grub/net/tcp.h (grub_net_tcp_stall): New proto. - (grub_net_tcp_unstall): Likewise. - -2012-06-22 Vladimir Serbinenko - - * grub-core/net/tftp.c: Decrease stall to 50 packets. - -2012-06-22 Vladimir Serbinenko - - * grub-core/net/net.c (grub_net_fs_open): Free resources on failed open. - -2012-06-22 Vladimir Serbinenko - - * tests/util/grub-shell.in: Fix a typo. - -2012-06-22 Vladimir Serbinenko - - Implement flow control for tftp. - - * grub-core/net/net.c (receive_packets): Decrease the stop to 10 - packets but stop only if stop condition is satisfied. - (grub_net_fs_read_real): Call packets_pulled after real read. Use - `stall' instead of `eof' as stop condition. - * grub-core/net/http.c (parse_line): Set `stall' on EOF. - (http_err): Likewise. - * grub-core/net/tftp.c (ack): Replace the first argument with data - instead of socket. - (tftp_receive): Stall if too many packets are in wait queue. - (tftp_packets_pulled): New function. - (grub_tftp_protocol): Set packets_pulled. - * include/grub/net.h (grub_net_packets): New field count. - (grub_net_put_packet): Increment count. - (grub_net_remove_packet): Likewise. - (grub_net_app_protocol): New field `packets_pulled'. - (grub_net): New field `stall'. - -2012-06-22 Vladimir Serbinenko - - * grub-core/net/net.c (receive_packets): Stop after 100 packets to let - sync part to handle them. - -2012-06-21 Vladimir Serbinenko - - * grub-core/kern/main.c (grub_set_prefix_and_root): Fix memory leak. - * grub-core/net/drivers/ieee1275/ofnet.c - (grub_ieee1275_net_config_real): Likewise. - -2012-06-21 Vladimir Serbinenko - - * grub-core/net/bootp.c (grub_net_configure_by_dhcp_ack): Don't create - the direct route for server/gateway. - -2012-06-21 Vladimir Serbinenko - - * grub-core/net/bootp.c (grub_net_configure_by_dhcp_ack): Prefer - IP address to server name since we may not hame the DNS. - -2012-06-21 Vladimir Serbinenko - - * grub-core/net/dns.c (grub_cmd_nslookup): Init addresses to 0 to avoid - freeing random buffer on failure. - * grub-core/net/net.c (grub_net_resolve_address): Likewise. - -2012-06-21 Vladimir Serbinenko - - * grub-core/net/bootp.c (grub_cmd_bootp): Fix packet allocation size. - -2012-06-21 Vladimir Serbinenko - - * grub-core/net/drivers/emu/emunet.c (get_card_packet): Allocate the - reserved bytes. - * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_recv): Likewise. - * grub-core/net/drivers/ieee1275/ofnet.c (get_card_packet): Likewise. - Handle malloc error correctly. - -2012-06-21 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_arglist_to_argv): Escape - blocks. - -2012-06-21 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Fix double - increment. - -2012-06-20 Vladimir Serbinenko - - * grub-core/net/dns.c (grub_cmd_nslookup): Use configured DNS servers if - none is explicitly specified. - -2012-06-20 Vladimir Serbinenko - - * grub-core/net/dns.c (grub_net_add_dns_server): Don't erase old servers - while reallocating. - -2012-06-20 Vladimir Serbinenko - - Respect netmask from bootp/dhcp. - - * grub-core/net/bootp.c (parse_dhcp_vendor): Parse mask. - (grub_net_configure_by_dhcp_ack): Use mask and grub_net_add_ipv4_local. - * grub-core/net/net.c (grub_net_add_addr): Split creating local route - into ... - (grub_net_add_ipv4_local): ... this. - (grub_cmd_addaddr): Use grub_net_add_ipv4_local. - * include/grub/net.h (GRUB_NET_BOOTP_NETMASK): New enum value. - (grub_net_add_ipv4_local): New proto. - -2012-06-20 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_linux_boot): Setup video before - determining EFI memory map size. - -2012-06-20 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Escape commas. - -2012-06-20 Vladimir Serbinenko - - * grub-core/kern/main.c (grub_set_prefix_and_root): Skip escaped commas - when looking for partition separator. - -2012-06-20 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): - Escape commas. - -2012-06-20 Vladimir Serbinenko - - Restructure FAT driver to avoid hook in label reading as it hits a - GCC bug. - - * include/grub/err.h (grub_err_t): New enum value GRUB_ERR_EOF. - * grub-core/fs/fat.c (grub_fat_iterate_context): New struct. - (grub_fat_iterate_dir): Split into ... - (grub_fat_iterate_init): ... this, ... - (grub_fat_iterate_fini): ... this, ... - (grub_fat_iterate_dir_next): ... and this. All users updated. - -2012-06-20 Vladimir Serbinenko - - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value - GRUB_IEEE1275_FLAG_BROKEN_REPEAT. - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set - GRUB_IEEE1275_FLAG_BROKEN_REPEAT on PowerBook3,3. - * include/grub/terminfo.h (grub_terminfo_input_state) [__powerpc__]: - New fields last_key and last_key_time. - * grub-core/term/terminfo.c (grub_terminfo_getkey): Transform - extended key-esc into extended key-extended key. - -2012-06-19 Vladimir Serbinenko - - Avoid unnecessary memcpy of whole video buffer. - - * grub-core/video/fb/video_fb.c (dirty): New struct. - (framebuffer): Add members current_dirty and previous_dirty. - (dirty): New function. - (grub_video_fb_fill_rect): Update dirty. - (common_blitter): Likewise. - (grub_video_fb_scroll): Likewise. - (doublebuf_blit_update_screen): Copy only dirty part. - (doublebuf_pageflipping_update_screen): Likewise. - (grub_video_fb_doublebuf_blit_init): Init dirty. - (doublebuf_pageflipping_init): Likewise. - (grub_video_fb_setup): Likewise. - -2012-06-19 Vladimir Serbinenko - - * grub-core/net/drivers/ieee1275/ofnet.c (search_net_devices): Decrease - poll rate. - -2012-06-19 Vladimir Serbinenko - - Fix wildcard regexp dot and other special characters handling. - Reported by: Robert Mabee. - - * grub-core/commands/wildcard.c (isregexop): Add "|+{}[]?". - (make_regex): Escape "|+{}[]". Transform '?' to '.?'. - (split_path): Trigger expansion on '?'. - (unescape): New function. - (wildcard_expand): Unescape parts copied without globbing. - * grub-core/script/execute.c (wildcard_escape): Escape '?'. - (grub_script_arglist_to_argv): Don't unescape expansions. - -2012-06-19 Vladimir Serbinenko - - * include/grub/net.h (grub_net_card): New member txbufsize. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum values - GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX and - GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN. - * grub-core/net/drivers/efi/efinet.c (grub_efinet_findcards): Use - txbufsize. - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Use - compatible property to check for macs. Set - GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX and - GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN on macs. - * grub-core/net/drivers/ieee1275/ofnet.c (card_open): Don't add suffix - if GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX is set. - (send_card_buffer): Use txbuf. - (grub_ofnet_findcards): Allocate txbuf. Simplify code flow and move - nested function out of the parent while on it. - -2012-06-19 Vladimir Serbinenko - - * grub-core/net/drivers/ieee1275/ofnet.c (get_card_packet): Fix packet - presence check. - (grub_ieee1275_net_config_real): Fix config pointer. - -2012-06-19 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): Extend - filename parsing to non-block devices. - -2012-06-19 Vladimir Serbinenko - - * grub-core/kern/device.c (grub_device_open): Remove dead code. - -2012-06-18 Vladimir Serbinenko - - * include/grub/elf.h: Rename R_PPC to GRUB_R_PPC to avoid collisions. - All users updated. - -2012-06-18 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Generate - UUID search command even if hints probing failed. - -2012-06-18 Vladimir Serbinenko - - * po/POTFILES.in: Regenerated. - -2012-06-17 Vladimir Serbinenko - - Speed-up video on fuloong. - - * grub-core/bus/bonito.c (grub_pci_device_map_range_cached): - New function. - (grub_pci_device_unmap_range): Handle non-cached address. - * grub-core/video/sis315pro.c (framebuffer): Remove render_target and - add direct_ptr. - (grub_video_sis315pro_video_fini): Unmap direct_ptr. - (grub_video_sis315pro_setup): Use cache address and grub_video_fb_setup. - (grub_video_sis315pro_set_active_render_target): Removed. - (grub_video_sis315pro_get_info_and_fini): Use uncached address. - (grub_video_adapter): Use grub_video_fb_set_active_render_target. - (grub_video_sis315pro_swap_buffers): Call grub_video_fb_swap_buffers and - sync caches. - * include/grub/mips/loongson/pci.h (grub_pci_device_map_range_cached): - New proto. - -2012-06-16 Vladimir Serbinenko - - * docs/grub.texi (Multi-boot manual config): New section. - -2012-06-15 Vladimir Serbinenko - - Avoid slow read-back from VRAM. - - * include/grub/video_fb.h (grub_video_fb_doublebuf_update_screen_t): - Move from here ... - * grub-core/video/fb/video_fb.c - (grub_video_fb_doublebuf_update_screen_t): ... here. Remove arguments. - * grub-core/video/fb/video_fb.c (framebuf_t): New type. - (front_target): Remove front_target. Add pages. - (grub_video_fb_init): Skip setting front_pages. - (grub_video_fb_fini): Likewise. - (doublebuf_blit_update_screen): Use pages. - (grub_video_fb_doublebuf_blit_init): Likewise. - (doublebuf_pageflipping_init): Allocate offscreen buffer. - (doublebuf_pageflipping_update_screen): Use offscreen buffer. - (grub_video_fb_setup): Prefer doublebuffing. - -2012-06-15 Vladimir Serbinenko - - * grub-core/normal/main.c (GRUB_MOD_INIT): Ignore errors when loading - gzio. - -2012-06-15 Vladimir Serbinenko - - Add loongson tests. - - * tests/util/grub-shell.in: Handle loongson. - * tests/partmap_test.in: Add loongson to the list of platform using ATA - drivers. - * grub-core/tests/boot/linux.init-mips.S (SHUTDOWN_MAGIC3) [REBOOT]: - Reboot instead of shutdown if REBOOT is defined. - -2012-06-15 Vladimir Serbinenko - - * grub-core/lib/mips/loongson/reboot.c (grub_reboot): Use 32-bit - sized ports since unlike on real hardware qemu supports only 32-bit - regs. - -2012-06-15 Vladimir Serbinenko - - * Makefile.util.def (grub-mkrescue): Enable on loongson. - * util/grub-mkrescue.in: Handle loongson. - -2012-06-14 Vladimir Serbinenko - - * util/getroot.c (convert_system_partition_to_system_disk) [__APPLE__]: - Set is_part appropriately. - (grub_util_biosdisk_get_grub_dev): Use is_part rather than comparing - names. Canonicalize partition without full disk. - -2012-06-13 Vladimir Serbinenko - - Revert usb-quiesce since it's wrong. - - * grub-core/disk/ieee1275/ofdisk.c (quiesce): Removed. - (grub_ofdisk_init): Don't do quiesce. - -2012-06-13 Vladimir Serbinenko - - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Apply - PowerMac workaround to Xserves as well. - Information supplied by: Benjamin Herrenschmidt. - -2012-06-13 Vladimir Serbinenko - - Don't assume that beginning address is also the entry point on ppc. - - * grub-core/loader/powerpc/ieee1275/linux.c (linux_entry): New variable. - (grub_linux_boot): Use linux_entry. - (grub_linux_load32): Fill linux_entry. Fix setting linux_addr. - (grub_linux_load64): Likewise. - -2012-06-13 Vladimir Serbinenko - - * util/grub-install.in: Fix cross-disk check on non-PreP machines. - -2012-06-13 Vladimir Serbinenko - - * grub-core/term/ieee1275/console.c (grub_console_fini): Don't - needlessly lose the console. - -2012-06-13 Vladimir Serbinenko - - * grub-core/normal/dyncmd.c (read_command_list): Don't access freed - space. - -2012-06-11 Vladimir Serbinenko - - Remove non-functional EFI grub_get_rtc. Put a better fatal message - than current grub_get_rtc() not implemented when booted with - coreboot without TSC. - - * grub-core/Makefile.am: Exclude efi/time.h from kernel headers. - Add machine/time.h to kernel headers on loongson. - * grub-core/Makefile.core.def (kernel): Remove - kern/generic/rtc_get_time_ms.c on qemu-multiboot-coreboot. - * grub-core/kern/efi/efi.c (grub_rtc_get_time_ms): Removed. - (grub_get_rtc): Likewise. - * grub-core/kern/generic/rtc_get_time_ms.c: Include grub/machine/time.h. - * grub-core/kern/i386/coreboot/init.c (grub_get_rtc): Removed. - * grub-core/kern/i386/pc/init.c: Include grub/machine/init.h. - * grub-core/kern/i386/tsc.c (grub_tsc_init) - [!GRUB_MACHINE_PCBIOS && !GRUB_MACHINE_IEEE1275]: Call grub_fatal - rather than installing known non-working time source. - * grub-core/kern/ieee1275/init.c (grub_get_rtc): Removed. - * grub-core/kern/mips/loongson/init.c: Include grub/machine/time.h. - * include/grub/time.h: Don't include machine/time.h. - * include/grub/efi/time.h: Removed. - * include/grub/i386/efi/time.h: Likewise. - * include/grub/i386/ieee1275/time.h: Likewise. - * include/grub/powerpc/ieee1275/time.h: Likewise. - * include/grub/sparc64/ieee1275/time.h: Likewise. - * include/grub/x86_64/efi/time.h: Likewise. - -2012-06-11 Vladimir Serbinenko - - Remove dot on i and j when combining with above diacritics. - - * include/grub/unicode.h (GRUB_UNICODE_DOTLESS_LOWERCASE_I): New enum - value. - (GRUB_UNICODE_DOTLESS_LOWERCASE_J): Likewise. - * grub-core/font/font.c (grub_font_construct_dry_run): Replace i and j - with dotless variants when any combining above is present. - -2012-06-09 Vladimir Serbinenko - - * tests/grub_script_expansion.in: Explicitly tell grep that we handle - text and not binary. - -2012-06-09 Vladimir Serbinenko - - Stop polling as soon as we have the packet we were waiting for. - - * include/grub/net.h (grub_net_poll_cards): New argument stop_condition. - All users updated. - * grub-core/net/arp.c (have_pending): New var. - (pending_req): Likewise. - (grub_net_arp_send_request): Fill pending_req and use have_pending as - stop indicator. - (grub_net_arp_receive): Set have_pending. - * grub-core/net/dns.c (recv_data): New field stop. - (recv_hook): Set stop. - (grub_net_dns_lookup): Init stop and use as stop condition. - * grub-core/net/http.c (http_establish): Use headers_recv as stop - condition. - * grub-core/net/net.c (grub_net_poll_cards): New argument - stop_condition. Stop when it goes true. - * grub-core/net/tcp.c (grub_net_tcp_open): Use `established' as stop - indicator. - * grub-core/net/tftp.c (tftp_open): Use `have_oack' as stop indicator. - -2012-06-09 Vladimir Serbinenko - - Keep TX and RX buffers on EFI rather than always allocate new ones. - - * include/grub/net.h (grub_net_card_driver): Allow driver to modify - card. All users updated. - (grub_net_card): New members txbuf, rcvbuf, rcvbufsize and txbusy. - * grub-core/net/drivers/efi/efinet.c (send_card_buffer): Reuse buffer. - (get_card_packet): Likewise. - (grub_efinet_findcards): Init new fields. - -2012-06-09 Vladimir Serbinenko - - * grub-core/term/ieee1275/serial.c (do_real_config): Fix cast to fix - compilation error on sparc64. - -2012-06-09 Vladimir Serbinenko - - Use ITC on IA64 rather than broken routine based on daytime. - - * grub-core/kern/efi/efi.c (grub_rtc_get_time_ms) [__ia64__]: Remove on - ia64. - (grub_get_rtc) [__ia64__]: Likewise. - * grub-core/kern/ia64/efi/init.c (divisor): New variable. - (get_itc): New function. - (grub_rtc_get_time_ms): Likewise. - (grub_machine_init): Calibrate ITC. - * include/grub/efi/time.h (grub_get_rtc), (GRUB_TICKS_PER_SECOND): - Keep only on non-ia64. Don't export since it's broken and used only - if TSC is unavailable. - -2012-06-09 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c (find_parent_device): Return the parent - even if it's used. - (name_devices): Replace #if 0 with #ifdef DEBUG_NAMES. - Skip if parent is unused. - -2012-06-08 Vladimir Serbinenko - - * tests/partmap_test.in: Skip on ppc due to serious firmware bug. - -2012-06-08 Vladimir Serbinenko - - Fix wildcard escaping. - - * grub-core/commands/wildcard.c (wildcard_escape): Moved from here ... - * grub-core/script/execute.c (wildcard_escape): .. to here. - Don't escape dot. - * grub-core/commands/wildcard.c (wildcard_unescape): Moved from here ... - * grub-core/script/execute.c (wildcard_unescape): .. to here. - Don't escape dot. - * grub-core/script/execute.c (gettext_append): Always escape. - (grub_script_arglist_to_argv): Always handle escaping/unescaping. - * grub-core/script/yylex.l: Don't cut away the escaping. - * tests/grub_script_echo1.in: Add tests with wildcard. - -2012-06-08 Vladimir Serbinenko - - * grub-core/bus/usb/serial/ftdi.c (real_config): Handle 1.5 stop bits. - (ftdi_hw_configure): Likewise. - * grub-core/bus/usb/serial/pl2303.c (GRUB_PL2303_STOP_BITS_1_5): New - define. - (real_config): Handle 1.5 stop bits. - (pl2303_hw_configure): Likewise. - -2012-06-08 Vladimir Serbinenko - - * Makefile.am: Add ppc linux bootcheck. - * grub-core/tests/boot/linux-ppc.cfg: New file. - * grub-core/tests/boot/linux.init-ppc.S: Likewise. - -2012-06-08 Vladimir Serbinenko - - * tests/grub_script_expansion.in: Skip network protocols. - -2012-06-08 Vladimir Serbinenko - - * tests/util/grub-shell.in: Use escc-ch-a port on ppc. - -2012-06-08 Vladimir Serbinenko - - * util/powerpc/ieee1275/grub-mkrescue.in: Handle (and ignore) - --rom-directory. - Add -graft-points. - -2012-06-08 Vladimir Serbinenko - - ESCC serial driver for conducting sautomated tests in qemu. - Not tested on real hardware. - - * include/grub/serial.h (grub_serial_port): New field escc_desc. - * grub-core/term/ieee1275/escc.c: New file. - * grub-core/Makefile.core.def (escc): New module. - -2012-06-08 Vladimir Serbinenko - - * grub-core/term/ieee1275/serial.c (do_real_config): Set handle to - invalid on error. - (serial_hw_fetch): Don't read invalid handle. - (serial_hw_put): Don't write into invalid handle. - -2012-06-08 Vladimir Serbinenko - - Add a 1.5 stop bits value. - - * grub-core/term/serial.c (grub_cmd_serial): Handle 1.5. - * include/grub/serial.h (grub_serial_stop_bits_t): Add - GRUB_SERIAL_STOP_BITS_1_5. - -2012-06-08 Vladimir Serbinenko - - * grub-core/commands/wildcard.c (wildcard_expand): Set default return - value rather than let it uninited. - -2012-06-07 Vladimir Serbinenko - - * grub-core/commands/wildcard.c (+check_file): New function. - (wildcard_expand): Don't expand to non-existing files, expand with - suffix and not attempt to expand if not needed. - -2012-06-07 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c (name_devices): Don't make disks - out of partitions containing other partitions. - -2012-06-07 Vladimir Serbinenko - - Pass PCIINFO on BIOS to OpenBSD since otherwise it fails to boot - on some qemu versions with GRUB. - - * include/grub/i386/openbsd_bootarg.h (OPENBSD_BOOTARG_PCIBIOS): New - define. - (grub_openbsd_bootarg_pcibios): New struct. - * grub-core/loader/i386/bsd.c (grub_openbsd_boot) [GRUB_MACHINE_PCBIOS]: - Add PCIINFO. - -2012-06-07 Vladimir Serbinenko - - * tests/util/grub-shell.in: Trim firmware output on EFI. - -2012-06-07 Vladimir Serbinenko - - * grub-core/Makefile.core.def (vga_text): Disable on muliboot - and coreboot since it's already in kernel. - -2012-06-07 Vladimir Serbinenko - - * util/getroot.c (grub_util_get_dm_node_linear_info): Moved from here... - * grub-core/kern/emu/hostdisk.c (grub_util_get_dm_node_linear_info): - to here. New return value start. All users updated. - Recursively scan linear mappings. - * include/grub/emu/hostdisk.h (grub_util_get_dm_node_linear_info): New - proto. - * grub-core/kern/emu/hostdisk.c (grub_hostdisk_find_partition_start): - Use grub_util_get_dm_node_linear_info. - * util/getroot.c (convert_system_partition_to_system_disk): Use - grub_util_info rather than grub_dprintf. - (grub_util_biosdisk_get_grub_dev): Add a new grub_util_info. - -2012-06-07 Vladimir Serbinenko - - Move handling of GRUB_QEMU_OPTS to grub-shell so that make check works. - - * Makefile.am: Remove GRUB_QEMU_OPTS handling. - * tests/util/grub-shell.in: Add GRUB_QEMU_OPTS handling. - -2012-06-07 Vladimir Serbinenko - - * include/grub/types.h (grub_set_unaligned64): New function. - * util/grub-setup.c (write_rootdev): Use unaligned access functions. - (setup): Likewise. - -2012-06-06 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (quiesce): New function. - (grub_ofdisk_fini): Quiesce USB devices. - -2012-06-06 Vladimir Serbinenko - - * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_boot): Sync - caches. - -2012-06-06 Vladimir Serbinenko - - * util/grub-fstest.c (cmd_crc): Use grub_get_unaligned32 for safety. - -2012-06-06 Vladimir Serbinenko - - * grub-core/disk/pata.c (grub_pata_pio_read) - [GRUB_MACHINE_MIPS_QEMU_MIPS]: Don't byteswap even on mipseb. - (grub_pata_pio_write) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Likewise. - -2012-06-06 Vladimir Serbinenko - - Extend automated tests to qemu-mips. - - * Makefile.am: reorganise tests and enable qemu-mips. - * configure.ac (COND_mipseb), (COND_mipsel): New conditions. - * grub-core/tests/boot/linux.init-mips.S: New file. - * tests/partmap_test.in: Handle ata0 disks. - * tests/util/grub-shell.in: Handle qemu-mips. Make defaults work on - non-pc i386. - -2012-06-06 Vladimir Serbinenko - - * Makefile.util.def (grub-mkrescue) Anable on mips_qemu_mips and - ia64. - * util/grub-mkrescue.in: Handle qemu-mips and ia64. Add missing - quotes while on it. - -2012-06-06 Vladimir Serbinenko - - * grub-core/kern/mips/qemu_mips/init.c (grub_exit): Implement. - (grub_halt): Likewise. - * grub-core/lib/mips/qemu_mips/reboot.c (grub_reboot): Likewise. - -2012-06-06 Vladimir Serbinenko - - * grub-core/term/serial.c (grub_serial_register) - [GRUB_MACHINE_MIPS_QEMU_MIPS]: Don't autostart console in order to bring - the behaviour in line with x86 platforms. - -2012-06-06 Vladimir Serbinenko - - * grub-core/commands/hdparm.c (le16_to_char): Always byte-swap strings. - (grub_ata_strncpy): Likewise. - (grub_ata_identify): Add missing byteswaps. - -2012-06-06 Vladimir Serbinenko - - * grub-core/term/i386/pc/vga_text.c (screen_write_char): Add missing - byte-swap. - (screen_read_char): Likewise. - (grub_vga_text_cls): Likewise. - -2012-06-06 Vladimir Serbinenko - - * grub-core/loader/efi/chainloader.c (copy_file_path): Handle non-ASCII - filenames. - (make_file_path): Likewise. - -2012-06-06 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (scan): Support vscsi on IBM - machines. - Tested by: Paulo Flabiano Smorigo. - Crucial information about API supplied by: Coleen . - Reviewed by: Coleen . - -2012-06-05 Vladimir Serbinenko - - * util/grub-mkimage.c: Disable -Wcast-align. - -2012-06-05 Vladimir Serbinenko - - * grub-core/genmod.sh.in: Enable objconv errors 2030, 2050 and 2031 - as they are fatal. - -2012-06-05 Vladimir Serbinenko - - * grub-core/Makefile.am (rs_decoder.S): Add missing -ffreestanding. - -2012-06-05 Vladimir Serbinenko - - * util/grub-probe.c (escape_of_path): Fix double free. - -2012-06-05 Vladimir Serbinenko - - * grub-core/commands/videoinfo.c (hook): Show pitch. - -2012-06-05 Vladimir Serbinenko - - * util/grub.d/20_linux_xen.in: Skip xen-syms. - -2012-06-05 Vladimir Serbinenko - - * util/grub-probe.c (escape_of_path): Don't add ieee1275/. - (probe): Add ieee1275 to OFW devices. - -2012-06-04 Vladimir Serbinenko - - * util/ieee1275/ofpath.c (of_path_of_scsi): Fix wrong format specifier. - -2012-06-04 Vladimir Serbinenko - - Handle IBM OFW path. - - * util/ieee1275/ofpath.c (find_obppath): Use devspec if obppath isn't - available. - (of_path_of_scsi): Handle vdevice. - -2012-06-03 Vladimir Serbinenko - - * grub-core/mmap/i386/pc/mmap.c (malloc_hook): - Allocate in multiples of 16 to avoid adding a few bytes free region the - windows bugs upon. - -2012-06-03 Vladimir Serbinenko - - * grub-core/commands/i386/pc/drivemap.c (install_int13_handler): - Allocate in multiples of 16 to avoid adding a few bytes free region the - windows bugs upon. - * grub-core/mmap/i386/pc/mmap.c (malloc_hook): Likewise. - -2012-06-02 Vladimir Serbinenko - - * grub-core/video/efi_gop.c (grub_video_gop_setup): Reject invalid - resolutions. - * grub-core/video/i386/pc/vbe.c (grub_vbe_get_preferred_mode): Likewise. - * grub-core/video/video.c (grub_video_edid_preferred_mode): Likewise. - -2012-06-02 Isao Shimizu - - * util/ieee1275/ofpath.c (check_sas): Fix sas path. - -2012-06-02 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (print_line): Fix off-by-one error which - resulted in \\ at the end of the line. - -2012-06-02 Vladimir Serbinenko - - * grub-core/kern/parser.c (grub_parser_state_transitions): Handle \t. - (grub_parser_cmdline_state): Likewise. - (grub_parser_split_cmdline): Likewise. - -2012-06-02 Vladimir Serbinenko - - * util/getroot.c (grub_guess_root_devices): Don't canonicalise - /dev/root and /dev/dm-*. - -2012-06-02 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (update_screen): Fix loop condition to - fix partially stale display. - -2012-06-02 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (backward_char): Use right line for - substraction. - -2012-06-02 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_write) [__linux__]: - Fix MBR remapping workaround. - (grub_util_biosdisk_read) [__linux__]: Likewise. - -2012-06-01 Vladimir Serbinenko - - * util/grub-install.in: Check for ieee1275 and not ieee1276. - -2012-05-31 Vladimir Serbinenko - - * configure.ac: Bump to beta6. - -2012-05-31 Christer Weinigel - - * grub-core/normal/main.c (grub_file_getline): Fix off-by-one error. - -2012-05-31 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_linux_boot): Use right version. - (grub_cmd_linux): Likewise. - -2012-05-31 Christer Weinigel - - Fix EHCI low-speed. - - * grub-core/bus/usb/ehci.c (GRUB_EHCI_MULT_ONE): Fix the value. - (GRUB_EHCI_MULT_TWO): Likewise. - (GRUB_EHCI_MULT_THREE): Likewise. - (GRUB_EHCI_CMASK_MASK): New enum value. - (GRUB_EHCI_SMASK_MASK): Likewise. - (GRUB_EHCI_CMASK_OFF): Likewise. - (GRUB_EHCI_SMASK_OFF): Likewise. - (grub_ehci_pci_iter): Enable periodic schedule. - (grub_ehci_parse_notrun): Likewise. - (grub_ehci_restore_hw): Likewise. - (grub_ehci_setup_qh): Set flags for low speed transfers. - (grub_ehci_find_qh): Use periodic list for low speed. - (grub_ehci_setup_transfer): Check periodic queue as well. - (grub_ehci_check_transfer): Likewise. - (grub_ehci_cancel_transfer): Cancel periodic transfer. - -2012-05-31 Paulo Flabiano Smorigo - - * util/grub-install.in: Write core.elf in PReP even if the --no-nvram - parameter is used. - -2012-05-31 Peter Jones - - * include/grub/i386/linux.h (linux_kernel_params): Add v206. - * grub-core/loader/i386/linux.c (grub_linux_boot): Use v206. - (grub_cmd_linux) [__x86_64__]: Validate grub_efi_system_table. - -2012-05-31 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_linux_boot): Fix overflow and - uninited variable. Allocate at least setup_sects. - -2012-05-30 Vladimir Serbinenko - - Fix handling of EFI with big memory maps. - - * grub-core/loader/i386/linux.c (GRUB_LINUX_CL_OFFSET): Removed. - (real_mode_mem): Likewise. - (real_mode_target): Likewise. - (real_mode_pages): Likewise. - (prot_mode_pages): Likewise. - (linux_params): New var. - (linux_cmdline): Likewise. - (free_pages): Don't set real mode variables. - (allocate_pages): Don't allocate real mode memory. - (grub_e820_add_region): Remove the limit. - (grub_linux_boot): Allocate and copy real mode memory. - (grub_linux_unload): Free linux_cmdline. - (grub_cmd_linux): Use temporary storage for parameters. - (grub_cmd_initrd): Likewise. - * include/grub/i386/linux.h (GRUB_E820_MAX_ENTRY): Removed. - (linux_kernel_params): Make it 1K big. - -2012-05-30 Vladimir Serbinenko - - * Makefile.util.def: Remove -Wno-format. - * grub-core/Makefile.core.def: Likewise. - -2012-05-30 Vladimir Serbinenko - - * tests/cmp_unit_test.c: Add missing failure message. - * tests/example_unit_test.c: Likewise. - * tests/printf_unit_test.c: Likewise. - -2012-05-30 Vladimir Serbinenko - - * grub-core/commands/gptsync.c (grub_cmd_gptsync): Propagate the - relaxation of protective MBR requirements. - -2012-05-29 Vladimir Serbinenko - - * configure.ac: Add condition for COND_HOST_XNU. - * Makefile.util.def (10_xnu): New script. - * util/grub.d/10_xnu.in: New file, extracted from 30_os_prober.in. - -2012-05-29 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S [__APPLE__]: Add a workaround for - objconv bug. - -2012-05-29 Vladimir Serbinenko - - * grub-core/gdb/i386/machdep.S: Make usable with Apple assembler. - Binary on other platforms stays identical. - -2012-05-28 Vladimir Serbinenko - - * configure.ac: Remove APPLE_CC and add -Wl,-allow_stack_execute on - Apple. - -2012-05-28 Vladimir Serbinenko - - * gentpl.py: Ignore error 2022 in objconv since it's irrelevant for us. - -2012-05-28 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/sys/types.h [__APPLE__]: Include stddef - rather than defining size_t ourselves to avoid conflict. - -2012-05-28 Vladimir Serbinenko - - * grub-core/fs/hfs.c (grub_hfs_dir): Use memset instead of - initialisation to avoid __bzero reference. - -2012-05-28 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S [__APPLE__]: Add Apple assembly - version. - * grub-core/commands/i386/pc/drivemap_int13h.S [__APPLE__]: Likewise. - * grub-core/kern/i386/pc/startup.S [__APPLE__]: Likewise. - * grub-core/lib/i386/relocator16.S [__APPLE__]: Likewise. - * grub-core/lib/i386/relocator_common.S [__APPLE__]: Likewise. - * grub-core/mmap/i386/pc/mmap_helper.S [__APPLE__]: Likewise. - -2012-05-28 Vladimir Serbinenko - - * grub-core/efiemu/runtime/efiemu.c: Replace APPLE_CC with __APPLE__. - * grub-core/kern/misc.c: Likewise. - * grub-core/loader/i386/xnu.c: Likewise. - * include/grub/i386/tsc.h: Likewise. - * include/grub/symbol.h: Likewise. - -2012-05-28 Vladimir Serbinenko - - * include/grub/list.h (grub_bad_type_cast_real): Remove return. - * include/grub/misc.h (ATTRIBUTE_ERROR): Make into noreturn attribute - on older compiler. - -2012-05-28 Vladimir Serbinenko - - * util/getroot.c (grub_util_biosdisk_get_grub_dev) [__APPLE__]: - Implement Apple flavour. - (convert_system_partition_to_system_disk) [__APPLE__]: Likewise. - -2012-05-28 Vladimir Serbinenko - - * include/grub/misc.h (memcmp) [__APPLE__]: Mark as regparm 0. - (memmove) [__APPLE__]: Likewise. - (memcpy) [__APPLE__]: Likewise. - (memset) [__APPLE__]: Likewise. - * grub-core/kern/misc.c (memcmp) [__APPLE__]: Likewise. - (memmove) [__APPLE__]: Likewise. - (memcpy) [__APPLE__]: Likewise. - (memset) [__APPLE__]: Likewise. - -2012-05-28 Vladimir Serbinenko - - * grub-core/genmod.sh.in: Fix a bug in Apple part which caused - dependency discard. - -2012-05-27 Vladimir Serbinenko - - * grub-core/normal/main.c (read_config_file): Provide config_file and - config_directory. - * util/grub.d/41_custom.in: Use config_directoy when available. - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/bfs.c (iterate_in_b_tree): Add missing NESTED_FUNC_ATTR. - (grub_bfs_dir): Likewise. - -2012-05-27 Peter Jones - - The old code gives arguments to a printf function which can't work - correctly, and the compiler complains. - - * grub-core/tests/example_functional_test.c (example_test): Add - missing text. - * grub-core/tests/lib/test.c (add_failure): Rewrite. - * include/grub/test.h (grub_test_assert_helper): New declaration. - (grub_test_assert): Use grub_test_assert_helper. - -2012-05-27 Vladimir Serbinenko - - * grub-core/Makefile.core.def (example_functional_test): Rename to ... - (exfctest): ... this to avoid overlong filenames. - All users updated. - -2012-05-27 Vladimir Serbinenko - - Handle "." and ".." on squashfs. - - * grub-core/fs/squash4.c (grub_fshelp_node): New field stsize. - Make inode numbers into stack. - (grub_squash_read_symlink): Use stack. - (grub_squash_iterate_dir): Use stack. Create "." and ".." nodes. - (make_root_node): Fill stack. - (grub_squash_open): Use stack. - -2012-05-27 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (open_device): Set dest->dev to 0 after - freeing. - -2012-05-27 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (print_option_help): Properly redirect - stderr on test calls. - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_find_file): Handle "." and "..". - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (list_file): Set mtime to correct value. - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Don't skip "." and - "..". - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/hfsplus.c (grub_hfsplus_catfile): New field parentid. - (grub_hfsplus_iterate_dir): Add "." and "..". - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/cpio.c (canonicalize): Handle "..". - (grub_cpio_find_file) [MODE_USTAR]: Handle hardlinks. - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (GRUB_BTRFS_ITEM_TYPE_INODE_REF): New enum value. - (find_path): Handle "." and "..". - -2012-05-27 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_file): New field hardlink. - (GRUB_AFFS_FILETYPE_HARDLINK): New enum value. - (grub_affs_iterate_dir): Handle hardlinks. - -2012-05-26 Matthew Garrett - - * grub-core/term/efi/console.c (grub_efi_console_init): Set text mode. - (grub_efi_console_fini): Likewise. - * grub-core/video/efi_gop.c (framebuffer): New field offscreen. - (grub_video_gop_fill_mode_info): Rename to ... - (grub_video_gop_fill_real_mode_info): ... this. - (grub_video_gop_fill_mode_info): New function. - (grub_video_gop_setup): Setup double framebuffer. - (grub_video_gop_get_info_and_fini): Use original framebuffer. - Free offscreen. - (grub_video_gop_swap_buffers): Copy framebuffer. - (grub_video_gop_fini): Free offscreen buffer. - * include/grub/efi/graphics_output.h (grub_efi_gop_blt_operation_t): - New enum. - (grub_efi_gop_blt_pixel): New struct. - -2012-05-26 Vladimir Serbinenko - - * gentpl.py: Remove error disabling for objconv. - -2012-05-26 Vladimir Serbinenko - - * configure.ac: Remove -Wunitialized as it's not available on older - compilers. - -2012-05-26 Vladimir Serbinenko - - Fix extent overflow comparator. - - * grub-core/fs/hfsplus.c (grub_hfsplus_extkey_internal): Add type. - (grub_hfsplus_read_block): Set type. - (grub_hfsplus_cmp_extkey): Compare type. - -2012-05-25 Vladimir Serbinenko - - * util/grub-fstest.c (cmd_cmp): Fix stat'ing of wrong file. - -2012-05-24 Vladimir Serbinenko - - * grub-core/fs/hfsplus.c (grub_hfsplus_label): Use found ptr rather - than 0. - -2012-05-24 Vladimir Serbinenko - - * Makefile.am (starfield_DATA): Add dejavu_bold_14.pf2. - (dejavu_bold_14.pf2): New target. - -2012-05-24 Vladimir Serbinenko - - * configure.ac: Fix djvu font detection. - -2012-05-23 Vladimir Serbinenko - - * grub-core/normal/misc.c (grub_normal_print_device_info): Dsiplay - ext* instead of ext2. - -2012-05-23 Vladimir Serbinenko - - * grub-core/normal/term.c (read_terminal_list): Terminate the terminal - name with \0. - -2012-05-22 Jordan Uggla - - * docs/grub-dev.texi: Remove dot from .png. - -2012-05-22 Vladimir Serbinenko - - * grub-core/partmap/gpt.c (grub_gpt_partition_map_iterate): Accept - protective entry in any slot. - * grub-core/partmap/msdos.c (grub_partition_msdos_iterate): Reject - if protective entry is found in any slot. - - Protective entry in non-first slot make no sense but is a widespread - brain damage. - -2012-05-22 Vladimir Serbinenko - - * grub-core/fs/squash4.c (grub_squash_read_data): Add missing byte-swap. - -2012-05-22 Vladimir Serbinenko - - * grub-core/fs/reiserfs.c (grub_reiserfs_iterate_dir): Fix size byteswap - with old reiserfs. - (grub_reiserfs_open): Don't free root. - -2012-05-22 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (grub_fshelp_find_file): Set currnode to 0 - after freeing for safety. - -2012-05-21 Vladimir Serbinenko - - * grub-core/commands/sleep.c (do_print): Add missing grub_refresh. - Reported by: Jordan Uggla. - -2012-05-21 Jordan Uggla - - * docs/grub.texi Fix documentation of GRUB_HIDDEN_TIMOUNT to match the - actual implementation. Specifically, clarify that the grub menu will - be displayed for GRUB_TIMOUT seconds after the hidden timeout has - passed. - -2012-05-21 Benjamin Herrenschmidt - - * grub-core/kern/powerpc/dl.c (trampoline_template): Use r12 instead - of r0. - -2012-05-21 Vladimir Serbinenko - - Remove unjustified hard dependency of normal.mod on gfxterm. - - * include/grub/term.h (grub_term_output): New member fullscreen. - * include/grub/gfxterm.h (grub_gfxterm_fullscreen): Removed. - * grub-core/term/gfxterm.c (grub_gfxterm_fullscreen): Make static. - (grub_gfxterm): Set .fullscreen. - * grub-core/normal/menu.c (menu_init): Use fullscreen. - * grub-core/gfxmenu/gfxmenu.c (GRUB_MOD_INIT): Likewise. - -2012-05-21 Vladimir Serbinenko - - * docs/grub.texi (Internationalisation/Filesystems): Add precisions - mentioning possible problems with non-ASCII (non-compliant) ISOs. - Mention case-insensitive AFFS, SFS and JFS. - -2012-05-21 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_mtime): Add missing grub_dl_ref. - -2012-05-21 Vladimir Serbinenko - - * grub-core/kern/fs.c (grub_fs_probe): Handle GRUB_ERR_OUT_OF_RANGE as - a bad FS. - -2012-05-18 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Mark plain - ISO9660 names as case-insensitive, lowercase it and remove trailing dot. - -2012-05-17 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_data): New field caseins. - (grub_jfs_mount): Fill caseins. - (grub_jfs_find_file): Respect caseins. - -2012-05-17 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Don't strrchr - through UTF-16. - -2012-05-17 Vladimir Serbinenko - - * grub-core/fs/fat.c (grub_fat_find_dir): Fix error message. - New argument origpath. All users updated. - -2012-05-15 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (read_data): Prevent overflow. - (read_attr): Ensure that we read start of possibly compressed block. - -2012-05-15 Vladimir Serbinenko - - * include/grub/ntfs.h (grub_ntfs_comp_table_element): New struct. - (grub_ntfs_comp): Use grub_ntfs_comp_table_element for comp_table. - All users updated. - -2012-05-14 Vladimir Serbinenko - - * Makefile.am (starfield_DATA): Replace dejavu.pf2 with dejavu_10.pf2, - dejavu_12.pf2, dejavu_14.pf2 and dejavu_16.pf2. - (dejavu.pf2): Replace with ... - (dejavu_10.pf2), (dejavu_12.pf2), (dejavu_14.pf2), (dejavu_16.pf2): - this. - -2012-05-14 Vladimir Serbinenko - - * util/grub.d/20_linux_xen.in: Add missing line. - -2012-05-14 Vladimir Serbinenko - - * include/grub/charset.h (GRUB_UTF16_UPPER_SURROGATE): Fix mask sizes. - (GRUB_UTF16_LOWER_SURROGATE): Likewise. - (grub_utf16_to_utf8): Likewise. - -2012-05-13 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (scan): Don't scan device tree if - GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS is set. - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set - GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS on IBM hardware. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value - GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS. - -2012-05-13 Vladimir Serbinenko - - * grub-core/kern/fs.c (grub_fs_probe): Handle GRUB_ERR_OUT_OF_RANGE as - a bad FS. - -2012-05-13 Vladimir Serbinenko - - * grub-core/fs/udf.c (read_string): Bail out on size=0. - (grub_udf_read_symlink): Handle read_string failure. - -2012-05-12 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (read_device_map): Improve TRANSLATORS - comment. - -2012-05-12 Vladimir Serbinenko - - Fix handling of UDF symlinks. - - * grub-core/fs/udf.c (read_string): New argument outbuf. - All users updated. - (grub_ufs_read_symlink): Rename to ... - (grub_udf_read_symlink): ... this. All users updated. - Handle symlinks with more than one component. - -2012-05-12 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_read_symlink): Fix handling of long - symlinks. Replace leading colon with a slash. - -2012-05-12 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_find_file): Handle multiple slashes in - filename. - -2012-05-12 Vladimir Serbinenko - - * grub-core/fs/bfs.c (find_in_b_tree) [MODE_AFS]: Fix handling of exact - match in inner node. - -2012-05-12 Vladimir Serbinenko - - * grub-core/fs/bfs.c (mount): Improve filesystem detection reliability. - * grub-core/fs/ext2.c (grub_ext2_mount): Likewise. - * grub-core/fs/hfs.c (grub_hfs_mount): Likewise. - * grub-core/fs/hfsplus.c (grub_hfsplus_mount): Likewise. - * grub-core/fs/jfs.c (grub_jfs_mount): Likewise. - * grub-core/fs/minix.c (grub_minix_mount): Likewise. - * grub-core/fs/ntfs.c (grub_ntfs_mount): Likewise. - * grub-core/fs/romfs.c (grub_romfs_mount): Likewise. - * grub-core/fs/xfs.c (grub_xfs_mount): Likewise. - -2012-05-11 Vladimir Serbinenko - - Use grub-probe and not cmp to check that disk is empty. - - * util/grub-install.in: Use grub-probe for zero-check. - * util/grub-probe.c (PRINT_ZERO_CHECK): New enum value. - (probe): Handle PRINT_ZERO_CHECK. - (argp_parser): Handle -t zero_check. - -2012-05-11 Vladimir Serbinenko - - Flush block cache on adding disk to device map. - - * grub-core/kern/emu/hostdisk.c (flush_initial_buffer): New function. - (grub_hostdisk_os_dev_to_grub_drive): Call flush_initial_buffer on - adding. - (read_device_map): Likewise. - (open_device): Flush on opening. - -2012-05-10 Vladimir Serbinenko - - * grub-core/fs/cpio.c (grub_cpio_find_file): Handle prefix. - (handle_symlink): Fix off-by-one error. - Canonicalize the target. - (grub_cpio_dir): Canonicalize the name. - Fix memory leak. - Set directory. - (grub_cpio_open): Canonicalize the name. - -2012-05-10 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix symlink - handling. - -2012-05-10 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_find_file): Fix handling of double slash. - * grub-core/fs/minix.c (grub_minix_find_file): Likewise. - -2012-05-10 Vladimir Serbinenko - - * util/grub-menulst2cfg.c (main): Check return value of fwrite. - * util/grub-mklayout.c (write_file): Likewise. New argument fname. - All users updated. - -2012-05-10 Vladimir Serbinenko - - * util/grub.d/20_linux_xen.in: Update initrd list based on 10_linux.in - counterpart. - -2012-05-10 Vladimir Serbinenko - - Fix UFS1 big file support. - - * grub-core/fs/ufs.c (INODE): Removed. - (INODE_SIZE): Always use 64-bit byte-swap since size field is always - 64-bit. - (INODE_MODE): Simplify. - (grub_ufs_inode): Use uint64_t for size and not int64_t. - (grub_ufs_lookup_symlink): Don't use INODE. - -2012-05-09 Vladimir Serbinenko - - Fix minixfs with non-power-of-two blocks since it's supported by minix. - - * grub-core/fs/minix.c (GRUB_MINIX_ZONESZ): Use block_size. - (grub_minix_data): Replace log_block_size with block_size. - (grub_minix_read_file): Use block_size but avoid 64-bit division. - (grub_minix_mount): Fill block_size. - -2012-05-09 Vladimir Serbinenko - - * configure.ac: Bump to beta5. - -2012-05-09 Vladimir Serbinenko - - Fix wrapped HFS+ handling. - - * grub-core/fs/fshelp.c (grub_fshelp_read_file): New argument - blocks_start. All users updated. - * grub-core/fs/hfsplus.c (grub_hfsplus_read_block): Don't add - wrapping offset. - (grub_hfsplus_read_file): Pass embedding offset to fshelp_read_file. - -2012-05-09 Vladimir Serbinenko - - Fix long symlinks on reiserfs. - - * grub-core/fs/reiserfs.c (grub_fshelp_node): New field size. - (grub_reiserfs_read_symlink): Use grub_reiserfs_read_real. - (grub_reiserfs_iterate_dir): Save size for non-directories. - (grub_reiserfs_open): Don't reread stat block as we already know the - size. - (grub_reiserfs_read): Split into... - (grub_reiserfs_read_real): ... and ... - (grub_reiserfs_read): ...this. - -2012-05-09 Vladimir Serbinenko - - Fix non-indexed JFS. - - * grub-core/fs/jfs.c (grub_jfs_sblock): New field flags. - (grub_jfs_data): New field namecomponentlen. - (grub_jfs_mount): Fill namecomponentlen. - (grub_jfs_getent): Use namecomponentlen rather than hardcoded 11. - -2012-05-08 Vladimir Serbinenko - - * grub-core/script/yylex.l: Ugly fix for "\\\n ". - * tests/grub_script_echo1.in: Add tests. - -2012-05-08 Vladimir Serbinenko - - * util/grub-install.in: Ignore empty devicetree directory. - -2012-05-08 Bean - - * grub-core/net/ip.c (reassemble): Make asm_buffer into asm_netbuff. - All users updated. - (free_rsm): Free header as well. - (free_old_fragments): Fix memory leak. - * grub-core/net/netbuff.c (grub_netbuff_free): Make return void. - * grub-core/net/tftp.c (tftp_receive): Fix memory leak. - (destroy_pq): Likewise. - * include/grub/net/netbuff.h (grub_netbuff_free): Make return void. - -2012-05-08 Vladimir Serbinenko - - * grub-core/commands/hashsum.c (grub_cmd_hashsum): Align space for - resulting hash as a precaution. - -2012-05-08 Vladimir Serbinenko - - * grub-core/net/bootp.c (set_env_limn_ro): Replace reserved ':' with - '_' in variable names. - * grub-core/net/net.c (grub_net_network_level_interface_register): - Likewise. - -2012-05-08 Vladimir Serbinenko - - Fix AFFS with non-512B blocks. - - * grub-core/fs/affs.c (grub_affs_rblock): Make type uint32_t. - (AFFS_MAX_LOG_BLOCK_SIZE): New definition. - (grub_affs_data): Replace blocksize with log_blocksize. - (grub_affs_read_block): Fix non-512B blocks. - (grub_affs_read_symlink): Likewise. - (grub_affs_iterate_dir): Likewise. Fix freeing corruption. - (grub_affs_read): Fix non-512B blocks. - (grub_affs_label): Likewise. - (grub_affs_mtime): Likewise. - (grub_affs_mount): Fix block detection routine. - -2012-05-08 Vladimir Serbinenko - - Add filesystem mtime to AFFS. - - * grub-core/fs/affs.c (grub_affs_file): Make type unsigned. - (aftime2ctime): New function. - (grub_affs_dir): Use aftime2ctime. - (grub_affs_label): Fix return value. - (grub_affs_mtime): New function. - (grub_affs_fs): Add mtime. - -2012-05-07 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_read_symlink): Convert latin1 into - UTF-8. - -2012-05-07 Vladimir Serbinenko - - * grub-core/fs/sfs.c (grub_sfs_read_symlink): Convert latin1 into - UTF-8. - -2012-05-07 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_iterate_dir): Mark as case insensitive. - -2012-05-07 Vladimir Serbinenko - - * grub-core/fs/sfs.c (grub_sfs_rblock): New fields createtime and - flags. - (FLAGS_CASE_SENSITIVE): New enum value. - (cache_entry): New struct. - (grub_fshelp_node): Add fields cache_off, next_extent, cache_allocated, - cache_size and cache. - (grub_sfs_data): Remove blocksize. All users switched to log_blocksize. - Add log_blocksize and fshelp_flags. - (grub_sfs_read_extent): Handle non-512 blocks. - (grub_sfs_read_block): Add cаche and handle non-512 blocks. - (grub_sfs_read_file): Handle non-512 blocks. - (grub_sfs_mount): Handle non-512 blocks. Fill log_blocksize and - fshelp_flags. - (grub_sfs_read_symlink): Handle non-512 blocks. - (grub_sfs_iterate_dir): Init new fields. Mark as case-insensitive. - (grub_sfs_dir): Free cache. - (grub_sfs_close): Likewise. - -2012-05-06 Vladimir Serbinenko - - * grub-core/fs/bfs.c (read_bfs_file): Fix overflow with over 2TiB - filesystems. - -2012-05-06 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_read_block): Fix theoretical overflow. - -2012-05-06 Vladimir Serbinenko - - * grub-core/commands/ls.c (grub_ls_list_files): Fix overflow. - -2012-05-06 Vladimir Serbinenko - - * grub-core/fs/sfs.c (grub_fshelp_node): Fix types. - (grub_sfs_read_extent): Likewise. - (grub_sfs_read_block): Likewise. - (grub_sfs_mount): Likewise. - (grub_sfs_iterate_dir): Likewise. - (grub_sfs_read_symlink): Use strncpy instead of strcpy. - (grub_sfs_read): Remove unnecessarry and wrong temporary variable. - -2012-05-04 Vladimir Serbinenko - - Fix errors on compressed NTFS with 512B clusters. - - * include/grub/ntfs.h (grub_ntfscomp_func_t): Use appropriately sized - types. - * grub-core/fs/ntfs.c (grub_ntfs_read): Return correct -1 on error and - not 0. - * grub-core/fs/ntfscomp.c (read_block): Use appropriately-sized types. - Relax check for inline extents. - (ntfscomp): Return correct -1 on error and not 0. - -2012-05-04 Vladimir Serbinenko - - * util/grub-install.in: Fix handling of prefix containing spaces. - -2012-05-04 Vladimir Serbinenko - - * grub-core/fs/squash4.c (grub_squash_inode): Fix offset field. - (grub_squash_read_data): Fix offset byte-swapping. - -2012-05-04 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_strcmp): Use unsigned comparison as - per common usage and preffered in several parts of code. - (grub_memcmp): Likewise. - (grub_strncmp): Likewise. - * include/grub/misc.h (grub_strcasecmp): Likewise. - (grub_strncasecmp): Likewise. - * Makefile.util.def (cmp_test): New test. - (grub_script_strcmp): Likewise. - * tests/cmp_unit_test.c: New file. - * tests/grub_script_strcmp.in: Likewise. - * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey): Add a comment. - -2012-05-04 Vladimir Serbinenko - - * include/grub/pci.h: Move enums into no-asm part. - -2012-05-04 Vladimir Serbinenko - - * grub-core/fs/bfs.c (bfs_strcmp) [MODE_AFS]: Use signed comparison. - -2012-05-04 Samuel Thibault - - * util/getroot.c (find_hurd_root_device): Try to make error message - and comments to translators clearer. - -2012-05-04 Vladimir Serbinenko - - * grub-core/commands/menuentry.c: Fix typo in TRANSLATORS comments. - -2012-05-04 Vladimir Serbinenko - - * grub-core/kern/fs.c (grub_fs_probe) [GRUB_UTIL]: Add workaround for - btrfs. - -2012-05-04 Vladimir Serbinenko - - * docs/grub.cfg: Update. - -2012-05-04 Vladimir Serbinenko - - * docs/grub.texi (PXE): Remove not present variables. - -2012-05-04 Vladimir Serbinenko - - * grub-core/net/net.c (defserver_set_env): New function. - (defserver_get_env): Likewise. - (GRUB_MOD_INIT): Register net_default_server and pxe_default_server. - -2012-05-03 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (read_device_map): Skip invalid Fedora - entries. - -2012-05-03 Vladimir Serbinenko - - * grub-core/commands/menuentry.c: Add TRANSLATORS comments. - * grub-core/kern/emu/hostdisk.c: Likewise. - -2012-05-03 Samuel Thibault - - Handle hurd userspace partitions. - - * util/getroot.c (find_hurd_root_device): New function. - (grub_guess_root_devices): Use find_hurd_root_device on Hurd. - -2012-05-03 Vladimir Serbinenko - - * util/getroot.c (convert_system_partition_to_system_disk); Add etherd - names. - Reported by: Bastian Blank. - -2012-05-03 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Fix offset when - crossing page boundary. - -2012-05-03 Vladimir Serbinenko - - Fix B-tree search in BFS, especially in presence of non-ASCII - characters. - - * grub-core/fs/bfs.c (bfs_strcmp): New function. - (find_in_b_tree): Use standard bsearch + btree algorithm. - -2012-05-03 Vladimir Serbinenko - - * util/grub-fstest.c (cmd_cmp): Avoid comparing devices, pipes - and so on. - -2012-05-03 Matthew Garrett -2012-05-03 Vladimir Serbinenko - - Suspend broadcom cards in order to stop their DMA. - - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add pci.h on x86 EFI. - * grub-core/Makefile.core.def (kernel): Add pci.c on x86 EFI. - (pci): Don't build on x86 EFI. - * grub-core/bus/pci.c (grub_pci_find_capability): New function. - * grub-core/kern/efi/mm.c (stop_broadcom) [__i386__ || __x86_64__]: - New function. - (grub_efi_finish_boot_services) [__i386__ || __x86_64__]: Call - stop_broadcom if running on EFI. - * include/grub/pci.h (GRUB_PCI_CLASS_NETWORK): New enum value. - (GRUB_PCI_CAP_POWER_MANAGEMENT): Likewise. - (GRUB_PCI_VENDOR_BROADCOM): Likewise. - (grub_pci_find_capability): New proto. - -2012-05-03 Vladimir Serbinenko - - * docs/grub.texi: Remove dot from the extension as it apparently - doesn't work with some makeinfo versions. - -2012-05-03 Vladimir Serbinenko - - * po/Makefile.in.in: Make msgfmt output in little-endian in accordance - with GRUB expectance. - -2012-05-03 Vladimir Serbinenko - - * util/grub-fstest.c (cmd_cmp): Compare directories recursively. - -2012-05-03 Vladimir Serbinenko - - * grub-core/fs/reiserfs.c (grub_reiserfs_iterate_dir): Put a trailing - zero after directory block since last entry may be not 0-terminated if - it ends on block boundary. Use continue instead of if spanning whole - loop. - -2012-05-03 Vladimir Serbinenko - - Support 4K sectors UDF inline files. - - * grub-core/fs/udf.c (grub_udf_file_entry): Don't specify padding size. - (grub_udf_extended_file_entry): Likewise. - (grub_fshelp_node): Name the anonymous union. Put block at the end. - All users updated. - (get_fshelp_size): New function. - (grub_udf_read_icb): Read whole block. - (grub_udf_iterate_dir): Likewise. - (grub_udf_dir): Likewise. - (grub_udf_open): Likewise. - -2012-05-03 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_get_file_block): Support triple indirect. - -2012-05-03 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Use proper check for - inline symlinks in addition to workaround. - -2012-05-03 Vladimir Serbinenko - - * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Handle read_inode errors. - -2012-05-03 Vladimir Serbinenko - - * grub-core/fs/xfs.c (GRUB_XFS_EXTENT_BLOCK): Fix bitmask. - -2012-05-03 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (nvlist_find_value): Fix return value. - -2012-05-02 Vladimir Serbinenko - - Fix reiserfs big seek times. - - * grub-core/fs/reiserfs.c (grub_reiserfs_get_item): New argument - exact. All users updated. - (grub_reiserfs_read): Use nearest btree search for seeking. - Fix return value on error. - -2012-05-02 Vladimir Serbinenko - - * grub-core/commands/legacycfg.c (legacy_file): Default to restricted - entries. - * grub-core/commands/menuentry.c (grub_cmd_menuentry): Likewise. - * docs/grub.texi: Update menuentry description. - -2012-05-02 Vladimir Serbinenko - - * util/grub-setup.c (setup): Remove duplicate call to embed. Fixes - crash when embedding onto filesystem. - -2012-05-02 Vladimir Serbinenko - - * util/getroot.c (find_root_devices_from_poolname): Handle spaces in the - name. - -2012-05-01 Vladimir Serbinenko - - * grub-core/net/ip.c (handle_dgram): Fix undeclared variable. - -2012-05-01 Vladimir Serbinenko - - * grub-core/normal/autofs.c (read_fs_list): Revert accidental wrong - commit. - -2012-05-01 Vladimir Serbinenko -2012-05-01 Bean - - * grub-core/net/ip.c (handle_dgram): Fix DHCP mac comparison. - -2012-05-01 Vladimir Serbinenko - - * grub-core/kern/file.c (grub_file_read): Read nothing if len = 0. - Special behaviour for len = 0 to read whole file isn't used anywhere and - can cause buffer ovewrflows in several places. - -2012-05-01 Vladimir Serbinenko - - * grub-core/normal/autofs.c (read_fs_list): Fix memory leak. - -2012-05-01 Vladimir Serbinenko - - Handle RAIDZ on non-512B sectors. - - * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member - max_children_ashift. - (fill_vdev_info_real): Fill max_children_ashift. - (read_device): Use max_children_ashift. - -2012-05-01 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (grub_fshelp_find_file): Fix memory leak. - -2012-05-01 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (read_device_map): Reject non-standard - disk names. - * docs/grub.texi: Update device.map parts. - -2012-05-01 Vladimir Serbinenko - - Don't scan into non-diskfilter devices having diskfilter names. - - * grub-core/disk/diskfilter.c (is_valid_diskfilter_name): New function. - (scan_disk): New argument accept_diskfilter. Fix recursion depth - handling. - (scan_disk_hook): New function. - -2012-04-29 Bean - - * grub-core/net/drivers/efi/efinet.c (get_card_packet): Fix buffer - allocation. - -2012-04-29 Mads Kiilerich (tiny) - - * configure.ac: Detect starfield theme font path - /usr/share/fonts/dejavu/DejaVuSans.ttf for Fedora. - -2012-04-26 Vladimir Serbinenko - - * grub-core/term/ieee1275/console.c (grub_console_dimensions): Use 80x24 - geometry on serial consoles. - -2012-04-26 Vladimir Serbinenko - - * grub-core/term/terminfo.c (grub_terminfo_readkey): Increase timeout - because of network consoles. - -2012-04-26 Vladimir Serbinenko - - * grub-core/term/terminfo.c (grub_terminfo_getkey): Fix incorrect queue - handling. - -2012-04-26 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (read_segment): Fix the case when disknr - falls on Q syndrom. - -2012-04-26 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (grub_nilfs2_palloc_entry_offset_log): - Fix argument to grub_nilfs2_palloc_bitmap_block_offset. - -2012-04-25 Vladimir Serbinenko - - * grub-core/fs/squash4.c (lzo_decompress): Set grub_errno on error. - Allocate at lest 8192 for temporary buffer as required for lzo. - -2012-04-25 Vladimir Serbinenko - - * grub-core/fs/fat.c (grub_fat_mount): Don't add logical_sector_bits - to cluster_bits, since it's already added in. - (grub_fat_read_data): Likewise. - -2012-04-25 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (grub_ntfs_mount): Support 256-byte sectors, - as long as cluster size is multiple of 512 bytes. - -2012-04-23 Vladimir Serbinenko - - * util/grub-mkrescue.in: Fix locale directory. - -2012-04-23 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (map): Make static. - -2012-04-23 Bean - - * util/grub-fstest.c (fstest): Add missing break. - -2012-04-22 Samuel Thibault - - Fix hurd build. - - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_size) [__GNU__]: Do - not define nr variable. - * util/getroot.c [__GNU__] (strip_extra_slashes, xgetcwd, exec_pipe, - find_root_devices_from_poolname, find_root_devices_from_libzfs, - grub_find_device): Do not define. - -2012-04-21 Vladimir Serbinenko - - Fix kfreebsd compile and behaviour. - - * grub-core/kern/emu/hostdisk.c (grub_util_follow_gpart_up): Fix - format-security. - * util/getroot.c: Fix wait.h include. - (grub_guess_root_devices): Error if grub_find_device fails. - (grub_util_get_geom_abstraction): Fix shadowing and format-security. - (grub_util_get_dev_abstraction): Likewise. - (grub_util_pull_device): Likewise. - (grub_util_get_grub_dev): Likewise. - * util/lvm.c (grub_util_lvm_isvolume): Likewise. - -2012-04-21 Vladimir Serbinenko - - Fix and unify wholedisk detection. - - * util/getroot.c (convert_system_partition_to_system_disk): New argument - is_part. All users updated. - (device_is_wholedisk): Removed. - (grub_util_biosdisk_get_grub_dev): Use is_part. - -2012-04-18 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_write): Fix opening - mode. - -2012-04-18 Vladimir Serbinenko - - * configure.ac: Bump to beta4. - -2012-04-18 Vladimir Serbinenko - - * grub-core/commands/search_wrap.c (grub_cmd_search): Handle old - --fs-uuid --set UUID syntax. - -2012-04-18 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_write): Fix message - disunification. - -2012-04-18 Vladimir Serbinenko - - * conf/Makefile.common (LDFLAGS_PLATFORM): Use explicit -Wl. - -2012-04-18 Mads Kiilerich - - * grub-mkconfig_lib.in: Ignore *.rpmnew and *.rpmsave. - -2012-04-18 Mike Gilbert - - * util/grub.d/10_linux.in: Fix detection of genkernel initramfs. - -2012-04-18 Bean - - * grub-core/disk/ata.c (grub_ata_strncpy): Put terminating zero at right - place. - -2012-04-18 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (open_device): New argument max. All - users updated. - (grub_util_biosdisk_read): Handle Linux partitions not exactly - corresponding to GRUB partitions. - (grub_util_biosdisk_write): Likewise. - -2012-04-18 Vladimir Serbinenko - - Scan mdraid before LVM. - - * include/grub/diskfilter.h (grub_diskfilter_register): Renamed to .. - (grub_diskfilter_register_front): ... this. - (grub_diskfilter_register_back): New function. - All users of grub_diskfilter_register updated. - -2012-04-18 Vladimir Serbinenko - - * util/grub-install.in: Fix an automatic target detection bug. - -2012-04-18 Vladimir Serbinenko - - * util/grub-install.in: New option --efi-directory. - -2012-04-17 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (allocate_pages): Overwrite low memory - boot services if we have no other choice. - -2012-04-14 Vladimir Serbinenko - - * util/grub-mknetdir.in: Rename --override-directory to --directory and - document it. - * tests/util/grub-shell.in: Update to --directory. - -2012-04-13 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c: Disable -Wstrict-aliasing. - -2012-04-13 Vladimir Serbinenko - - * grub-core/fs/minix.c (grub_minix_data): Fix ino type. - (grub_minix_read_file): Likewise. - (grub_minix_read_inode): Likewise. - (grub_minix_find_file): Likewise. - (grub_minix_dir): Likewise. - -2012-04-13 Vladimir Serbinenko - - * util/grub-setup.c (setup): Fix partition handling and blocklist - check. - -2012-04-13 Vladimir Serbinenko - - * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align): Remove - redundant buggy overlap check. - -2012-04-11 Vladimir Serbinenko - - * tests/util/grub-shell.in: Set pkgdatadir when calling grub-mkrescue - and grub-mknetdir. - -2012-04-11 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_cmd_linux): Avoid accessing - kh.loadflags on pre-2.00 kernels. - -2012-04-11 Vladimir Serbinenko - - Terminate UNDI and PXE before launching the payload to avoid problems - with DMA. - - * grub-core/commands/boot.c (grub_loader_noreturn): Rename to ... - (grub_loader_flags): ... this. All users updated. - (grub_loader_boot): Check for GRUB_LOADER_FLAG_NORETURN. - * grub-core/loader/i386/pc/pxechainloader.c (grub_cmd_pxechain): Mark - loader as GRUB_LOADER_FLAG_PXE_NOT_UNLOAD. - * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_shutdown): New - function. - (grub_pxe_restore): Likewise. - (fini_hnd): New var. - (GRUB_MOD_INIT): Register shutdown hook. - (GRUB_MOD_FINI): Shutdown and unregister shutdown hook. - * include/grub/loader.h (GRUB_LOADER_FLAG_NORETURN): New const. - (GRUB_LOADER_FLAG_PXE_NOT_UNLOAD): Likewise. - (grub_loader_set): Rename second argument to flags. - -2012-04-07 Vladimir Serbinenko - - * grub-core/normal/charset.c (grub_ucs4_to_utf8): Return number of - written bytes. - (grub_get_num_of_utf8_bytes): New function. - (grub_ucs4_to_utf8_alloc): Use grub_get_num_of_utf8_bytes. - * grub-core/normal/menu_entry.c (run): Convert entry to UTF-8 before - executing it. - * include/grub/charset.h (grub_get_num_of_utf8_bytes): New proto. - (grub_ucs4_to_utf8): Change return type. - -2012-04-07 Vladimir Serbinenko - - * grub-core/commands/usbtest.c (usb_print_str): Silence spurious - warning. - * grub-core/fs/bfs.c (hop_level): Likewise. - * grub-core/net/bootp.c (grub_cmd_bootp): Likewise. - -2012-04-07 Vladimir Serbinenko - - * grub-core/lib/adler32.c: Recode due to license unclearness. - -2012-04-07 Vladimir Serbinenko - - * grub-core/io/lzopio.c (read_block_header): Fix incorrect byte swapping - (test_header): Likewise. - -2012-04-07 Vladimir Serbinenko - - Fix --help formatting. - - * util/grub-mkconfig_lib.in (print_option_help): New function. - (grub_fmt): Likewise. - * util/grub-install.in: Use print_option_help and grub_fmt. - * util/grub-kbdcomp.in: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2012-04-07 Vladimir Serbinenko - - * linguas.sh: Remove autogenerated *.po. - -2012-04-04 Vladimir Serbinenko - - * po/README: Move language fetcing to ... - * linguas.sh: ... here. - * po/README: Point to linguas.sh. - -2012-04-04 Vladimir Serbinenko - - * po/README: Exclude ko.po due to disclaimer problems. - -2012-04-04 Vladimir Serbinenko - - * grub-core/gettext/gettext.c (grub_gettext_pread): Fix the case when - len = 0. - (grub_gettext_translate_real): Handle 0th string. - (grub_gettext_translate): Ensure that "" isn't translated. - -2012-04-04 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_memberlist): Add - TRANSLATORS comment. - (grub_diskfilter_print_partmap): Propagate changing of error into - warning. - -2012-04-04 Vladimir Serbinenko - - * include/grub/diskfilter.h (grub_diskfilter_vg): Increase extent_size - to uint64_t to prevent overflow. - (grub_diskfilter_lv): Increase start_extent and extent_count - to uint64_t to prevent overflow. - -2012-04-01 Vladimir Serbinenko - - * configure.ac: Increase version. - -2012-04-01 Vladimir Serbinenko - - Introduce en@cyrillic en@hebrew en@arabic and en@greek. - - * po/Rules-translit: New file. - * po/arabic.sed: Likewise. - * po/cyrillic.sed: Likewise. - * po/greek.sed: Likewise. - * po/hebrew.sed: Likewise. - * po/README: Add en@cyrillic en@hebrew en@arabic and en@greek. - * po/Makefile.in.in: Add extra_dist4. - -2012-04-01 Vladimir Serbinenko - - Handle big-endian minixfs (fixes minixfs tests on bigendian). - - * grub-core/fs/minix.c: Replace le with minix. Add necessary defines, - modify names. Introduce MODE_BIGENDIAN. - * grub-core/fs/minix_be.c: New file. - * grub-core/fs/minix2_be.c: Likewise - * grub-core/fs/minix3_be.c: Likewise. - * Makefile.util.def (libgrubmods): Add minix_be, minix2_be and - minix3_be. - * grub-core/Makefile.core.def (minix_be): New module. - (minix2_be): Likewise. - (minix3_be): Likewise. - -2012-04-01 Felix - - * grub-core/loader/efi/appleloader.c (devpath_7): New var. - (devs): Add MBP 2011. - -2012-04-01 Vladimir Serbinenko - - * grub-core/font/font.c (blit_comb): Handle dagesh somewhat. - -2012-04-01 Vladimir Serbinenko - - * grub-core/normal/cmdline.c (print_completion): New field - prompt_len. - (grub_cmdline_get): Handle width properly. - -2012-04-01 Vladimir Serbinenko - - * grub-core/commands/lsacpi.c (options): Add missing terminator. - -2012-03-31 Vladimir Serbinenko - - * include/grub/datetime.h (grub_datetime2unixtime): Fix handling of days - after 29th of February. - -2012-03-31 Vladimir Serbinenko - - Fix exfat endianness handling. - - * grub-core/fs/fat.c (grub_fat_data): Make fat_sector 32-bit. - (grub_fat_mount) [MODE_EXFAT]: Fix bpb.num_reserved_sectors byte-swap. - (grub_fat_iterate_dir) [MODE_EXFAT]: Fix attr byte-swap. - Byte-swap utf16 when necessary. - (grub_fat_label) [MODE_EXFAT]: Byte-swap utf16 when necessary. - -2012-03-31 Anton Blanchard -2012-03-31 Vladimir Serbinenko - - Fix btrfs endianness handling. - - * grub-core/fs/btrfs.c (key_cmp): Use grub_le_to_cpu for clarity. - (lower_bound): Make root uint64_t. Use root in le. - (grub_btrfs_read_logical): Fix template key init. Fix address byteswap. - (find_path): Fix template key init. - (grub_btrfs_dir): Fix mtime byteswap. - * include/grub/types.h (grub_cpu_to_le64_compile_time): New macro. - -2012-03-31 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_read_logical): New argument - recursion_depth. Break infinite resursions. All users updated. - -2012-03-31 Vladimir Serbinenko - - * util/getroot.c (convert_system_partition_to_system_disk): Fix use - after free. - Reported by: Peter Jones. - -2012-03-31 Anton Blanchard - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Do not byteswap - 8 bit values. - -2012-03-28 Vladimir Serbinenko - - * util/grub-install.in: Fix nvram call for PreP. - -2012-03-28 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_memberlist): Degrade - the error when some elements are missing into a warning. - -2012-03-28 Vladimir Serbinenko - - * grub-core/normal/charset.c (bidi_line_wrap): Fix out-of-range swap. - -2012-03-28 Colin Watson - - * docs/grub.texi (Invoking grub-probe): New section. - Reported by: Filipus Klutiero. Fixes Debian bug #666031. - -2012-03-27 Vladimir Serbinenko - - Fix tab and wide character handling in editor and menu. - - * grub-core/normal/charset.c (grub_unicode_aglomerate_comb): Don't - agglomerate control characters with combining marks. - (bidi_line_wrap): Allow break on tab. - (grub_unicode_get_comb_start): New function. - * grub-core/normal/menu_entry.c: Restructure to handle wide characters - and tab correctly. - * grub-core/normal/menu_text.c (print_entry): Replace \n, \r, \b and \e - with a space. - * grub-core/normal/term.c (print_ucs4_terminal): New argument - fixed_tab_size. All users updated. - * include/grub/term.h (GRUB_TERM_TAB_WIDTH): New const. - (grub_term_getcharwidth): Handle \t. - * include/grub/unicode.h (grub_unicode_glyph_dup): Fix allocation - and copy. - -2012-03-26 Vladimir Serbinenko - - Handle big-endian mdraid. - - * Makefile.util.def (libgrubkern): Add mdraid_linux_be.c. - * grub-core/Makefile.core.def (mdraid09_be): New module. - * grub-core/disk/mdraid_linux.c: Use grub_md_to_cpu* and grub_cpu_to_md* - rather than grub_le_to_cpu* and grub_cpu_to_le*. - * grub-core/disk/mdraid_linux_be.c: New file. - -2012-03-26 Vladimir Serbinenko - - * grub-core/gettext/gettext.c (GRUB_MOD_INIT): Handle errors. - -2012-03-19 Vladimir Serbinenko - - * util/getroot.c (grub_make_system_path_relative_to_its_root): Fix - missing quotes which caused confusion among translators. - -2012-03-19 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in: Fix typo. - -2012-03-19 Vladimir Serbinenko - - * grub-core/script/argv.c (grub_script_argv_split_append): Skip leading - spaces. - * tests/grub_script_leading_whitespace.in: New file. - * Makefile.util.def (grub_script_leading_whitespace): New test. - -2012-03-19 Vladimir Serbinenko - - * grub-core/kern/dl.c (grub_dl_add): Make global in order for gdb_grub - to work. - -2012-03-19 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_label): Use first label if second one - starts with control character. - -2012-03-19 Vladimir Serbinenko - - * grub-core/gdb/cstub.c (grub_gdb_inbuf): Increase the size to avoid - overflow. - (grub_gdb_outbuf): Likewise. - -2012-03-19 Vladimir Serbinenko - - * grub-core/commands/menuentry.c (grub_normal_add_menu_entry): Add - zero terminator. Fixes a crash. - -2012-03-11 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (allocate_pages): Don't allocate - beyond 4 GiB. - (grub_cmd_linux): Use GRUB_LINUX_BZIMAGE_ADDR for non-relocatable - images independently of preffered adderss field. - -2012-03-11 Vladimir Serbinenko - - * grub-core/commands/i386/pc/play.c: Improve TRANSLATORS comments. - * grub-core/commands/regexp.c: Likewise. - * grub-core/loader/i386/linux.c: Likewise. - * grub-core/partmap/msdos.c: Likewise. - * grub-core/script/execute.c: Likewise. - * grub-core/term/gfxterm.c: Likewise. - -2012-03-11 Vladimir Serbinenko - - Add variable parsing in $"..." and fix several mismatches with bash. - - * Makefile.util.def (grub_script_gettext): New test. - * grub-core/script/execute.c (parse_string): New function. - (gettext_append): Likewise. - (grub_script_arglist_to_argv): Use gettext_append. - * grub-core/script/yylex.l: Fix slash and newline handling in $"...". - * tests/grub_script_gettext.in: New file. - -2012-03-11 Vladimir Serbinenko - - Fix handling of leading spaces in scripts. - - * grub-core/normal/cmdline.c (grub_cmdline_get): Don't strip leading - spaces. - * grub-core/normal/main.c (grub_file_getline): Remove all preprocessing - other than skipping \r. All users updated. - * tests/grub_script_echo1.in: Add space-related tests. - * util/grub-menulst2cfg.c (main): Remove useless space skipping. - -2012-03-11 Vladimir Serbinenko - - * grub-core/commands/cat.c (grub_cmd_cat): Fix termination key check. - -2012-03-10 Vladimir Serbinenko - - * configure.ac: Bump up the version to beta2. - -2012-03-10 Vladimir Serbinenko - - Fix gettext reload bugs (e.g. inability to disable gettext - once enabled). - - * grub-core/gettext/gettext.c: Encapsulate all static variables in - main_context and secondary_context. All functions updated. - (grub_gettext_translate): Rename to ... - (grub_gettext_translate_real): ... this. Return NULL on failed - translate. - (grub_gettext_translate): Handle secondary context. - (grub_gettext_delete_list): Close file and zero-out the context. - (grub_mofile_open): Don't call grub_gettext_delete_list. - Don't close file. - (grub_gettext_init_ext): Call grub_gettext_init_ext. Skip loading - if locale="" to avoid pointless error message. - (grub_gettext_env_write_lang): Update lang even if load fails. - Handle secondary context. - (grub_gettext_reread_prefix): New function. - (read_main): Likewise. - (read_secondary): Likewise. - (GRUB_MOD_INIT): Handle secondary context. Hook and export variables. - (GRUB_MOD_FINI): Handle secondary context. Don't close file. - * grub-core/normal/main.c (read_lists): Call grub_gettext_reread_prefix. - * include/grub/normal.h (grub_gettext_reread_prefix): New proto. - -2012-03-10 Vladimir Serbinenko - - * configure.ac: Decrease warning level to avoid spurious warnings and - to be able to compile with GCC 4.2. - * Makefile.util.def: Remove -Wno-error=logical-op. - -2012-03-10 William Bittner - - * util/import_unicode.py: Add missing brackets around string for - python 3 support. - -2012-03-10 Vladimir Serbinenko - - Fix efi chainloader on network root. - - * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Handle - network devices. - * grub-core/net/drivers/efi/efinet.c (grub_efinet_get_device_handle): - New function. - -2012-03-10 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_progress_bar.c (grub_gui_progress_bar): Remove - unused show_text member. - * docs/grub.texi: Document "text" property. - -2012-03-10 Vladimir Serbinenko - - * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Fix format - in dprintf. - -2012-03-10 Vladimir Serbinenko - - Fix IMSM handling on Fedora. - - * util/getroot.c (grub_util_is_imsm): New function. - (grub_util_get_dev_abstraction): Treat IMSM as simple device, not RAID. - -2012-03-10 Vladimir Serbinenko - - * Makefile.am: Strip gold section. - * conf/Makefile.common: Likewise. - * gentpl.py: Likewise. - * grub-core/Makefile.core.def: Likewise. - * grub-core/genmod.sh.in: Likewise. - -2012-03-10 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Use stat if grub-probe on root fails. - * util/grub.d/20_linux_xen.in: Likewise. - Based on Debian patch. - -2012-03-10 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Fix syntax error resulting in - Richard Laager's patch. - * util/grub.d/20_linux_xen.in: Propagate Richard Laager's patch. - -2012-03-10 Vladimir Serbinenko - - * tests/partmap_test.in: Replace qemu-img usage with dd to decrease - dependencies. - -2012-03-10 Richard Laager - - * util/grub.d/10_linux.in: Fix ZFS root passing. - -2012-03-10 Vladimir Serbinenko - - * grub-core/commands/videoinfo.c: Add TRANSLATORS comments. - * grub-core/commands/xnu_uuid.c: Likewise. - * grub-core/loader/efi/appleloader.c: Likewise. - * grub-core/script/execute.c: Likewise. - * grub-core/script/main.c: Likewise. - * util/grub-mkfont.c: Likewise. - -2012-03-10 Vladimir Serbinenko - - * util/grub-mkfont.c (options): Use more appropriate "select" that - "set" for face index. - -2012-03-10 Vladimir Serbinenko - - * util/grub-editenv.c (options): Gettextize command summaries. - -2012-03-10 Vladimir Serbinenko - - * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Use - "out of memory" error messagge. - -2012-03-10 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_memberlist): Add scanning - of diskfilter for diskfilter on diskfilter support. - -2012-03-10 Vladimir Serbinenko - - * util/getroot.c (exec_pipe): Ensure that the child is not localised. - -2012-03-10 Vladimir Serbinenko - - * util/grub-install.in: Check for themes/starfield/theme.txt and not - themes/starfield. - -2012-03-10 Vladimir Serbinenko - - * grub-core/gnulib/regcomp.c (regerror): Fix out-of-range array lookup. - -2012-03-10 Vladimir Serbinenko - - * grub-core/gdb/i386/idt.c (grub_gdb_breakpoint): Remove old debug code. - -2012-03-10 Vladimir Serbinenko - - * grub-core/commands/hashsum.c (grub_cmd_hashsum): Remove dot at the end - of error message. - -2012-03-09 Vladimir Serbinenko - - * util/grub-install.in: Fix install non-PreP IEEE1275 install. - -2012-03-09 Vladimir Serbinenko - - * grub-core/commands/i386/pc/sendkey.c (GRUB_MOD_INIT): Fix confusing - message. - * util/grub-install.in: Fix and gettextize error message. - -2012-03-08 Vladimir Serbinenko - - * util/grub-fstest.c (options): Replace N with NUM and S with STRING. - Gettextize. - * util/grub-mount.c (options): Likewise. - -2012-03-08 Vladimir Serbinenko - - * grub-core/commands/probe.c (options): Replace VAR with VARNAME and - gettextize. - * grub-core/commands/search_wrap.c (options): Likewise. - -2012-03-08 Vladimir Serbinenko - - * grub-core/normal/charset.c (bidi_line_wrap): Fix a spurious warning. - -2012-03-08 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S (multiboot_trampoline): Fix - size calculation. - * grub-core/kern/i386/realmode.S (realidt): Assume default BIOS IDT if - none is known. - -2012-03-08 Vladimir Serbinenko - - * grub-core/net/net.c (grub_net_addr_to_str): Don't translate - "temporary" since it's used in identifier and is limited in space. - -2012-03-08 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. Include *.h since they contain - translatable strings as well. - -2012-03-08 Vladimir Serbinenko - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Add missing - byte-swap on big-endian. - Reported by: Lennart Sorensen - -2012-03-07 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (prot_init_space): New variable. - (allocate_pages): Improve dprintf. - (grub_cmd_linux): Fill prot_init_space. Fix improper usage of - code32_start. Fill code32_start and kernel_alignment in params. - (grub_cmd_initrd): Use prot_init_space. - -2012-03-06 Vladimir Serbinenko - - * util/grub-mkstandalone.in: Propagate grub-mkimage.c change. - -2012-03-06 Vladimir Serbinenko - - * util/grub-install.in: Add missing dot at the end of sentence. - -2012-03-06 Vladimir Serbinenko - - * grub-core/commands/videoinfo.c: Add TRANSLATORS comments. - * grub-core/commands/videotest.c: Likewise. - * grub-core/loader/i386/linux.c: Likewise. - -2012-03-06 Vladimir Serbinenko - - * grub-core/commands/acpi.c (options): Fix a dot in the middle of the - sentence. - Reported by: Milo Casagrande. - -2012-03-06 Vladimir Serbinenko - - * grub-core/commands/acpi.c: Add TRANSLATORS comments. - * grub-core/commands/gptsync.c: Likewise. - * grub-core/commands/hashsum.c: Likewise. - * grub-core/commands/i386/pc/sendkey.c: Likewise. - * grub-core/commands/legacycfg.c: Likewise. - * grub-core/io/gzio.c: Likewise. - * grub-core/net/net.c: Likewise. - * grub-core/term/gfxterm.c: Likewise. - * grub-core/term/terminfo.c: Likewise. - * grub-core/tests/test_blockarg.c: Likewise. - * grub-core/video/video.c: Likewise. - * util/grub-install.in: Likewise. - * util/grub-mkfont.c: Likewise. - -2012-03-06 Vladimir Serbinenko - - * util/grub-mkimage.c (help_filter): Add missing capitalisation. - -2012-03-06 Vladimir Serbinenko - - * grub-core/commands/search_wrap.c (options): Fix a typo. - Reported by: David Prévot. - -2012-03-06 Vladimir Serbinenko - - * util/grub-kbdcomp.in: Change "layout" to "keyboard layout" in - description. - -2012-03-06 Vladimir Serbinenko - - * util/grub-script-check.c (main): Fix a syntax error message which was - unclear. - -2012-03-06 Vladimir Serbinenko - - * util/grub-mkrescue.in (usage): Fix ROM capitalisation. - -2012-03-06 Vladimir Serbinenko - - * grub-core/commands/search_wrap.c (options): Fix wrong copy-paste in - messages. - -2012-03-06 Vladimir Serbinenko - - * util/grub-fstest.c (options): Remove OPTION_ARG_OPTIONAL from options - without argument. - * util/grub-mount.c (options): Likewise. - -2012-03-05 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Unify diskboot.img size message. - -2012-03-05 Vladimir Serbinenko - - * grub-core/net/http.c: Add TRANSLATORS comments. - * grub-core/normal/cmdline.c: Likewise. - * grub-core/normal/misc.c: Likewise. - * grub-core/partmap/msdos.c: Likewise. - * grub-core/parttool/msdospart.c: Likewise. - * grub-core/script/execute.c: Likewise. - * grub-core/script/main.c: Likewise. - * grub-core/term/terminfo.c: Likewise. - * grub-core/video/bitmap.c: Likewise. - * util/grub-install.in: Likewise. - * util/grub-mkimage.c: Likewise. - * util/grub-mklayout.c: Likewise. - * util/grub-setup.c: Likewise. - -2012-03-05 Vladimir Serbinenko - - * util/grub-mount.c (fuse_init): Unify cryptomount and loopback messages - with similar messages in grub-fstest. - -2012-03-05 Vladimir Serbinenko - - * util/grub-install.in: Unify "option requires an argument" message - with similar messages in other files. - * util/grub-mkconfig.in: Likewise. - -2012-03-05 Vladimir Serbinenko - - * util/grub-set-default.in: Replace printf with gettext_printf (the - string in in question is already translated from grub-reboot) - -2012-03-05 Vladimir Serbinenko - - * configure.ac: Bump up the version to beta1. - -2012-03-04 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (allocate_pages): Fix handling of the - case when min_align = 0. - -2012-03-04 Vladimir Serbinenko - - * grub-core/normal/charset.c (bidi_line_wrap): Fix a spurious warning - and fix a case when line_start overflows. - -2012-03-04 Vladimir Serbinenko - - * util/grub-reboot.in (usage): Mention id posibility. - * util/grub-set-default.in (usage): Likewise. - -2012-03-04 Vladimir Serbinenko - - * include/grub/misc.h (ALIGN_UP_OVERHEAD): New define. - * grub-core/loader/i386/linux.c (grub_cmd_initrd): Align initrds at 4. - * grub-core/loader/i386/pc/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/ia64/efi/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/mips/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/powerpc/ieee1275/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/sparc64/ieee1275/linux.c (grub_cmd_initrd): Likewise. - -2012-03-04 Vladimir Serbinenko - - * grub-core/commands/menuentry.c (options): Remove - GRUB_ARG_OPTION_REPEATABLE. - Reported by: Andreas Vogel - -2012-03-04 Andreas Vogel - - * grub-core/normal/main.c (grub_normal_free_menu): Fix memory leak. - -2012-03-04 Hideki EIRAKU - - * grub-core/normal/menu_entry.c (kill_line): Fix a crash and off-by-one - error. - -2012-03-04 Vladimir Serbinenko - - Use sort -V by the idea of Georgi Georgiev. - - * util/grub-mkconfig_lib.in (version_sort): New function. - (version_test_numeric): Use version_sort. - -2012-03-04 Vladimir Serbinenko - - Use submenus in grub-mkconfig. - - * util/grub-mkconfig.in: Define GRUB_ACTUAL_DEFAULT. - * util/grub-mkconfig_lib.in (grub_quote): New function. - (gettext_printf): Use gettext and not gettext_quoted to fix several - messages. - * util/grub.d/10_hurd.in: Use submenus. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - * util/grub.d/10_illumos.in: Add missing quoting. - * util/grub.d/10_windows.in: Likewise. - -2012-03-04 Vladimir Serbinenko - - Fix menu title instability bug. - - * grub-core/commands/menuentry.c (options): New option --id. - (grub_normal_add_menu_entry): New argument id. All users updated. - (grub_cmd_menuentry): Handle --id. - (grub_menu_init): Accept unknown arguments. - * grub-core/normal/main.c (features): Add feature_menuentry_id and - feature_menuentry_options. - * grub-core/normal/menu.c (grub_menu_execute_entry): Use id for - saved_entry. - (get_entry_number): Match with id as well. - * include/grub/menu.h (grub_menu_entry): New member id. - * util/grub-mkconfig_lib.in (grub_get_device_id): New function. - * util/grub.d/00_header.in: Define menuentry_id_option. - * util/grub.d/10_hurd.in: Define id. - * util/grub.d/10_illumos.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - -2012-03-04 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_return): Replace ambiguous - "scope" with "body". - -2012-03-03 Vladimir Serbinenko - - * include/grub/i386/linux.h (linux_kernel_header): Fix init_size type. - * grub-core/loader/i386/linux.c (grub_cmd_linux): Differentiate between - prot_size and prot_file_size. - -2012-03-03 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (is_lv_readable): New argument "easily". - All users updated. If easily=1 require raid-5/-6 to be full. - (is_node_readable): Likewise. - (scan_devices): Scan incomplete but readable LVs at the end. - (grub_diskfilter_memberlist): Pull missing devices. - (insert_array): Skip scanning until device is complete or scan is - done otherwise. - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Fix wrong - check. - * include/grub/diskfilter.h (grub_diskfilter_lv): New member scanned. - * util/raid.c (grub_util_raid_getmembers): Handle "removed" disks. - -2012-03-03 Matthew Garrett -2012-03-03 Vladimir Serbinenko - - Avoid EFI boot services when loading Linux. - - * grub-core/lib/i386/relocator.c (grub_relocator32_boot): New argument - avoid_efi_bootservices. All users updated. - * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align): New - argument avoid_efi_bootservices. All users updated. - Use grub_efi_mmap_iterate on EFI, grub_mmap_iterate if available. - * grub-core/loader/i386/linux.c (allocate_pages): New arguments - align, min_align, relocatable, prefered_address. All users updated. - Allocate avoiding boot services if kernel is relocatable. - (grub_cmd_linux): Check if kernel is relocatable. - * grub-core/mmap/efi/mmap.c (grub_machine_mmap_iterate): Move most to .. - (grub_efi_mmap_iterate): ... here. New argument avoid_efi_boot_services. - Skip GRUB_EFI_BOOT_SERVICES_DATA and GRUB_EFI_BOOT_SERVICES_CODE if - avoid_efi_boot_services. - (grub_machine_mmap_iterate): Wrap grub_efi_mmap_iterate. - * include/grub/i386/linux.h (linux_kernel_header): Update to 2.10. - (linux_kernel_params): Likewise. - -2012-03-03 Matthew Garrett -2012-03-03 Vladimir Serbinenko - - Use EDID on EFI. - - * grub-core/kern/efi/efi.c (grub_efi_get_variable): New argument - datasize_out. - * grub-core/video/efi_gop.c (check_protocol): Check that GOP has usable - modes. Set gop_handle. - (grub_video_gop_get_edid): New function. - (grub_gop_get_preferred_mode): Likewise. - (grub_video_gop_setup): Use grub_gop_get_preferred_mode. - (grub_video_efi_gop_adapter): Set .get_edid. - * include/grub/efi/edid.h: New file. - * include/grub/efi/efi.h (grub_efi_get_variable): Update proto. - -2012-03-03 Vladimir Serbinenko - - * util/grub-install.in: Load efivars unconditionally. - -2012-03-03 Vladimir Serbinenko - - * po/Rules-piglatin: Change suffix from .po-update-en to - .po-update-en-piglatin. - -2012-03-03 Vladimir Serbinenko - - Add a pig farm. - - * po/piglatin.sed: New file. - * po/en@piglatin.header: Likewise. - * po/Rules-piglatin: Likewise. - * po/README: Add en@piglatin to autogenerated languages. - -2012-03-03 Vladimir Serbinenko - - * grub-core/commands/date.c (GRUB_MOD_INIT): Remove non-uniform - "Command for ...". - * grub-core/commands/hdparm.c (options): Use "Display" rather than - "Check" since we don't check anything. - * grub-core/commands/i386/cpuid.c (options): Clarify that long mode - is 64-bit one. - * grub-core/commands/search_wrap.c (options): Clarify the conditions. - * grub-core/disk/geli.c (grub_md_sha256_real): Fix typo. - (grub_md_sha512_real): Likewise. - -2012-03-03 Vladimir Serbinenko - - * grub-core/commands/gptsync.c: Fix typographic quoting. - * grub-core/commands/ieee1275/suspend.c: Likewise. - * grub-core/commands/parttool.c: Likewise. - * grub-core/commands/search_wrap.c: Likewise. - * grub-core/commands/videoinfo.c: Likewise. - * grub-core/gfxmenu/gui_label.c: Likewise. - * grub-core/hello/hello.c: Likewise. - * grub-core/kern/emu/main.c: Likewise. - * grub-core/net/net.c: Likewise. - * grub-core/normal/menu.c: Likewise. - * grub-core/normal/menu_text.c: Likewise. - * grub-core/normal/misc.c: Likewise. - * util/grub-editenv.c: Likewise. - * util/grub-install.in: Likewise. - * util/grub-kbdcomp.in: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/grub-setup.c: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2012-03-02 Vladimir Serbinenko - - * grub-core/commands/acpihalt.c: Add TRANSLATORS comments. - * grub-core/commands/keystatus.c: Likewise. - * grub-core/commands/loadenv.c: Likewise. - * grub-core/commands/probe.c: Likewise. - * grub-core/commands/regexp.c: Likewise. - * grub-core/commands/true.c: Likewise. - * grub-core/commands/videoinfo.c: Likewise. - * grub-core/disk/cryptodisk.c: Likewise. - * grub-core/disk/ldm.c: Likewise. - * grub-core/disk/loopback.c: Likewise. - * grub-core/disk/luks.c: Likewise. - * grub-core/fs/zfs/zfsinfo.c: Likewise. - * grub-core/kern/disk.c: Likewise. - * grub-core/kern/emu/hostdisk.c: Likewise. - -2012-03-02 Vladimir Serbinenko - - * grub-core/fs/zfs/zfsinfo.c (print_vdev_info): Add TRANSLATORS comment. - * util/grub-install.in: Add missing quote in the comment. - -2012-03-02 Vladimir Serbinenko - - * grub-core/commands/i386/pc/drivemap.c: Add TRANSLATORS comments. - * grub-core/commands/lsmmap.c: Likewise. - * grub-core/commands/minicmd.c: Likewise. - * grub-core/commands/mips/loongson/lsspd.c: Likewise. - * grub-core/commands/regexp.c: Likewise. - * grub-core/gdb/gdb.c: Likewise. - * grub-core/term/gfxterm.c: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mkfont.c: Likewise. - * util/grub-mklayout.c: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - -2012-03-02 Vladimir Serbinenko - - * grub-core/commands/videoinfo.c (hook): Replace "Direct" - with "Direct color" and "Packed" with "Packed pixel". - (grub_cmd_videoinfo): Simplify legend. - -2012-03-02 Vladimir Serbinenko - - * util/getroot.c (grub_make_system_path_relative_to_its_root): Fix - absolutely unclear error message. - -2012-03-02 Vladimir Serbinenko - - * util/grub-mkstandalone.in: Remove confusing leftover print. - -2012-03-02 Vladimir Serbinenko - - * grub-core/fs/zfs/zfsinfo.c (print_vdev_info): Add TRANSLATORS - comments. - * grub-core/gdb/gdb.c (grub_cmd_gdbstub): Likewise. - (GRUB_MOD_INIT): Likewise. - * grub-core/loader/i386/linux.c (grub_cmd_linux): Clarify that it's - VGA mode. - * grub-core/net/net.c (grub_net_route_address): Add TRANSLATORS - comments. - * util/grub-install.in (usage): Likewise. - Spell ID in whole letters. - Add missing ending dot. - Quote variables. - * util/grub-reboot.in: Fix capitalisation. - * util/grub-set-default.in: Likewise. - -2012-03-02 Vladimir Serbinenko - - * util/getroot.c (strip_extra_slashes) [CYGWIN]: #ifdef-out. - (exec_pipe) [CYGWIN || MINGW32]: Likewise. - (find_root_devices_from_poolname) [CYGWIN || MINGW32]: Likewise. - (find_root_devices_from_libzfs) [CYGWIN || MINGW32]: Likewise. - Disable -Werror for -Wdeprecated-declarations. - (grub_guess_root_devices) [CYGWIN || MINGW32]: #ifdef-out. - (get_dm_uuid) [!HAVE_DEVICE_MAPPER]: Likewise. - (grub_util_get_dm_abstraction) [! __linux__]: #ifdef-out. - (grub_util_get_grub_dev): Make luks handling dependent on - HAVE_DEVICE_MAPPER and not __linux__. - (get_win32_path): Fix format security. - (grub_find_zpool_from_dir) [CYGWIN || MINGW32]: #ifdef-out. - (grub_make_system_path_relative_to_its_root) [CYGWIN || MINGW32]: - Don't try grub_find_zpool_from_dir. - (grub_make_system_path_relative_to_its_root) [!__linux__]: - #ifdef-out paresdir. - -2012-03-02 Vladimir Serbinenko - - * util/grub-pe2elf.c (usage): Add missing noreturn. - (write_section_data): Rename name to shname to avoid shadowing. - (write_symbol_table): Rename name to symname to avoid shadowing. - Fix write_reloc_section call. - -2012-03-02 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S: Move decompressor_end to .bss - to ensure that it's after the last byte of .text. - -2012-03-02 Vladimir Serbinenko - - * util/ieee1275/ofpath.c (my_isdigit): New function. - (trailing_digits): Use my_isdigit. - (strip_trailing_digits): Likewise. - -2012-03-02 Vladimir Serbinenko - - * util/resolve.c (read_dep_list): Use grub_isspace instead of isspace. - * grub-core/kern/emu/hostdisk.c (read_device_map): Likewise. - -2012-03-02 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S: Define __start. - -2012-03-02 Vladimir Serbinenko - - * gentpl.py (kernel): Remove the use of TARGET_OBJ2ELF after strip since - strip already transforms he format. - -2012-03-02 Vladimir Serbinenko - - * conf/i386-pc-cygwin-img-ld.sc: Define also _edata and __edata. - -2012-02-29 Vladimir Serbinenko - - * util/grub-install.in: Add missing gettext init. - * util/grub-kbdcomp.in: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/grub.d/00_header.in: Likewise. - * util/grub.d/10_hurd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2012-02-29 Vladimir Serbinenko - - * po/Rules-swiss: Fix header comment. - -2012-02-29 Andreas Vogel - - * grub-core/kern/misc.c (grub_xvasprintf): Fix an exit path which - resulted in leak of arguments. - -2012-02-29 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S: Use separate - reed_solomon_size const definition instead of computing it since - Apple assembler doesn't support the later. - -2012-02-29 Vladimir Serbinenko - - * gentpl.py (kernel): Rewrite Apple part. - -2012-02-29 Vladimir Serbinenko - - * include/grub/kernel.h (FOR_MODULES): Check module magic. - -2012-02-29 Vladimir Serbinenko - - * util/grub-mkimagexx.c (locate_sections): Support non-standard - ELF section gap. - (load_image): Likewise. - -2012-02-29 Vladimir Serbinenko - - * configure.ac: Fix a typo in previous commit. - -2012-02-29 Vladimir Serbinenko - - Don't add -Wl,-N on Apple platform. - - * configure.ac (TARGET_LDFLAGS_OLDMAGIC): New subst. - * conf/Makefile.common: Use TARGET_LDFLAGS_OLDMAGIC instead of -Wl,-N - -2012-02-29 Vladimir Serbinenko - - * grub-core/Makefile.core.def (lzma_decompress): Use - TARGET_IMG_BASE_LDOPT rather than hardcoding -Wl,-Ttext. - -2012-02-29 Vladimir Serbinenko - - * grub-core/genmod.sh.in: Rewrite the Apple part. - -2012-02-29 Vladimir Serbinenko - - * grub-core/loader/machoXX.c (grub_macho_load): Fix signed vs unsigned - comparison. - -2012-02-29 Vladimir Serbinenko - - * acinclude.m4 (grub_CHECK_PIC): New test. - * configure.ac: Add -fno-PIC to TARGET_CFLAGS if -fPIC is default. - -2012-02-29 Vladimir Serbinenko - - * include/grub/libgcc.h (__STDC_VERSION__): Define if it's not yet so - to avoid the warning. - -2012-02-29 Vladimir Serbinenko - - * grub-core/boot/i386/pc/diskboot.S (firstlist): Rename to ... - (LOCAL(firstlist)): ... this. Move it before the firstlist and not - after. All users updated. - -2012-02-29 Vladimir Serbinenko - - Use the common size routine in hostfs so we can read disks as well. - - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors): Rename to .. - (grub_util_get_fd_size): ... this. Return size in bytes. - All users updated. - * grub-core/kern/emu/hostfs.c (grub_hostfs_open): Use - grub_util_get_fd_size. - -2012-02-29 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__APPLE__]: - Add blocksize retrieval. - -2012-02-29 Vladimir Serbinenko - - * configure.ac: Restore CFLAGS after efiemu check. - -2012-02-29 Vladimir Serbinenko - - * configure.ac: Move -fnested-functions to CPPFLAGS to workaround - Apple bug. - -2012-02-29 Vladimir Serbinenko - - * grub-core/Makefile.am (MACHO2IMG): Add missing variable. - -2012-02-29 Vladimir Serbinenko - - * grub-core/commands/i386/pc/halt.c (grub_halt): Add noreturn attribute. - (grub_cmd_halt): Likewise. - -2012-02-29 Vladimir Serbinenko - - * grub-core/lib/i386/relocator16.S: Declare LOCAL(relocator16_end) - for local arithmetics. - Break %sp init into 2 instructions. - Add 0 byte at the end. - -2012-02-29 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (read_segment): Initialise err - before loops. - -2012-02-29 Vladimir Serbinenko - - * grub-core/lib/xzembed/xz_dec_stream.c (hash_validate): Use void * - for context. - -2012-02-29 Vladimir Serbinenko - - * grub-core/disk/ldm.c (make_vg): Init part.name. - (grub_ldm_detect): Silence spurious warning. - (grub_util_is_ldm): Likewise. - -2012-02-29 Vladimir Serbinenko - - * grub-core/loader/i386/xnu.c (grub_xnu_boot): Init fsbfreq to - sane value to avoid a spurious warning. - -2012-02-29 Vladimir Serbinenko - - * include/grub/dl.h: Switch from APPLE_CC to __APPLE__. - (GRUB_MOD_LICENSE) [ASM_FILE]: Make into macro. All users updated. - -2012-02-29 Vladimir Serbinenko - - * include/grub/symbol.h (EXT_C) [!ASM_FILE]: Redefine with strings. - * grub-core/lib/i386/backtrace.c (grub_backtrace): Use EXT_C. - -2012-02-29 Vladimir Serbinenko - - * grub-core/gdb/i386/machdep.S: Use VARIABLE and EXT_C instead of - hardcoding the relevant info. - -2012-02-29 Vladimir Serbinenko - - * grub-core/gnulib/argp-fmtstream.c (__argp_get_display_len): Add - missing const qualifiers. - * grub-core/gnulib/argp-fmtstream.h (__argp_get_display_len): Likewise. - -2012-02-29 Vladimir Serbinenko - - * util/getroot.c [__APPLE__]: Add missing includes. - (grub_util_biosdisk_is_floppy): Fix usage of undefined variable. - -2012-02-29 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Silence spurious warning. - -2012-02-29 Vladimir Serbinenko - - * util/ieee1275/ofpath.c: Rename devname to sys_devname everywhere to - avoid conflicts. - -2012-02-29 Vladimir Serbinenko - - * util/ieee1275/grub-ofpathname.c: Add missing config.h include. - -2012-02-29 Vladimir Serbinenko - - * util/grub-setup.c (setup) [!__linux__]: Add missing file declaration - and grub_file_close call. - -2012-02-29 Vladimir Serbinenko - - Add LZSS Mach-O support (needed for new xnu kernelcache). - - * grub-core/Makefile.core.def (xnu): Add file lzss.c - * grub-core/loader/lzss.c: New file. - * grub-core/loader/xnu.c (grub_xnu_load_driver): Close binaryfile - on Mach-O open failure. - * grub-core/loader/macho.c (grub_macho_close): Free uncompressedXX. - Don't free cmdsXX in uncompressedXX is set. - (grub_macho_file): Init new fields. - New argument is_64bit. All users updated. - Handle compressed. Error out if no suitable architecture is found. - Don't close file. - (grub_macho_open): New argument is_64bit. All users updated. - * grub-core/loader/macho32.c: Add defines for new fields. - * grub-core/loader/macho64.c: Likewise. - * grub-core/loader/machoXX.c (grub_macho_contains_macho): Make static. - (grub_macho_parse): Handle compressed. - Defer actual processing if compressed. - (grub_macho_cmds_iterate): Decompress if compressed. New argument - "filename". All users updated. - (grub_macho_size): New argument "filename". All users updated. - (grub_macho_get_entry_point): Likewise. - (grub_macho_load): Handle compressed. - * include/grub/macho.h (grub_macho_lzss_header): New struct. - (GRUB_MACHO_LZSS_OFFSET): New define. - (grub_decompress_lzss): New proto. - * include/grub/machoload.h (grub_macho_file): New fields to handle - compressed. - (grub_macho_contains_macho64): Remove proto. - (grub_macho_contains_macho32): Likewise. - * util/grub.d/30_os-prober.in: Use kernel cache if available. - -2012-02-29 Vladimir Serbinenko - - * grub-core/disk/pata.c (grub_pata_readwrite): Fix ATAPI protocol error. - -2012-02-28 Vladimir Serbinenko - - Fix make dist. - - * Makefile.am (starfield_theme_files): New var. - (starfield_DATA): Use starfield_theme_files. - (EXTRA_DIST): Add starfield_theme_files. Add starfield source files. - Add bootcheck-related files. - * conf/Makefile.extra-dist (EXTRA_DIST): Add several missing files. - * docs/Makefile.am (EXTRA_DIST): Add font_char_metrics.png - and font_char_metrics.txt. - * grub-core/Makefile.core.def (kernel): Update extra_dist. - (setjmp): Add lib/ia64/longjmp.S. - * po/Makefile.in.in (DISTFILES): Add POTFILES-shell.in and grub.d.sed. - * po/POTFILES.in: Regenerate. - * po/Rules-swiss: use DISTFILES.common.extra2 and not - DISTFILES.common.extra1. - * util/devicemap.c: Removed. - * grub-core/lib/i386/relocator_backward.S: Likewise. - * util/import_gcry.py: Remove unused files. Add extra_dist for - ChangeLog. - -2012-02-28 Vladimir Serbinenko - - * grub-core/gettext/gettext.c (grub_mofile_open): Call - grub_gettext_delete_list before changing grub_gettext_max to avoid - running out of array bounds. - -2012-02-28 Vladimir Serbinenko - - * grub-core/term/i386/pc/vga_text.c: Add GRUB_MACHINE_MULTIBOOT to - grub_vga_text_init/grub_vga_text_fini. - -2012-02-28 Vladimir Serbinenko - - * grub-core/loader/i386/xnu.c (grub_xnu_boot): Fix format specification. - -2012-02-27 Vladimir Serbinenko - - * configure.ac: Bump to 2.00~beta0. - -2012-02-27 Vladimir Serbinenko - - * util/getroot.c (grub_find_root_devices_from_btrfs): Add - missing initialisation. - -2012-02-27 Vladimir Serbinenko - - * grub-core/partmap/msdos.c (message_warn): Clarify messages. - -2012-02-27 Vladimir Serbinenko - - Support v2 xnu boot arguments. - - * grub-core/loader/i386/xnu.c (grub_cpu_xnu_fill_devicetree): - New argument fsbfreq_out. - (grub_xnu_set_video): Receive an argument grub_xnu_boot_params_common. - (grub_xnu_boot): Support v2 arguments. Disable PIC so that APIC can - be used. - * grub-core/loader/machoXX.c (grub_macho_load): New argument - darwin_version. - * grub-core/loader/xnu.c (grub_xnu_darwin_version): New variable. - * include/grub/i386/xnu.h (grub_xnu_boot_params_common): New struct. - (grub_xnu_boot_params): Rename to ... - (grub_xnu_boot_params_v1): ...this. Use grub_xnu_boot_params_common. - (grub_xnu_boot_params_v2): New struct. - -2012-02-27 Vladimir Serbinenko - - * grub-core/efiemu/prepare.c (grub_efiemu_crc): Add missing - zeroing of CRC field before computing CRC. - -2012-02-27 Vladimir Serbinenko - - * grub-core/lib/relocator.c (malloc_in_range): Fix memory leak. - Change order of allocations to decrease fragmentation. - -2012-02-27 Vladimir Serbinenko - - * Makefile.util.def (grub-ofpathname): Enable on all platforms. - -2012-02-27 Colin Watson - - Use write-combining MTRR to speed up video with buggy BIOSes. - - * grub-core/video/i386/pc/vbe.c (framebuffer): New member mtrr. - (cpuid): New define. - (rdmsr): Likewise. - (wrmsr): Likewise. - (mtrr_base): Likewise. - (mtrr_mask): Likewise. - (grub_vbe_enable_mtrr_entry): New function. - (grub_vbe_enable_mtrr): Likewise. - (grub_vbe_disable_mtrr): Likewise. - (grub_vbe_bios_set_display_start): Disable mtrr when handing the - control off to BIOS. - (grub_video_vbe_init): Fill mtrr. - (grub_video_vbe_fini): Disable mtrr. - (grub_video_vbe_get_info_and_fini): Likewise. - (grub_video_vbe_setup): Enable mtrr. - -2012-02-27 Colin Watson - - * include/grub/partition.h (grub_partition_map): Change prototype of - embed to take a maximum value for nsectors. - * include/grub/emu/hostdisk.h (grub_util_ldm_embed): Likewise. - * include/grub/fs.h (grub_fs): Likewise. - * grub-core/partmap/msdos.c (embed_signatures): New array. - (pc_partition_map_embed): Check for and avoid sectors matching any - of the signatures in embed_signatures, up to max_nsectors. - * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restrict - returned sector map to max_nsectors. - * grub-core/disk/ldm.c (grub_util_ldm_embed): Likewise. - * grub-core/fs/btrfs.c (grub_btrfs_embed): Likewise. - * grub-core/fs/zfs/zfs.c (grub_zfs_embed): Likewise. - * util/grub-setup.c (setup): Allow for the embedding area being - split into multiple blocklists. Tell dest_partmap->embed the - maximum number of sectors we care about. - -2012-02-27 Vladimir Serbinenko - - * include/grub/fs.h (grub_fs) [GRUB_UTIL]: Add blocklist_install field. - Specify blocklist_install and reserver_first_sector for all fs. - * util/grub-setup.c (setup): Use FIBMAP/FIEMAP on Linux. Check resulting - blocklists. - -2012-02-27 Vladimir Serbinenko - - * util/grub-install.in: Clarify strings. - Fix source dir check. - -2012-02-27 Richard Laager - - * util/getroot.c (grub_find_root_devices_from_mountinfo): Handle - "zfs" and "fuse.zfs" as synonyms. - -2012-02-27 Vladimir Serbinenko - - * configure.ac: Put platform and target_cpu substitutions back since - they are used for directories. - -2012-02-27 Richard Laager -2012-02-27 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Add ZFS-related arguments. - * util/grub.d/20_linux_xen.in: Likewise. - -2012-02-27 Richard Laager - - * util/getroot.c (find_root_devices_from_poolname): Handle vdevs - with full paths. - -2012-02-27 Richard Laager - - * util/getroot.c (grub_find_root_devices_from_mountinfo): Add missing - unescape. - -2012-02-27 Vladimir Serbinenko - - Don't use insecure popen in getroot. - - * util/getroot.c (get_mdadm_uuid): Move pipe logic to ... - (exec_pipe): ... here. - (find_root_devices_from_poolname): Use exec_pipe. - -2012-02-27 Vladimir Serbinenko - - Remove platform and target_cpu replacement. - - * configure.ac: Remove platform and target_cpu substitutions. - * tests/util/grub-shell.in: Use modinfo. - * util/powerpc/ieee1275/grub-mkrescue.in: Specify powerpc-ieee1275 - explicitly. - -2012-02-27 Vladimir Serbinenko - - Autodetect platform in grub-install but allow override. - - * util/grub-install.in: Autodetect platform. Support --target and - --directory. Read platform from modinfo.sh. - -2012-02-27 Vladimir Serbinenko - - Support btrfs multi-volume probe. - - * util/getroot.c (btrfs_ioctl_dev_info_args) [__linux__]: New struct. - (btrfs_ioctl_fs_info_args) [__linux__]: Likewise. - (BTRFS_IOC_DEV_INFO) [__linux__]: New define. - (BTRFS_IOC_FS_INFO) [__linux__]: Likewise. - (grub_find_root_devices_from_btrfs) [__linux__]: New function. - (grub_find_root_devices_from_mountinfo) [__linux__]: Use - grub_find_root_devices_from_btrfs if on btrfs. - -2012-02-27 Vladimir Serbinenko - - Remove any awareness of *.c util files about target. - - * Makefile.util.def (grub-setup): Split to ... - (grub-bios-setup): ... and this. - (grub-sparc64-setup): ... and this. - * configure.ac: Don't add machine_CPPFLAGS into HOST_CPPFLAGS. - * docs/man/grub-setup.h2m: Split into ... - * docs/man/grub-sparc64-setup.h2m: ... this. - * docs/man/grub-bios-setup.h2m: ... and this. - * include/grub/dl.h (grub_dl) [GRUB_UTIL]: Remove struct. - * include/grub/elf.h (Elf_*) [GRUB_UTIL]: Remove types. - (GRUB_TARGET_WORDSIZE) [GRUB_UTIL]: Remove. - (grub_target_addr_t): Remove. - (grub_target_size_t): Remove. - (grub_target_ssize_t): Remove. - * util/grub-install.in: Use new grub-*-setup. - * util/grub-mkimagexx.c (Elf_Word): New define. - (Elf_Half): Likewise. - (Elf_Section): Likewise. - (ELF_ST_TYPE): Likewise. - * util/grub-setup.c: Switch from GRUB_MACHINE_SPARC64 to - GRUB_SETUP_SPARC64 and from GRUB_MACHINE_PCBIOS to GRUB_SETUP_BIOS. - -2012-02-27 Vladimir Serbinenko - - Replace grub_target_addr with more appropriate types. - - * grub-core/commands/efi/fixvideo.c (scan_card): Replace - grub_target_addr with grub_addr. - * grub-core/commands/iorw.c (grub_cmd_read): Replace - grub_target_addr with grub_port. - (grub_cmd_write): Likewise. - * grub-core/commands/memrw.c (grub_cmd_read): Replace - grub_target_addr with grub_addr. - (grub_cmd_write): Likewise. - * grub-core/video/efi_uga.c (find_line_len): Likewise. - -2012-02-27 Vladimir Serbinenko - - * include/grub/efi/api.h (grub_efi_runtime_services): Add missing - const qualifier for vendor_guid. - -2012-02-27 Vladimir Serbinenko - - * grub-core/efiemu/runtime/efiemu.c (efiemu_get_variable): Add missing - const qualifier. - (efiemu_memequal): Likewise. - (find_variable): Likewise. - -2012-02-27 Vladimir Serbinenko - - Fix missing console prototype on qemu-mips. - - * include/grub/mips/qemu_mips/console.h: New file. - -2012-02-27 Matthew Garrett -2012-02-27 Vladimir Serbinenko - - * grub-core/kern/efi/efi.c (grub_efi_get_variable): Add new function. - * include/grub/efi/efi.h: Likewise. - * include/grub/efi/api.h: Add guid for EFI-specified variables. - * include/grub/charset.h (GRUB_MAX_UTF16_PER_UTF8): New definition. - * grub-core/normal/charset.c (grub_utf8_process): Move from here ... - * include/grub/charset.h (grub_utf8_process): ... to here. Inline. - * grub-core/normal/charset.c (grub_utf8_to_utf16): Move from here ... - * include/grub/charset.h (grub_utf8_to_utf16): ... to here. Inline. - -2012-02-27 Matthew Garrett - - * include/grub/efi/pci.h: New file to define EFI PCI protocols. - -2012-02-27 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_iterate): Fix off-by-one - error. - -2012-02-27 Vladimir Serbinenko - - * configure.ac: Remove inappropriate use of program_transform_name - on grubdir and bootdir but allow explicit specification of those - variables. - -2012-02-27 Vladimir Serbinenko - - * util/grub-mknetdir.in (grub_prefix): Removed. - (subdir): Use @bootdirname@ and @grubdirname@. - -2012-02-27 Vladimir Serbinenko - - Replace PACKAGE_TARNAME with PACKAGE in pkglibdir and pkgdatadir. - -2012-02-27 Vladimir Serbinenko - - * po/POTFILES.in: Regenerated. - -2012-02-27 Vladimir Serbinenko - - Remove improper use of program_transform_name on pkglibrootdir. - - * configure.ac (pkglibrootdir): Removed. - (grub-mkimage): Replace PKGLIBROOTDIR with PKGLIBDIR. - * util/grub-mkimage.c: Likewise. - -2012-02-27 Vladimir Serbinenko - - * grub-core/normal/menu_text.c (grub_print_message_indented_real): Fix a - warning. - -2012-02-27 Vladimir Serbinenko - - * util/grub-install.in: Use file identifier if no UUID is available - or user explicitly prompted for it. - -2012-02-27 Navdeep Parhar - - * grub-core/loader/i386/bsd.c (freebsd_zfsguid): New variable. - (freebsd_get_zfs): New function. - (grub_freebsd_boot): Pass zfs UUID. - (grub_cmd_freebsd): Set zfs UUID. - -2012-02-27 Vladimir Serbinenko - - * conf/Makefile.common (platformdir): Base on pkglibdir and not - pkglibrootdir. - -2012-02-27 Mike Gilbert - - Add configure flag to control libzfs integration. - - * configure.ac: Add AC_ARG_ENABLE(libzfs ...) and associated logic. - -2012-02-26 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (insert_array): Choose the smallest - device. - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Reject too - small devices. - -2012-02-26 Vladimir Serbinenko - - Remove grub_{modname}_init and grub_{modname}_fini. They should never - be used directly if it's really a module and GRUB_MOD_INIT shouldn't - be used on non-modules. - - * grub-core/commands/boot.c (GRUB_MOD_INIT) [LOONGSON || QEMU_MIPS]: - Rename to grub_boot_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to grub_boot_fini. - * grub-core/commands/keylayouts.c (GRUB_MOD_INIT) - [LOONGSON || QEMU_MIPS]: Rename to grub_keylayouts_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to grub_keylayouts_fini. - * grub-core/font/font_cmd.c (GRUB_MOD_INIT) - [LOONGSON || QEMU_MIPS]: Rename to grub_font_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to grub_font_fini. - * grub-core/kern/mips/loongson/init.c: Replace explicit protos with - includes. - (grub_machine_init): Remove empty inits. - * grub-core/kern/mips/qemu_mips/init.c: Replace explicit protos with - includes. - (grub_machine_init): Remove empty inits. - * grub-core/term/arc/console.c: Remove explicit proto. - * grub-core/term/at_keyboard.c (GRUB_MOD_INIT) - [LOONGSON || QEMU_MIPS]: Rename to grub_at_keyboard_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to - grub_at_keyboard_fini. - * grub-core/term/gfxterm.c (GRUB_MOD_INIT) - [LOONGSON || QEMU_MIPS]: Rename to grub_gfxterm_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to - grub_gfxterm_fini. - * grub-core/term/i386/pc/vga_text.c (GRUB_MOD_INIT) - [LOONGSON || QEMU_MIPS]: Rename to grub_vgatext_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to - grub_vgatext_fini. - * grub-core/term/ieee1275/console.c: Remove explicit proto. - * grub-core/term/serial.c (GRUB_MOD_INIT) - [LOONGSON || QEMU_MIPS]: Rename to grub_serial_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to - grub_serial_fini. - * grub-core/term/terminfo.c (GRUB_MOD_INIT) - [LOONGSON || QEMU_MIPS]: Rename to grub_terminfo_init. - (GRUB_MOD_FINI) [LOONGSON || QEMU_MIPS]: Rename to - grub_terminfo_fini. - * grub-core/video/bitmap.c (GRUB_MOD_INIT): Removed. - (GRUB_MOD_FINI): Likewise. - * grub-core/video/radeon_fuloong2e.c (GRUB_MOD_INIT) - [LOONGSON]: Rename to grub_video_radeon_fuloong2e_init. - (GRUB_MOD_FINI) [LOONGSON]: Rename to - grub_video_radeon_fuloong2e_fini. - * grub-core/video/sis315pro.c (GRUB_MOD_INIT) - [LOONGSON]: Rename to grub_video_sis315pro_init. - (GRUB_MOD_FINI) [LOONGSON]: Rename to - grub_video_sis315pro_fini. - * grub-core/video/sm712.c (GRUB_MOD_INIT) - [LOONGSON]: Rename to grub_video_sm712_init. - (GRUB_MOD_FINI) [LOONGSON]: Rename to - grub_video_sm712_fini. - * include/grub/at_keyboard.h (grub_at_keyboard_init): New proto. - (grub_at_keyboard_fini): Likewise. - * include/grub/dl.h (GRUB_MOD_INIT) [!GRUB_UTIL && !EMU]: - Don't declare grub_{modname}_init. - (GRUB_MOD_INIT) [!GRUB_UTIL && !EMU]: Don't declare grub_{modname}_fini. - * include/grub/keyboard_layouts.h (grub_keylayouts_init) [!EMU]: - New proto. - (grub_keylayouts_fini) [!EMU]: Likewise. - * include/grub/serial.h (grub_serial_init) [!EMU]: - New proto. - (grub_serial_fini) [!EMU]: Likewise. - * include/grub/terminfo.h (grub_terminfo_init) [!EMU]: - New proto. - (grub_terminfo_fini) [!EMU]: Likewise. - * include/grub/video.h (grub_font_init) [!EMU]: - New proto. - (grub_font_fini) [!EMU]: Likewise. - (grub_gfxterm_init) [!EMU]: Likewise. - (grub_gfxterm_fini) [!EMU]: Likewise. - (grub_video_sm712_init) [!EMU]: Likewise. - (grub_video_sm712_fini) [!EMU]: Likewise. - (grub_video_sis315pro_init) [!EMU]: Likewise. - (grub_video_sis315pro_fini) [!EMU]: Likewise. - (grub_video_radeon_fuloong2e_init) [!EMU]: Likewise. - (grub_video_radeon_fuloong2e_fini) [!EMU]: Likewise. - -2012-02-26 Vladimir Serbinenko - - Make nand a prefix for nand devices. - - * grub-core/disk/ieee1275/nand.c (grub_nand_open): Use prefix nand. - -2012-02-26 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_stpcpy): Move from here ... - * include/grub/misc.h (grub_stpcpy): ... to here. Inlined. - -2012-02-26 Vladimir Serbinenko - - * include/grub/env.h (grub_env_find): Remove prototype. - * grub-core/kern/env.c (grub_env_find): Make static. - (grub_env_set): Remove useless set. - -2012-02-26 Vladimir Serbinenko - - * grub-core/kern/i386/realmode.S: Remove useless align. - -2012-02-26 Vladimir Serbinenko - - * include/grub/dl.h (grub_dl_load_file): Don't export. - -2012-02-26 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_open): Remove useless - grub_dprintf. - -2012-02-26 Vladimir Serbinenko - - * grub-core/disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Remove useless - grub_errors. - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Simplify by - not reloading whole superblock but only the part which is really needed. - Remove useless grub_errors. - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Remove useless - grub_errors. - -2012-02-26 Vladimir Serbinenko - - Don't export grub_get_rtc. - - * include/grub/i386/pc/time.h (grub_get_rtc): Don't export. - * grub-core/commands/i386/pc/play.c (play): Use grub_get_time_ms. - -2012-02-26 Vladimir Serbinenko - - * grub-core/genmod.sh.in: Add -R .note.GNU-stack to strip. - -2012-02-26 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (insert_array): Remove scanner_name - argument since it can be deduced from diskfilter. All users updated. - -2012-02-26 Vladimir Serbinenko - - Remove prio_list. - - * include/grub/list.h (grub_prio_list): Removed. - (GRUB_PRIO_LIST_PRIO_MASK): Removed. All users switched to - GRUB_COMMAND_PRIO_MASK. - (GRUB_PRIO_LIST_FLAG_ACTIVE): Removed. All users switched to - GRUB_COMMAND_FLAG_ACTIVE. - (grub_prio_list_insert): Removed. - (grub_prio_list_remove): Likewise. - (GRUB_AS_PRIO_LIST): Likewise. - (GRUB_AS_PRIO_LIST_P): Likewise. - * include/grub/command.h (GRUB_COMMAND_PRIO_MASK): New define. - (GRUB_COMMAND_FLAG_ACTIVE): Likewise. - * grub-core/kern/list.c (grub_prio_list_insert): Remove. - * grub-core/kern/command.c (grub_register_command_prio): Inline - the prio_list code. - (grub_unregister_command): Likewise. - -2012-02-26 Vladimir Serbinenko - - Fix interrupt mixup from previous commit. - - * include/grub/i386/pc/int.h (grub_i386_idt): New struct. - (grub_realidt): New var. - * grub-core/lib/i386/relocator16.S (grub_relocator16_idt): New variable - Load idt. - * grub-core/lib/i386/relocator.c (grub_relocator16_idt): - New declaration. - (grub_relocator16_boot): Set grub_relocator16_idt. - * grub-core/kern/i386/realmode.S (realidt): Renamed to ... - (LOCAL(realidt)): ... this. - * grub-core/boot/i386/pc/startup_raw.S: Pass pointer to realidt in eax. - * grub-core/kern/i386/pc/startup.S: Save pointer to realidt. - (grub_realidt): New variable. - -2012-02-26 Vladimir Serbinenko - - * grub-core/lib/i386/backtrace.c (grub_cmd_backtrace): Move from ... - * grub-core/lib/backtrace.c (grub_cmd_backtrace): ... to here. - * grub-core/lib/i386/backtrace.c (GRUB_MOD_INIT): Move from ... - * grub-core/lib/backtrace.c (GRUB_MOD_INIT): ... to here. - Gettextize. - * grub-core/lib/i386/backtrace.c (GRUB_MOD_FINI): Move from ... - * grub-core/lib/backtrace.c (GRUB_MOD_FINI): ... to here. - * po/POTFILES.in: Regenerate. - -2012-02-26 Vladimir Serbinenko - - * grub-core/commands/probe.c (grub_cmd_probe): Gettextise UUID and label - errors. - -2012-02-26 Vladimir Serbinenko - - * grub-core/gnulib/argp-fmtstream.c (__argp_get_display_len): Stop on - \0. - (add_length): Likewise. - -2012-02-26 Vladimir Serbinenko -2012-02-26 Lubomir Kundrak - - GDB serial and backtrace support. - - * grub-core/kern/i386/realmode.S (real_to_prot): Reload IDT. - (prot_to_real): Likewise. - * grub-core/kern/i386/int.S (grub_bios_interrupt): Remove IDT reload. - * grub-core/Makefile.core.def (backtrace): New module. - (gdb): Likewise. - * grub-core/gdb/cstub.c: New file. - * grub-core/gdb/gdb.c: Likewise. - * grub-core/gdb/i386/idt.c: Likewise. - * grub-core/gdb/i386/machdep.S: Likewise. - * grub-core/gdb/i386/signal.c: Likewise. - * grub-core/lib/i386/backtrace.c: Likewise. - * grub-core/lib/backtrace.c: Likewise. - * include/grub/backtrace.h: Likewise. - * include/grub/gdb.h: Likewise. - * include/grub/i386/gdb.h: Likewise. - -2012-02-26 Vladimir Serbinenko - - * grub-core/gnulib/argp-fmtstream.c (__argp_get_display_len): - New function. - (add_length): Likewise. - (__argp_fmtstream_update): Handle strings with non-ASCII chars. - * grub-core/gnulib/argp-fmtstream.h (__argp_get_display_len): New - proto. - * grub-core/gnulib/argp-help.c (argp_args_usage): Use - __argp_get_display_len. - -2012-02-26 Vladimir Serbinenko - - $"..." support in scripts. - - * grub-core/script/execute.c (grub_script_arglist_to_argv): Handle - GRUB_SCRIPT_ARG_TYPE_GETTEXT. - * grub-core/script/yylex.l: Likewise. - * include/grub/script_sh.h (GRUB_SCRIPT_ARG_TYPE_GETTEXT): New enum - value. - -2012-02-26 Vladimir Serbinenko - - * gentpl.py: Remove obsolete pkglib_DATA handling. - -2012-02-26 Vladimir Serbinenko - - Don't transform PACKAGE_TARNAME following a discussion on autoconf - mailing list. - - * util/grub-install.in: Don't transform PACKAGE_TARNAME. - * util/grub-kbdcomp.in: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mkconfig_lib.in: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2012-02-26 Vladimir Serbinenko - - Remove GRUB_PREFIX. - - * util/grub-mkconfig.in: Remove GRUB_PREFIX. - * util/grub.d/00_header.in: Compute prefix in the only place it's still - used for backward compatibility. - -2012-02-26 Vladimir Serbinenko - - Add new all_video module. - - * grub-core/Makefile.am (moddep.lst): Make dependent on video.lst. - * grub-core/Makefile.core.def (all_video): New module. - * grub-core/genmoddep.awk: Generate dependency of all_video from - video.lst. - * grub-core/lib/fake_module.c: New file. - * grub-core/normal/main.c (features): Add feature_all_video_module. - * util/grub.d/00_header.in: Define locale_dir based on $prefix and - don't do explicit search again. - insmod all_video in load_video if available. - -2012-02-26 Vladimir Serbinenko - - Another round of string clarification and adding TRANSLATORS comments. - -2012-02-26 Vladimir Serbinenko - - * util/grub-mknetdir.in: Remove erroneous reference to install_device. - -2012-02-26 Vladimir Serbinenko - - * grub-core/normal/charset.c (grub_utf8_to_ucs4_alloc): Fix return type - to grub_ssize_t. - * grub-core/normal/main.c (grub_normal_init_page): Fix msg_len type. - * include/grub/charset.h (grub_utf8_to_ucs4_alloc): Fix prototype. - -2012-02-26 Vladimir Serbinenko - - * grub-core/normal/menu_text.c (grub_print_message_indented_real): Add - trailing newline implicitly. All users updated. - -2012-02-26 Vladimir Serbinenko - - Implement serial on IEEE1275 and EFI. - - * docs/grub.texi (Platform-specific limitations): Fix the columen video - on emu. Mention arc and emu as the only platforms without serial - support. - * grub-core/Makefile.core.def (serial): Enable on all terminfomodule and - ieee1275 platforms. - * grub-core/term/efi/serial.c: New file. - * grub-core/term/ieee1275/serial.c: Likewise. - * grub-core/term/serial.c (grub_serial_find): Disable direct port - specification if no ns8250 driver is available. - (grub_cmd_serial): Likewise. - (GRUB_MOD_INIT) [GRUB_MACHINE_IEEE1275]: Init ofserial. - (GRUB_MOD_INIT) [GRUB_MACHINE_EFI]: Init efiserial. - * include/grub/efi/api.h (GRUB_EFI_SERIAL_IO_GUID): New define. - (grub_efi_parity_type_t): New type. - (grub_efi_stop_bits_t): Likewise. - (grub_efi_serial_io_interface): New struct. - * include/grub/serial.h (grub_serial_port): Make 'broken' field - available for all interfaces. - Add EFI and IEEE1275 fields. - (grub_ofserial_init): New proto. - (grub_efiserial_init): Likeiwse. - * util/grub.d/00_header.in: Don't check for the presence of serial - module. - -2012-02-26 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (scan): Fix improper use of device - name as if it was an alias. - -2012-02-25 Vladimir Serbinenko - - * grub-core/commands/lsacpi.c (options): Fix typo. - -2012-02-25 Vladimir Serbinenko - - Convert grub-emu to argp. - - * grub-core/Makefile.core.def (kernel): Add kern/emu/argp_common.c on - emu. - * util/argp_common.c: Rename to ... - * grub-core/kern/emu/argp_common.c: ... this. All users updated. - Add missing includes. - * grub-core/kern/emu/main.c: Convert to argp. - * po/POTFILES.in: Regenerate. - * util/grub-install.in (usage): Make first letter lowcase in messages - for uniformity. - * util/grub-setup.c (options): Likewise. - -2012-02-24 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_progress_bar.c (progress_bar_set_property): - Put back accidently commented-out code. - -2012-02-24 Vladimir Serbinenko - - * grub-core/fs/hfsplus.c (grub_hfsplus_btree_iterate_node): Add btree - loop check using Brent algorithm. - (grub_hfsplus_btree_search): Likewise. - -2012-02-24 Vladimir Serbinenko - - * util/grub-install.in: Fix usage of wrong device for PreP install. - -2012-02-24 Vladimir Serbinenko - - * conf/Makefile.common (CFLAGS_GNULIB): Add - -Wno-unsafe-loop-optimizations. - * configure.ac: Remove -Wmissing-declarations and -Wmissing-prototypes - on tools. - * grub-core/commands/legacycfg.c: Add pragma to skip - -Wunsafe-loop-optimizations. - (check_password_md5_real): Fix loop counter type. - * grub-core/commands/testload.c (grub_cmd_testload): Fix over the EOF - reading. - * grub-core/disk/ldm.c (grub_util_get_ldm): Fix logic error. - * grub-core/fs/zfs/zfs_sha256.c (zio_checksum_SHA256): Add safety - loop condition. - * grub-core/io/gzio.c: Add pragma to skip -Wunsafe-loop-optimizations. - * grub-core/lib/LzmaEnc.c (GetOptimum): Avoid possible infinite loop. - * grub-core/net/net.c (grub_net_route_address): Add safety loop - condition. - * grub-core/normal/charset.c (bidi_line_wrap): Likewise. - * grub-core/normal/cmdline.c (grub_set_history): Fix loop types and - avoid possible infinite loops. - * grub-core/script/parser.y: Add pragma to skip -Wmissing-declarations - and -Wunsafe-loop-optimizations. - * grub-core/script/yylex.l: Likewise. - * util/grub-mkfont.c: Add pragma to skip -Wunsafe-loop-optimizations. - (print_glyphs): Avoid infinite loops. - * util/grub-mkimage.c (compress_kernel_xz): Fix format security. - -2012-02-24 Grégoire Sutre - - * grub-core/commands/lsacpi.c (disp_acpi_xsdt_table): Fix loop condition - to avoid infinite loop. - (disp_acpi_rsdt_table): Likewise. - -2012-02-24 Vladimir Serbinenko - - * grub-core/font/font.c (grub_font_load): Add support for default - path for fonts ($prefix/fonts). - * grub-core/kern/corecmd.c (grub_core_cmd_insmod): Unify condition - for checking if string is a path. - * grub-core/normal/main.c (features): Add feature_default_font_path. - * util/grub-mkconfig.in: Skip mangling of GRUB_FONT into GRUB_FONT_PATH. - * util/grub.d/00_header.in: Use default directory if possible. - * util/grub-install.in: Install unicode.pf2. - -2012-02-24 Vladimir Serbinenko - - * po/README: Add de_CH and en@quot to po/LINGUAS generation command. - * po/Rules-swiss: New file. - * po/swiss.sed: Likewise. - -2012-02-23 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (find_device): Fix typos. - * grub-core/fs/zfs/zfs.c (read_device): Likewise. - * util/grub-mkrelpath.c (argp_parser): Likewise. - Reported by: Yuri Chornoivan. - -2012-02-23 Dalet Omega - - * grub-core/gfxmenu/gui_label.c (label_set_property): Add template - for usual informative messages. - -2012-02-23 Dalet Omega - - Starfield theme. - - * Makefile.am: Define starfield_DATA and dejavu.pf2 generation. - * conf/Makefile.common: Define starfielddir. - * configure.ac: Configure starfield. - * themes/starfield/COPYING.CC-BY-SA-3.0: New file. - * themes/starfield/README: Likewise. - * themes/starfield/blob_w.png: Likewise. - * themes/starfield/boot_menu_c.png: Likewise. - * themes/starfield/boot_menu_e.png: Likewise. - * themes/starfield/boot_menu_n.png: Likewise. - * themes/starfield/boot_menu_ne.png: Likewise. - * themes/starfield/boot_menu_nw.png: Likewise. - * themes/starfield/boot_menu_s.png: Likewise. - * themes/starfield/boot_menu_se.png: Likewise. - * themes/starfield/boot_menu_sw.png: Likewise. - * themes/starfield/boot_menu_w.png: Likewise. - * themes/starfield/slider_c.png: Likewise. - * themes/starfield/slider_n.png: Likewise. - * themes/starfield/slider_s.png: Likewise. - * themes/starfield/src/blob_nw.xcf: Likewise. - * themes/starfield/src/bootmenu/: Likewise. - * themes/starfield/src/bootmenu/center.xcf: Likewise. - * themes/starfield/src/bootmenu/corner.xcf: Likewise. - * themes/starfield/src/bootmenu/side.xcf: Likewise. - * themes/starfield/src/slider_c.xcf: Likewise. - * themes/starfield/src/slider_n.xcf: Likewise. - * themes/starfield/src/slider_s.xcf: Likewise. - * themes/starfield/src/terminalbox/: Likewise. - * themes/starfield/src/terminalbox/center.xcf: Likewise. - * themes/starfield/src/terminalbox/corner.xcf: Likewise. - * themes/starfield/src/terminalbox/side.xcf: Likewise. - * themes/starfield/starfield.png: Likewise. - * themes/starfield/terminal_box_c.png: Likewise. - * themes/starfield/terminal_box_e.png: Likewise. - * themes/starfield/terminal_box_n.png: Likewise. - * themes/starfield/terminal_box_ne.png: Likewise. - * themes/starfield/terminal_box_nw.png: Likewise. - * themes/starfield/terminal_box_s.png: Likewise. - * themes/starfield/terminal_box_se.png: Likewise. - * themes/starfield/terminal_box_sw.png: Likewise. - * themes/starfield/terminal_box_w.png: Likewise. - * themes/starfield/theme.txt: Likewise. - -2012-02-23 Vladimir Serbinenko - - * util/grub.d/00_header.in: Add missing export theme. - -2012-02-22 Vladimir Serbinenko - - * util/ieee1275/ofpath.c: Remove include of malloc.h since stdlib is - already included. - Reported by: Eren D. - -2012-02-22 Vladimir Serbinenko - - * conf/Makefile.common (grubdatadir): Removed. - (Makefile.am): Move eveything grubdata to pkgdata. - -2012-02-22 Vladimir Serbinenko - - * grub-core/commands/acpihalt.c (get_sleep_type): - Remove unused variable. - -2012-02-22 Vladimir Serbinenko - - * include/grub/acpi.h (GRUB_ASCII_OPCODE): Add - GRUB_ACPI_OPCODE_STRING_CONST, GRUB_ACPI_OPCODE_BUFFER, - GRUB_ACPI_OPCODE_CREATE_WORD_FIELD - and GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD. - * grub-core/commands/acpihalt.c [GRUB_DSDT_TEST]: Replace include of - i18n with gettext no-op. - (skip_data_ref_object): Support GRUB_ACPI_OPCODE_BUFFER and - GRUB_ACPI_OPCODE_STRING_CONST. - (get_sleep_type): Support GRUB_ACPI_OPCODE_CREATE_WORD_FIELD and - GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD. Add handling of unknown opcodes. - -2012-02-22 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. - -2012-02-22 Vladimir Serbinenko - - * Makefile.util.def (libgrubmods.a): Add -Wno-error=logical-op - -Wno-error=missing-noreturn. - -2012-02-22 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_read_block): Avoid <= in loop - condition to avoid possibly infinite loops. - * grub-core/lib/pbkdf2.c (grub_crypto_pbkdf2): Likewise. - * grub-core/lib/xzembed/xz_dec_bcj.c (bcj_powerpc): Likewise. - -2012-02-22 Vladimir Serbinenko - - * grub-core/normal/charset.c (bidi_line_wrap): Avoid <= in loop - condition to avoid possibly infinite loops. - -2012-02-22 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (read_device_map): Add missing noreturn - on show_error. - -2012-02-22 Vladimir Serbinenko - - * grub-core/kern/disk.c (grub_disk_write): Add missing const qualifier. - -2012-02-22 Vladimir Serbinenko - - * grub-core/kern/corecmd.c (grub_core_cmd_ls): Add missing var init. - -2012-02-22 Vladimir Serbinenko - - * util/bin2h.c (usage): Add missing attribute noreturn. - -2012-02-22 Vladimir Serbinenko - - * grub-core/commands/testload.c (grub_cmd_testload): Fix overflow - if the size isn't divisible by 512. - -2012-02-22 Vladimir Serbinenko - - Make list_push and list_remove functions rather than inline functions - to decrease size and avoid aliasing violations. - - * include/grub/list.h (grub_list_push): Move to ... - * grub-core/kern/list.c (grub_list_push): ... here. Don't inline. - * include/grub/list.h (grub_list_remove): Move to ... - * grub-core/kern/list.c (grub_list_remove): ... here. Don't inline. - -2012-02-22 Vladimir Serbinenko - - * configure.ac: Disable for now -Wstack-protector, -Wunreachable-code - and -Wunused-result. - -2012-02-21 Vladimir Serbinenko - - * grub-core/net/net.c (grub_cmd_deladdr): Fix index. - Reported by: Seth Goldberg - -2012-02-21 Vladimir Serbinenko - - * configure.ac: Add -fno-builtin-gettext on host if NLS is disabled. - -2012-02-19 Samuel Thibault - - * util/grub-mkconfig.in (GRUB_CMDLINE_GNUMACH): Export variable. - * util/grub.d/10_hurd.in: Include GRUB_CMDLINE_GNUMACH in gnumach - command line. - * docs/grub.texi (Simple configuration): Document - GRUB_CMDLINE_GNUMACH. - -2012-02-18 Vladimir Serbinenko - - * conf/Makefile.common (platform_SCRIPTS): New variable. - (platform_PROGRAMS): Likewise. - * gentpl.py: Mark *,module and *.image for install. - * grub-core/gdb_grub.in: Add a notice of expected environment. - * grub-core/Makefile.core.def (gdb_grub): Mark for install. - (gmodule.pl): Likewise. - -2012-02-18 Vladimir Serbinenko - - Replace grub_checkkey with grub_getkey_noblock. - - * grub-core/kern/term.c (grub_checkkey): Replaced with ... - (grub_getkey_noblock): ... this. All users updated. - -2012-02-18 Vladimir Serbinenko - - * grub-core/kern/emu/console.c: Move to ... - * grub-core/term/emu/console.c: ...here. - (grub_ncurses_getkey): Fix return value if no key is detected. - -2012-02-12 Vladimir Serbinenko - - * include/grub/test.h (grub_unit_test_init): Add missing prototype. - (grub_unit_test_fini): Likewise. - * tests/lib/unit_test.c (main): Remove extra nested external prototype. - -2012-02-12 Vladimir Serbinenko - - * include/grub/test.h (GRUB_UNIT_TEST) - -2012-02-12 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_break): Clarify logic. - Better error handling. - (grub_script_return): Likewise. - * grub-core/script/lexer.c (grub_script_lexer_yywrap): Likewise. - -2012-02-12 Vladimir Serbinenko - - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (__GNU_LIBRARY__): Avoid - rimplicit redifinition. - -2012-02-12 Vladimir Serbinenko - - * docs/grub.texi (Internationalisation): Detail (lack of) collation in - GRUB. - -2012-02-12 Vladimir Serbinenko - - * grub-core/normal/cmdline.c (grub_cmdline_get): Don't gettext prompt. - * grub-core/normal/main.c (grub_normal_read_line_real): Gettext - prompt here. - -2012-02-12 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (zfs_fetch_nvlist): Mark unknown member here - as GRUB_ERR_BUG. Don't malloc if no device is available. - -2012-02-12 Vladimir Serbinenko - - * grub-core/term/terminfo.c (grub_terminfo_output_unregister): - Mark calling with invalid term as GRUB_ERR_BUG. - -2012-02-12 Vladimir Serbinenko - - * grub-core/net/tftp.c (tftp_receive): Silently discard too short - packets rather than raising an error. - -2012-02-12 Vladimir Serbinenko - - * grub-core/loader/xnu.c (grub_xnu_writetree_toheap_real): Avoid set - in if. - -2012-02-12 Vladimir Serbinenko - - * grub-core/loader/efi/appleloader.c (grub_cmd_appleloader): Move - diagnostic to dprintf. - * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Likewise. - -2012-02-12 Vladimir Serbinenko - - * grub-core/kern/corecmd.c (grub_core_cmd_ls): Handle error in parsing - device name. - -2012-02-12 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (locate_attr): Avoid set in if. - (grub_ntfs_iterate_dir): Likewise. - -2012-02-12 Vladimir Serbinenko - - Efiemu stylistic fixes and gettext. - - * grub-core/efiemu/i386/loadcore32.c - (grub_arch_efiemu_relocate_symbols32): Avoid set in if. - * grub-core/efiemu/i386/loadcore64.c - (grub_arch_efiemu_relocate_symbols64): Likewise. - * grub-core/efiemu/i386/pc/cfgtables.c - (grub_machine_efiemu_init_tables): Likewise. - * grub-core/efiemu/loadcore.c (grub_efiemu_resolve_symbols): Likewise. - (grub_efiemu_loadcore_initXX): Add a filename argument. - All users updated. - Improved error message. - * grub-core/efiemu/loadcore_common.c (grub_efiemu_loadcore_init): - Add a filename argument. - All users updated. - * grub-core/efiemu/symbols.c (grub_efiemu_set_virtual_address_map): - Reclassify double relocation as GRUB_ERR_BUG. - -2012-02-12 Vladimir Serbinenko - - * grub-core/commands/i386/pc/play.c (grub_cmd_play): Improve error - handling. - -2012-02-12 Vladimir Serbinenko - - * grub-core/commands/hdparm.c (grub_cmd_hdparm): Allow running - on partition. - -2012-02-12 Vladimir Serbinenko - - * include/grub/misc.h (grub_error_save): Fix cleaning grub_errno. - -2012-02-12 Vladimir Serbinenko - - Improve string. Gettextize. - -2012-02-11 Vladimir Serbinenko - - * configure.ac: Remove -Winline altogether and -Wmissing-prototypes on - utils. - * util/import_gcry.py: Add -Wno-strict-aliasing on checked modules. - -2012-02-11 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (grub_diskfilter_print_partmap) - [GRUB_UTIL]: New function. - (insert_array) [GRUB_UTIL]: Store partmaps. - * include/grub/diskfilter.h (grub_diskfilter_pv) [GRUB_UTIL]: New member - partmaps. - (grub_diskfilter_print_partmap) [GRUB_UTIL]: New proto. - * util/grub-probe.c (probe_partmap): Call grub_diskfilter_print_partmap. - (probe_abstraction): Print diskfilter and not raid. - Reported by: Lennart Sorensen - -2012-02-11 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Explicitly init decompress_size. - * util/grub-mkimagexx.c (MASK3): New define. - (add_value_to_slot_20b): Use MASK3. - (add_value_to_slot_21): Likewise. - (relocate_addresses): Fix format specification. - (load_image): Explicitly init symtab_section. - -2012-02-11 Vladimir Serbinenko - - * util/getroot.c (grub_find_root_devices_from_mountinfo): Fix types. - (grub_util_biosdisk_get_grub_dev): Fix format specification. - -2012-02-11 Vladimir Serbinenko - - * grub-core/kern/emu/full.c (grub_arch_dl_get_tramp_got_size): Enable - on powerpc. - Reported by: Lennart Sorensen - -2012-02-11 Vladimir Serbinenko - - * gentpl.py: Add missing license header. - * docs/grub.texi: Update copyright year. - -2012-02-10 Grégoire Sutre - - Source grub-mkconfig_lib from the build directory at build time. - Suggested by: Vladimir Serbinenko. - - * gentpl.py (manpage): Set pkgdatadir to $(builddir) on help2man call. - * util/grub-install.in: Define pkgdatadir if not already set, and source - grub-mkconfig_lib from there. - * util/grub-kbdcomp.in: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2012-02-10 Vladimir Serbinenko - - Increase warning level. - - * conf/Makefile.common (CFLAGS_GNULIB): Add -Wno-redundant-decls - -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition. - * configure.ac (HOST_CFLAGS): Add bunch of -W arguments. - (TARGET_CFLAGS): Likewise. - (HOST_CFLAGS): Add -Werror unless --disable-werror is activated. - * grub-core/Makefile.core.def (decompressor_xz): Add - -Wno-unreachable-code. - (normal): Add -Wno-redundant-decls. - (xzio): Add -Wno-unreachable-code. - (lzopio): Add -Wno-redundant-decls -Wno-error. - * grub-core/commands/acpi.c: Add exception to -Wcast-align. - * grub-core/commands/lsacpi.c: Add exception to -Wcast-align. - * grub-core/gensymlist.sh: Add exception to -Wmissing-format-attribute. - * grub-core/kern/dl.c: Add exception to -Wcast-align. - * grub-core/kern/efi/efi.c (grub_efi_modules_addr): Likewise. - * grub-core/kern/i386/coreboot/init.c: Add exception to - -Wsuggest-attribute=noreturn. - * grub-core/kern/ia64/dl.c: Add exception to -Wcast-align. - * grub-core/kern/ia64/dl_helper.c: Likewise. - * grub-core/kern/mips/dl.c: Likewise. - * grub-core/kern/sparc64/dl.c: Likewise. - * grub-core/lib/LzmaEnc.c: Add exception to -Wshadow. - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (memcpy): Likewise. - (memcmp): Likewise. - * grub-core/lib/pbkdf2.c: Add exception to -Wunreachable-code. - * grub-core/loader/ia64/efi/linux.c: Add exception to -Wcast-align. - * grub-core/loader/mips/linux.c: Likewise. - * grub-core/loader/multiboot_elfxx.c: Likewise. - * grub-core/script/parser.y: Add exception to -Wunreachable-code. - * grub-core/video/sm712.c: Add exception to -Wcast-align. - * util/import_gcry.py: Add -Wno-cast-align to modules checked by hand. - * grub-core/font/font.c (grub_font_loader_init): Add explicit cast and - fixme. - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Likewise. - * grub-core/kern/i386/multiboot_mmap.c (grub_machine_mmap_init): - Fix prototype. - -2012-02-10 Vladimir Serbinenko - - * grub-core/lib/i386/relocator16.S: Fix incorrect use of absolute - address. - -2012-02-10 Vladimir Serbinenko - - * grub-core/commands/legacycfg.c (grub_cmd_legacy_kernel): - Avoid improper use of strings. - (grub_cmd_legacy_initrdnounzip): Likewise. - -2012-02-10 Vladimir Serbinenko - - * include/grub/emu/misc.h (grub_util_warn): Add missing format - attribute. - (grub_util_info): Likewise. - (grub_util_error): Likewise. - -2012-02-10 Vladimir Serbinenko - - * util/grub-mount.c (fuse_init): Avoid improper use of strings. - * util/grub-fstest.c (fstest): Likewise. - -2012-02-10 Vladimir Serbinenko - - * grub-core/disk/geli.c (grub_md_sha256_real): Respect format security. - (grub_md_sha512_real): Likewise. - (grub_util_get_geli_uuid): Likewise. - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors): Likewise. - (grub_util_biosdisk_open): Fix format specification. - Respect format security. - * grub-core/kern/emu/misc.c (xmalloc): Respect format security. - (xrealloc): Likewise. - (xasprintf): Likewise. - -2012-02-10 Vladimir Serbinenko - - * util/import_gcry.py: Include grub/crypto.h in init.c. - -2012-02-10 Vladimir Serbinenko - - * util/grub-mkimage.c (compress_kernel_lzma): Respect format security. - (generate_image): Make prefix a const char *. - Fix format specifications. Respect format security. - Avoid void * arithmetics. - Avoid shadowing. - (argp_parser): Remove unused variable. Respect format security. - * util/grub-mkimagexx.c (relocate_symbols): Avoid shadowing. - (count_funcs) [!MKIMAGE_ELF64]: #if-out. - (count_funcs): Remove unused variable. - (relocate_addresses): Fix format specification. - Disable x86-64 with elf32. Remove unused variables. - (add_fixup_entry): Avoid shadowing. - (make_reloc_section): Fix format specification. - Use assert. - (locate_sections): Fix format specifications. - (load_image): Avoid shadowing. - -2012-02-10 Vladimir Serbinenko - - * util/grub-setup.c (setup): Remove unused variable. Avoid shadowing. - Fix format specifications. Respect format security. - Don't translate already translated grub_errmsg. - (argp_parser): Remove unused variable - -2012-02-10 Vladimir Serbinenko - - * util/grub-mkrelpath.c (argp_parser): Remove unused variable. - -2012-02-10 Vladimir Serbinenko - - * util/grub-mkpasswd-pbkdf2.c (argp_parser): Remove unused variable. - (main): Likewise. Use xmalloc. Respect format security. - -2012-02-10 Vladimir Serbinenko - - * util/grub-mklayout.c (console_grub_equivalence): Make "layout" - a const char *. - (argp_parser): Remove unused variable. - -2012-02-10 Vladimir Serbinenko - - * util/grub-mkfont.c (grub_font_info): Make name a const char *. - (add_pixel): Make static. - (add_font): Likewise. - (write_string_section): Make name and str a const char *. - (write_be16_section): Make name a const char *. - (print_glyphs): Make static. - (write_font_ascii_bitmap): Likewise. - (write_font_width_spec): Likewise. - (write_font_pf2): Likewise. - (argp_parser): Remove unused variable. - Respect format security. - (main): Avoid shadowing. Respect format security. - -2012-02-10 Vladimir Serbinenko - - * util/grub-editenv.c (argp_parser): Make static. - (create_envblk_file): Use xmalloc. - (open_envblk_file): Likewise. - Resepect format security. - (set_variables): Respect format security. - -2012-02-10 Vladimir Serbinenko - - * util/getroot.c (grub_find_device): Respect format security. - (get_mdadm_uuid): Remove unused variable. - (grub_util_pull_device): Dont call gettext on already translated - grub_errmsg. - (find_system_device): Remove unused variable. - (grub_util_get_grub_dev): Likewise. - (grub_make_system_path_relative_to_its_root): Respect format security. - -2012-02-10 Vladimir Serbinenko - - * util/grub-fstest.c (execute_command): Make first argument - a const char *. - (read_file): Avoid shadowing. - Reuse underlying error message if device open fails. - (cmd_cmp): Respect format security. - (root): Make const char *. - (fstest): Remove args argument and use global copy. - Respect format security. - (argp_parser): Make static. - (main): Make default_root const char *. - -2012-02-10 Vladimir Serbinenko - - * util/grub-mount.c (root): Make const char *. - (execute_command): Make first argument a const char *. - (fuse_init): Respect format security. - (argp_parser): Make static. Remove unused variable. - (main): Make default_root a const char *. - Respect format security. - -2012-02-10 Vladimir Serbinenko - - * util/grub-probe.c (probe): Don't call gettext on already translated - grub_errmsg. - Remove unused variables. - (argp_parser): Remove unused variable. - -2012-02-10 Vladimir Serbinenko - - * util/grub-script-check.c (argp_parser): Remove unused variable. - (main): Rename read to curread to avoid shadowing. - -2012-02-10 Vladimir Serbinenko - - * util/misc.c (grub_util_write_image_at): Fix format specification. - (grub_util_write_image): Likewise. - (grub_script_execute_argument_to_string): Removed (unused). - (grub_script_execute_menuentry): Likewise. - (grub_putchar): Likewise. - -2012-02-10 Vladimir Serbinenko - - * include/grub/symbol.h (EXT_C) [GRUB_UTIL]: Removed. - (FUNCTION) [GRUB_UTIL]: Likewise. - (VARIABLE) [GRUB_UTIL]: Likewise. - -2012-02-10 Vladimir Serbinenko - - * include/grub/misc.h: Avoid evaluationg NEED_ENABLE_EXECUTE_STACK and - NEED_REGISTER_FRAME_INFO in GRUB_UTIL. - -2012-02-10 Vladimir Serbinenko - - * grub-core/partmap/bsdlabel.c (iterate_real): Fix freeing of static - buffer. - -2012-02-10 Vladimir Serbinenko - - * grub-core/lib/LzmaEnc.c (LzmaEnc_FastPosInit): Made static. - (LzmaEnc_SaveState): Removed (unused). - (LzmaEnc_RestoreState): Likewise. - (LzmaEnc_InitPriceTables): Made static. - (LzmaEnc_Construct): Likewise. - (LzmaEnc_FreeLits): Likewise. - (LzmaEnc_Destruct): Likewise. - (LzmaEnc_Init): Likewise. - (LzmaEnc_InitPrices): Likewise. - (LzmaEnc_Finish): Likewise. - (LzmaEnc_PrepareForLzma2): Removed (unused). - (LzmaEnc_MemPrepare): Likewise. - (LzmaEnc_GetNumAvailableBytes): Likewise. - (LzmaEnc_GetCurBuf): Likewise. - (LzmaEnc_CodeOneMemBlock): Likewise. - -2012-02-10 Vladimir Serbinenko - - * grub-core/disk/ldm.c (grub_util_get_ldm): Remove unused variables. - (grub_util_ldm_embed): Likewise. - -2012-02-10 Vladimir Serbinenko - - * util/grub-editenv.c (print_var): Rename name to varname to - avoid shadowing. - (main): Rename index to curindex to avoid shadowing. - Make filename a const char *. - -2012-02-10 Vladimir Serbinenko - - * grub-core/script/lexer.c (grub_script_lexer_init): Rename getline - to arg_getline to avoid shadowing. - -2012-02-10 Vladimir Serbinenko - - * grub-core/partmap/gpt.c (gpt_partition_map_embed): Rename disk to - disk_ to avoid shadowing. - -2012-02-10 Vladimir Serbinenko - - * grub-core/lib/LzFind.c (MatchFinder_GetIndexByte): Rename index to - curindex to avoid shadowing. - Make static. - (MatchFinder_GetNumAvailableBytes): Make static. - -2012-02-10 Vladimir Serbinenko - - * grub-core/fs/squash4.c (direct_read): Rename read to curread to - avoid shadowing. - -2012-02-10 Vladimir Serbinenko - - * grub-core/disk/cryptodisk.c (grub_cryptodisk_endecrypt): Rename - argument from encrypt to do_encrypt to avoid shadowing. - -2012-02-09 Vladimir Serbinenko - - * grub-core/loader/multiboot_elfxx.c (grub_multiboot_load_elf): Fix - incorrect nesting of #if's. - -2012-02-09 Vladimir Serbinenko - - * grub-core/commands/lsacpi.c (disp_acpi_xsdt_table): #if'-out the - checks which are always false on some platforms. - (grub_cmd_lsacpi): Likewise. - * grub-core/kern/misc.c (grub_strtoul): Likewise. - * grub-core/loader/multiboot.c (grub_multiboot_set_video_mode): - Likewise. - -2012-02-09 Vladimir Serbinenko - - * grub-core/disk/diskfilter.c (read_segment): Renome unreachable code. - * grub-core/net/ip.c (grub_net_recv_ip4_packets): Likewise. - -2012-02-09 Vladimir Serbinenko - - * grub-core/gnulib/regex.h (re_pattern_buffer): Declare buffer as - re_dfa_t to avoid breaking alignment invariants. - * grub-core/gnulib/regex_internal.h (re_dfa_t): Moved to ... - * grub-core/gnulib/regex.h (re_dfa_t): ... here. - -2012-02-09 Vladimir Serbinenko - - * grub-core/loader/i386/xnu.c (grub_xnu_boot): Fix printf. - * grub-core/loader/ia64/efi/linux.c (grub_cmd_fpswa): Likewise. - -2012-02-09 Vladimir Serbinenko - - * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_init): - Fix declaration. - -2012-02-09 Vladimir Serbinenko - - * grub-core/bus/usb/ehci.c (grub_ehci_ehcc_read32): Restructure to - conserve alignment invariants. - (grub_ehci_ehcc_read16): Likewise. - (grub_ehci_oper_read32): Likewise. - (grub_ehci_oper_write32): Likewise. - (grub_ehci_pci_iter) [!GRUB_HAVE_UNALIGNED_ACCESS]: Check alignment. - Conserve alignment invariants. - -2012-02-09 Vladimir Serbinenko - - * grub-core/kern/emu/full.c (grub_emu_post_init): Remove raid reinit. - * include/grub/disk.h [GRUB_MACHINE_EMU]: Remove now useless LVM/RAID - declarations. - -2012-02-09 Vladimir Serbinenko - - * grub-core/kern/emu/hostfs.c (grub_hostfs_close): - Remove unused variable. - -2012-02-09 Vladimir Serbinenko - - * grub-core/efiemu/loadcore_common.c (grub_efiemu_loadcore_load): - Remove set in if. - -2012-02-09 Vladimir Serbinenko - - * include/grub/net.h: Remove double declarations. - -2012-02-09 Vladimir Serbinenko - - Remove "payload" command in ia64 Linux loader since I couldn't - find any evidence of it being used for anything. - Replace "relocate" command with an environment variable - - * grub-core/loader/ia64/efi/linux.c (ia64_boot_param): Remove extra - fields. - (ia64_boot_payload): Removed. - (last_payload): Likewise. - (RELOCATE_OFF): Likewise. - (RELOCATE_ON): Likewise. - (RELOCATE_FORCE): Likewise. - (relocate): Likewise. - (free_pages): Don't free payloads. - (grub_load_elf64): Use common error messages. - Use "linux_relocate" variable. - Increase the space after boot_params. - (grub_cmd_payload): Removed. - (grub_cmd_relocate): Likewise. - (grub_cmd_fpswa): Improve messages. - (cmd_payload): Removed. - (cmd_relocate): Likewise. - (GRUB_MOD_INIT): Don't register "payload" and "relocate". - (GRUB_MOD_FINI): Don't unregister "payload" and "relocate". - -2012-02-09 Vladimir Serbinenko - - Convert UHCI to DMA framework. - - * grub-core/bus/usb/uhci.c (grub_uhci): Add chunk and phys members. - (grub_uhci_pci_iter): Fill new members - (grub_alloc_td): Use P2V and V2P functions. - (grub_free_queue): Likewise. - (grub_alloc_qh): Likewise. - (grub_uhci_setup_transfer): Likewise. - (grub_uhci_check_transfer): Likewise. - -2012-02-09 Vladimir Serbinenko - - * grub-core/video/colors.c (grub_video_parse_color): Fix error message. - Remove assignment in if while on it. - -2012-02-09 Vladimir Serbinenko - - * util/grub-mkstandalone.in: Fix modules directory. - -2012-02-09 Vladimir Serbinenko - - * util/grub-mkimage.c (image_targets): Set default_compression to lzma - on i386-pc target. - (argp_parser): Accept "auto" as compression specification. - -2012-02-09 Vladimir Serbinenko - - Fix `help' with unloaded modules. - - * include/grub/normal.h (grub_dyncmd_get_cmd): New proto. - * grub-core/normal/dyncmd.c (grub_dyncmd_get_cmd): New function. - (grub_dyncmd_dispatcher): Small stylistic fix. - * grub-core/commands/help.c (grub_cmd_help): Load missing modules when - explicit help is requested. - -2012-02-09 Vladimir Serbinenko - - * grub-core/fs/cpio.c (grub_cpio_dir): Fix a bug with multiple listing. - Explicitly init restart while on it. - -2012-02-09 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/wchar.h (mbrtowc): Set pwc to zero to avoid - uninited variable. - -2012-02-08 Vladimir Serbinenko - - * util/grub-mknetdir.in: Use . rather than source for POSIX - compatibility. - -2012-02-08 Vladimir Serbinenko - - * util/grub-probe.c (main): Fix trailing space in compatibility hint. - -2012-02-08 Vladimir Serbinenko - - * grub-core/kern/partition.c (grub_partition_get_name): Fix uninited - variable. - -2012-02-08 Vladimir Serbinenko - - * grub-core/commands/hdparm.c (grub_cmd_hdparm): Accept device name - without quotes. - -2012-02-08 Vladimir Serbinenko - - * grub-core/net/net.c (GRUB_MOD_INIT): Don't register netfs. - -2012-02-08 Vladimir Serbinenko - - * grub-core/kern/partition.c (grub_partition_get_name): Fix reverse - iteration of partitions. - -2012-02-08 Vladimir Serbinenko - - Improve gettext support. Stylistic fixes and error handling fixes while - on it. - -2012-02-07 Vladimir Serbinenko - - * grub-core/lib/i386/relocator16.S: Revert moving A20 code into PM - part. Instead setup the correct stack in RM. - * grub-core/lib/i386/relocator.c (grub_relocator16_boot): Reserve place - for stack. - * include/grub/i386/relocator_private.h: New file. - -2012-02-05 Vladimir Serbinenko - - * grub-core/commands/minicmd.c (GRUB_MOD_INIT): Add missing SIZE - argument. - * util/grub-fstest.c (options): Add missing DEVICE part. - -2012-02-05 Vladimir Serbinenko - - Clarify and unify messages. - - * grub-core/commands/hashsum.c (options): Unify messages. - * grub-core/commands/keystatus.c (GRUB_MOD_INIT): Don't mark a - literal-only message as translatable. - * grub-core/commands/lsacpi.c (GRUB_MOD_INIT): Likewise. - * grub-core/loader/ia64/efi/linux.c (GRUB_MOD_INIT): Likewise. - * grub-core/commands/legacycfg.c (GRUB_MOD_INIT): Add quoting around - commands. - * grub-core/commands/menuentry.c (options): Clarify that it's a keyboard - key, not the key used to unlock. Clarify what it's used for. - * grub-core/kern/emu/hostdisk.c (read_device_map): Unify error message. - * grub-core/loader/xnu.c (grub_xnu_load_driver): Remove erroneous colon. - * grub-core/script/main.c (GRUB_MOD_INIT): Clarify [n] to be [NUM]. - * util/grub-editenv.c (options): Unify "verbose" message. - * util/grub-fstest.c (read_file): Unify error message. - (fstest): Add quotes around commands. - (options): Unify "verbose" message. - * util/grub-install.in: Add quotes around variable name. - * util/grub-kbdcomp.in: Unify error message. - * util/grub-mkfont.c (main): Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mklayout.c (options): Unify "verbose" message. - * util/grub-mkstandalone.in: Unify help and verbose messages. - * util/grub-mount.c (options): Unify "verbose" message. - * util/grub-probe.c (options): Likewise. - * util/grub-script-check.c (options): Likewise. - * util/grub-setup.c (setup): Unify no-terminator message. - (options): Use DEVICE and not DEV. - Unify "verbose" message. - * util/ieee1275/ofpath.c (xrealpath): Unify error message. - -2012-02-05 Vladimir Serbinenko - - Improve and unify messages. - - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors): Add argument - name. All users updated. - Print filename in error. - (read_device_map): Print filename in error. - * util/getroot.c (grub_guess_root_devices): Print filename in error. - (grub_util_get_os_disk): Likewise. - (grub_util_biosdisk_get_grub_dev): Likewise. - (grub_util_check_block_device): Likewise. - (grub_util_check_char_device): Likewise. - (grub_make_system_path_relative_to_its_root): Likewise. - * util/grub-editenv.c (create_envblk_file): Likewise. - (open_envblk_file): Likewise. - (write_envblk): Likewise. - * util/grub-fstest.c (cmd_cp): Likewise. - (cmd_cat): Likewise. - (cmd_cmp): Likewise. - * util/grub-menulst2cfg.c (main): Likewise. - * util/grub-mkfont.c (write_font_ascii_bitmap): Likewise. - (write_font_width_spec): Likewise. - (write_font_pf2): Likewise. - * util/grub-mkimage.c (generate_image): New argument outname. - All users updated. - Remove unreacheable message. - (options): Unify messages. - (help_filter): Likewise. - * util/grub-mklayout.c (usage): Removed (unused). - (main): Print filename in error. - * util/grub-mkrescue.in: Fix wrong quoting. - * util/grub-setup.c (setup): Print filename in error. - * util/ieee1275/ofpath.c (vendor_is_ATA): Likewise. - (check_sas): Likewise. - * util/misc.c (grub_util_get_fp_size): Removed. - (grub_util_get_image_size): Print filename in error. - (grub_util_read_at): Removed. - (grub_util_read_image): Print filename in error. - (grub_util_load_image): Likewise. - (grub_util_write_image_at): New argument filename. All users updated. - Print filename in error. - (grub_util_write_image): New argument filename. All users updated. - Print filename in error. - * util/raid.c (grub_util_raid_getmembers): Print filename in error. - * util/resolve.c (grub_util_resolve_dependencies): Likewise. - -2012-02-05 Vladimir Serbinenko - - * grub-core/Makefile.core.def (pxechain): New module. - * grub-core/loader/i386/pc/pxechainloader.c: New file. - * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_get_cached): New - function. - (grub_pc_net_config_real): Use grub_pxe_get_cached. - * include/grub/i386/pc/pxe.h (grub_pxe_get_cached): New proto. - -2012-02-05 Vladimir Serbinenko - - * grub-core/kern/err.c (GRUB_MAX_ERRMSG): Move to ... - * include/grub/err.h (GRUB_MAX_ERRMSG): ... here. - * include/grub/err.h (grub_error_saved): New struct. - (grub_errmsg): Make array size explicit. - * include/grub/misc.h (grub_error_save): New function. - (grub_error_load): Likewise. - * grub-core/kern/err.c (grub_error_stack_items): Use grub_error_saved. - (grub_error_push): Update `errno' member name. - (grub_error_pop): Likewise - * grub-core/net/tftp.c (tftp_data): New member save_err. - (tftp_receive): Save error. - (tftp_open): Restore error. - -2012-02-05 Vladimir Serbinenko - - * grub-core/lib/i386/relocator16.S (grub_relocator16_start): Move switch - to real mode down to execute A20-related code in protected mode as - intended. - -2012-02-05 Grégoire Sutre - - * grub-core/disk/diskfilter.c (grub_diskfilter_make_raid): Return - NULL when the argument `level' has an unexpected value. - -2012-02-04 Vladimir Serbinenko - - Move platform-dependent files from $prefix to $prefix/$platform. - - * config.h.in (GRUB_TARGET_CPU): New definition. - (GRUB_PLATFORM): Likewise. - * configure.ac: Define GRUB_TARGET_CPU and GRUB_PLATFORM. - * grub-core/commands/parttool.c (grub_cmd_parttool): Update dir. - * grub-core/efiemu/main.c (grub_efiemu_autocore): Likewise. - * grub-core/kern/dl.c (grub_dl_load): Likewise. - * grub-core/normal/autofs.c (read_fs_list): Likewise. - * grub-core/normal/crypto.c (read_crypto_list): Likewise. - * grub-core/normal/dyncmd.c (read_command_list): Likewise. - * grub-core/normal/term.c (read_terminal_list): Likewise. - * grub-core/gettext/gettext.c (grub_mofile_open_lang): Use - $prefix/locale. - (grub_gettext_init_ext): Likewise. - * grub-core/normal/main.c (GRUB_MOD_INIT): Define grub_cpu and - grub_platform. - * util/grub-install.in: Update directories. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - -2012-02-04 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_claimmap): Change to - grub_error framework. All users updated. - -2012-02-04 Vladimir Serbinenko - - * grub-core/gettext/gettext.c: Mostly rewritten to avoid using - lists (by always binsearching), improve caching (cache strings - used for binsearch, not only results), improve - maintainability (by using more structured binary search) and correct - error handling. - -2012-02-04 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_return): Fix warning. - -2012-02-04 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_return): Fix potential - NULL-dereference. - Reported by: Jim Meyering. - -2012-02-03 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. - * util/grub-install.in: Gettextize the strings missed in first pass. - -2012-02-03 Vladimir Serbinenko - - * Makefile.util.def (grub-mkdevicemap): Removed. - * include/grub/emu/hostdisk.h (grub_util_get_os_disk): New proto. - * include/grub/util/deviceiter.h: Removed. - * util/deviceiter.c: Likewise. - * util/getroot.c (grub_util_get_os_disk): New function. - * util/grub-install.in: Remove grub-mkdevicemap. Use -t disk as - replacement for EFI. - * util/grub-mkdevicemap.c: Removed. - * util/grub-probe.c (probe): Handle PRINT_DISK. - (argp_parser): Handle -t disk. - -2012-02-03 Vladimir Serbinenko - - * util/grub-mkfont.c: Migrate to argp. - * util/grub-mklayout.c: Likewise. - * util/grub-mkpasswd-pbkdf2.c: Likewise. - * util/grub-mkrelpath.c: Likewise. - * util/grub-probe.c: Likewise. - * util/grub-script-check.c: Likewise. - -2012-02-03 Vladimir Serbinenko - - * util/grub-reboot.in: Add missing datarootdir. - Add missing newline. - * util/grub-set-default.in: Add missing datarootdir. - * util/powerpc/ieee1275/grub-mkrescue.in: Add missing newline. - * util/grub-mkrescue.in: Likewise. - -2012-02-03 Vladimir Serbinenko - - * util/grub.d/30_os-prober.in: Fix TRANSLATORS comment. - -2012-02-03 Vladimir Serbinenko - - * util/grub-kbdcomp.in: Add decent help and gettextize. - * docs/man/grub-kbdcomp.h2m: New file. - -2012-02-03 Vladimir Serbinenko - - Migrate grub-mkimage.c to argp. - - * Makefile.util.def (grub-mkimage): Add util/argp_common.c. - (grub-setup): Likewise. - * util/grub-setup.c (print_version): Move to ... - * util/argp_common.c (print_version): ... here. - * util/grub-setup.c (argp_program_version_hook): Move to ... - * util/argp_common.c (argp_program_version_hook): ... here. - * util/grub-setup.c (argp_parser): Add exit (1) on fatal error for - safety. - * util/grub-mkimage.c (main): Migrate to argp. - -2012-02-03 Vladimir Serbinenko - - * util/grub-mkrescue.in: Use same message as - util/powerpc/ieee1275/grub-mkrescue.in with %s in place of command - for better translations. - -2012-02-03 Vladimir Serbinenko - - * util/powerpc/ieee1275/grub-mkrescue.in: Gettextize. Unify the command - options with generic grub-mkrescue.in with the goal of future - merge. - -2012-02-03 Vladimir Serbinenko - - * grub-core/kern/mm.c: Add missing include of i18n.h - * grub-core/lib/relocator.c: Likewise. - -2012-02-03 Vladimir Serbinenko - - * grub-core/loader/ia64/efi/linux.c (find_mmap_size): Replace fatal with - error. - (allocate_pages): Check return value. - Replace fatal with error. - (grub_linux_boot): Replace printf with dprintf. - Check find_mmap_size return value. - Replace fatal with error. - Don't call grub_machine_fini. - (grub_load_elf64): Replace printf with dprintf. - (grub_cmd_linux): Likewise. - (grub_cmd_initrd): Likewise. - (grub_cmd_payload): Likewise. - -2012-02-03 Vladimir Serbinenko - - * grub-core/loader/i386/xnu.c (grub_cmd_devprop_load): Fix error - message. - * grub-core/video/radeon_fuloong2e.c - (grub_video_radeon_fuloong2e_setup): Likewise. - * grub-core/video/sis315pro.c (grub_video_sis315pro_setup): Likewise. - * grub-core/video/video.c (grub_video_set_mode): Don't override - standard out of memory message. - -2012-02-03 Grégoire Sutre - - NetBSD disk wedge support. - - * grub-core/kern/emu/hostdisk.c (grub_hostdisk_find_partition_start) - [__NetBSD__]: Handle NetBSD disk wedges. - * util/getroot.c (convert_system_partition_to_system_disk) - [__NetBSD__]: Likewise. - -2012-02-03 Mark Wooding - - * util/grub-mkconfig.in: Use umask rather than chmod to create - grub.cfg.new to avoid insecure grub.cfg. - -2012-02-03 Vladimir Serbinenko - - * grub-core/commands/ls.c: Gettextize. - * grub-core/commands/setpci.c: Likewise. - * grub-core/commands/videotest.c: Likewise. - * grub-core/disk/geli.c: Likewise. - * grub-core/kern/mm.c: Likewise. - * grub-core/lib/relocator.c: Likewise. - * grub-core/loader/efi/appleloader.c: Likewise. - * grub-core/loader/i386/xnu.c: Likewise. - * grub-core/loader/ia64/efi/linux.c: Likewise. - * grub-core/loader/xnu.c: Likewise. - * grub-core/net/dns.c: Likewise. - * grub-core/net/net.c: Likewise. - * grub-core/script/lexer.c: Likewise. - * grub-core/script/parser.y: Likewise. - * grub-core/script/yylex.l: Likewise. - * util/getroot.c: Likewise. - * util/grub-setup.c: Likewise. - -2012-02-03 Vladimir Serbinenko - - * grub-core/fs/reiserfs.c (grub_reiserfs_get_item): Use proper error - number. - -2012-02-03 Vladimir Serbinenko - - * grub-core/disk/ldm.c (grub_util_ldm_embed): Correct error message. - -2012-02-03 Vladimir Serbinenko - - * grub-core/commands/search_file.c (SEARCH_TARGET): Remove obsolete - macro. - * grub-core/commands/search_label.c (SEARCH_TARGET): Likewise. - * grub-core/commands/search_uuid.c (SEARCH_TARGET): Likewise. - -2012-02-03 Vladimir Serbinenko - - * util/grub-mkstandalone.in: Fix help messages. Gettextize. - * util/grub-install.in: Gettextize. - * util/grub-mkconfig.in: Likewise. - * util/grub-mkconfig_lib.in: Replace gettext with echo -n and not echo - if not available. - (grub_warn): Gettextize. - * util/grub-mknetdir.in: Gettextize. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/grub.d/00_header.in: Likewise. - * util/grub.d/10_hurd.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - * po/POTFILES-shell.in: Regenerate. - -2012-02-03 Richard Laager - - * util/grub-mkimage.c (main): Fix format-security warning. - * util/grub-mkrelpath.c (main): Likewise. - * util/grub-probe.c (main): Likewise. - -2012-02-03 Richard Laager - - * util/grub-probe.c (probe): Don't crash on canonicalize_file_name - failure. - Put back lost PRINT_DRIVE. - -2012-02-03 Richard Laager - - * util/getroot.c (find_root_devices_from_libzfs): Fix compilation error. - (grub_guess_root_devices): Replace strlen with sizeof. - Avoid crash. - (find_root_devices_from_poolname): Remove unused variable. - Handle raidzN. - -2012-02-03 Vladimir Serbinenko - - Support install on multi-device filesystems. - - * include/grub/emu/getroot.h (grub_guess_root_device): Renamed to ... - (grub_guess_root_devices): ...this. Return char **. All users updated. - * include/grub/emu/misc.h (grub_find_root_device_from_mountinfo): - Removed. - * util/getroot.c (find_root_device_from_libzfs): Moved pool logic to ... - (find_root_devices_from_poolname): ... here. - (grub_find_root_devices_from_mountinfo): Return char **. Make static. - Support zfs-fuse. - (grub_guess_root_device): Rename to ... - (grub_guess_root_devices): ... this. Return char **. All users updated. - * util/grub-install.in: Handle multi-device filesystems. - * util/grub-probe.c (probe). Make device_names a char **. Add delim - argument. All users updated. - Handle multi-device filesystems. - Use 'delim' as separator. - Remove device check to allow filesystems on file. - (main): Support -0 argument. Handle multi-device. - * util/grub-setup.c (setup): Remove root argument. Handle multi-device. - Fix a cross-device check while on it. - (arguments): Remove root_dev. - (argp_parser): Remove -r. - (main): Remove root_dev. - -2012-02-01 Vladimir Serbinenko - - * grub-core/fs/zfs/zfscrypt.c: Add link to documentation. - -2012-02-01 Vladimir Serbinenko - - * grub-core/commands/videotest.c (grub_cmd_videotest): Fix subset - symbol. - Reported by: NODA, Kai . - -2012-02-01 Vladimir Serbinenko - - Fix ehci on amd64. - - * grub-core/bus/usb/usbhub.c (grub_usb_hub_add_dev): Use %p to print - pointers. - * grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): Likewise. - (grub_ehci_setup_qh): Likewise. - (grub_ehci_find_qh): Likewise. - (grub_ehci_transaction): Likewise. - (grub_ehci_setup_transfer): Likewise. - (grub_ehci_check_transfer): Likewise. - (grub_ehci_portstatus): Likewise. - (grub_ehci_detect_dev): Likewise. - (grub_ehci_transfer_controller_data): New field td_last_phys. - (grub_ehci_setup_transfer): Fill td_last_phys. - (grub_ehci_check_transfer): Use td_last_phys. - -2012-02-01 Seth Goldberg - - * grub-core/normal/context.c (grub_env_extractor_close): Don't crash - if no submenu is present. - -2012-02-01 Aleš Nesrsta - - CBI support. - - * include/grub/usb.h (grub_usbms_protocol_t): New values - GRUB_USBMS_PROTOCOL_CB and GRUB_USBMS_PROTOCOL_CBI. - * grub-core/disk/usbms.c (GRUB_USBMS_CBI_CMD_SIZE): New define. - (GRUB_USBMS_CBI_ADSC_REQ): Likewise. - (grub_usbms_dev): Add subclass, protocol and intrpt. - Remove in_maxsz and out_maxsz. - (grub_usbms_reset): Rename to ... - (grub_usbms_bo_reset): .. this. - (grub_usbms_cbi_cmd): New function. - (grub_usbms_cbi_reset): Likewise. - (grub_usbms_reset): Likewise. - (grub_usbms_attach): Recognize cbi. Same subclass and protocol. - (grub_usbms_transfer): Rename to ... - (grub_usbms_transfer_bo): ... this. - (grub_usbms_transfer_cbi): Likewise. - (grub_usbms_transfer): Likewise. - -2012-02-01 Aleš Nesrsta -2012-02-01 Vladimir Serbinenko - - EHCI support. All of the credit goes to Aleš Nesrsta. I've just added - the support for the CS5536 modification thereos and few bugfixes. - - * grub-core/Makefile.core.def (ehci): New module. - * grub-core/bus/usb/ehci.c: New file. - * grub-core/bus/usb/usbhub.c (grub_usb_hub_add_dev): New arguments - port and hubaddr. All users updated. - Save port and hubaddr into dev structure. - * include/grub/cs5536.h (GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE): New - define. - * include/grub/pci.h (grub_dma_phys2virt): New function. - (grub_dma_virt2phys): Likewise. - * include/grub/usb.h (grub_usb_device): New members port and hubaddr. - -2012-01-31 Vladimir Serbinenko - - * grub-core/fs/fat.c (grub_fat_mount) [!MODE_EXFAT]: Remove fstype - check as some mkfs implementations omit it. - -2012-01-31 Vladimir Serbinenko - - * docs/grub.texi (Unicode): Mention identifier and space limitations. - -2012-01-31 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_sblock): Make volname a char array. - Add new member volname2. - (grub_jfs_label): Use volname2 if available. - -2012-01-31 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (grub_nilfs2_super_block): Expand volume_name - over last_mounted as seen in image generated by mkfs.nilfs2. - (grub_nilfs2_label): Use sizeof for the size of s_volume_name. - -2012-01-31 Vladimir Serbinenko - - * grub-core/fs/fat.c (grub_fat_dir_entry) [MODE_EXFAT]: Expand label - to 15 UTF-16 characters as seen in FS generated by mkexfatfs. - (grub_fat_label) [MODE_EXFAT]: Use macros for size. - -2012-01-31 Vladimir Serbinenko - - * grub-core/fs/romfs.c (grub_romfs_mount): Fix a bug with labels going - over the sector. - -2012-01-31 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (get_filesystem_dnode): Support space in - subvolume name (by removing a bogus and useless check). - -2012-01-31 Vladimir Serbinenko - - * grub-core/fs/ext2.c (grub_ext2_label): Fix field size. Change to - sizeof while on it. - -2012-01-30 Vladimir Serbinenko - - * grub-core/disk/scsi.c (grub_scsi_read_capacity): Renamed to ... - (grub_scsi_read_capacity10): ... this. - (grub_scsi_read_capacity16): New function. - (grub_scsi_open): Use read_capacity16 if read_capacity10 returned - 0xffffffff. - Fix off-by-one error. - * include/grub/scsi.h (grub_scsi): Rename size to last_block and make it - 64-bit unsigned. - * include/grub/scsicmd.h (grub_scsi_read_capacity): Rename to ... - (grub_scsi_read_capacity10): ... this. - (grub_scsi_read_capacity_data): Rename to ... - (grub_scsi_read_capacity10_data): ... this. Rename size to last_block. - (grub_scsi_read_capacity16): New struct. - (grub_scsi_read_capacity16_data): Likewise. - (grub_scsi_cmd_t): Rename grub_scsi_cmd_read_capacity to - grub_scsi_cmd_read_capacity10. - New command grub_scsi_cmd_read_capacity16. - -2012-01-30 Vladimir Serbinenko - - SCSI >2TiB support. - - * grub-core/disk/scsi.c (grub_scsi_read16): New function. - (grub_scsi_write16): Likewise. - (grub_scsi_read): Use read16 when necessary. - (grub_scsi_write): Likewise. - * include/grub/scsicmd.h (grub_scsi_read16): New struct. - (grub_scsi_write16): Likewise. - (grub_scsi_cmd_t): Add READ16 and WRITE16. - -2012-01-30 Vladimir Serbinenko - - SCSI write support (for usbms mainly). - - * grub-core/disk/scsi.c (grub_scsi_write10): Uncomment. Make buffer - a const pointer. - (grub_scsi_write): Implement. - * include/grub/scsi.h (grub_scsi_dev): Make write buffer a const pointer - -2012-01-30 Vladimir Serbinenko - - * grub-core/io/lzopio.c (uncompress_block): Fix use of incorrect - variable. - -2012-01-29 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/string.h (memchr): New function. - -2012-01-29 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. - -2012-01-29 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/assert.h (assert_real): Replace grub_fatal - with grub_printf to avoid unnecessary fatal failure. - -2012-01-29 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/limits.h (SHRT_MAX): New define. - (INT_MAX): Likewise. - * grub-core/lib/posix_wrap/stdio.h (snprintf): New function. - * grub-core/lib/posix_wrap/stdlib.h (abs): Likewise. - * grub-core/lib/posix_wrap/string.h (memcmp): Likewise. - (strcpy): Likewise. - (strstr): Likewise. - (strchr): Likewise. - (strncpy): Likewise. - (strcat): Likewise. - (strncat): Likewise. - (strcoll): Likewise. - * include/grub/types.h (GRUB_SHRT_MAX): New define. - (GRUB_INT_MAX): Likewise. - -2012-01-29 Vladimir Serbinenko - - * grub-core/gnulib/regcomp.c (regerror): Don't use abort on - unexpected error. - (optimize_utf8): Likewise. - * grub-core/lib/posix_wrap/stdlib.h (abort): Removed. - -2012-01-29 Vladimir Serbinenko - - * grub-core/boot/i386/pc/lnxboot.S: Use - GRUB_DECOMPRESSOR_MAX_DECOMPRESSOR_SIZE. - * grub-core/boot/i386/pc/startup_raw.S: Ensure about boot_dev - location. - * include/grub/offsets.h (GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE): New - definition. - (GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE): Likewise. - -2012-01-29 Vladimir Serbinenko - - * util/getroot.c (grub_util_get_dm_node_linear_info): Fix memory leak. - * grub-core/disk/cryptodisk.c (cryptodisk_cleanup): Disable for - now to avoid double free. - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_dev): Rename to - hostdisk. - * include/grub/disk.h (grub_disk_dev_id): New id HOSTDISK. - * util/grub-probe.c (escape_of_path): Always return a new copy. - (print_full_name): Escape path. - (probe): Don't call grub_util_devname_to_ofpath on NULL. - Fix hints on abstractions. - -2012-01-29 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): - Don't add "root" line if no compatibility hont is available. - Suggested by: Seth Goldberg. - -2012-01-29 Vladimir Serbinenko - - * include/grub/ata.h (grub_ata): Add a new element maxbuffer. - * grub-core/disk/ata.c (grub_ata_readwrite): Limit to ata->maxbuffer. - * grub-core/disk/pata.c (grub_pata_open): Set ata->maxbuffer. - * grub-core/disk/ahci.c (grub_ahci_open): Likewise. - -2012-01-29 Vladimir Serbinenko - - * include/grub/zfs/dnode.h (DN_MIN_INDBLKSHIFT): Removed. - -2012-01-29 Vladimir Serbinenko - - * util/grub-pe2elf.c (ehdr): Make static. - (shdr): Likewise. - (num_sections): Likewise. - (offset): Likewise. - -2012-01-29 Vladimir Serbinenko - - Eliminate ofpath limits and possible overflows. - - * util/ieee1275/ofpath.c (grub_util_info) [STANDALONE]: New function. - (OF_PATH_MAX): Removed. - (MAX_DISK_CAT): New const. - (find_obppath): Use allocated rather than preallocated buffer. - Return result. Argument of_path removed. All users updated. - Add missing fdstat. - (xrealpath): New function. - (block_device_get_sysfs_path_and_link): Remove sysfs argument. - Allocate rather than use preallocated buffer. All users updated. - (__of_path_common): Use allocated rather than preallocatecd buffer. - Return result. Argument of_path removed. All users updated. - (vendor_is_ATA): Read only needed part form the file. - (check_sas): Allocate depending on contents rather than fixed. - (main) [STANDALONE]: Handle NULL result. - -2012-01-29 Vladimir Serbinenko - - * grub-core/normal/completion.c (iterate_dev): Close the disk. - -2012-01-29 Vladimir Serbinenko - - Cryptodisk write support. - - * grub-core/disk/cryptodisk.c (grub_crypto_pcbc_encrypt): New function. - (grub_cryptodisk_decrypt): Moved logic to ... - (grub_cryptodisk_endecrypt): ...this. New argument "encrypt". - (grub_cryptodisk_write): Implement. - * grub-core/kern/emu/hostdisk.c (nwrite): Rename to ... - (grub_util_fd_write): ... this. Make global. - * include/grub/emu/hostdisk.h (grub_util_fd_write): New proto. - -2012-01-29 Vladimir Serbinenko - - * include/grub/list.h (grub_list_remove): Don't crash if element is - removed twice. - -2012-01-29 Vladimir Serbinenko - - Rename ofconsole to console. - - * grub-core/commands/terminal.c (handle_command): Handle ofconsole - as sysnonym to console. - * grub-core/term/ieee1275/ofconsole.c: Renamed to .. - * grub-core/term/ieee1275/console.c: ... this. All users updated. - Rename grub_ofconsole_ to grub_console_. All users updated - (grub_console_term_output): Rename "ofconsole" to "console". - * grub-core/term/terminfo.c (grub_cmd_terminfo): Handle "ofconsole" - as "console". - -2012-01-29 Vladimir Serbinenko - - * grub-core/loader/i386/pc/plan9.c (grub_cmd_plan9): Remove PXE - handling. - * include/grub/disk.h (grub_disk_dev_id): Remove obsolete - GRUB_DISK_DEVICE_UUID_ID, GRUB_DISK_DEVICE_PXE_ID and - GRUB_DISK_DEVICE_FILE_ID. - -2012-01-29 Vladimir Serbinenko - - * grub-core/kern/partition.c (grub_partition_get_name): Simplify logic - and improve performance. - -2012-01-29 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): Fix - missing ieee1275/ prefix on whole disk. - -2012-01-29 Vladimir Serbinenko - - * include/grub/powerpc/ieee1275/util/biosdisk.h: Remove. - * include/grub/powerpc/ieee1275/biosdisk.h: Likewise. - -2012-01-29 Vladimir Serbinenko - - * grub-core/fs/cpio.c (handle_symlink): Fix a bug. - -2012-01-29 Vladimir Serbinenko - - Merge common RAID and LVM logic to an abstract diskfilter. - Add LDM support using the same framework. - - * Makefile.util.def (libgrubkern): Add grub-core/disk/ldm.c, - grub-core/disk/diskfilter.c and grub-core/partmap/gpt.c. - (libgrubmods): Remove grub-core/disk/raid.c and - grub-core/partmap/gpt.c. - * grub-core/Makefile.core.def (ldm): New module. - (raid): Renamed to diskfilter. All users updated. - * grub-core/disk/raid.c: Moved to ... - * grub-core/disk/diskfilter.c: ... here. - * grub-core/disk/diskfilter.c: Rename grub_raid_ to grub_diskfilter_. - (lv_num): New var. - (find_array): Renamed to ... - (find_lv): ... this. Support multi-LV. Skip nameless LVs - (grub_is_array_readable): Renamed to ... - (grub_is_lv_readable): ... this. Support multinode hierarchy. - (insert_array): New argument id. - (is_node_readable): New function. - (scan_device): Rename to ... - (scan_disk): .. this. Restrict to one disk. - (scan_devices): New function. - (grub_diskfilter_iterate): Support multi-LV. - Skip invisible and nameless LVs. - (grub_diskfilter_memberlist): Support multi-LV. - (grub_diskfilter_read_node): New function. - (grub_raid_read): Most of logic moved to ... - (read_segment): ... here - (read_lv): New function. - (grub_diskfilter_get_vg_by_uuid): New function. - (grub_diskfilter_make_raid): Likewise. - * grub-core/disk/ldm.c: New file. - * grub-core/disk/lvm.c (vg_list): Removed. - (lv_count): Likewise. - (scan_depth): Likewise. - (is_lv_readable): Likewise. - (grub_lvm_getvalue): Advance pointer past the number. - (find_lv): Removed. - (do_lvm_scan): Refactored into ... - (grub_lvm_detect): ... this. Support raid. - (grub_lvm_iterate): Removed. - (grub_lvm_memberlist): Likewise. - (grub_lvm_open): Likewise. - (grub_lvm_close): Likewise. - (read_lv): Likewise. - (read_node): Likewise. - (is_node_readable): Likewise. - (is_lv_readable): Likewise. - (grub_lvm_read): Likewise. - (grub_lvm_write): Likewise. - (grub_lvm_dev): Use diskfilter - (GRUB_MOD_INIT): Likewise. - (GRUB_MOD_FINI): Likewise. - * grub-core/disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Use - new interface. - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Likewise. - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. - * grub-core/disk/raid5_recover.c (grub_raid5_recover): Use - grub_diskfilter_read_node. - Fix a bug with xor. - * grub-core/disk/raid6_recover.c (grub_raid6_recover): Use - grub_diskfilter_read_node. - Support GRUB_RAID_LAYOUT_MUL_FROM_POS. - * grub-core/kern/disk.c (grub_disk_dev_list): Make global. - (grub_disk_dev_iterate): Move from here... - * include/grub/disk.h (grub_disk_dev_iterate): ... to here. Inlined. - * grub-core/kern/emu/hostdisk.c (grub_hostdisk_find_partition_start): - Make global. - (grub_hostdisk_find_partition_start): Likewise. - (grub_hostdisk_os_dev_to_grub_drive): New function. - (grub_util_biosdisk_get_osdev): Check that disk is biosdisk. - * grub-core/kern/emu/hostdisk.c (make_device_name): Move to ... - * util/getroot.c (make_device_name): ... here. - * grub-core/kern/emu/hostdisk.c (grub_util_get_dm_node_linear_info): - Move to ... - * util/getroot.c (grub_util_get_dm_node_linear_info): ...here. - * grub-core/kern/emu/hostdisk.c - (convert_system_partition_to_system_disk): Move to ... - * util/getroot.c (convert_system_partition_to_system_disk): ...here. - * grub-core/kern/emu/hostdisk.c (device_is_wholedisk): Move to ... - * util/getroot.c (device_is_wholedisk): ... here. - * grub-core/kern/emu/hostdisk.c (find_system_device): Move to ... - * util/getroot.c (find_system_device): ... here. - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_present): - Move to ... - * util/getroot.c (grub_util_biosdisk_is_present): ...here. - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): - Move to ... - * util/getroot.c (grub_util_biosdisk_get_grub_dev): ... here. - Handle LDM. - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): - Move to ... - * util/getroot.c (grub_util_biosdisk_is_floppy): ... here. - * grub-core/partmap/gpt.c (grub_gpt_partition_map_iterate): Made global. - * include/grub/disk.h (grub_disk_dev_id): Replaced RAID and LVM with - DISKFILTER. - * include/grub/raid.h: Renamed to ... - * include/grub/diskfilter.h: ... this. - * include/grub/diskfilter.h: Rename grub_raid_* to grub_diskfilter_* - (GRUB_RAID_LAYOUT_*): Make into array. - (GRUB_RAID_LAYOUT_MUL_FROM_POS): New value. - (grub_diskfilter_vg): New struct. - (grub_diskfilter_pv_id): Likewise. - (grub_raid_member): Removed. - (grub_raid_array): Likewise. - (grub_diskfilter_pv): New struct. - (grub_diskfilter_lv): Likewise. - (grub_diskfilter_segment): Likewise. - (grub_diskfilter_node): Likewise. - (grub_diskfilter_get_vg_by_uuid): New proto. - (grub_raid_register): Inline. - (grub_diskfilter_unregister): Likewise. - (grub_diskfilter_make_raid): New proto. - (grub_diskfilter_vg_register): Likewise. - (grub_diskfilter_read_node): Likewise. - (grub_diskfilter_get_pv_from_disk) [GRUB_UTIL]: Likewise. - * include/grub/emu/hostdisk.h (grub_util_get_ldm): New proto. - (grub_util_is_ldm): Likewise. - (grub_util_ldm_embed) [GRUB_UTIL]: Likewise. - (grub_hostdisk_find_partition_start): Likewise. - (grub_hostdisk_os_dev_to_grub_drive): Likewise. - * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_LDM): - New definition. - (grub_gpt_partition_map_iterate): New proto. - * include/grub/lvm.h (grub_lvm_vg): Removed. - (grub_lvm_pv): Likewise. - (grub_lvm_lv): Likewise. - (grub_lvm_segment): Likewise. - (grub_lvm_node): Likewise. - * util/getroot.c [...] - * util/grub-probe.c (probe_raid_level): Handle diskfilter. - (probe_abstraction): Likewise. - * util/grub-setup.c (setup): Remove must_embed. Support LDM. - (main): Remove dead logic. - -2012-01-28 Vladimir Serbinenko - - Simplify root device discover and don't fail when trying to open - incorrect devices. - - * grub-core/disk/efi/efidisk.c (get_diskname_from_path_real): New - function. - (get_diskname_from_path): Likewise. - (grub_efidisk_get_device_name): Use get_diskname_from_path instead - of iterating. - -2012-01-27 Vladimir Serbinenko - - * grub-core/Makefile.core.def (setpci): Enable on all PCI platforms. - -2012-01-27 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (nvlist_find_value): Check that we don't go - pastthe end. - -2012-01-27 Vladimir Serbinenko - - * util/grub-install.in: Add missing \. - Reported by: gentoofan - -2012-01-26 Vladimir Serbinenko - - * grub-core/fs/squash4.c (xz_decompress): Fix return value. - (direct_read): Use correct compressed size. - (grub_squash_read_data): Likewise. - -2012-01-26 Vladimir Serbinenko - - * docs/grub.texi (Platform limitations): New section. - (Platform-specific operations): Likewise. - * docs/grub-dev.texi (Porting): Likewise. - -2012-01-25 Vladimir Serbinenko - - IEEE1275 disk write support. - - * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_write): Make buffer - const void *. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_write): Likewise. - * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_read): Move open - and seek loginc to ... - (grub_ofdisk_prepare): ... here. - (grub_ofdisk_write): Implement. - -2012-01-25 Vladimir Serbinenko - - ARC disk write support. - - * grub-core/disk/arc/arcdisk.c (handle_writable): New var. - (reopen): New argument writable. All users updated. - Handle required access mode. - (grub_arcdisk_write): Implement. - * include/grub/arc/arc.h (grub_arc_file_access): New enum. - (grub_arc_firmware_vector): Make buffer to write a const buffer. - -2012-01-25 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_device): New field size. - (read_sblock): Don't attempt to read superblocks outside the disk size. - -2012-01-25 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (grub_nilfs2_load_sb): Use device size from - first superblock to find the second one when possible. - -2012-01-25 Vladimir Serbinenko - - * util/grub-install.in: Fix an ARC bug. - Print a warning if no platform-specific setup is available. - -2012-01-24 Vladimir Serbinenko - - Use static allocation rather than scratch pointer in reed_solomon. - It decreases its size significantly and avoids a variable in .text. - - * grub-core/lib/reed_solomon.c (scratch): Removed. - (chosenstat): New const or static array. - (sigma): Likewise. - (errpot): Likewise. - (errpos): Likewise. - (sy): Likewise. - (mstat): Likewise. - (errvals): Likewise. - (eqstat): Likewise. - (pol_evaluate): Replace x with log_x argument. All users updated. - (syndroms): Removed. - (gauss_solve): Use statically allocated arrays. - (rs_recover): Likewise. - Calculate syndroms directly. - (decode_block): Use statically allocated arrays. - (grub_reed_solomon_add_redundancy) [TEST]: Fix -DTEST compilation. - (main) [TEST]: Allow -DTEST -DSTANDALONE. - -2012-01-24 Vladimir Serbinenko - - Eliminate fixed limit on reed solomon decoder length. - - * grub-core/boot/i386/pc/lnxboot.S: Scan for multiboot signature - rather than hardcoding the address. - * grub-core/boot/i386/pc/startup_raw.S: Add new data field - no_reed_solomon_length. - Move gate_a20 to no-reed-solomon part. - Don't force a particular size of no reed-solomon part. - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): - Removed. - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH): New define. - * util/grub-setup.c (setup): Read no_rs_length from the image itself. - -2012-01-24 Vladimir Serbinenko - - * grub-core/commands/wildcard.c (match_files): Handle filenames - without explicit device. - (wildcard_expand): Don't add explicit device if not already present. - * tests/grub_script_echo1.in: Add a new expansion test. - -2012-01-24 Vladimir Serbinenko - - Replace single-linked with double-linked lists. It results in more - compact and more efficient code. - - * grub-core/kern/list.c (grub_list_push): Moved from here ... - * include/grub/list.h (grub_list_push): ... to here. Set prev. - (grub_list_remove): Moved from here ... - * include/grub/list.h (grub_list_remove): ... here. Use and set prev. - (grub_prio_list_insert): Set prev. - * include/grub/list.h (grub_list): Add prev. All users updated. - -2012-01-24 Vladimir Serbinenko - - Handle newer autotools. Add some missing quotes while on it. - - * Makefile.am (pkglib_DATA): Remove update-grub_lib. - (pkglib_DATA): Move grub-mkconfig_lib from here ... - (pkgdata_DATA): ... here. - * Makefile.util.def (update-grub_lib): Removed. - * conf/Makefile.common (pkglib_DATA): Removed. - (pkglib_SCRIPTS): Likewise. - (pkgdata_DATA): New variable. - * tests/util/grub-shell-tester.in: Replace pkglib with pkgdata where - needed. - Add missing quotes. - Remove unused variable while on it. - * tests/util/grub-shell.in: Likewise. - * util/grub-install.in: Likewise. - * util/grub-mkconfig.in: Likewise. - * util/grub-mknetdir.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-mkstandalone.in: Likewise. - * util/grub.d/00_header.in: Likewise. - * util/grub.d/10_hurd.in: Likewise. - * util/grub.d/10_illumos.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - * util/update-grub_lib.in: Removed. - -2012-01-24 Seth Goldberg - - * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_recv): Relax checks as - a workaround for intel problem. - -2012-01-23 Paulo de Rezende Pinatti -2012-01-23 Vladimir Serbinenko -2012-01-23 pfsmorigo - - * util/grub-install.in: Support dd'in into PreP partition. - * util/grub-probe.c (probe): Support discovering partition type. - (main): Support -t msdos_parttype. - -2012-01-23 Vladimir Serbinenko - - * grub-core/normal/crypto.c (grub_crypto_autoload): Prevent - infinite recursion using counter. - * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_init): Defer s->crc32 - init to skip it if the magic check fails. - (dec_stream_header): Init s->crc32. - -2012-01-22 Vladimir Serbinenko -2012-01-22 Zachary Bedell -2012-01-22 Richard Laager - - * grub-core/fs/zfs/zfs.c (uberblock_verify): New parameter size. - All users updated. - (find_bestub): Determine correct size. - (fill_vdev_info_real): Fill ashift. New argument. All users updated. - (scan_disk): Align the size down. - Call check pool before find_bestub to have ashift. - -2012-01-22 Vladimir Serbinenko - - * grub-core/lib/relocator.c (malloc_in_range): Remove couple of - dprintf in no-malloc zone. - -2012-01-22 Mario Limonciello - - * configure.ac: Add back in test for limits.h. - -2012-01-20 Vladimir Serbinenko - - Support 4K-sector NTFS. - - * include/grub/ntfs.h (GRUB_NTFS_MAX_MFT): Increase to 8. - (grub_ntfs_data): Remove blocksize. - * grub-core/fs/ntfs.c (fixup): Fix size comparison. - Remove data argument. All users updated. - -2012-01-20 Vladimir Serbinenko - - * grub-core/kern/mips/arc/init.c (grub_total_modules_size): Mark as - being in .text to avoid dprel references. - * include/grub/mips/loongson/kernel.h (grub_arch_machine): Likewise. - * include/grub/mips/loongson/memory.h (grub_arch_memsize): Likewise. - (grub_arch_highmemsize): Likewise. - * include/grub/mips/loongson/time.h (grub_arch_busclock): Likewise. - * include/grub/mips/qemu_mips/memory.h (grub_arch_memsize): Likewise. - * include/grub/mips/time.h (grub_arch_cpuclock): Likewise. - -2012-01-18 Vladimir Serbinenko - - Support powerpc with GCC that defines __PPC__ but not __powerpc__. - - * config.h.in (__powerpc__) [__PPC__ && !__powerpc__]: New definition. - * grub-core/lib/setjmp.S: Treat __PPC__ as equivalent to __powerpc__. - -2012-01-18 Vladimir Serbinenko - - * include/grub/datetime.h (grub_get_datetime_cmos): Don't define in - GRUB_UTIL. - (grub_set_datetime_cmos): Likewise. - -2012-01-18 Vladimir Serbinenko - - Make XZ compression parameters dependent on target and not host CPU. - - * configure.ac: Define GRUB_TARGET_CPU_XYZ series. - * grub-core/lib/xzembed/xz_config.h: Use GRUB_TARGET_CPU_XYZ. - -2012-01-18 Vladimir Serbinenko - - * grub-core/kern/powerpc/dl.c (grub_arch_dl_get_tramp_got_size): Remove - set but not used variable. - -2012-01-14 Vladimir Serbinenko - - * grub-core/fs/reiserfs.c (grub_reiserfs_uuid): Reject 0-uuid as - created when no uuid support is compiled into mkfs.reiser. - -2012-01-14 Vladimir Serbinenko - - * grub-core/fs/hfs.c (macroman_to_utf8): Convert / to :. - (utf8_to_macroman): Do the opposite. - * grub-core/fs/hfsplus.c (grub_hfsplus_iterate_dir): Convert / to :. - -2012-01-14 Vladimir Serbinenko - - * configure.ac: Refise build qemu_mips w/o unifont. - -2012-01-14 Vladimir Serbinenko - - Eliminate grub_min/grub_max prone to overflow usage. - - * grub-core/bus/usb/usbhub.c (grub_usb_add_hub): Eliminate grub_min. - (poll_nonroot_hub): Likewise. - * grub-core/fs/affs.c (grub_affs_iterate_dir): Likewise. - (grub_affs_label): Likewise. - * grub-core/fs/btrfs.c (grub_btrfs_lzo_decompress): Likewise. - * grub-core/fs/hfs.c (grub_hfs_dir): Likewise. - (grub_hfs_label): Likewise. - * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey): Likewise. - * grub-core/fs/zfs/zfs.c (MIN): Remove. - (zap_leaf_array_equal): Use grub_size. Remove MIN. - (zap_leaf_array_get): Likewise. - (dnode_get_path): Likewise. - * grub-core/io/lzopio.c (grub_lzopio_read): Eliminate grub_min. - * grub-core/io/xzio.c (grub_xzio_read): Likewise. - * grub-core/script/execute.c (grub_script_break): Likewise. - * grub-core/script/lexer.c (grub_script_lexer_record): Eliminate - grub_max. - * grub-core/script/yylex.l (grub_lexer_yyrealloc): Likewise. - * include/grub/misc.h (grub_min): Removed. - (grub_max): Likewise. - -2012-01-14 Samuel Thibault - - * grub-core/fs/ext2.c (grub_ext2_iterate_dir): Ignore entries with - direct.inode = 0. - -2012-01-14 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/wctype.h (CHARCLASS_NAME_MAX): New define. - -2012-01-14 Vladimir Serbinenko - - * include/grub/datetime.h (grub_datetime2unixtime): Fix offset. - -2012-01-14 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/stdlib.h (MB_CUR_MAX): Moved from here ... - * grub-core/lib/posix_wrap/wchar.h (MB_CUR_MAX): ... here. Value fixed. - -2012-01-14 Vladimir Serbinenko - - * grub-core/fs/fshelp.c (grub_fshelp_find_file): Use grub_strcasecmp - rather than a hack for grub_strncasemap. - -2012-01-14 Vladimir Serbinenko - - Support multiple initrds - Note: part of this was accidently committed in r3739. - - * grub-core/loader/i386/linux.c (grub_cmd_initrd): Support multiple - initrd. - * grub-core/loader/i386/pc/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/ia64/efi/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/mips/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/powerpc/ieee1275/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/sparc64/ieee1275/linux.c (grub_cmd_initrd): Likewise. - -2012-01-14 Vladimir Serbinenko - - * grub-core/disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Skip - disks with unknown size. - * grub-core/disk/raid.c (scan_devices): Allow disks with unknown sizes. - -2012-01-14 Vladimir Serbinenko - - Remove defines pertaining to arbitrary limits not affecting GRUB - anymore. - - * grub-core/fs/ext2.c (EXT2_PATH_MAX): Removed. - (EXT2_MAX_SYMLINKCNT): Likewise. - * grub-core/fs/nilfs2.c (NILFS_BTREE_LEVEL_MAX): Likewise. - * grub-core/net/tftp.c (TFTP_MAX_PACKET): Likewise. - * include/grub/i386/pc/pxe.h (GRUB_PXE_MIN_BLKSIZE): Likewise. - (GRUB_PXE_MAX_BLKSIZE): Likewise. - * include/grub/normal.h (GRUB_MAX_CMDLINE): Likewise. - * include/grub/zfs/dnode.h (DN_MAX_INDBLKSHIFT): Likewise. - (DN_MAX_OBJECT_SHIFT): Likewise. - (DN_MAX_OFFSET_SHIFT): Likewise. - (DN_MAX_OBJECT): Likewise. - (DNODES_PER_LEVEL_SHIFT): Likewise. - * include/grub/zfs/spa.h (SPA_MAXBLOCKSHIFT): Likewise. - (SPA_MAXBLOCKSIZE): Likewise. - (SPA_BLOCKSIZES): Likewise. - * include/grub/zfs/zap_impl.h (MZAP_MAX_BLKSHIFT): Likewise. - (MZAP_MAX_BLKSZ): Likewise. - -2012-01-14 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (grub_zfs_read): Remove useless alloc and - handle NULL appropriately. - Remove MIN. - -2012-01-13 Vladimir Serbinenko - - Fix efiemu. - - * grub-core/efiemu/runtime/efiemu.c: explicitly include right - cpu/types.h. - (efiemu_set_virtual_address_map): Remove UINT_TO_PTR. - * configure.ac: Fix efiemu check. - -2012-01-13 Vladimir Serbinenko - - * util/grub.d/30_os-prober.in: Fix occurence of grub-probe instead of - grub_probe. - Reported by: adamwill - -2012-01-12 Seth Goldberg - - * grub-core/lib/arg.c (grub_arg_parse): Fix NULL pointer dereference. - -2012-01-12 Vladimir Serbinenko - - Fix handling of wide characters in gfxterm. - - * grub-core/term/gfxterm.c (grub_colored_char): Remove width and index. - (clear_char): Likewise. - (paint_char): Skip code == NULL chars. - (grub_gfxterm_putchar): Set code = NULL on "shadowed" positions. - -2012-01-12 Vladimir Serbinenko - - * grub-core/normal/charset.c: Move comment to right place. - -2012-01-11 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_bblock): Revert flags. - (GRUB_AFFS_FLAG_FFS): Put back where it was. - (grub_affs_mount): Revert the correct version checking. - -2012-01-11 Vladimir Serbinenko - - * docs/grub.texi (Unicode): Mention several other unsupported features. - -2011-12-26 Vladimir Serbinenko - - * grub-core/fs/squash4.c (squash_mount): Mark endian conversion in - case statements as compile-time one. - (direct_read): Prevent spurious warnings. - (grub_squash_read_data): Likewise. - -2011-12-26 Vladimir Serbinenko - - Various squash4 fixes and LZO and XZ support. - - * Makefile.util.def (libgrubmods.a): Add xzembed directory to cppflags. - Add xzembed source files. - * grub-core/Makefile.core.def (squash4): Add xzembed and minilzo flags. - * grub-core/fs/squash4.c (grub_squash_super): New field compression. - (grub_squash_inode): New subtype long_dir. - (SQUASH_TYPE_LONG_DIR): New inode type. - (COMPRESSION): New enum. - (XZBUFSIZ): New const. - (grub_squash_data): New fields blksz, decompress, xzdec, xzbuf. - (read_chunk): Use data->decompress. - (zlib_decompress): New function. - (lzo_decompress): Likewise. - (xz_decompress): Likewise. - (squash_mount): Set new data fields. - (grub_squash_iterate_dir): Handle long dir. - (squash_unmount): Free xzdec and xzbuf. - (grub_squash_open): Check ino type. - (direct_read): Stylistic fixes. Use data->decompress. - (grub_squash_read_data): Likewise. - * grub-core/io/gzio.c (grub_gzio): Remove disk_input. - (get_byte): Likewise. - (grub_zlib_disk_read): Removed. - * grub-core/lib/posix_wrap/sys/types.h (ssize_t): New type. - (GRUB_POSIX_BOOL_DEFINED): New define. - * grub-core/lib/posix_wrap/unistd.h: Include sys/types.h. - * grub-core/lib/xzembed/xz.h: Addmissing includes. - [!GRUB_POSIX_BOOL_DEFINED]: Define bool. - * include/grub/deflate.h (grub_zlib_disk_read): Removed. - -2011-12-26 Vladimir Serbinenko - - Don't override more informative errors. - - * grub-core/commands/acpi.c (grub_cmd_acpi): Don't override errors. - * grub-core/font/font.c (open_section): Likewise. - * grub-core/loader/i386/bsd.c (grub_bsd_load_aout): New argument - filename. Don't override errors. - (grub_cmd_openbsd_ramdisk): Don't override errors. - * grub-core/loader/i386/linux.c (grub_cmd_linux): Likewise. - (grub_cmd_initrd): Likewise. - * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Likewise. - (grub_cmd_initrd): Likewise. - * grub-core/loader/ia64/efi/linux.c (grub_load_elf64): Likewise. - (grub_cmd_linux): Likewise. - (grub_cmd_initrd): Likewise. - (grub_cmd_payload): Likewise. - * grub-core/loader/mips/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/multiboot.c (grub_cmd_multiboot): Likewise. - (grub_cmd_module): Likewise. - * grub-core/loader/powerpc/ieee1275/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/sparc64/ieee1275/linux.c (grub_cmd_initrd): Likewise. - * grub-core/loader/xnu.c (grub_xnu_load_driver): Likewise. - (grub_cmd_xnu_mkext): Likewise. - (grub_cmd_xnu_ramdisk): Likewise. - (grub_xnu_check_os_bundle_required): Likewise. - (grub_xnu_load_kext_from_dir): Likewise. - (grub_cmd_xnu_kextdir): Likewise. - * grub-core/loader/xnu_resume.c (grub_xnu_resume): Likewise. - -2011-12-25 Vladimir Serbinenko - - * grub-core/fs/minix.c (grub_minix_mount) [MODE_MINIX3]: Treat 0xffff - as 1024 in block size field. Found on one of my test images. - Small optimisation while on it. - -2011-12-25 Vladimir Serbinenko - - * docs/grub.texi (Filesystems): Mention SFS as Latin1 filesystem. - * grub-core/fs/sfs.c (grub_sfs_mount): Fix a memory leak while on it. - (grub_sfs_iterate_dir): Convert Latin1 to UTF8. Stylistic and - performance fixes while on it. - (grub_sfs_close): Fix memory leak while on it. - (grub_sfs_label): Convert Latin1 to UTF-8. - -2011-12-25 Vladimir Serbinenko - - * grub-core/fs/hfs.c (grub_hfs_dir): Cap keylen to actually available - space to avoid overflows. - (grub_hfs_label): Convert from macroman to UTF-8. - -2011-12-25 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_label): Interpret label as latin1. - -2011-12-25 Vladimir Serbinenko - - * grub-core/normal/menu.c (menu_init): Don't stop menu init at gfxterm. - -2011-12-25 Vladimir Serbinenko - - * unicode: Import Unicode 6.0 data. - -2011-12-25 Vladimir Serbinenko - - * grub-core/term/gfxterm.c (grub_gfxterm_putchar): Don't set values - outside of range. - -2011-12-25 Vladimir Serbinenko - - Avoid cutting in the middle of UTF-8 character. - - * include/grub/charset.h (grub_getend): New function. - * grub-core/script/function.c (grub_script_function_find): Use - grub_getend. - * grub-core/normal/completion.c (add_completion): Likewise. - -2011-12-25 Vladimir Serbinenko - - * grub-core/normal/charset.c (grub_ucs4_to_utf8): Small stylistic fix. - (grub_bidi_line_logical_to_visual): Skip tags. They are deprecated. - * include/grub/unicode.h (GRUB_UNICODE_TAG_START): New enum value. - (GRUB_UNICODE_TAG_END): Likewise. - (GRUB_UNICODE_LAST_VALID): Likewise. - -2011-12-25 Vladimir Serbinenko - - * include/grub/unicode.h (grub_unicode_compact_range): Replace end with - len and make it smaller. All users updated. - * util/import_unicode.py: Put length and not end character. - Check length. - -2011-12-25 Vladimir Serbinenko - - Make better Unicode-compliant and unify some UTF-8 code pathes. - - * grub-core/normal/charset.c (grub_utf8_to_utf16): Don't eat possibly - valid character. - (grub_is_valid_utf8): Use grub_utf8_process. - Check resulting code range. - (grub_utf8_to_ucs4): Use grub_utf8_process. - * include/grub/charset.h (grub_utf16_to_utf8): Don't eat up a possibly - valid character. - -2011-12-25 Vladimir Serbinenko - - * grub-core/io/bufio.c (grub_bufio_read): Fix handling of corner cases. - -2011-12-25 Vladimir Serbinenko - - * docs/grub.texi (Filesystems): Mention AFS. - -2011-12-25 Vladimir Serbinenko - - * docs/grub.texi (Filesystems): Clarify restrictions. - (Regexp): Mention non-Unicode regexp behaviour. - (Other): Mention non-Unicode matching behaviour. - -2011-12-24 Vladimir Serbinenko - - Make HFS implementation use MacRoman. - - * grub-core/fs/hfs.c (MAX_UTF8_PER_MAC_ROMAN): New define. - (macroman): New const array. - (macroman_to_utf8): New function. - (utf8_to_macroman): Likewise. - (grub_hfs_find_dir): Use utf8_to_macroman. - (grub_hfs_dir): Use macroman_to_utf8. - Set case_insensitive. - -2011-12-24 Vladimir Serbinenko - - * docs/grub.texi (Filesystems): Add IEEE1275 full-path example. - -2011-12-24 Vladimir Serbinenko - - Integrate hints into autogeneration scripts. - - * docs/grub.texi (Filesystems): Add a hostdisk example. - * Makefile.util.def (grub-mkdevicemap): Remove ofpath. - (grub-probe): Add ofpath. - * gentpl.py: Remove group nosparc64. - * grub-core/commands/search.c (cache_entry): New struct. - (cache): New var. - (FUNC_NAME): Use and save cache. Fix handling of trailing comma. - * grub-core/commands/search_wrap.c (options): Add platform-specific - hint options. - (grub_cmd_search): Handle platform-specific hints. - (GRUB_MOD_INIT): Declare grub_cmd_search as accept_dash. - * grub-core/kern/emu/hostdisk.c (map): New field device_map. - (grub_util_biosdisk_data): Likewise. - (grub_util_biosdisk_open): Set device_map. - (read_device_map): Handle "" as indication of no map. - Set device_map. - (find_system_device): Add hostdisk/ prefix for autogenerated entries. - (grub_util_biosdisk_get_compatibility_hint): New function. - * grub-core/normal/main.c (features): Add feature_platform_search_hint. - * include/grub/emu/hostdisk.h - (grub_util_biosdisk_get_compatibility_hint): New proto. - * util/grub-install.in: Don't call grub-mkdevicemap. - Add platform-specific hint to load.cfg. - * util/grub-mkconfig.in: Don't call grub-mkdevicemap. - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Add - hints. Set root preliminary to compatibility hint, not to OS name. - * util/grub-probe.c (PRINT_*): Add hints. - (print): Make static. - (escape_of_path): New function. - (guess_bios_drive): Likewise. - (guess_efi_drive): Likewise. - (guess_baremetal_drive): Likewise. - (print_full_name): Likewise. - (probe): Handle hints. - (main): Likewise. - * util/ieee1275/devicemap.c: Removed. - * util/ieee1275/ofpath.c (find_obppath): Allow to fail. All users - updated. - (grub_util_devname_to_ofpath): Return NULL on failure. - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Fix - resource leak. - * util/getroot.c (grub_util_pull_device): Fix memory leak. - - * po/POTFILES.in: Regenerated. - - Allow purely long options - - * grub-core/lib/arg.c (SHORT_ARG_HELP): Removed. - (SHORT_ARG_USAGE): Likewise. - (grub_arg_show_help): Compare opt with help_options. - (parse_option): Receive opt as argument. If makes big simplificatons. - All users updated - -2011-12-24 Vladimir Serbinenko - - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (WORDS_BIGENDIAN): - Restructure to avoid warning. - -2011-12-24 Vladimir Serbinenko - - * util/grub-install.in: Account for possible escaped comma in device - name. - -2011-12-24 Vladimir Serbinenko - - * util/ieee1275/ofpath.c (of_path_of_ide): Fix address for secondary - channel. - -2011-12-24 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_devalias_iterate): Fix - allocation and zero-setting. - (grub_ieee1275_get_devname): Check that alias is complete. - -2011-12-24 Vladimir Serbinenko - - * grub-core/kern/disk.c (grub_disk_read): Fix hook calling for - unaligned segments. - -2011-12-24 Vladimir Serbinenko - - * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Add ieee1275/ - prefix. - (grub_ofdisk_open): Check and discard ieee1275 prefix. - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): - Add ieee1275 prefix. - -2011-12-23 Vladimir Serbinenko - - * docs/grub.texi (Filesystems): Update. - -2011-12-23 Vladimir Serbinenko - - Support odc, newc and bigendian cpio formats. - - * Makefile.util.def (libgrubmods): Add odc.c, newc.c and cpio_be.c. - * grub-core/Makefile.core.def (newc): New module. - (odc): Likewise. - (cpio_be): Likewise. - * grub-core/fs/cpio.c (ALIGN_CPIO): New macro. - (MAGIC): Likewise. - (MAGIC2): Likewise. - (head) [MODE_ODC]: Adapt for the format. - (head) [MODE_NEWC]: Likewise. - (head) [!MODE_*]: Write fields of interest as arrays. - (MAGIC_USTAR): Removed. - (read_number) [MODE_NEWC]: Change to hex. - (read_number) [!MODE_*]: Parse binary arrays. - (grub_cpio_find_file): Factor out the code for better structure and - always use read_number. - (grub_cpio_mount): Use MAGIC and MAGIC2. - (grub_cpio_dir): Exit on first hook non-0 return. - (grub_cpio_fs) [MODE_ODC]: Set name to odc. - (grub_cpio_fs) [MODE_NEWC]: Set name to newc. - (GRUB_MOD_INIT) [MODE_ODC]: Set name to odc. - (GRUB_MOD_INIT) [MODE_NEWC]: Set name to newc. - (GRUB_MOD_FINI) [MODE_ODC]: Set name to odc. - (GRUB_MOD_FINI) [MODE_NEWC]: Set name to newc. - * grub-core/fs/newc.c: New file. - * grub-core/fs/odc.c: Likewise. - * grub-core/fs/cpio_be.c: Likewise. - -2011-12-23 Vladimir Serbinenko - - Fix handling of tar numbers occupying the whole field. - - * grub-core/fs/cpio.c (read_number): New function. - (grub_cpio_find_file): Use read_number instead of strtoull. - -2011-12-23 Vladimir Serbinenko - - * grub-core/fs/cpio.c (grub_cpio_find_file): Fix handling of names - occupying the whole field size. - -2011-12-23 Lukas Anzinger - - * util/grub-mkconfig_lib.in (version_test_gt): Fix variable names. - -2011-12-23 Vladimir Serbinenko - - * grub-core/net/net.c (grub_cmd_delroute): Add missing out condition. - -2011-12-23 Seth Goldberg - - * grub-core/Makefile.core.def (lzma_decompress): Add missing - TARGET_IMG_LDFLAGS. - -2011-12-23 Vladimir Serbinenko - - * util/getroot.c (ESCAPED_PATH_MAX): New define. - (mountinfo_entry): Increase the field size to take escaping into - account. - (find_root_device_from_libzfs): Add one byte to size of strings for - security. - -2011-12-23 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (grub_reed_solomon_add_redundancy): Add - an assert. - * util/grub-setup.c (setup): Likewise. - -2011-12-23 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S: Add missing argument for - _LzmaDecodeA. - -2011-12-22 Vladimir Serbinenko - - * docs/grub.texi (Internationalisation): New section. - -2011-12-22 Vladimir Serbinenko - - * docs/grub.texi (Loopback booting): New section. - -2011-12-22 Keshav P R - - * util/grub-mkstandalone.in: Fix minor typo errors. - -2011-12-20 Vladimir Serbinenko - - IPv6, TCP, HTTP, ICMP and DNS support. Several cleanups and bugfixes. - - * grub-core/Makefile.core.def (net): Add net/dns.c, net/tcp.c, - net/icmp.c and net/icmp6.c. - (http): New module. - (priority_queue): Likewise. - * grub-core/io/bufio.c: Rewritten. - * grub-core/lib/legacy_parse.c (legacy_command): New argument type - TYPE_WITH_CONFIGFILE_OPTION. - (legacy_commands): Add bootp and dhcp. - (is_option): Handle TYPE_WITH_CONFIGFILE_OPTION. - (grub_legacy_parse): Likewise. - * grub-core/lib/priority_queue.c: New file. - * grub-core/net/arp.c: Add missing license header. - (arp_find_entry): Removed. - (arp_find_entry): Likewise. - (grub_net_arp_resolve): Rename to ... - (grub_net_arp_send_request): ...this. - (grub_net_arp_receive): New card argument. - * grub-core/net/bootp.c (parse_dhcp_vendor): Clean up. - Set router and DNS server. - (grub_net_configure_by_dhcp_ack): Handle routing information. - (grub_cmd_bootp): Set checksum. - (grub_bootp_init): Remove net_dhcp. - * grub-core/net/dns.c: New file. - * grub-core/net/drivers/efi/efinet.c (send_card_buffer): Wait for - completion. - (get_card_packet): Handle allocation. - (grub_efinet_findcards): Set mtu. - * grub-core/net/drivers/emu/emunet.c: Add missing license header. - (get_card_packet): Handle allocation. - (emucard): Set mtu. - * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_recv): Handle allocation - (GRUB_MOD_INIT): Set mtu. - * grub-core/net/drivers/ieee1275/ofnet.c (grub_ofnetcard_data): Remove - mtu. - (get_card_packet): Handle allocation. - (grub_ofnet_findcards): Set mtu. - * grub-core/net/ethernet.c (send_ethernet_packet): Add compile time - assert. - (grub_net_recv_ethernet_packet): Handle IPv6. - * grub-core/net/http.c: New file. - * grub-core/net/icmp.c: Likewise. - * grub-core/net/icmp6.c: Likewise. - * grub-core/net/ip.c (ip6addr): New type. - (ip6hdr): Likewise. - (reassemble): Likewise. - (cmp): New function. - (reassembles): New variable. - (grub_net_ip_chksum): Handle 0xffff sum and unaligned buffers. - (id): New variable. - (send_fragmented): New function. - (grub_net_send_ip_packet): Rename to ... - (grub_net_send_ip4_packet): ... this. Send fragmented if needed. - Handle non-UDP. - (grub_net_recv_ip_packets): Rename to ... - (handle_dgram): ... this. Check checksum. Handle non-UDP. - (free_rsm): New function. - (free_old_fragments): Likewise. - (grub_net_recv_ip4_packets): New function. - (grub_net_send_ip6_packet): Likewise. - (grub_net_send_ip_packet): Likewise. - (grub_net_recv_ip6_packets): Likewise. - (grub_net_recv_ip_packets): Likewise. - * grub-core/net/net.c (grub_net_link_layer_entry): New struct. - (LINK_LAYER_CACHE_SIZE): New const. - (link_layer_find_entry): New function. - (grub_net_link_layer_add_address): Likewise. - (grub_net_link_layer_resolve_check): Likewise. - (grub_net_link_layer_resolve): Likewise. - (grub_net_ipv6_get_slaac): Likewise. - (grub_net_ipv6_get_link_local): Likewise. - (grub_cmd_ipv6_autoconf): Likewise. - (parse_ip): Handle one number representation. - (parse_ip6): New functoion. - (match_net): Handle IPv6. - (grub_net_resolve_address): Handle IPv6 and DNS. - (grub_net_resolve_net_address): Handle IPv6. - (route_cmp): New function. - (grub_net_route_address): Find best route. - (grub_net_addr_to_str): Handle IPv6. - (grub_net_addr_cmp): New function. - (grub_net_add_addr): Register local route. - (print_net_address): Handle net address. - (grub_net_poll_cards): Retransmit TCP. - (grub_net_poll_cards_idle_real): Likewise. - (have_ahead): New function. - (grub_net_seek_real): Use underlying seek. - (GRUB_MOD_INIT): Register net_ipv6_autoconf and init dns. - * grub-core/net/tcp.c: New file. - * grub-core/net/tftp.c (tftp_data): Add priority_queue. - (cmp): New function. - (ack): Likewise. - (tftp_receive): Handle unordered input. - (destroy_pq): New function. - (tftp_close): Close pq. - * grub-core/net/udp.c: Put missing license header. - (grub_net_udp_socket): New function. - (udp_socket_register): Likewise. - (grub_net_udp_close): Likewise. - (grub_net_recv_udp_packet): Check checksum. - * include/grub/efi/api.h (grub_efi_simple_network): Add status. - * include/grub/misc.h (grub_memchr): New function. - * include/grub/net.h (GRUB_NET_*_SIZE): New enum. - (grub_net_card_driver): Return buf in recv. - (grub_net_slaac_mac_list): New struct. - (grub_network_level_protocol_id): Add ipv6. - (grub_net_network_level_addr): Likewise. - (grub_net_network_level_net_addr): Likewise. - (grub_net_app_protocol): Add seek. - (grub_net_socket): Removed. - (grub_net_sockets): Likewise. - (grub_net_socket_register): Likewise. - (grub_net_socket_unregister): Likewise. - (FOR_NET_SOCKETS): Likewise. - (grub_net_add_addr): Add const. - (GRUB_NET_BOOTP_*): New enum. - (grub_net_addr_cmp): New proto. - (GRUB_NET_MAX_STR_ADDR_LEN): Take IPV6 into account. - (GRUB_NET_MAX_STR_HWADDR_LEN): New define. - (grub_net_hwaddr_to_str): NEw proto. - (FOR_NET_NETWORK_LEVEL_INTERFACES): New macro. - (FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE): Handle NULL. - (grub_dns_init): New proto. - (grub_dns_fini): Likewise. - (grub_net_tcp_retransmit): Likewise. - (grub_net_link_layer_add_address): Likewise. - (grub_net_link_layer_resolve_check): Likewise. - (grub_net_link_layer_resolve): Likewise. - (grub_net_dns_lookup): Likewise. - (grub_net_add_dns_server): Likewise. - (grub_net_remove_dns_server): Likewise. - (GRUB_NET_TRIES): New const. - (GRUB_NET_INTERVAL): Likewise. - * include/grub/net/arp.h: Mostly rewritten. - * include/grub/net/ethernet.h (grub_net_ethertype_t): New enum. - * include/grub/net/ip.h: Mostly rewritten. - * include/grub/net/netbuff.h: Indent. - * include/grub/net/tcp.h: New file. - * include/grub/net/udp.h: Mostly rewritten. - * include/grub/priority_queue.h: New file. - * include/grub/types.h (PRIdGRUB_SSIZE): New define. - (grub_swap_bytes64_compile_time): Likewise. - (grub_cpu_to_be16_compile_time): Likewise. - (grub_cpu_to_be32_compile_time): Likewise. - (grub_cpu_to_be64_compile_time): Likewise. - (grub_be_to_cpu64_compile_time): Likewise. - -2011-12-16 Vladimir Serbinenko - - * grub-core/commands/i386/pc/drivemap.c (int13slot): Replace - UINT_TO_PTR with cast. - -2011-12-15 Vladimir Serbinenko - - * util/import_gcry.py: Skip _gcry_rmd160_mixblock and serpent_test. We - don't use them. - -2011-12-15 Vladimir Serbinenko - - * util/import_gcry.py: Don't add include camellia.h to camellia.c. It's - already there. - -2011-12-15 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Clean multiboot header to avoid - confusing ipxe. - -2011-12-15 Vladimir Serbinenko - - * grub-core/lib/libgcrypt/cipher/md4.c (transform) [WORDS_BIGENDIAN]: - Add missing const attribute. - * grub-core/lib/libgcrypt/cipher/md5.c (transform) [WORDS_BIGENDIAN]: - Likewise. - * grub-core/lib/libgcrypt/cipher/rmd160.c (transform) [WORDS_BIGENDIAN]: - Likewise. - -2011-12-15 Vladimir Serbinenko - - * grub-core/lib/libgcrypt/cipher/serpent.c (serpent_key_prepare): Fix - misaligned access. - (serpent_setkey): Likewise. - (serpent_encrypt_internal): Likewise. - (serpent_decrypt_internal): Likewise. - (serpent_encrypt): Don't put an alignment-increasing cast. - (serpent_decrypt): Likewise. - (serpent_test): Likewise. - -2011-12-15 Vladimir Serbinenko - - * grub-core/loader/multiboot.c (grub_cmd_module): Fix target address. - -2011-12-15 Vladimir Serbinenko - - Replace UINT_TO_PTR and PTR_TO_UINT with explicit grub_addr_t casts. - - * include/grub/types.h (UINT_TO_PTR): Removed. All users switched to - grub_addr_t casts. - (PTR_TO_UINT64): Likewise. - (PTR_TO_UINT32): Likewise. - -2011-12-15 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Decrease the higher limit - because of stack. - * util/grub-setup.c (setup): Don't add redundancy past the higher load - limit. - -2011-12-15 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_label.c (label_paint): Handle the case - text_width > available width a bit more gracefully. - -2011-12-15 Vladimir Serbinenko - - * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Fix - current address calculation. - -2011-12-15 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (decode_block): Allocate on heap and not - stack. - (encode_block): Likewise. - -2011-12-15 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S: Clear direction flag for - certainety. - -2011-12-15 Vladimir Serbinenko - - * grub-core/boot/i386/pc/startup_raw.S: Move realmode routines to - non-RS part to avoid RS messing with GDT. - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): - Increase to suit in realmode routines. - -2011-12-15 Vladimir Serbinenko - - * grub-core/kern/i386/realmode.S: Increase alignment. - * grub-core/boot/i386/pc/startup_raw.S: Likewise. - -2011-12-14 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (init_powx): Set gf_powx_inv[0] just to - be deterministic. - (syndroms): Compute 0 syndrom. - (rs_recover): Use 0 syndrom. - -2011-12-14 Vladimir Serbinenko - - * include/grub/kernel.h (FOR_MODULES): Make it a bit faster. - -2011-12-14 Vladimir Serbinenko - - * include/grub/types.h (GRUB_PROPERLY_ALIGNED_ARRAY): Add missing - brackets. - -2011-12-14 Vladimir Serbinenko - - * grub-core/gfxmenu/widget-box.c (get_left_pad): Take corners into - account. - (get_top_pad): Likewise. - (get_right_pad): Likewise. - (get_bottom_pad): Likewise. - -2011-12-14 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_list.c (draw_menu): Don't use assignment in if. - -2011-12-14 Vladimir Serbinenko - - * include/grub/efi/api.h (grub_efi_memory_descriptor): Add packed - attribute as the structure isn't guaranteed to be properly aligned. - (grub_efi_pci_device_path): Likewise. - (grub_efi_pccard_device_path): Likewise. - (grub_efi_memory_mapped_device_path): Likewise. Additionaly explicitly - specify the size of `memory_type'. - (grub_efi_vendor_device_path): Likewise. - (grub_efi_controller_device_path): Likewise. - (grub_efi_acpi_device_path): Likewise. - (grub_efi_expanded_acpi_device_path): Likewise. - (grub_efi_atapi_device_path): Likewise. - (grub_efi_scsi_device_path): Likewise. - (grub_efi_fibre_channel_device_path): Likewise. - (grub_efi_1394_device_path): Likewise. - (grub_efi_usb_device_path): Likewise. - (grub_efi_usb_class_device_path): Likewise. - (grub_efi_i2o_device_path): Likewise. - (grub_efi_mac_address_device_path): Likewise. - (grub_efi_ipv4_device_path): Likewise. - (grub_efi_ipv6_device_path): Likewise. - (grub_efi_infiniband_device_path): Likewise. - (grub_efi_uart_device_path): Likewise. - (grub_efi_vendor_messaging_device_path): Likewise. - (grub_efi_hard_drive_device_path): Likewise. - (grub_efi_cdrom_device_path): Likewise. - (grub_efi_vendor_media_device_path): Likewise. - (grub_efi_file_path_device_path): Likewise. - (grub_efi_protocol_device_path): Likewise. - (grub_efi_piwg_device_path): Likewise. - (grub_efi_bios_device_path): Likewise. - -2011-12-14 Vladimir Serbinenko - - * include/grub/charset.h (grub_utf16_to_utf8): Make src a const pointer. - (grub_ucs4_to_utf8_alloc): Likewise. - (grub_ucs4_to_utf8): Likewise. - * grub-core/normal/charset.c (grub_ucs4_to_utf8): Likewise. - (grub_ucs4_to_utf8_alloc): Likewise. - -2011-12-14 Vladimir Serbinenko - - AFFS never uses unicode. - - * include/grub/charset.h (GRUB_MAX_UTF8_PER_LATIN1): New const. - (grub_latin1_to_utf8): New inline function. - * grub-core/fs/affs.c (grub_affs_iterate_dir): Convert latin1 to UTF8. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/romfs.c (grub_romfs_mount): Fix pointer comparison - overflow. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/squash4.c (grub_squash_inode): Fix field sizes. - (grub_squash_dirent_header): Likewise. - (read_chunk): Don't double swap. - (grub_squash_iterate_dir): Fix swap sizes. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_getent): Handle UTF16 endianness. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/hfs.c (grub_hfs_find_node): Handle unaligned keys. - (grub_hfs_iterate_dir): Likewise. - -2011-12-13 Vladimir Serbinenko - - Fix video on platforms where unaligned access is forbidden. - Make several optimisations while on it. - - * grub-core/video/fb/fbblit.c (grub_video_fbblit_replace_directN): - Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. - (grub_video_fbblit_replace_32bit_1bit): Likewise. - (grub_video_fbblit_replace_24bit_1bit) [!GRUB_HAVE_UNALIGNED_ACCESS]: - Disable. - (grub_video_fbblit_replace_16bit_1bit): - Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. - (grub_video_fbblit_replace_8bit_1bit): Likewise. - (grub_video_fbblit_replace_BGRX8888_RGBX8888): Likewise. - (grub_video_fbblit_replace_BGRX8888_RGB888): Likewise. - (grub_video_fbblit_replace_BGR888_RGBX8888): Likewise. - (grub_video_fbblit_replace_BGR888_RGBX8888): Likewise. - (grub_video_fbblit_replace_BGR888_RGB888): Likewise. - (grub_video_fbblit_replace_RGBX8888_RGB88): Likewise. - (grub_video_fbblit_replace_RGB888_RGBX888): Likewise. - (grub_video_fbblit_replace_RGB888_RGBX8888): Likewise. - (grub_video_fbblit_replace_index_RGBX8888): Likewise. - (grub_video_fbblit_replace_index_RGB888): Likewise. - (grub_video_fbblit_blend_BGRA8888_RGBA8888): Likewise. - (grub_video_fbblit_blend_BGR888_RGBA8888): Likewise. - (grub_video_fbblit_blend_RGBA8888_RGBA8888): Likewise. - (grub_video_fbblit_blend_RGB888_RGBA8888): Likewise. - (grub_video_fbblit_blend_index_RGBA8888): Likewise. - (grub_video_fbblit_blend_XXXA8888_1bit): Likewise. - (grub_video_fbblit_blend_XXX888_1bit) [!GRUB_HAVE_UNALIGNED_ACCESS]: - Disable. - (grub_video_fbblit_blend_XXX565_1bit): - Optimise and use GRUB_VIDEO_FB_ADVANCE_POINTER. - * grub-core/video/fb/fbfill.c (grub_video_fbfill_direct32): Likewise. - * grub-core/video/fb/fbutil.c (grub_video_fb_get_video_ptr): Return - void *. - * grub-core/video/fb/video_fb.c (common_blitter) - [!GRUB_HAVE_UNALIGNED_ACCESS]: Skip disabled blitters. - (grub_video_fb_create_render_target_from_pointer) - [!GRUB_HAVE_UNALIGNED_ACCESS]: Check alignment. - * include/grub/fbutil.h (grub_video_fb_get_video_ptr): Return void *. - * include/grub/i386/types.h (GRUB_HAVE_UNALIGNED_ACCESS): New - definition. - * include/grub/x86_64/types.h (GRUB_HAVE_UNALIGNED_ACCESS): Likewise. - -2011-12-13 Vladimir Serbinenko - - * grub-core/kern/sparc64/dl.c (grub_arch_dl_relocate_symbols): Support - HH22 and HM10 relocations. - -2011-12-13 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vsnprintf_real): Fix fmt2 parsing. - -2011-12-13 Vladimir Serbinenko - - * grub-core/commands/videotest.c (grub_cmd_videotest): Check that - allocation succeeded. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_convert_string): Make first - argument a u8 pointer. All users updated. - Handle unaligned buffers. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Force inlining of - add_part to workaround compiler bug. - -2011-12-13 Vladimir Serbinenko - - * include/grub/kernel.h (FOR_MODULES): Preserve alignment invariants. - -2011-12-13 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_add_elfsyms): - Reserve alignment invariants. - (grub_multiboot_load): Likewise. - (retrieve_video_parameters): Likewise. - (grub_multiboot_make_mbi): Likewise. - -2011-12-13 Vladimir Serbinenko - - * grub-core/loader/i386/xnu.c (grub_xnu_devprop_remove_property): Fix - incorrect pointer. - -2011-12-13 Vladimir Serbinenko - - * grub-core/disk/pata.c (grub_pata_pio_read): Handle unaligned buffer. - (grub_pata_pio_write): Likewise. - -2011-12-13 Vladimir Serbinenko - - Add noreturn attributes and remove unreachable code. - - * grub-core/bus/cs5536.c (grub_cs5536_smbus_wait): Remove unreachable - code. - * grub-core/commands/halt.c (grub_cmd_halt): Remove unreachable - code. Mark as noreturn. - * grub-core/commands/minicmd.c (grub_mini_cmd_exit): Likewise. - * grub-core/commands/reboot.c (grub_cmd_reboot): Likewise. - * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Remove - unreachable code. - * grub-core/kern/main.c (grub_main): Mark as noreturn. - * grub-core/kern/rescue_reader.c (grub_rescue_run): Likewise. - * grub-core/lib/posix_wrap/stdlib.h (abort): Likewise. - * grub-core/normal/menu.c (run_menu): Remove unreachable code. - * include/grub/kernel.h (grub_main): Mark as noreturn. - * include/grub/reader.h (grub_rescue_run): Likewise. - -2011-12-13 Vladimir Serbinenko - - * include/grub/i386/qemu/memory.h (grub_machine_mmap_init): Remove - redundant declaration. - -2011-12-13 Vladimir Serbinenko - - * include/grub/net.h (grub_net_network_level_interfaces): Remove - redundant declaration. - (FOR_NET_NETWORK_LEVEL_INTERFACES): Move to appropriate place. - -2011-12-13 Vladimir Serbinenko - - * grub-core/commands/hdparm.c (le16_to_char): Make src and dest uint16 * - to ensure alignment. - (grub_hdparm_print_identify): Make argument uint16 * to ensure - alignment. Ensure tmp alignment. - (grub_cmd_hdparm): Ensure buf alignment. - * grub-core/disk/ata.c (grub_ata_strncpy): Make src and dest uint16 * - to ensure alignment. - (grub_ata_dumpinfo): Ensure text alignment. - (grub_atapi_identify): Preserve alignment invariant. - (grub_ata_identify): Likewise. Use grub_get_unaligned32 when necessary. - -2011-12-13 Vladimir Serbinenko - - * include/grub/emu/misc.h (xasprintf): Add missing format attribute. - * include/grub/mips/kernel.h (grub_halt): Remove redundant declaration. - * include/grub/mips/qemu_mips/kernel.h (grub_halt): Likewise. - * include/grub/misc.h (grub_reboot) - [GRUB_MACHINE_EMU || GRUB_MACHINE_QEMU_MIPS]: Export. - (grub_halt) [__mips__]: Likewise. - -2011-12-13 Vladimir Serbinenko - - * include/grub/efi/memory.h (grub_machine_mmap_iterate): - Remove redundant declaration. - (grub_mmap_get_post64): Likewise. - (grub_mmap_get_upper): Likewise. - (grub_mmap_get_lower): Likewise. - -2011-12-13 Vladimir Serbinenko - - * grub-core/partmap/dvh.c (grub_dvh_is_valid): Make argument - uint32_t * to ensure alignment. - (dvh_partition_map_iterate): Make `block' a union to ensure alignment. - -2011-12-13 Vladimir Serbinenko - - * grub-core/partmap/sunpc.c (grub_sun_is_valid): Make argument - uint16_t * to ensure alignment. - (sun_pc_partition_map_iterate): Make `block' a union to ensure - alignment. - -2011-12-13 Vladimir Serbinenko - - * grub-core/partmap/sun.c (grub_sun_is_valid): Make argument uint16_t * - to ensure alignment. - (sun_partition_map_iterate): Make `block' a union to ensure alignment. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (u16at): Make into inline function. - Handle unaligned pointers. - (u32at): Likewise. - (u64at): Likewise. - (fixup): Use byte access instead of v16at. - (find_attr): Fix imporper usage of v32at. - (read_data): Likewise. - (list_file): Handle byte-swapping and unaligned strings. - (grub_ntfs_label): Likewise. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/udf.c (grub_udf_partmap): Add packed attribute - as it's not necessarily aligned. - -2011-12-13 Vladimir Serbinenko - - * grub-core/kern/mips/qemu_mips/init.c (grub_at_keyboard_init): Remove - redundant declaration. - (grub_serial_init): Likewise. - (grub_terminfo_init): Likewise. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (DVA_OFFSET_TO_PHYS_SECTOR): Make into inline - function. - (ZAP_HASH_IDX): Likewise. - (ZAP_LEAF_HASH_SHIFT): Likewise. - (ZAP_LEAF_HASH_NUMENTRIES): Likewise. - (LEAF_HASH): Likewise. - (ZAP_LEAF_NUMCHUNKS): Likewise. - (ZAP_LEAF_CHUNK): Likewise. Changed pointer arithmetic to preserve - alignment invariants. Return pointer. All users updated. - (ZAP_LEAF_ENTRY): Make into inline function. - (NBBY): Removed. - (xor): LIkewise. - (xor_out): Use grub_crypto_xor. - (dnode_get_path): Use grub_get_unaligned. - (nvlist_find_value): Likewise. - (grub_zfs_nvlist_lookup_uint64): Likewise. - (grub_zfs_nvlist_lookup_string): Likewise. - (get_nvlist_size): Likewise. - (grub_zfs_open): Likewise. - (fill_fs_info): Likewise. - (grub_zfs_dir): Likewise. - * include/grub/zfs/zap_leaf.h (zap_leaf_phys): Adapt to preserve - alignment invariants. - * include/grub/zfs/zio.h (zio_eck_t): Mark as packed as it's not - necessarily aligned. - -2011-12-13 Vladimir Serbinenko - - * grub-core/net/netbuff.c (grub_netbuff_alloc): Ensure proper alignment. - -2011-12-13 Vladimir Serbinenko - - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Change pointer - arithmetic to conserve alignment invariants. - -2011-12-13 Vladimir Serbinenko - - * include/grub/efiemu/efiemu.h (grub_efiemu_get_memory_map): Remove - redundant declaration. - (grub_efiemu_mm_obtain_request): Likewise. - (grub_efiemu_prepare): Likewise. - -2011-12-13 Vladimir Serbinenko - - * include/grub/list.h: Explicitly cast return of grub_bad_type_cast - to match types. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/hfsplus.c (grub_hfsplus_btree_recoffset): Handle the - case of aunaligned recptr. - (grub_hfsplus_read_block): Declare extoverflow as key to ensure - alignment. - (grub_hfsplus_btree_search): Handle unaligned index. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Use grub_get_unaligned16 - to get freetag and skip. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (grub_nilfs2_btree_node): Add zero-size keys - array. - (grub_nilfs2_btree_node_dkeys): Ensure return pointer alignment. - (grub_nilfs2_btree_lookup): Ensure buffer alignment. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/romfs.c (grub_romfs_iterate_dir): Properly align - name for checksum and fix allocation algorithm. - -2011-12-13 Vladimir Serbinenko - - * include/grub/types.h (grub_properly_aligned_t): New type. - (GRUB_PROPERLY_ALIGNED_ARRAY): New macro. - (grub_get_unaligned16): Add explicit casts. - (grub_get_unaligned32): Likewise. - (grub_get_unaligned64): Likewise. - (grub_set_unaligned16): New function. - (grub_set_unaligned32): Likewise. - -2011-12-13 Vladimir Serbinenko - - * grub-core/normal/datetime.c (grub_weekday_names): Make const. - -2011-12-13 Vladimir Serbinenko - - * grub-core/fs/udf.c (read_string): Macroify GRUB_MAX_UTF8_PER_UTF16. - * grub-core/fs/jfs.c (grub_jfs_diropen): Likewise. - * grub-core/fs/fat.c (grub_fat_iterate_dir): Likewise. - -2011-12-13 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c (set_scancodes): Fix preprocessor - conditionals. - -2011-12-13 Vladimir Serbinenko - - * grub-core/kern/emu/main.c (main): Add missing const qualifier. - * grub-core/loader/efi/appleloader.c (devdata): Likewise. - -2011-12-13 Vladimir Serbinenko - - Unify and improve RAID and crypto xor. - - * grub-core/disk/raid.c (grub_raid_block_xor): Removed. All users - changed to grub_crypto_xor - * grub-core/lib/crypto.c (grub_crypto_xor): Moved from here ... - * include/grub/crypto.h (grub_crypto_xor): ... here. Inlined. - Use bigger types when possible. - -2011-12-13 Vladimir Serbinenko - - * grub-core/disk/raid.c (scan_devices): Fix condition. - -2011-12-13 Vladimir Serbinenko - - * grub-core/net/drivers/ieee1275/ofnet.c (bootp_response_properties): - Make name a const ptr. - -2011-12-13 Vladimir Serbinenko - - * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_finddevice): Make - first argument a const pointer. - * grub-core/kern/ieee1275/openfw.c (grub_children_iterate): Likewise. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_finddevice): Update - proto. - (grub_children_iterate): Likewise. - (grub_machine_mmap_iterate): Remove redundant declaration. - -2011-12-13 Vladimir Serbinenko - - * grub-core/commands/acpi.c (grub_acpi_create_ebda) [!x86]: Disable. - (grub_cmd_acpi) [!x86]: Disable EBDA. - -2011-12-13 Vladimir Serbinenko - - Enable UTF8 in gnulib regexp. - - * config.h.in (RE_ENABLE_I18N) [!GRUB_UTIL]: New define. - * grub-core/lib/posix_wrap/ctype.h (islower): Use grub_islower. - (isupper): Use grub_isupper. - (isascii): New inline function. - * grub-core/lib/posix_wrap/wchar.h: Replace dummy with real contents. - * grub-core/lib/posix_wrap/wctype.h: Likewise. - * grub-core/normal/charset.c (grub_utf8_process): New function. - (grub_utf8_to_utf16): Use grub_utf8_process. - (grub_encode_utf8_character): New function. - (grub_ucs4_to_utf8): Use grub_encode_utf8_character. - * include/grub/charset.h (grub_utf8_process): New declaration. - (grub_encode_utf8_character): Likewise. - * include/grub/misc.h (grub_islower): New inline function. - (grub_isupper): Likewise. - (grub_strchrsub): Moved down to fix the definitions. - -2011-12-13 Vladimir Serbinenko - - * grub-core/bus/usb/ohci.c (grub_ohci_check_transfer): Add an unsigned - specification. - -2011-12-13 Vladimir Serbinenko - - * include/grub/loader.h (grub_loader_register_preboot_hook): - Use struct preboot * and not void * for handle. All users updated. - (grub_loader_unregister_preboot_hook): Likewise. - -2011-12-12 Vladimir Serbinenko - - * include/grub/charset.h (GRUB_MAX_UTF8_PER_UTF16): New const. - * grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Change to - UTF-16-BE. All users updated. - (grub_hfsplus_cmp_catkey): Fix unicode handling. - (grub_hfsplus_iterate_dir): Likewise. - (grub_hfsplus_label): Likewise. - -2011-12-12 Vladimir Serbinenko - - * grub-core/disk/ahci.c (grub_ahci_pciinit): Fix compat condition. - -2011-11-30 Vladimir Serbinenko - - Add missing const qualifiers. - - * grub-core/commands/i386/pc/sendkey.c (keysym): Add missing const. - * grub-core/commands/lspci.c (grub_pci_classname): Likewise. - * grub-core/commands/menuentry.c (hotkey_aliases): Likewise. - * grub-core/disk/lvm.c (grub_lvm_getvalue): Likewise. - (grub_lvm_check_flag): Likewise. - * grub-core/efiemu/i386/coredetect.c - (grub_efiemu_get_default_core_name): Likewise - * grub-core/efiemu/main.c (grub_efiemu_autocore): Likewise. - * grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Likewise. - * grub-core/fs/ntfs.c (fixup): Likewise. - * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Likewise. - * grub-core/fs/zfs/zfs.c (decomp_entry): Likewise. - (fzap_lookup): Likewise. - (zap_lookup): Likewise. - * grub-core/gnulib/regcomp.c (init_dfa): Likewise. - * grub-core/lib/legacy_parse.c (check_option): Likewise. - * grub-core/lib/posix_wrap/langinfo.h (nl_langinfo): Likewise. - * grub-core/loader/i386/bsd.c (grub_bsd_add_meta): Likewise. - (grub_freebsd_add_meta_module): Likewise. - (grub_cmd_freebsd_module): Likewise. - * grub-core/loader/i386/xnu.c (tbl_alias): Likewise. - * grub-core/loader/xnu.c (grub_xnu_register_memory): Likewise. - (grub_xnu_writetree_get_size): Likewise. - (grub_xnu_writetree_toheap_real): Likewise. - (grub_xnu_find_key): Likewise. - (grub_xnu_create_key): Likewise. - (grub_xnu_create_value): Likewise. - (grub_xnu_register_memory): Likewise. - (grub_xnu_check_os_bundle_required): Likewise. - (grub_xnu_scan_dir_for_kexts): Likewise. - (grub_xnu_load_kext_from_dir): Likewise. - * grub-core/normal/color.c (color_list): Likewise. - * grub-core/normal/completion.c (current_word): Likewise. - * grub-core/normal/menu_entry.c (insert_string): Likewise. - * grub-core/term/serial.c (grub_serial_find): Likewise. - * grub-core/term/tparm.c (grub_terminfo_tparm): Likewise. - * include/grub/efiemu/efiemu.h (grub_efiemu_get_default_core_name): - Likewise. - * include/grub/i386/bsd.h (grub_bsd_add_meta): Likewise. - (grub_freebsd_add_meta_module): Likewise. - * include/grub/lib/arg.h (grub_arg_option): Likewise. - * include/grub/net.h (grub_net_card_driver): Likewise. - (grub_net_card): Likewise. - (grub_net_app_protocol): Likewise. - * include/grub/parttool.h (grub_parttool_argdesc): Likewise. - * include/grub/serial.h (grub_serial_find): Likewise. - * include/grub/tparm.h (grub_terminfo_tparm): Likewise. - * include/grub/xnu.h (grub_xnu_create_key): Likewise. - (grub_xnu_create_value): Likewise. - (grub_xnu_find_key): Likewise. - (grub_xnu_scan_dir_for_kexts): Likewise. - (grub_xnu_load_kext_from_dir): Likewise. - - * include/grub/zfs/zio_checksum.h (zio_checksum_t): Moved from here ... - * grub-core/fs/zfs/zfs.c (zio_checksum_t): ...here. - * include/grub/zfs/zio_checksum.h (zio_checksum_info): - Moved from here ... - * grub-core/fs/zfs/zfs.c (zio_checksum_info): ... here. Added missing const. - -2011-11-28 Colin Watson - - * util/getroot.c (find_root_device_from_libzfs): Use xasprintf. - -2011-11-27 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (recovery): Fix spelling. - (read_device): Fix size calculation. - -2011-11-25 Robert Millan - - * util/getroot.c [HAVE_LIMITS_H]: Include `'. - (find_root_device_from_libzfs): Add zpool output parser to be used - as fallback when libzfs isn't available. - -2011-11-25 Seth Goldberg - - * po/Makefile.in.in: Add missing escape-continuation. - -2011-11-25 Vladimir Serbinenko - - * grub-core/fs/cpio.c (grub_cpio_dir): Handle subdirs correctly. - -2011-11-16 Vladimir Serbinenko - - * grub-core/kern/dl.c (grub_dl_load_segments): Fix alignment handling. - -2011-11-16 Vladimir Serbinenko - - * grub-core/kern/dl.c (grub_dl_unload): Fix freeing segments. - -2011-11-16 Vladimir Serbinenko - - * grub-core/kern/x86_64/efi/callwrap.S: Fix the comment. - -2011-11-14 Vladimir Serbinenko - - * grub-core/lib/adler32.c: Add missing license specification. - * grub-core/lib/crc64.c: Likewise. - * grub-core/loader/i386/pc/plan9.c: Likewise. - * grub-core/partmap/plan.c: Likewise. - -2011-11-13 Lubomir Kundrak - - Add facility to debug GRUB with gdb under qemu. - - * grub-core/gdb_grub.in: New file. - * grub-core/gmodule.pl.in: Likewise. - * grub-core/Makefile.core.def (gmodule.pl): New script. - (gdb_grub): Likewise. - -2011-11-13 Vladimir Serbinenko - - * util/grub-mount.c (argp_parser): Accept relative pathes. - * util/grub-fstest.c (argp_parser): Likewise. - -2011-11-13 Vladimir Serbinenko - - Plan9 support. - - * Makefile.util.def (libgrubmods): Add - grub-core/partmap/plan.c. - * docs/grub.texi: Notice Plan9 support. - * grub-core/Makefile.core.def (plan9): New module. - (part_plan): Likewise. - * grub-core/loader/i386/pc/plan9.c: New file. - * grub-core/partmap/plan.c: Likewise. - * include/grub/msdos_partition.h (GRUB_PC_PARTITION_TYPE_PLAN9): New - define. - (GRUB_PC_PARTITION_TYPE_LINUX_SWAP): Likewise. - * include/grub/mm.h (grub_extend_alloc): New inline function. - -2011-11-13 Vladimir Serbinenko - - Make Reed-Solomon faster by using power of generator representation of - GF(256)*. - - * grub-core/lib/reed_solomon.c (grub_uint16_t) [TEST]: Removed. - (gf_double_t): Likewise. - (gf_invert): Removed. - (gf_powx): New array. - (gf_powx_inv): Likewise. - (scratch): Move higher. - (gf_reduce): Removed. - (gf_mul): Use powx. - (gf_invert): Likewise. - (init_inverts): Replaced with ... - (init_powx): ...this. All users updated. - (pol_evaluate): Replace multiplications with additions. - (rs_encode): Likewise. - (gauss_eliminate): Call gf_invert. - (grub_reed_solomon_add_redundancy): Call init_powx. - (grub_reed_solomon_recover): Call init_powx unconditionally. - -2011-11-12 Vladimir Serbinenko - - * grub-core/partmap/gpt.c (gpt_partition_map_embed): Fix spelling. - -2011-11-12 Vladimir Serbinenko - - * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restore - disk->partiton for safety. - -2011-11-12 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): - Fix a memory leak. - (grub_util_biosdisk_get_grub_dev): Add a useful debug info. - -2011-11-12 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (find_system_device): Fix a memory leak. - -2011-11-12 Vladimir Serbinenko - - * include/grub/lvm.h (grub_lvm_pv): Correct start type. - -2011-11-12 Vladimir Serbinenko - - Fix spaces handling in proc/self/mountinfo. - - * util/getroot.c (unescape): New function. - (grub_find_root_device_from_mountinfo): Use unescape. - -2011-11-12 Vladimir Serbinenko - - Support ZFS embedding. - - * grub-core/fs/zfs/zfs.c (grub_zfs_embed): New function. - (grub_zfs_fs): Register grub_zfs_embed. - -2011-11-12 Vladimir Serbinenko - - Fix MIPS compilation. - - * grub-core/boot/mips/startup_raw.S: Use GRUB_DECOMPRESSOR_* - * include/grub/offsets.h: Rename decompressor fields from - GRUB_KERNEL_* to GRUB_DECOMPRESSOR_*. - * util/grub-mkimage.c (image_targets): Use new names. - -2011-11-12 Vladimir Serbinenko - - Defer multiboot device parsing until we're in compressed part. - - * grub-core/boot/i386/pc/lnxboot.S: Remove setting dos_part and - bsd_part. setdevice has fallen into disuse. - * grub-core/boot/i386/pc/startup_raw.S (dos_part): Removed. - (bsd_part): Likewise. - (boot_dev): New variable. - (multiboot_trampoline): Don't parse multiboot device. - Pass multiboot device in %edx. - * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Parse - grub_boot_device. - * grub-core/kern/i386/pc/init.c (grub_machine_get_bootlocation): - Likewise. - * grub-core/kern/i386/pc/startup.S: Save edx. - (grub_boot_drive): Removed. - (grub_install_dos_part): Likewise. - (grub_install_bsd_part): Likewise. - (grub_boot_device): New variable. - * include/grub/i386/pc/kernel.h (grub_install_dos_part): Removed. - (grub_install_bsd_part): Likewise. - (grub_boot_drive): Likewise. - (grub_boot_device): New variable. - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): - Removed. - (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. - (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Moved lower. - (GRUB_KERNEL_MACHINE_INSTALL_BSD_PART): Removed. - (GRUB_KERNEL_MACHINE_INSTALL_DOS_PART): Likewise. - * util/grub-install.in: Remove redundant condition. - -2011-11-12 Vladimir Serbinenko - - Fix bug introduced by previous commit. - - * grub-core/boot/i386/pc/startup_raw.S: Compute RS start correctly. - -2011-11-12 Vladimir Serbinenko - - Use decompressors framework on i386-pc. It increases core size - by 46 bytes but improves compatibility and maintainability. - - * grub-core/Makefile.core.def (lzma_decompress): New image. - (kernel): Add i386_pc_ldflags. - * grub-core/kern/i386/pc/startup.S: Move intial part to .. - * grub-core/boot/i386/pc/startup_raw.S: ... here. Pass pointers - to real_to_prot, prot_to_real and device info. - * include/grub/offsets.h: Renamed decompressor offsets. - * util/grub-mkimage.c (grub_compression_t): New cmpression lzma. - (image_target_desc): Remove raw_size and rename decompressor fields. - (compress_kernel): Handle lzma. - (generate_image): Handle decompressors on i386-pc. - -2011-11-12 Vladimir Serbinenko - - * configure.ac: Add -fno-asynchronous-unwind-tables. - -2011-11-12 Vladimir Serbinenko - - Move assembly code to C by using intwrap. It increases core size - by 88 bytes but improves compatibility and maintainability. - - * grub-core/kern/i386/pc/startup.S (grub_console_putchar): Moved to ... - * grub-core/term/i386/pc/console.c (grub_console_putchar_real): - ... here. Translated to C. - * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Moved to ... - * grub-core/term/i386/pc/console.c (grub_console_getkey): - ... here. Translated to C. - * grub-core/kern/i386/pc/startup.S (grub_console_getxy): Moved to ... - * grub-core/term/i386/pc/console.c (grub_console_getxy): - ... here. Translated to C. - * grub-core/kern/i386/pc/startup.S (grub_console_gotoxy): Moved to ... - * grub-core/term/i386/pc/console.c (grub_console_gotoxy): - ... here. Translated to C. - * grub-core/kern/i386/pc/startup.S (grub_console_cls): Moved to ... - * grub-core/term/i386/pc/console.c (grub_console_cls): - ... here. Translated to C. - * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Moved to .. - * grub-core/term/i386/pc/console.c (grub_console_setcursor): - ... here. Translated to C. - * grub-core/kern/i386/pc/startup.S (grub_get_rtc): Moved to .. - * grub-core/kern/i386/pc/init.c (grub_get_rtc): ... here. - Translated to C. - * grub-core/term/i386/pc/console.c (int10_9): New function. - (grub_console_putchar): Likewise. - * include/grub/i386/pc/console.h: Removed the not anymore shared - functions. - -2011-11-12 Vladimir Serbinenko - - Move grub_chainloader_real_boot out of the kernel. - - * grub-core/Makefile.am: Remove machine/loader.h. - * grub-core/kern/i386/pc/startup.S (grub_chainloader_real_boot): - Removed. - * grub-core/lib/i386/relocator.c (grub_relocator16_esi): New extern - variable. - (grub_relocator16_keep_a20_enabled): Likewise. - (grub_relocator16_boot): Fill new variables. - * grub-core/lib/i386/relocator16.S: Add gate a20 handling. - * grub-core/loader/i386/pc/chainloader.c (grub_chainloader_boot): Use - relocator. - (grub_chainloader_unload): Likewise. - (grub_chainloader_cmd): Likewise. - * include/grub/i386/pc/loader.h: Removed. - * include/grub/i386/relocator.h (grub_relocator16_state): Add a20 - and esi. All initialisers updated. - -2011-11-12 Vladimir Serbinenko -2011-11-12 Colin Watson - - * Makefile.util.def (grub-mount): New util. - * .bzrignore: Add grub-mount. - * configure.ac: Check for fuse and enable grub-mount if available. - * docs/man/grub-mount.h2m: New file. - * util/grub-mount.c: Likewise. - -2011-11-11 Vladimir Serbinenko - - * grub-core/commands/efi/fixvideo.c: Gettextize. - * grub-core/commands/hashsum.c: Likewise. - * grub-core/commands/i386/cmostest.c: Likewise. - * grub-core/commands/i386/pc/drivemap.c: Likewise. - * grub-core/commands/i386/pc/lsapm.c: Likewise. - * grub-core/commands/i386/pc/sendkey.c: Likewise. - * grub-core/commands/lsmmap.c: Likewise. - * grub-core/commands/menuentry.c: Likewise. - * grub-core/commands/mips/loongson/lsspd.c: Likewise. - * grub-core/commands/setpci.c: Likewise. - * grub-core/loader/i386/bsd.c: Likewise. - * grub-core/loader/i386/linux.c: Likewise. - * util/getroot.c: Likewise. - * util/grub-editenv.c: Likewise. - * util/grub-fstest.c: Likewise. - * util/grub-mkfont.c: Likewise. - * util/grub-mkimage.c: Likewise. - * util/grub-mkpasswd-pbkdf2.c: Likewise. - * util/grub-pe2elf.c: Likewise. - * util/grub-probe.c: Likewise. - * util/grub-setup.c: Likewise. - * util/ieee1275/ofpath.c: Likewise. - * util/misc.c: Likewise. - * util/raid.c: Likewise. - -2011-11-11 Robert Millan - - * util/getroot.c (grub_util_get_geom_abstraction): Remove - __attribute__((unused)) from `os_dev', which *is* being used. - -2011-11-11 Vladimir Serbinenko - - * include/grub/dl.h (GRUB_ARCH_DL_TRAMP_SIZE) [__ia64__]: Add back - forgotten define. - (GRUB_ARCH_DL_GOT_ALIGN) [__ia64__]: Redefine in terms of - GRUB_IA64_DL_GOT_ALIGN. - (GRUB_ARCH_DL_TRAMP_ALIGN) [__ia64__]: Redefine in terms of - GRUB_IA64_DL_TRAMP_ALIGN. - -2011-11-11 Vladimir Serbinenko - - Replace grub_fatal with normal errors in i386 linux loader. - - * grub-core/loader/i386/linux.c (find_efi_mmap_size): Return 0 on error. - (allocate_pages): Check find_efi_mmap_size return value. - (grub_e820_add_region): Return error. - (grub_linux_boot): Check mmap return value. - -2011-11-11 Vladimir Serbinenko - - * grub-core/commands/acpihalt.c: Gettextized. - * grub-core/commands/cacheinfo.c: Likewise. - * grub-core/commands/cmp.c: Likewise. - * grub-core/commands/efi/loadbios.c: Likewise. - * grub-core/commands/gptsync.c: Likewise. - * grub-core/commands/ieee1275/suspend.c: Likewise. - * grub-core/commands/legacycfg.c: Likewise. - * grub-core/commands/memrw.c: Likewise. - * grub-core/commands/minicmd.c: Likewise. - * grub-core/commands/parttool.c: Likewise. - * grub-core/commands/time.c: Likewise. - * grub-core/commands/videoinfo.c: Likewise. - * grub-core/disk/geli.c: Likewise. - * grub-core/disk/i386/pc/biosdisk.c: Likewise. - * grub-core/disk/luks.c: Likewise. - * grub-core/disk/lvm.c: Likewise. - * grub-core/font/font_cmd.c: Likewise. - * grub-core/fs/zfs/zfscrypt.c: Likewise. - * grub-core/fs/zfs/zfsinfo.c: Likewise. - * grub-core/gfxmenu/view.c: Likewise. - * grub-core/kern/emu/hostdisk.c: Likewise. - * grub-core/kern/emu/main.c: Likewise. - * grub-core/kern/emu/misc.c: Likewise. - * grub-core/kern/emu/mm.c: Likewise. - * grub-core/kern/mips/arc/init.c: Likewise. - * grub-core/kern/mips/loongson/init.c: Likewise. - * grub-core/kern/partition.c: Likewise. - * grub-core/lib/i386/halt.c: Likewise. - * grub-core/lib/mips/arc/reboot.c: Likewise. - * grub-core/lib/mips/loongson/reboot.c: Likewise. - * grub-core/loader/i386/pc/chainloader.c: Likewise. - * grub-core/loader/i386/xnu.c: Likewise. - * grub-core/loader/multiboot.c: Likewise. - * grub-core/net/bootp.c: Likewise. - * grub-core/net/net.c: Likewise. - * grub-core/normal/term.c: Likewise. - * grub-core/partmap/bsdlabel.c: Likewise. - * grub-core/parttool/msdospart.c: Likewise. - * grub-core/term/gfxterm.c: Likewise. - * grub-core/term/terminfo.c: Likewise. - * grub-core/video/i386/pc/vbe.c: Likewise. - * util/grub-menulst2cfg.c: Likewise. - * util/grub-mkdevicemap.c: Likewise. - * util/grub-mklayout.c: Likewise. - * util/grub-mkrelpath.c: Likewise. - * util/grub-script-check.c: Likewise. - * util/ieee1275/grub-ofpathname.c: Likewise. - * util/resolve.c: Likewise. - -2011-11-11 Vladimir Serbinenko - - Support %1$d syntax. - - * tests/printf_unit_test.c: New file. - * Makefile.util.def (printf_test): New test. - * grub-core/kern/misc.c (grub_vsnprintf_real): Support %1$d syntax. - -2011-11-11 Vladimir Serbinenko - - * grub-core/hook/datehook.c (grub_read_hook_datetime): Small stylistic - fix. - -2011-11-11 Vladimir Serbinenko - - * grub-core/efiemu/mm.c (grub_efiemu_mmap_fill): Change printf into - dprintf. - * grub-core/font/font.c (grub_font_load): Likewise. - -2011-11-11 Vladimir Serbinenko - - * util/grub-macho2img.c: Add comment concerning gettext. - * grub-core/lib/legacy_parse.c: Likewise. - -2011-11-11 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vprintf): Add missing va_end. - (grub_xvasprintf): Likewise. - -2011-11-11 Vladimir Serbinenko - - Add const keyword to grub_env_get and gettextize week days. - - * grub-core/hook/datehook.c (grub_datetime_names): Make const. - (grub_read_hook_datetime): Return const char *. - * grub-core/kern/env.c (grub_env_get): Return const char *. All users - updated. - * grub-core/normal/datetime.c (grub_weekday_names): Make const. - Mark for gettext. - (grub_get_weekday_name): Return const char *. Call gettext. - * grub-core/script/argv.c (grub_script_argv_append): Receive const - char * and len as the argument. All users updated. - (grub_script_argv_split_append): Receive const char *. - * include/grub/datetime.h (grub_get_weekday_name): Update proto. - * include/grub/env.h (grub_env_get): Likewise. - (grub_env_read_hook_t): Return const char *. - * include/grub/script_sh.h (grub_script_argv_append): Update proto. - (grub_script_argv_split_append): Likewise. - -2011-11-11 Vladimir Serbinenko - - * grub-core/normal/main.c (grub_normal_execute): Remove leftover call. - -2011-11-11 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_strstr): Moved from here ... - * include/grub/misc.h (grub_strstr): ... here. Make static and inline. - -2011-11-11 Vladimir Serbinenko - - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_set_property): - Fix prototype. - -2011-11-11 Vladimir Serbinenko - - Fix mips compilation. - - * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec): Restrict hash_id to - normal decoder. - (hashes): Use in embed decoder as well (for sizes). - (dec_stream_header): Fix embed decompressor logic. - (dec_stream_footer): Likewise. - -2011-11-11 Vladimir Serbinenko - - * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Issue - an error and not a fatal on unrecognised relocation types. - -2011-11-11 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): - Issue error rather than printf on unknown arguments. - -2011-11-11 Vladimir Serbinenko - - * grub-core/kern/ieee1275/ieee1275.c (grub_ieee1275_set_property): - Make buf a const. - -2011-11-11 Vladimir Serbinenko - - * grub-core/fs/zfs/zfscrypt.c (GRUB_MOD_INIT), (GRUB_MOD_FINI): - Fix module name. - -2011-11-11 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (grub_ntfs_read_symlink): Stylistic fix. Remove - leftover debug printf. - -2011-11-11 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_embed): Spelling fix. - -2011-11-11 Vladimir Serbinenko - - * grub-core/efiemu/main.c (grub_efiemu_register_configuration_table): - A stylistic fix. - -2011-11-11 Vladimir Serbinenko - - * grub-core/commands/probe.c (grub_cmd_probe): Fix error message. - -2011-11-10 Shea Levy - - Allow all modules to perform serial IO - - * grub-core/term-serial.c (grub_serial_find): Remove static qualifier - * include/grub/serial.h (grub_serial_port_configure): New inline - function. - (grub_serial_port_fetch): Likewise. - (grub_serial_port_put): Likewise. - (grub_serial_port_fini): Likewise. - (grub_serial_find): New proto. - -2011-11-10 Vladimir Serbinenko - - Put symlink at the end of the node and fix a potential - memory corruption. - - * grub-core/fs/iso9660.c (grub_fshelp_node): New field have_symlink. - Make symlink into an array. - (set_rockridge): Set have_symlink and alloc_dirents. - (grub_iso9660_read_symlink): Use new layout. - (grub_iso9660_iterate_dir): Fix memory corruption. - Use new layout. - (grub_iso9660_dir): Set have_symlink. - (grub_iso9660_open): Likewise. - -2011-11-10 Vladimir Serbinenko - - Remove local keyword. - - * util/grub-mkconfig_lib.in (version_test_numeric): Remove local. - (version_test_gt): Likewise. - (version_find_latest): Likewise. - (gettext_printf): Likewise. - * util/grub.d/10_windows.in (get_os_name_from_boot_ini): Likewise. - -2011-11-10 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (zfs_mount): Fix spurious warning. - -2011-11-10 Vladimir Serbinenko - - Fix ZFS memory and resource leaks. - - * grub-core/fs/zfs/zfs.c (fill_vdev_info_real): New paramter inserted. - All users updated. - Free type on exit. - (fill_vdev_info): New parameter inserted. All users updated. - (check_pool_label): Likewise. - (scan_disk): Likewise. - (scan_devices): Close non-inserted disks. - (fzap_iterate): Free l. - (unmount_device): Free children descripto memory. - -2011-11-10 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix grub_strncat - argument (access out of bounds). - -2011-11-10 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Fix RAID10 logic for - >= 6 drives. - -2011-11-10 Vladimir Serbinenko - - * include/grub/i386/netbsd_bootinfo.h (grub_netbsd_btinfo_bootwedge): - Fix declaration. - -2011-11-09 Vladimir Serbinenko - - Fix several memory leaks. - - * grub-core/fs/btrfs.c (grub_btrfs_dir): Fix memory leak. - * grub-core/fs/cpio.c (grub_cpio_find_file): Likewise. - (grub_cpio_dir): Likewise. - * grub-core/fs/fat.c (grub_fat_label): Likewise. - * grub-core/fs/jfs.c (grub_jfs_label): Likewise. - * grub-core/fs/romfs.c (grub_romfs_close): Likewise. - (grub_romfs_label): Likewise. - * grub-core/fs/squash4.c (squash_mount): Use zalloc for safety. - (squash_unmount): New function. - (grub_squash_dir): Fix memory leak. - (grub_squash_open): Likewise. - (grub_squash_read): Likewise. - (grub_squash_mtime): Likewise. - * grub-core/fs/xfs.c (grub_xfs_open): Likewise. - * grub-core/fs/zfs/zfs.c (check_pool_label): Likewise. - * util/grub-fstest.c (fstest): Likewise. - -2011-11-09 Vladimir Serbinenko - - * include/grub/misc.h (grub_strncat): Fix the order of conditionals to - avoid accessing beyond the array. - -2011-11-09 Vladimir Serbinenko - - * configure.ac: Add missing -mXX to TARGET_CPPFLAGS. - -2011-11-09 Vladimir Serbinenko - - Several AFFS fixes. - - * grub-core/fs/affs.c (grub_affs_bblock): Replace flags with version. - (GRUB_AFFS_FLAG_FFS): Removed. - (GRUB_AFFS_SYMLINK_SIZE): Likewise. - (GRUB_AFFS_FILETYPE_DIR): Make positive and unsigned. - (GRUB_AFFS_FILETYPE_DIR), (GRUB_AFFS_FILETYPE_REG): Fix a mix-up. - (grub_fshelp_node): Make block 32-bit. - Add block_cache and last_block_cache. - (grub_affs_read_block): Fill and use block cache. - (grub_affs_read_file): Removed. - (grub_affs_mount): Zero-fill node. Fix version check. Don't reread - boot block. - (grub_affs_read_symlink): Fix symlink size. Add a \0 at the end for - safety. - (grub_affs_iterate_dir): Use more appropriate types. Zero-fill allocated - space. - (grub_affs_close): Free block cache. - (grub_affs_read): Use grub_fshelp_read_file directly. - -2011-11-08 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (read_dva): Issue an error if read failed - with no error set. - -2011-11-08 Vladimir Serbinenko - - * grub-core/lib/LzmaEnc.c (LzmaEnc_CodeOneBlock): Remove set but not - used variable. - * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): - Likewise. - -2011-11-08 Vladimir Serbinenko - - Fix potential problem with calling zfs_to_cpu and cpu_to_be in a row. - - * grub-core/fs/zfs/zfscrypt.c (grub_zfs_decrypt_real): Use explicit - byteswap when needed. - -2011-11-08 Vladimir Serbinenko - - Fix FreeBSD compilation. - - * grub-core/disk/geli.c (GRUB_MD_SHA256) [GRUB_UTIL]: Redefine in a way - to avoid circular dependency. - (GRUB_MD_SHA512) [GRUB_UTIL]: Likewise. - * util/getroot.c (grub_util_follow_gpart_up): Move from here... - * grub-core/kern/emu/hostdisk.c (+grub_util_follow_gpart_up): ... here. - -2011-11-08 Vladimir Serbinenko - - Fix ZFS crypto error types. - - * grub-core/fs/zfs/zfscrypt.c (grub_ccm_decrypt): Fix return type. - (grub_gcm_decrypt): Likewise. - (grub_zfs_load_key_real): Fix error code type. Handle possible error - from PBKDF2. - -2011-11-08 Vladimir Serbinenko - - Illumos support. - - * Makefile.util.def (10_illumos): New script. - * configure.ac: Set COND_HOST_ILLUMOS. - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__sun__]: - Support Illumos calls. - (find_partition_start) [__sun__]: Likewise. - (convert_system_partition_to_system_disk) [__sun__]: Likewise. - (device_is_wholedisk) [__sun__]: Handle Illumos naming scheme. - (grub_util_biosdisk_get_grub_dev) [__sun__]: Handle Illumos. - * util/getroot.c (find_root_device_from_libzfs) [__sun__]: Return raw - device. - * util/grub-probe.c (probe) [__sun__]: Do character check. - * util/grub.d/10_illumos.in: New file. - -2011-11-08 Vladimir Serbinenko - - Support escaped commas in hostdisk. - - * grub-core/kern/emu/hostdisk.c (unescape_cmp): New function. - (find_grub_drive): Use unescape_cmp. - (make_device_name): Escape commas. - -2011-11-08 Vladimir Serbinenko - - * util/grub.d/10_kfreebsd.in: Use ${grub_mkrelpath} not grub-mkrelpath. - -2011-11-08 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (zap_iterate): Remove set but not used - variable. - -2011-11-08 Vladimir Serbinenko - - Support trampoline jumps on powerpc. - - * grub-core/kern/dl.c (grub_dl_load_segments) [__powerpc__]: Follow - __ia64__ path. - (grub_dl_load_segments): Set mod->sz. - (grub_dl_flush_cache): Flush whole space occupied by module, not just - segments. - * grub-core/kern/ia64/dl.c (nopm): Make const while on it. - (jump): Likewise. - * grub-core/kern/powerpc/dl.c (grub_arch_dl_get_tramp_got_size): New - function. - (trampoline): New struct. - (trampoline_template): New const. - (grub_arch_dl_relocate_symbols): Create trampolines on overflow. - * include/grub/dl.h (grub_dl): Add sz element. - [__powerpc__]: Follow __ia64__. - (GRUB_ARCH_DL_TRAMP_ALIGN): Define on ppc. - (GRUB_ARCH_DL_GOT_ALIGN): Likewise. - (GRUB_ARCH_DL_TRAMP_SIZE): Likewise. - (grub_arch_dl_get_tramp_got_size) [__powerpc__]: New proto. - -2011-11-06 Vladimir Serbinenko - - ZFS crypto support. - - * Makefile.util.def (libgrubmods): Add grub-core/fs/zfs/zfscrypt.c. - * grub-core/Makefile.core.def (zfscrypt): New module. - * grub-core/fs/zfs/zfs.c (subvolume): New structure. - (grub_zfs_data): Replace mdn with subvol. Put case_insensitivity inside - it. All users updated. - (grub_zfs_decrypt): New var. - (grub_zfs_load_key): Likewise. - (zio_checksum_functions): Add SHA256+MAC. - (zio_checksum_verify): Handle incomplete comparison due to MAC. - (zio_read): Handle encrypted blocks. - (zap_verify): Remove incorrect check. - (fzap_iterate): Handle non-standard fzap. - (zap_iterate): Likewise. - (zap_iterate_u64): New function. - (dnode_get_fullpath): Load keys. - * grub-core/fs/zfs/zfscrypt.c: New file. - * grub-core/lib/crypto.c (grub_crypto_cipher_close): Removed. - (grub_crypto_ecb_encrypt): Make input const. - * include/grub/crypto.h (grub_crypto_cipher_close): Inline. - (grub_crypto_ecb_encrypt): Make input const. - (GRUB_CIPHER_AES): New macro. - * include/grub/zfs/dmu.h (dmu_object_type): Add DMU_OT_DSL_KEYCHAIN. - * include/grub/zfs/dsl_dir.h (dsl_dir_phys): Add keychain. - * include/grub/zfs/spa.h (grub_zfs_endian): Moved from here ... - * include/grub/zfs/zfs.h (grub_zfs_endian): ... here. Added GURB_ZFS_ - prefix. All users updated. - (grub_zfs_add_key): New proto. - (grub_zfs_decrypt): Likewise. - (grub_zfs_load_key): Likewise. - * include/grub/zfs/zio.h (zio_checksum): Add SHA256+MAC. - * util/grub-fstest.c (options): Add -K option. - (argp_parser): Likewise. - -2011-11-05 Vladimir Serbinenko - - Support zle compression on ZFS. - - * grub-core/fs/zfs/zfs.c (zle_decompress): New function. - (decomp_table): Add zle. - * include/grub/zfs/zio.h (zio_compress): Add zle. - -2011-11-05 Vladimir Serbinenko - - Support BtrFS embedding. - - * grub-core/fs/btrfs.c (grub_btrfs_embed) [GRUB_UTIL]: New function. - (grub_btrfs_fs) [GRUB_UTIL]: Set embed. - * include/grub/fs.h (grub_fs) [GRUB_UTIL]: New field embed. - * util/grub-setup.c (setup): Use fs embedding if available. - Add additional sanity check. - -2011-11-05 Vladimir Serbinenko - - * util/grub-install.in: Fix condition for config_opt. - -2011-11-04 Vladimir Serbinenko - - Support third redundancy strip on raidz3. - - * grub-core/fs/zfs/zfs.c (recovery): Add Gauss for general case. - Return error on singularity. All users updated. - (read_device): Don't stop on 3rd failure on raidz3. - -2011-11-04 Vladimir Serbinenko - - Support case-insensitive ZFS subvolumes. - - * grub-core/fs/zfs/zfs.c (mzap_lookup): New parameter case_insensitive. - All users updated. - (zap_hash): Likewise. - (name_cmp): New function. - (zap_leaf_array_equal): New parameter case_insensitive. - All users updated. - (zap_leaf_lookup): Likewise. - (fzap_lookup): Likewise. - (zap_lookup): Likewise. - (dnode_get_path): New parameter case_insensitive. Retrieve case - sensitiviness of a volume. All users updated. - (dnode_get_fullpath): New parameter case_insensitive. - All users updated. - (grub_zfs_dir): Set info.case_insensitiveness. - -2011-11-04 Vladimir Serbinenko - - Support second redundancy strip on raidz(2,3). - - * grub-core/fs/zfs/zfs.c (powx): New array. - (powx_inv): Likewise. - (poly): New const. - (xor_out): New function. - (gf_mul): Likewise. - (recovery): Likewise. - (read_device): Use second redundancy strip. - -2011-11-04 Vladimir Serbinenko - - Use a power of generator representation of GF(256) multiplication group - to save space time and complexity. - - * grub-core/disk/raid6_recover.c (raid6_table1): Removed. - (raid6_table2): Likewise. - (powx): New array. - (powx_inv): Likewise. - (poly): New const. - (grub_raid_block_mul): Replace with ... - (grub_raid_block_mulx): ...this. - (grub_raid6_init_table): Rewritten. - (grub_raid6_recover): Use power of generator representation. - -2011-11-04 Vladimir Serbinenko - - * grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector - for the right device. - -2011-11-04 Vladimir Serbinenko - - * include/grub/kernel.h (grub_module_header): Make type into uint32 as - expected by grub-mkimage and it's more clear since there is no implicit - padding. - -2011-11-04 Vladimir Serbinenko - - * grub-core/disk/raid.c (scan_devices): Don't derference NULL on whole - disk. - * grub-core/disk/lvm.c (do_lvm_scan): Likewise. - -2011-11-03 Philipp Matthias Hahn - - * util/grub-mkrescue.in: Fix handling xorriso option. - -2011-11-03 Vladimir Serbinenko - - * grub-core/gettext/gettext.c (grub_gettext_init_ext): Exit if local is - NULL. - -2011-11-03 crocket - - * util/grub.d/10_linux.in: Add Slackware initrd naming. - -2011-11-03 Vladimir Serbinenko - - XZ CRC64 and SHA256 support. - - * Makefile.util.def (libgrubmods): Add crc64.c. - * grub-core/Makefile.core.def (crc64): New module. - * grub-core/lib/crc64.c: New file. - * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_hash) - [!GRUB_EMBED_DECOMPRESSOR]: Rename crc32_context to hash_context. - Fix the type. - (MAX_HASH_SIZE): New define. - (xz_dec) [!GRUB_EMBED_DECOMPRESSOR]: Add generic hash fields. - (dec_block) [!GRUB_EMBED_DECOMPRESSOR]: Handle non-crc32 hashes. - (index_update) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. - (dec_index) [!GRUB_EMBED_DECOMPRESSOR]: Likewise. - (crc32_validate) [!GRUB_EMBED_DECOMPRESSOR]: Rename to ... - (hash_validate) [!GRUB_EMBED_DECOMPRESSOR]: ... this. - Handle non-crc32 hashes. - (hashes) [!GRUB_EMBED_DECOMPRESSOR]: New variable. - (dec_stream_header): Handle non-crc32 hashes. - (dec_stream_footer): Likewise. - (dec_block_header): Likewise. - (dec_main): Likewise. - (xz_dec_init): Likewise. - (xz_dec_reset): Likewise. - (xz_dec_end): Likewise. - * util/import_gcry.py: Add CRC64 line. - -2011-11-03 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_mtime) [MODE_UFS2]: Check mtime field - as well. - -2011-11-03 Vladimir Serbinenko - - Make reiserfs label retrieval similar to other *_label functions. - - * grub-core/fs/reiserfs.c (grub_reiserfs_superblock): New field label. - (REISERFS_MAX_LABEL_LENGTH): Removed. - (REISERFS_LABEL_OFFSET): Likewise. - (grub_reiserfs_label): Rewritten. - -2011-11-03 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (grub_nilfs2_mtime): Use correct superblock - field. - -2011-11-03 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (read_device): Support raidz3. - -2011-11-02 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (read_device): Add ability to sustain a single - drive failure on both raidz and raidz2. - -2011-11-02 Vladimir Serbinenko - - Fix RAIDZ(2) for >= 5 devices. - - * grub-core/fs/zfs/zfs.c (read_device): Fix length formula. Remove - asize argument. All users updated. - -2011-11-01 Vladimir Serbinenko - - Fix RAIDZ(2). - - * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New member ashift. - (fill_vdev_info_real): Set ashift. - (read_device): Rewrite RAIDZ part based on reverse engineering. - -2011-10-31 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_extent_read): Add sanity check and - don't report potentially unavialiable fields in debug output. - (find_path): Fix double-free and memory leak. - -2011-10-31 Vladimir Serbinenko - - Read label on UFS1. - - * grub-core/fs/ufs.c (grub_ufs_label): Remove MODE_UFS2 condition. - (grub_ufs_fs): Always set .label. - -2011-10-31 Vladimir Serbinenko - - Use shifts in UFS. - - * grub-core/fs/ufs.c (UFS_LOG_BLKSZ): New macro. - (grub_ufs_data): New field log2_blksz. - (grub_ufs_read_file): Use shifts. - (grub_ufs_mount): Check block size and logarithm it. - -2011-10-31 Vladimir Serbinenko - - * grub-core/fs/ufs.c (grub_ufs_lookup_symlink): Fix handling of - long symlinks. - -2011-10-30 Vladimir Serbinenko - - Handle symlinks and long names on tar and cpio. - - * grub-core/fs/cpio.c (ATTR_TYPE): New definition. - (ATTR_FILE): Likewise. - (ATTR_DIR): Likewise. - (ATTR_LNK): Likewise. - (grub_cpio_data) [MODE_USTAR]: New fields linkname and linkname_alloc. - (grub_cpio_find_file): Fill mode, handle linkname field as well as - L and K entries. - (grub_cpio_mount): Zero-fill data. - (handle_symlink): New function. - (grub_cpio_dir): Handle symlinks. - (grub_cpio_open): Likewise. - (grub_cpio_close) [MODE_USTAR]: Free linkname. - -2011-10-30 Vladimir Serbinenko - - Fix iso9660 filename limitations and fix memory leaks. - - * grub-core/fs/iso9660.c (set_rockridge): Free sua at the end. - (grub_iso9660_iterate_dir): Fix slash handling in symlinks. - -2011-10-30 Vladimir Serbinenko - - Fix JFS file name length limitations. - - * grub-core/fs/jfs.c (grub_jfs_inode): Fix in-place symlink length. - (grub_jfs_diropen): Fix maximum filename length. - (grub_jfs_getent): Fix filename length. - (grub_jfs_lookup_symlink): Fix size checks. - -2011-10-30 Vladimir Serbinenko - - * grub-core/loader/mips/linux.c (loongson_machtypes): Fix fuloong type - string. - -2011-10-30 Vladimir Serbinenko - - Leverage BFS implementation to read AFS. - - * Makefile.util.def (libgrubmods): Add afs.c. - * grub-core/Makefile.core.def (afs): New module - * grub-core/fs/afs.c: New file. - * grub-core/fs/bfs.c [MODE_AFS]: Adapt for AFS. - -2011-10-30 Vladimir Serbinenko - - * grub-core/fs/bfs.c: Macroify and add some necessary sanity checks. - -2011-10-30 Vladimir Serbinenko - - * grub-core/fs/bfs.c: Run indent. - -2011-10-30 Vladimir Serbinenko - - BFS implementation based on the specification. - - * grub-core/fs/bfs.c: New file. - * Makefile.util.def (libgrubmods): Add bfs.c. - * grub-core/Makefile.core.def (bfs): New module. - -2011-10-30 Vladimir Serbinenko - - * util/grub-fstest.c (cmd_cp): Clarify error message. - (cmd_cmp): Likewise. - -2011-10-30 Yves Blusseau - - * po/POTFILES.in: Regenerate because of the removal of afs, afs_be, befs - and befs_be. - -2011-10-29 Vladimir Serbinenko - - Remove afs and befs because of copyright problem. - - * grub-core/fs/afs.c: Removed. - * grub-core/fs/afs_be.c: Removed. - * grub-core/fs/befs.c: Removed. - * grub-core/fs/befs_be.c: Removed. - * Makefile.util.def (libgrubkern): Remove afs, afs_be, befs and befs_be. - * grub-core/Makefile.core.def (afs): Removed. - (afs_be): Likewise. - (befs): Likewise. - (befs_be): Likewise. - -2011-10-28 Vladimir Serbinenko - - Prefer rockridge over Joliet. - - * grub-core/fs/iso9660.c (grub_iso9660_mount): Move rockridge detection - to ... - (set_rockridge): ... here. - (grub_iso9660_mount): Check rockridge on the primary label when - discovering. Ignore Joliet if Rockridge is present. - -2011-10-28 Vladimir Serbinenko - - Use shifts in nilfs2. - - * grub-core/fs/nilfs2.c (LOG_INODE_SIZE): New definition. - (LOG_NILFS_DAT_ENTRY_SIZE): Likewise. - (grub_nilfs2_palloc_entries_per_group): Replace with ... - (grub_nilfs2_log_palloc_entries_per_group): ... this. - (grub_nilfs2_palloc_group): Use shifts and bitmasks. - (grub_nilfs2_entries_per_block): Replaced with ... - (grub_nilfs2_log_entries_per_block_log): ... this. - (grub_nilfs2_blocks_per_group): Replaced with ... - (grub_nilfs2_blocks_per_group_log): ... this. - (grub_nilfs2_blocks_per_desc_block): Replaced with ... - (grub_nilfs2_blocks_per_desc_block_log): ... this. - (grub_nilfs2_palloc_desc_block_offset): Replaced with ... - (grub_nilfs2_palloc_desc_block_offset_log): ... this. - (grub_nilfs2_palloc_entry_offset): Replaced ... - (grub_nilfs2_palloc_entry_offset_log): ... this. Use shifts. - (grub_nilfs2_dat_translate): Use shifts. - (grub_nilfs2_read_inode): Likewise. - (GRUB_MOD_INIT): Ensure that logs are correct. - -2011-10-28 Vladimir Serbinenko - - Use shifts in minix filesystem. - - * grub-core/fs/minix.c (GRUB_MINIX_ZONESZ): Use log_block_size. - (GRUB_MINIX_ZONE2SECT): Likewise. - (grub_minix_data): Replace block_size with log_block_size. - (grub_minix_read_file): Use shifts. - (grub_minix_mount): Check block size and take a logarithm. - -2011-10-28 Vladimir Serbinenko - - Use shifts in squash4. - - * grub-core/fs/squash4.c (grub_squash_data): New field log2_blksz. - (squash_mount): Check block size and take logarithm. - (direct_read): Use shifts. - -2011-10-28 Vladimir Serbinenko - - Correct befs block counting logic. - - * grub-core/fs/afs.c (GRUB_AFS_BLOCKS_PER_DI_RUN): Replaced with... - (GRUB_AFS_LOG_BLOCKS_PER_DI_RUN): ... this. - (GRUB_AFS_BLOCKRUN_LOG_SIZE): New definition. - (grub_afs_read_inode): Use block_shift. - (RANGE_SHIFT): New definition. - (grub_afs_read_block): Account for RANGE_SHIFT, emit errors on - unexpected conditions, use shifts and appropriate types. - (GRUB_MOD_INIT): Check the value of GRUB_AFS_BLOCKRUN_LOG_SIZE. - -2011-10-28 Vladimir Serbinenko - - * grub-core/disk/raid.c (scan_devices): Check partition. - * grub-core/disk/lvm.c (do_lvm_scan): Likewise. - -2011-10-27 Vladimir Serbinenko - - Support BFS (befs) UUID. - - * grub-core/fs/afs.c (grub_afs_inode): Make small_data zero-size. - (grub_afs_small_data_element_header): New struct. - (grub_afs_read_inode): Read complete inode. Fix ino type while on it. - (grub_afs_read_attribute) [MODE_BFS]: New function. - (grub_afs_iterate_dir): Allocate for complete inode. - (grub_afs_mount): Likewise. - (grub_afs_uuid) [MODE_BFS]: New function. - (grub_afs_fs) [MODE_BFS]: Add .uuid. - -2011-10-27 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (read_device): Silence spurious warning. - (zfs_unmount): Fix memory leak. - -2011-10-26 Vladimir Serbinenko - - Support NTFS reparse points. - - * grub-core/fs/ntfs.c (list_file): Set symlink type when appropriate. - (symlink_descriptor): New struct. - (grub_ntfs_read_symlink): New function. - (grub_ntfs_iterate_dir): Use grub_ntfs_read_symlink. - (grub_ntfs_open): Likewise. - -2011-10-26 Vladimir Serbinenko - - * include/grub/ntfs.h: Add GRUB_NTFS_ prefix. All users updated. - -2011-10-26 Vladimir Serbinenko - - fstest xnu_uuid subcommand. - - * grub-core/commands/xnu_uuid.c (libgrubkrn): Add - grub-core/commands/xnu_uuid.c. - * util/grub-fstest.c (CMD_XNU_UUID): New enum value. - (fstest): Handle xnu_uuid. - (options): Document xnu_uuid. - (argp_parser): Parse xnu_uuid. - -2011-10-26 Vladimir Serbinenko - - * grub-core/commands/xnu_uuid.c (grub_cmd_xnu_uuid): Support - -l argument. Add newline at the end if printing. - (GRUB_MOD_INIT): Document -l. - -2011-10-26 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (grub_nilfs2_uuid): Add missing field length. - -2011-10-26 Vladimir Serbinenko - - ZFS multi-device and version 33 support. - - * Makefile.util.def (libgrubkern): Add grub-core/fs/zfs/zfsinfo.c. - * grub-core/fs/zfs/zfs.c (grub_zfs_device_desc): New struct. - (grub_zfs_data): Add multidev-ice-related fields. - (zio_checksum_verify): Zero-pad printed values. Print checksum name. - (dva_get_offset): Make dva const. - (zfs_fetch_nvlist): New function. - (fill_vdev_info_real): Likewise. - (fill_vdev_info): Likewise. - (check_pool_label): Likewise. - (scan_disk): Likewise. - (scan_devices): Likewise. - (read_device): Likewise. - (read_dva): Likewise. - (zio_read_gang): Use read_dva. - (zio_read_data): Likewise. - (zap_leaf_lookup): Add missing endian conversion. - (zap_verify): Add missing endian conversion. All users updated. - (fzap_lookup): Likewise. - (fzap_iterate): Likewise. - (dnode_get_path): Handle SA bonus. - (nvlist_find_value): Make input const. All users updated. - (unmount_device): New function. - (zfs_unmount): Use unmount_device. - (zfs_mount): Use scan_disk. - (zfs_mtime): New function. - (grub_zfs_open): Handle system attributes. - (fill_fs_info): Likewise. - (grub_zfs_dir): Likewise. - (grub_zfs_fs): Add mtime. - * grub-core/fs/zfs/zfsinfo.c (print_vdev_info): Add missing return. - * include/grub/zfs/sa_impl.h (SA_TYPE_OFFSET): New definition. - (SA_MTIME_OFFSET): Likewise. - (SA_SYMLINK_OFFSET): Likewise. - * include/grub/zfs/zfs.h (SPA_VERSION): Increase to 33. - * util/grub-fstest.c (CMD_ZFSINFO): New enum value. - (fstest): Support zfsinfo. - (argp_parser): Likewise. - -2011-10-26 Vladimir Serbinenko - - * include/grub/datetime.h (grub_datetime2unixtime): Fix off-by-one - error. - -2011-10-26 Vladimir Serbinenko - - ZFS fixes. - - * grub-core/fs/zfs/zfs.c (fzap_iterate): Fix handling of indexes - sharing the same block. Iterate over correct number of indices. - (dnode_get_path): Handle symlinks correctly. - -2011-10-25 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_sblock): Fix offset to volname. - -2011-10-25 Vladimir Serbinenko - - Read label on HFS+. - - * grub-core/fs/hfsplus.c (grub_hfsplus_cmp_catkey_id): New function. - (grub_hfsplus_btree_search): Fix types. - (grub_hfsplus_label): Implement. - -2011-10-25 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (grub_ntfs_uuid): Fix a memory leak. - -2011-10-25 Vladimir Serbinenko - - * grub-core/fs/fat.c (grub_fat_uuid): Make uppercase to match Linux. - -2011-10-25 Vladimir Serbinenko - - Fix symlink handling on iso9660. - - * grub-core/fs/iso9660.c (grub_fshelp_node): Remove dir_off. Add symlink - All users updated. - (grub_iso9660_susp_iterate): Accept zero-size iterate. - (grub_iso9660_read_symlink): Moved most of code ... - (grub_iso9660_iterate_dir): ... here. Fill node->symlink. - -2011-10-25 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): - Use union to avoid breaking strict-aliasing rules. - -2011-10-25 Vladimir Serbinenko - - Support multi-extent iso files. - - * grub-core/fs/iso9660.c (grub_iso9660_data): Remove first_sector. - Add node. - (grub_fshelp_node): Revamp. All users updated. - (FLAG_*): New enum. - (read_node): New function. - (grub_iso9660_susp_iterate): Use read_node. Receive a node as argument. - All users updated. - (grub_iso9660_mount): Don't attempt to read sua when there is none. - (get_node_size): New function. - (grub_iso9660_iterate_dir): Use read_node. Agglomerate multi-extent - entries. - Fix memory leak on . and .. - (grub_iso9660_read): Use read_node. - (grub_iso9660_close): Free node. - -2011-10-25 Vladimir Serbinenko - - Fix tar 4G limit and handle paths containing dot. - - * grub-core/fs/cpio.c (grub_cpio_data): Use grub_off_t for offsets. - (canonicalize): New function. - (grub_cpio_find_file): Use canonicalize. Store offs in - grub_disk_addr_t. - (grub_cpio_dir): Use grub_disk_addr_t. - (grub_cpio_open): Likewise. - -2011-10-25 Vladimir Serbinenko - - Fix handling of uncompressed blocks on squashfs and break 4G limit. - - * grub-core/fs/squash4.c (grub_squash_super): Add block_size. Remove - unused flags. - (grub_squash_inode): Add long_file and block_size. - (grub_squash_cache_inode): New struct. - (grub_squash_dirent): Make types into enum. - (SQUASH_TYPE_LONG_REGULAR): New type. - (grub_squash_frag_desc): Add field size. - (SQUASH_BLOCK_FLAGS): New enum. - (grub_squash_data): Use grub_squash_cache_inode. - (grub_fshelp_node): Make ino_chunk 64-bit. - (read_chunk): Minor argument change. All users updated. - (squash_mount): Use correct le_to_cpu. - (grub_squash_open): Handle LONG_REGULAR. - (direct_read): New function. - (grub_squash_read_data): Handle blocks correctly. - -2011-10-25 Vladimir Serbinenko - - * grub-core/kern/disk.c (grub_disk_read_small): Fix memory leak. - -2011-10-25 Vladimir Serbinenko - - * grub-core/fs/romfs.c (grub_romfs_open): Add missing return. - -2011-10-24 Vladimir Serbinenko - - Fix 2G limit on ZFS. - - * grub-core/fs/zfs/zfs.c (zio_checksum_verify): Use more appropriate - types. - (uberblock_verify): Likewise. - (dmu_read): Likewise. - (grub_zfs_read): Likewise. Remove invalid cast. - -2011-10-24 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_blkno): Use more appropriate types. - (grub_jfs_blkno): Fix incorrect shift. - (grub_jfs_read_file): Use more appropriate types. - -2011-10-24 Vladimir Serbinenko - - Support triple indirect on minix2 and minix3. - - * grub-core/fs/minix.c (grub_minix_inode) [MODE_MINIX2 || MODE_MINIX3]: - Declare triple_indir_zone. - (grub_minix_get_file_block) [MODE_MINIX2 || MODE_MINIX3]: Handle triple - indirect. - -2011-10-24 Vladimir Serbinenko - - Minix FS fixes. - - * grub-core/fs/minix.c (GRUB_MINIX_INODE_SIZE): Size is always 32-bit. - (grub_minix_inode) [!MODE_MINIX2 && !MODE_MINIX3]: Make size 32-bit. - Rename ctime to mtime. All users updated. - (grub_minix_get_file_block): Fix types and double indirect computations. - -2011-10-23 Vladimir Serbinenko - - * grub-core/fs/fat.c (grub_fat_label) [MODE_EXFAT]: Set *label to 0 - if no label is found. - (grub_fat_iterate_dir): Fix file size type. - (grub_fat_iterate_dir): Likewise. - -2011-10-23 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (gf_invert): Declare as const and - save some space. - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. - -2011-10-23 Vladimir Serbinenko - - * util/import_gcry.py: Automatically fix camellia.c and camellia.h. - -2011-10-23 Vladimir Serbinenko - - * util/import_gcry.py: Accept space between # and include. - -2011-10-23 Vladimir Serbinenko - - * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/longjmp.S. - -2011-10-23 Vladimir Serbinenko - - Fine grainely disable warnings on lexer. Remove Wno-error on it. - - * grub-core/Makefile.core.def (normal): Remove -Wno-error. - * grub-core/script/lexer.c: Declare yytext_ptr to avoid having - yylex_strncpy. - * grub-core/script/yylex.l: Add fine-grained #pragma. - -2011-10-23 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/string.h (memcpy) [GRUB_UTIL]: - New inline function. - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (memcpy) [GRUB_UTIL]: - Likewise. - (memset) [GRUB_UTIL]: Likewise. - (memcmp) [GRUB_UTIL]: Likewise. - -2011-10-23 Vladimir Serbinenko - - * include/grub/misc.h (grub_memcpy): Declare grub_memcpy with static - inline function rather than a define. - -2011-10-23 Vladimir Serbinenko - - * util/grub-setup.c: Add missing include. - -2011-10-23 Vladimir Serbinenko - - * util/ieee1275/grub-ofpathname.c: Add missing include. - -2011-10-23 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S (grub_exit): Add missing zeroing-out. - * grub-core/lib/i386/reboot_trampoline.S (grub_reboot_start): - Likewise. - -2011-10-23 Vladimir Serbinenko - - * grub-core/io/lzopio.c (test_header): Fix incorrect memcmp instead of - grub_memcmp usage. - -2011-10-23 Vladimir Serbinenko - - * util/grub-install.in: Add datarootdir as per automake manual - suggestion. - * util/grub-mknetdir.in: Likewise. - -2011-10-23 Vladimir Serbinenko - - * util/grub.d/10_hurd.in: Add datarootdir as per automake manual - suggestion. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - -2011-10-20 Vladimir Serbinenko - - Remove redundant grub_kernel_image_size. - - * grub-core/kern/i386/coreboot/init.c (grub_machine_init): Use - _edata and _start. - * grub-core/kern/i386/coreboot/startup.S: Move multiboot header after - the small code. It moves it only by few bytes but simplifies the code. - * grub-core/kern/i386/pc/init.c (grub_machine_init): Use _edata and - _start. - * grub-core/kern/i386/pc/startup.S: Use _edata and _start. - (grub_kernel_image_size): Removed. - * grub-core/kern/i386/qemu/startup.S: Use _edata and _start. - (grub_kernel_image_size): Removed. - [APPLE_CC]: Remove apple compiler support. i386-qemu port can't be - compiled with Apple toolchain. - * grub-core/kern/sparc64/ieee1275/crt0.S: Remove leftover fields. - * include/grub/i386/pc/kernel.h (grub_kernel_image_size): Removed. - * include/grub/i386/qemu/kernel.h (grub_kernel_image_size): Removed. - (grub_total_module_size): Likewise. - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE): - Removed. - (GRUB_KERNEL_I386_PC_COMPRESSED_SIZE): Put it lower. - (GRUB_KERNEL_I386_PC_INSTALL_DOS_PART): Likewise. - (GRUB_KERNEL_I386_PC_INSTALL_BSD_PART): Likewise. - (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): Likewise. - (GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE): Removed. - (GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE): Likewise. - (GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE): Likewise. - * include/grub/sparc64/ieee1275/kernel.h (grub_kernel_image_size): - Removed. - (grub_total_module_size): Removed. - * util/grub-mkimage.c (image_target_desc): Remove image_size. - (image_targets): Likewise. - Set .compressed_size to no field on sparc. - (generate_image): Remove kernel_image_size handling. - -2011-10-19 Szymon Janc - - * grub-core/bus/usb/uhci.c (grub_uhci_setup_transfer): Fix possible - NULL pointer dereference. - -2011-10-19 Vladimir Serbinenko - - Removed unused GRUB_BOOT_VERSION. Check for kernel version is better - done with a dedicated section. - - * grub-core/boot/sparc64/ieee1275/boot.S: Remove GRUB_BOOT_VERSION. - Ensure the correct position of boot_path. - * grub-core/kern/i386/efi/startup.S: Remove GRUB_BOOT_VERSION. - * grub-core/kern/i386/pc/startup.S: Likewise. Ensure correct position of - other fields. - * grub-core/kern/x86_64/efi/startup.S: Remove GRUB_BOOT_VERSION. - * include/grub/boot.h: Removed. All references removed. - * include/grub/sparc64/ieee1275/boot.h (GRUB_BOOT_MACHINE_VER_MAJ): - Removed. - (GRUB_BOOT_MACHINE_BOOT_DEVPATH): Make it lower. - -2011-10-19 Vladimir Serbinenko - - * util/grub-install.in: Declare IEEE1275 as able to find out the disk - name. - -2011-10-19 Vladimir Serbinenko - - * grub-core/kern/main.c (grub_set_prefix_and_root): Init prefix. - -2011-10-19 Vladimir Serbinenko - - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): - Don't add the bogus brackets. - -2011-10-19 Vladimir Serbinenko - - ExFAT support. - - * Makefile.util.def (libgrubmods.a): Add grub-core/fs/exfat.c. - * grub-core/Makefile.core.def (exfat): New module. - * grub-core/fs/exfat.c: New file. - * grub-core/fs/fat.c (GRUB_FAT_DIR_ENTRY_SIZE): Removed. - (GRUB_FAT_ATTR_*): Make into an enum. - (GRUB_FAT_ATTR_LONG_NAME) [MODE_EXFAT]: Removed. - (GRUB_FAT_ATTR_VALID) [MODE_EXFAT]: Remove GRUB_FAT_ATTR_VOLUME_ID. - (GRUB_FAT_ATTR_VOLUME_ID) [MODE_EXFAT]: Removed. - (GRUB_FAT_MAXFILE): Removed. - (grub_exfat_bpb) [MODE_EXFAT]: New struct. - (grub_current_fat_bpb_t): New type. - (grub_fat_dir_entry) [MODE_EXFAT]: New struct. - (grub_fat_dir_node) [MODE_EXFAT]: New struct. - (grub_fat_dir_node_t): New type. - (grub_fat_data) [MODE_EXFAT]: Remove root_sector and num_root_sectors. - (fat_log2) [MODE_EXFAT]: Removed. - (grub_fat_mount): Use grub_current_fat_bpb_t. Add some sanity checks. - (grub_fat_mount) [MODE_EXFAT]: Handle ExFAT. - (grub_fat_iterate_dir) [MODE_EXFAT]: New function. - (grub_fat_find_dir) [MODE_EXFAT]: Handle ExFAT. - (grub_fat_label) [MODE_EXFAT]: New function. - (grub_fat_fs) [MODE_EXFAT]: Set name to "exfat" and - reserved_first_sector to 0. - -2011-10-19 Vladimir Serbinenko - - Move grub_reboot out of the kernel. - - * grub-core/Makefile.core.def (reboot): Add platform-specific files. - * grub-core/kern/efi/efi.c (grub_reboot): Moved to ... - * grub-core/lib/efi/reboot.c: ... here. - * grub-core/kern/i386/efi/startup.S: Remove including of realmode.S. - * grub-core/kern/i386/ieee1275/startup.S: Likewise. - * grub-core/kern/i386/pc/startup.S (grub_exit): Inline cold_reboot. - * grub-core/kern/i386/realmode.S (grub_reboot): Moved to... - * grub-core/lib/i386/reboot_trampoline.S: ... here. - * grub-core/kern/ieee1275/openfw.c (grub_reboot): Moved to... - * grub-core/lib/ieee1275/reboot.c: ... here. - * grub-core/kern/mips/arc/init.c (grub_reboot): Moved to... - * grub-core/lib/mips/arc/reboot.c: ... here. - * grub-core/kern/mips/loongson/init.c (grub_reboot): Moved to... - * grub-core/lib/mips/loongson/reboot.c: ...here. - * grub-core/kern/mips/qemu_mips/init.c (grub_reboot): Moved to... - * grub-core/lib/mips/qemu_mips/reboot.c: ... here. - * include/grub/emu/misc.h (grub_reboot): New function declaration. - * include/grub/i386/reboot.h: New file. - * include/grub/mips/loongson/ec.h: Fix includes. - * include/grub/mips/qemu_mips/kernel.h (grub_reboot): Removed. - * include/grub/misc.h (grub_reboot): Don't mark as kernel function. - * grub-core/lib/i386/reboot.c: New file. - -2011-10-18 Vladimir Serbinenko - - Make grub_prefix into module to fix the arbitrary limit and save - some space. - - * grub-core/kern/emu/main.c (grub_prefix): Removed. - * grub-core/kern/i386/coreboot/startup.S (grub_prefix): Likewise. - * grub-core/kern/i386/efi/startup.S (grub_prefix): Likewise. - * grub-core/kern/i386/ieee1275/startup.S (grub_prefix): Likewise. - * grub-core/kern/i386/pc/startup.S (grub_prefix): Likewise. - * grub-core/kern/i386/qemu/startup.S (grub_prefix): Likewise. - * grub-core/kern/ia64/efi/startup.S (grub_prefix): Likewise. - * grub-core/kern/mips/startup.S (grub_prefix): Likewise. - * grub-core/kern/powerpc/ieee1275/startup.S (grub_prefix): Likewise. - * grub-core/kern/sparc64/ieee1275/crt0.S (grub_prefix): Likewise. - * grub-core/kern/x86_64/efi/startup.S (grub_prefix): Likewise. - * include/grub/ia64/efi/kernel.h: Removed. - * include/grub/kernel.h: New module type OBJ_TYPE_PREFIX. - (grub_prefix): Removed. - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_PREFIX): Removed. - (GRUB_KERNEL_I386_PC_PREFIX_END): Likewise. - (GRUB_KERNEL_I386_QEMU_PREFIX): Likewise. - (GRUB_KERNEL_I386_QEMU_PREFIX_END): Likewise. - (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX): Likewise. - (GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END): Likewise. - (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX): Likewise. - (GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END): Likewise. - (GRUB_KERNEL_MIPS_LOONGSON_PREFIX): Likewise. - (GRUB_KERNEL_MIPS_LOONGSON_PREFIX_END): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END): Likewise. - (GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise. - (GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise. - (GRUB_KERNEL_I386_EFI_PREFIX): Likewise. - (GRUB_KERNEL_I386_EFI_PREFIX_END): Likewise. - (GRUB_KERNEL_IA64_EFI_PREFIX): Likewise. - (GRUB_KERNEL_IA64_EFI_PREFIX_END): Likewise. - (GRUB_KERNEL_X86_64_EFI_PREFIX): Likewise. - (GRUB_KERNEL_X86_64_EFI_PREFIX_END): Likewise. - (GRUB_KERNEL_I386_COREBOOT_PREFIX): Likewise. - (GRUB_KERNEL_I386_COREBOOT_PREFIX_END): Likewise. - (GRUB_KERNEL_I386_MULTIBOOT_PREFIX): Likewise. - (GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END): Likewise. - (GRUB_KERNEL_I386_IEEE1275_PREFIX): Likewise. - (GRUB_KERNEL_I386_IEEE1275_PREFIX_END): Likewise. - (GRUB_KERNEL_MACHINE_PREFIX): Likewise. - (GRUB_KERNEL_MACHINE_PREFIX_END): Likewise. - * grub-core/kern/main.c (grub_set_prefix_and_root): Retrieve grub_prefix - from module. - * util/grub-mkimage.c (image_target_desc): Removed prefix and - prefix_end. - (image_targets): Likewise. - (generate_image): Put prefix as a module. - -2011-10-16 Vladimir Serbinenko - - Replace grub_module_iterate with FOR_MODULES. - - * grub-core/disk/memdisk.c (GRUB_MOD_INIT): Switched to new interface. - * grub-core/kern/efi/efi.c (grub_arch_modules_addr): Renamed to... - (grub_efi_modules_addr): ...this. - * grub-core/kern/efi/init.c (grub_modbase): New variable. - (grub_efi_init): Set grub_modbase. - * grub-core/kern/emu/main.c (grub_arch_modules_addr): Removed. - (grub_modbase): New variable. - * grub-core/kern/i386/coreboot/init.c (grub_arch_modules_addr): Removed. - (grub_modbase): New variable. - (grub_machine_init): Set grub_modbase. - * grub-core/kern/i386/pc/init.c (grub_arch_modules_addr): Removed. - (grub_modbase): New variable. - (grub_machine_init): Set grub_modbase. - * grub-core/kern/ieee1275/init.c (grub_arch_modules_addr): Removed. - (grub_modbase): New variable. - (grub_machine_init): Set grub_modbase. - * grub-core/kern/main.c (grub_module_iterate): Remove. - (grub_modules_get_end): Use grub_modbase. - (grub_load_modules): Use FOR_MODULES. - (grub_load_config): Likewise. - * grub-core/kern/mips/arc/init.c (grub_arch_modules_addr): Removed. - (grub_modbase): New variable. - (grub_machine_init): Set grub_modbase. - * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): Removed. - (grub_modbase): New variable. - (grub_machine_init): Set grub_modbase. - * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): - Removed. - (grub_modbase): New variable. - (grub_machine_init): Set grub_modbase. - * include/grub/efi/efi.h (grub_efi_modules_addr): New declaration. - * include/grub/kernel.h (grub_arch_modules_addr): Removed. - (grub_module_iterate): Likewise. - (grub_modbase): New variable declaration. - (FOR_MODULES): New macro. - -2011-10-16 Vladimir Serbinenko - - * configure.ac: Check for __ctzdi2 and __ctzsi2. - * include/grub/libgcc.h: Include __ctzdi2 and __ctzsi2 if present. - -2011-10-16 Vladimir Serbinenko - - Fix few obvious type discrepancies. - - * grub-core/fs/affs.c (grub_affs_read_file): Use grub_off_t for offset. - * grub-core/fs/afs.c (grub_afs_read_file): Likewise. - * grub-core/fs/fshelp.c (grub_fshelp_find_file): Remove leftover - variable. - * grub-core/fs/hfs.c (grub_hfs_read_file): Use grub_off_t for offset - and connected types. - * grub-core/fs/nilfs2.c (grub_nilfs2_read_file): Use grub_off_t for - offset. - (grub_nilfs2_iterate_dir): Use grub_off_t for fpos. - * grub-core/fs/sfs.c (grub_sfs_read_file): Use grub_off_t for offset. - * grub-core/fs/ufs.c (grub_ufs_read_file): Use grub_off_t for offset - and connected types. - -2011-10-16 Vladimir Serbinenko - - Fix python 3.x incompatibilities. - - * gentpl.py: Put brackets around print strings. - * util/import_gcry.py: Open explicitly as utf-8. - Use in instead of has_key. - -2011-10-16 Vladimir Serbinenko - - * grub-core/fs/xfs.c (grub_xfs_inode): New field fork_offset. - (GRUB_XFS_INO_AGBITS): Make into inline function. - (GRUB_XFS_INO_INOINAG): Likewise. - (GRUB_XFS_INO_AG): Likewise. - (GRUB_XFS_FSB_TO_BLOCK): Likewise. - (GRUB_XFS_EXTENT_OFFSET): Likewise. - (GRUB_XFS_EXTENT_BLOCK): Likewise. - (GRUB_XFS_EXTENT_SIZE): Likewise. - (GRUB_XFS_ROUND_TO_DIRENT): Likewise. - (GRUB_XFS_NEXT_DIRENT): Likewise. - (grub_xfs_read_block): Rewrite the btree parsing. Fixes invalid BMAP. - (grub_xfs_read_file): Fix offset type. - -2011-10-15 Robert Millan - - * util/getroot.c (grub_util_get_grub_dev): Fix OS selection #ifdefs. - -2011-10-15 Robert Millan - - Fix build problem on FreeBSD and GNU/kFreeBSD. - - * util/getroot.c [__FreeBSD_kernel__]: Include `'. - -2011-10-14 Vladimir Serbinenko - - Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested. - - * grub-core/fs/hfsplus.c (grub_hfsplus_btree): Use more appropriate - types. - (grub_hfsplus_btree_recoffset): Likewise. - (grub_hfsplus_btree_recptr): Likewise. - (grub_hfsplus_find_block): Likewise. - (grub_hfsplus_btree_search): Likewise. - (grub_hfsplus_read_block): Likewise. - (grub_hfsplus_read_file): Likewise. - (grub_hfsplus_mount): Likewise. - (grub_hfsplus_btree_iterate_node): Likewise. - (grub_hfsplus_btree_search): Likewise. - (grub_hfsplus_iterate_dir): Likewise. - (grub_hfsplus_read): A small code simplification. - -2011-10-14 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c - (convert_system_partition_to_system_disk): Don't assume that children - of mapper nodes are mapper nodes. - -2011-10-14 Vladimir Serbinenko - - * grub-core/lib/posix_wrap/ctype.h (isxdigit): Use grub_isxdigit. - * include/grub/misc.h (grub_isxdigit): New function. - * grub-core/video/colors.c (my_isxdigit): Removed. All users - switched to grub_isxdigit. - * grub-core/term/serial.c (grub_serial_find): Fix in case of port - number starting with a letter. - -2011-10-09 Robert Millan - - LVM support for FreeBSD and GNU/kFreeBSD. - - * util/lvm.c (grub_util_lvm_isvolume): Enable on FreeBSD and - GNU/kFreeBSD. - (LVM_DEV_MAPPER_STRING): Move from here ... - * include/grub/util/lvm.h (LVM_DEV_MAPPER_STRING): ... to here. - * util/getroot.c: Include `'. - (grub_util_get_dev_abstraction): Enable - grub_util_biosdisk_is_present() on FreeBSD and GNU/kFreeBSD. - Check for LVM abstraction on FreeBSD and GNU/kFreeBSD. - (grub_util_get_grub_dev): Replace "/dev/mapper/" with - `LVM_DEV_MAPPER_STRING'. Enable LVM and mdRAID only on platforms that - support it. - * util/grub-setup.c (main): Check for LVM also on FreeBSD and - GNU/kFreeBSD. - * util/grub.d/10_kfreebsd.in: Load `geom_linux_lvm' kernel module - when LVM abstraction is required for ${GRUB_DEVICE}. - -2011-10-06 Szymon Janc - - Add support for LZO compression in GRUB: - - import of minilzo library, - - LZO decompression for btrfs, - - lzop files decompression. - - * grub-core/io/lzopio.c: New file. - * grub-core/lib/adler32.c: Likewise. - * grub-core/lib/minilzo/lzoconf.h: Likewise. - * grub-core/lib/minilzo/lzodefs.h: Likewise. - * grub-core/lib/minilzo/minilzo.c: Likewise. - * grub-core/lib/minilzo/minilzo.h: Likewise. - * Makefile.util.def (libgrubmods.a): Add grub-core/io/lzopio.c, - grub-core/lib/adler32.c, grub-core/io/lzopio.c, - grub-core/lib/minilzo/minilzo.c to common. - * Makefile.util.def (libgrubmods.a): Add flags required by minilzo to - cflags in cppflags. - * grub-core/Makefile.core.def (btrfs): Likewise. - * grub-core/Makefile.core.def (lzopio): New module. - (adler32): Likewise. - * grub-core/fs/btrfs.c: Include minilzo.h. - (GRUB_BTRFS_COMPRESSION_LZO): New define. - (GRUB_BTRFS_LZO_BLOCK_SIZE): Likewise. - (GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE): Likewise. - (grub_btrfs_lzo_decompress): New function. - (grub_btrfs_extent_read): Add support for LZO compression type. - * include/grub/types.h (GRUB_UCHAR_MAX): New define. - (GRUB_USHRT_MAX): Likewise. - (GRUB_UINT_MAX): Likewise. - * grub-core/lib/posix_wrap/limits.h (USHRT_MAX): Likewise. - (UINT_MAX): Likewise. - (CHAR_BIT): Likewise. - * grub-core/lib/posix_wrap/sys/types.h (ULONG_MAX): Moved to - grub-core/lib/posix_wrap/limits.h - (UCHAR_MAX): Likewise. - * include/grub/file.h (grub_file_filter_id): New compression filter - GRUB_FILE_FILTER_LZOPIO. - * include/grub/file.h (grub_file_filter_id): Set - GRUB_FILE_FILTER_LZOPIO as GRUB_FILE_FILTER_COMPRESSION_LAST. - * include/grub/types.h (grub_get_unaligned16): New function. - (grub_get_unaligned32): Likewise. - (grub_get_unaligned64): Likewise. - * util/import_gcry.py (cryptolist): Add adler32. - -2011-10-05 Vladimir Serbinenko - - * grub-core/Makefile.core.def: Eliminate rarely used emu_condition. This - in perspective decreases the complexity of build system and fixes - compilation right now. - -2011-10-01 Ales Nesrsta - - * grub-core/bus/usb/uhci.c: Changes made by Rock Cui - thanks! - (fixed problem related to using UHCI with coreboot). - -2011-08-25 BVK Chaitanya - - * gentpl.py: Use Autogen macros so that the output template file - (Makefile.tpl) size is reduced. - -2011-09-29 Mads Kiilerich - - * grub-core/Makefile.core.def (kernel): Add kern/i386/int.S to - extra_dist. - -2011-09-29 Mario Limonciello - - * util/misc.c (grub_util_get_disk_size) [__MINGW32__]: Strip trailing - slashes on PHYSICALDRIVE%d paths when making Windows CreateFile calls. - -2011-09-29 Mario Limonciello - - * grub-core/kern/emu/misc.c (canonicalize_file_name) [__MINGW32__]: Use - _fullpath. - -2011-09-29 Mario Limonciello - - Remove extra declaration of sleep for mingw32. - - * util/misc.c (sleep) [__MINGW32__]: Removed. - * include/grub/util/misc.h (sleep) [__MINGW32__]: Likewise. - -2011-09-28 Grégoire Sutre - - * include/grub/bsdlabel.h (grub_partition_bsd_disk_label): Add fields - type and packname. - * include/grub/i386/netbsd_bootinfo.h (NETBSD_BTINFO_BOOTDISK): - Resurrected. - (NETBSD_BTINFO_BOOTWEDGE): New definition. - (grub_netbsd_btinfo_bootwedge): New struct. - * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): - New function. - (grub_cmd_netbsd): Call grub_netbsd_add_boot_disk_and_wedge. - -2011-09-28 Thomas Haller - - * grub-core/loader/multiboot_elfxx.c (Elf_Shdr): Set according to - loader. - -2011-09-28 Andreas Born - - Fix incorrect identifiers in bash-completion. - - * util/bash-completion.d/grub-completion.bash.in - (_grub_mkpasswd-pbkdf2): Rename to ... - (_grub_mkpasswd_pbkdf2): ... this. All users updated. - (_grub_script-check): Rename to ... - (_grub_script_check): ... this. All users updated. - -2011-09-28 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): - Return 0 if disk isn't biosdisk. - -2011-09-17 Grégoire Sutre - - * Makefile.util.def (grub-mkrelpath): Add LIBUTIL for getrawpartition(3) - on NetBSD. - * Makefile.util.def (grub-fstest): Likewise. - -2011-09-17 Grégoire Sutre - - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors) [__NetBSD__]: - Get sector size from disk label. - -2011-09-05 Colin Watson - - * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Return 1 for - */README* as well as README*. - Reported by: Axel Beckert. - -2011-08-23 Vladimir Serbinenko - - * grub-core/kern/mips/loongson/init.c (grub_machine_init): Handle the - case of less than 256 MiB of RAM. - -2011-08-23 Vladimir Serbinenko - - * grub-core/commands/wildcard.c (make_regex): Handle @. - -2011-08-23 Vladimir Serbinenko - - * util/grub-install.in: Move cryptodisk logic to appropriate place. - -2011-08-21 Szymon Janc - - * acinclude.m4: Use AC_LANG_PROGRAM macro to generate source code for - AC_LANG_CONFTEST macros. - -2011-08-20 Szymon Janc - - Add grub-fstest option to uncompress data for commands. - - * util/grub-fstest.c (uncompress): New var. - (options): New option -u. - -2011-08-20 Szymon Janc - - * grub-core/loader/i386/linux.c (grub_linux_setup_video): Add - GRUB_VIDEO_DRIVER_RADEON_FULOONG2E to switch case statement. - -2011-08-20 Szymon Janc - - * grub-core/io/gzio.c (grub_gzio_open): Always return original io if - file type was not recognized correctly (not gzip or corrupted). - -2011-08-19 Vladimir Serbinenko - - * grub-core/kern/mips/loongson/init.c (grub_reboot): Reboot Fuloong. - * include/grub/cs5536.h (GRUB_CS5536_MSR_DIVIL_RESET): New definition. - -2011-08-19 Vladimir Serbinenko - - * grub-core/Makefile.core.def (kernel): Add video/radeon_fuloong2e.c on - loongson. - * grub-core/kern/mips/loongson/init.c (grub_machine_init): Init - video_radeon_fuloong2e. - * grub-core/video/radeon_fuloong2e.c: New file. - * include/grub/video.h (grub_video_id_t): Add new ID - GRUB_VIDEO_DRIVER_RADEON_FULOONG2E. - -2011-08-19 Vladimir Serbinenko - - * include/grub/mips/loongson.h (GRUB_CPU_LOONGSON_COP0_PRID): New - define. - * grub-core/kern/mips/loongson/init.c (grub_machine_init): Check - that PRID matches the detected subplatform and reset the subplatform - if it doesn't. - -2011-08-19 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vprintf): Fix a bug on malloc failure. - -2011-08-19 Vladimir Serbinenko - - Fix PCI iterating on functions >= 4. - - * grub-core/bus/pci.c (grub_pci_iterate): Remove useless ghost skipping. - * include/grub/mips/loongson/pci.h (GRUB_LOONGSON_OHCI_GHOST_FUNCTION): - Removed. - (GRUB_LOONGSON_EHCI_GHOST_FUNCTION): Likewise. - (grub_pci_read): Fix bitmask. - (grub_pci_read_word): Likewise. - (grub_pci_read_byte): Likewise. - (grub_pci_write): Likewise. - (grub_pci_write_word): Likewise. - (grub_pci_write_byte): Likewise. - -2011-08-19 Vladimir Serbinenko - - * configure.ac: Don't impose march=loongson2f on loongson platform. (It - can still be specified in TARGET_CFLAGS) - -2011-08-19 Vladimir Serbinenko - - Rename Fuloong into Fuloong 2F. Add new ID for Fuloong2E. - - * grub-core/Makefile.core.def (fwstart_fuloong): Rename fwstart_fuloong - into fwstart_fuloong2f. Use boot/mips/loongson/fuloong2f.S. - * grub-core/boot/mips/loongson/fuloong.S: Rename to ... - * grub-core/boot/mips/loongson/fuloong2f.S: ... this. - (FULOONG): Rename to ... - (FULOONG2F): ... this. All users updated. - * grub-core/boot/mips/startup_raw.S (machtype_fuloong_str): Rename to - (machtype_fuloong2f_str): ... this. - (machtype_fuloong2e_str): New string. - Check for machtype_fuloong2e_str. - * grub-core/loader/mips/linux.c (loongson_machtypes) - [GRUB_MACHINE_MIPS_LOONGSON]: Add GRUB_ARCH_MACHINE_FULOONG2E. - * grub-core/term/serial.c (loongson_defserial) - [GRUB_MACHINE_MIPS_LOONGSON]: New array. - (grub_serial_register) [GRUB_MACHINE_MIPS_LOONGSON]: Use - loongson_defserial. - * include/grub/mips/loongson/kernel.h (GRUB_ARCH_MACHINE_FULOONG): - Rename to ... - (GRUB_ARCH_MACHINE_FULOONG2F): ... this. - (GRUB_ARCH_MACHINE_FULOONG2E): New const. - * util/grub-mkimage.c (image_target_desc): Rename IMAGE_FULOONG_FLASH - to IMAGE_FULOONG2F_FLASH. All users updated. - (image_targets): Rename images. - * util/grub-mkstandalone.in: Accept fuloong2f and fuloong2e. - -2011-08-19 Szymon Janc - - Make enable of disk cache statistics code configurable. - - * configure.ac: --enable-cache-stats added. - * config.h.in (DISK_CACHE_STATS): New define. - * grub-core/Makefile.core.def (cacheinfo): New command. - * include/grub/disk.h(grub_disk_cache_get_performance): New function. - * grub-core/commands/cacheinfo.c: New file. - * grub-core/commands/minicmd.c (grub_rescue_cmd_info): Updated and - moved to cacheinfo.c. - * grub-core/kern/disk.c: Use DISK_CACHE_STATS to disable disk cache - debug code. - * include/grub/disk.h: Likewise. - -2011-08-19 Szymon Janc - - * Makefile.am (AUTOMAKE_OPTIONS): = Added -Wno-portability flag. - * grub-core/Makefile.am: Likewise. - -2011-08-16 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_iterate): Skip with - non-zero pull. - -2011-08-16 Vladimir Serbinenko - - * grub-core/fs/jfs.c (grub_jfs_read_file): New parameter ino. - All users updated. - (grub_jfs_lookup_symlink): Use correct starting inode. - -2011-08-16 Vladimir Serbinenko - - * util/grub-setup.c (main): Add missing gcry initialisation. - -2011-08-16 Vladimir Serbinenko - - Don't accept text modes on EFI when booting Linux. - - * grub-core/loader/i386/linux.c (ACCEPTS_PURE_TEXT): New define. - (grub_linux_boot) [!ACCEPTS_PURE_TEXT]: Restrict to graphics modes. - -2011-08-15 Mario Limonciello -2011-08-15 Colin Watson - - * util/grub-probe.c (probe): Canonicalise the path argument, fixing - use of "/path/.." as in grub-install for EFI as well as handling - symlinks correctly. - Fixes Debian bug #637768. - -2011-08-15 Colin Watson - - * util/grub-probe.c: Remove duplicate #include. - -2011-08-10 Robert Millan - - Detect LSI MegaRAID SAS (`mfi') devices on GNU/kFreeBSD. - - * util/deviceiter.c [__FreeBSD_kernel__] (get_mfi_disk_name): New - function. - [__FreeBSD_kernel__] (grub_util_iterate_devices): Scan for mfi - (/dev/mfid[0-9]+) devices using get_mfi_disk_name(). - -2011-08-03 Robert Millan - - * include/grub/zfs/zap_leaf.h (typedef union zap_leaf_chunk): Mark - la_array as packed. - Reported by: Zachary Bedell - -2011-07-26 Colin Watson - - * configure.ac: The Loongson port requires grub-mkfont due to its - use of -DUSE_ASCII_FAILBACK. Raise an error if it is not going to - be built. - -2011-07-26 Colin Watson - - * util/grub-install.in: Don't source grub-mkconfig_lib until after - processing arguments (otherwise help2man fails when GRUB has not yet - been installed). - -2011-07-25 Vladimir Serbinenko - - New script grub-mkstandalone. - - * Makefile.util.def (grub-mkstandalone): New script. - * docs/man/grub-mkstandalone.h2m: New file. - * util/grub-mkstandalone.in: Likewise. - -2011-07-25 Vladimir Serbinenko - - Support ATA disks with 4K sectors. - - * include/grub/ata.h (grub_ata): New member log_sector_size. - * grub-core/disk/ata.c (grub_ata_dumpinfo): Show sector size. - (grub_ata_identify): Read sector size. - (grub_ata_readwrite): Use log_sector_size rather than hardcoded value. - -2011-07-25 Vladimir Serbinenko - - * util/grub-install.in: Don't use uhci outside of x86. - -2011-07-25 Vladimir Serbinenko - - * util/grub-mkrescue.in: Add missing quotes. - -2011-07-25 Vladimir Serbinenko - - * grub-core/normal/menu.c (grub_menu_execute_entry): Fix NULL - dereference. - -2011-07-23 Vladimir Serbinenko - - * grub-core/disk/pata.c (grub_pata_readwrite): Add missing wait. - -2011-07-23 Vladimir Serbinenko - - * include/grub/video.h: add missing EXPORT_FUND on - grub_video_edid_checksum and grub_video_edid_preferred_mode. - -2011-07-23 Vladimir Serbinenko - - * include/grub/mips/kernel.h: Fix define conflict. - -2011-07-23 Vladimir Serbinenko - - * grub-core/kern/mips/cache_flush.S [GRUB_MACHINE_MIPS_LOONGSON]: Flush - all four ways. - -2011-07-21 Colin Watson - - Preferred resolution detection for VBE. - - * grub-core/video/video.c (grub_video_edid_checksum): New function. - (grub_video_edid_preferred_mode): Likewise. Try EDID followed by - the Flat Panel extension, in line with the X.org VESA driver. - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_flat_panel_info): - New function. - (grub_vbe_bios_get_ddc_capabilities): Likewise. - (grub_vbe_bios_read_edid): Likewise. - (grub_vbe_get_preferred_mode): Likewise. - (grub_video_vbe_setup): When the mode is "auto", try to get the - preferred mode from VBE, and use the largest mode that is no larger - than the preferred mode (some BIOSes expose a preferred mode that is - not in their mode list!). If this fails, fall back to 640x480 as a - safe conservative choice. - (grub_video_vbe_get_edid): New function. - (grub_video_vbe_adapter): Add get_edid. - * include/grub/video.h (struct grub_vbe_edid_info): New structure. - (struct grub_video_adapter): Add get_edid. - (grub_video_edid_checksum): Add prototype. - (grub_video_edid_preferred_mode): Likewise. - * include/grub/i386/pc/vbe.h (struct grub_vbe_flat_panel_info): New - structure. - - * grub-core/commands/videoinfo.c (print_edid): New function. - (grub_cmd_videoinfo): Print EDID if available. - - * util/grub.d/00_header.in (GRUB_GFXMODE): Default to "auto". This - is more appropriate on a wider range of platforms than 640x480. - * docs/grub.texi (Simple configuration): Update GRUB_GFXMODE - documentation. - -2011-07-10 Vladimir Serbinenko - - * util/grub-install.in: Recognize ESP mounted at /boot/EFI. - -2011-07-10 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. - -2011-07-10 Vladimir Serbinenko - - * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix - incorrect memory usage. - -2011-07-10 Vladimir Serbinenko - - * util/grub-install.in: Source grub-mkconfig_lib. - -2011-07-08 Vladimir Serbinenko - - Remove getroot.c from core on emu platform. - - * grub-core/Makefile.core.def (kernel): Remove kern/emu/getroot.c and - kern/emu/raid.c. - * grub-core/kern/emu/main.c (main): Don't try to guess root device. It's - useless. - * grub-core/kern/emu/misc.c (get_win32_path): Moved from here... - * util/getroot.c (get_win32_path): ... here. - * grub-core/kern/emu/misc.c (fini_libzfs): Moved from here... - * util/getroot.c (fini_libzfs): ... here. - * grub-core/kern/emu/misc.c (grub_get_libzfs_handle): Moved from here... - * util/getroot.c (grub_get_libzfs_handle): ... here. - * grub-core/kern/emu/misc.c (grub_find_zpool_from_dir): - Moved from here... - * util/getroot.c (grub_find_zpool_from_dir): ... here. - * grub-core/kern/emu/misc.c - (grub_make_system_path_relative_to_its_root): Moved from here... - * util/getroot.c (grub_make_system_path_relative_to_its_root): ... here. - * grub-core/kern/emu/getroot.c: Moved from here ... - * util/getroot.c: ... here. All users updated. - * grub-core/kern/emu/raid.c: Moved from here ... - * util/raid.c: ... here. All users updated. - -2011-07-08 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. - -2011-07-07 Vladimir Serbinenko - - Fix compilation on GNU/Linux. - - * grub-core/kern/emu/getroot.c (grub_util_pull_device) [!FreeBSD]: - Disable geli. - (grub_util_get_grub_dev) [!FreeBSD]: Likewise. - (grub_util_pull_device) [HAVE_DEVICE_MAPPER]: Fix const and func name. - * grub-core/disk/cryptodisk.c (grub_cryptodisk_open): Fix proto. - -2011-07-07 Vladimir Serbinenko -2011-07-07 Michael Gorven -2011-07-07 Clemens Fruhwirth - - LUKS and GELI support. - - * Makefile.util.def (libgrubkern.a): Add grub-core/lib/crypto.c, - grub-core/disk/luks.c, grub-core/disk/geli.c, - grub-core/disk/cryptodisk.c, grub-core/disk/AFSplitter.c, - grub-core/lib/pbkdf2.c, grub-core/commands/extcmd.c, - grub-core/lib/arg.c. - (libgrubmods.a): Remove gcrypts cflags and cppflags. - Remove grub-core/commands/extcmd.c, grub-core/lib/arg.c, - grub-core/lib/crypto.c, grub-core/lib/libgcrypt-grub/cipher/sha512.c, - grub-core/lib/libgcrypt-grub/cipher/crc.c and grub-core/lib/pbkdf2.c. - (grub-bin2h): Add libgcry.a. - (grub-mkimage): Likewise. - (grub-mkrelpath): Likewise. - (grub-script-check): Likewise. - (grub-editenv): Likewise. - (grub-mkpasswd-pbkdf2): Likewise. - (grub-pe2elf): Likewise. - (grub-fstest): Likewise. - (grub-mkfont): Likewise. - (grub-mkdevicemap): Likewise. - (grub-probe): Likewise. - (grub-ofpath): Likewise. - (grub-mklayout): Likewise. - (example_unit_test): Likewise. - (grub-menulst2cfg): Likewise. - * autogen.sh (UTIL_DEFS): Add Makefile.utilgcry.def. - * grub-core/Makefile.core.def (cryptodisk): New module. - (luks): Likewise. - (geli): Likewise. - * grub-core/disk/AFSplitter.c: New file. - * grub-core/disk/cryptodisk.c: Likewise. - * grub-core/disk/geli.c: Likewise. - * grub-core/disk/luks.c: Likewise. - * grub-core/kern/emu/getroot.c (get_dm_uuid): New function based on - grub_util_is_lvm. - (grub_util_get_dm_abstraction): New function. - (grub_util_follow_gpart_up): Likewise. - (grub_util_get_geom_abstraction): Likewise. - (grub_util_get_dev_abstraction): Use new functions. - (grub_util_pull_device): Pull GELI and LUKS. - (grub_util_get_grub_dev): Handle LUKS and GELI. - * grub-core/kern/emu/hostdisk.c (grub_util_get_fd_sectors): New function. - (grub_util_biosdisk_open): Use grub_util_get_fd_sectors. - (follow_geom_up): Removed. - (grub_util_fd_seek): New function. - (open_device): Use grub_util_fd_seek. - (nread): Rename to .. - (grub_util_fd_read): ... this. All users updated. - * grub-core/lib/crypto.c (grub_crypto_ecb_decrypt): A better prototype. - (grub_crypto_cbc_decrypt): Likewise. - (grub_crypto_hmac_write): Likewise. - (grub_crypto_hmac_buffer): Likewise. - (grub_password_get): Extend to util. - * include/grub/crypto.h (gcry_cipher_spec) [GRUB_UTIL]: - New member modname. - (gcry_md_spec) [GRUB_UTIL]: Likewise. - * include/grub/cryptodisk.h: New file. - * include/grub/disk.h (grub_disk_dev_id): Rename LUKS to CRYPTODISK. - * include/grub/emu/getroot.h (grub_dev_abstraction_types): Add - LUKS and GELI. - (grub_util_follow_gpart_up): New proto. - * include/grub/emu/hostdisk.h (grub_util_fd_seek): Likewise. - (grub_util_fd_read): Likewise. - (grub_cryptodisk_cheat_mount): Likewise. - (grub_util_cryptodisk_print_uuid): Likewise. - (grub_util_get_fd_sectors): Likewise. - * util/grub-fstest.c (mount_crypt): New var. - (fstest): Mount crypto if requested. - (options): New option -C. - (argp_parser): Parse -C. - (main): Init and fini gcry. - * util/grub-install.in: Support cryptodisk install. - * util/grub-mkconfig.in: Export GRUB_ENABLE_CRYPTODISK. - * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Support - cryptodisk. - (prepare_grub_to_access_device): Likewise. - * util/grub-mkpasswd-pbkdf2.c (main): Use grub_password_get. - * util/grub-probe.c (probe_partmap): Support cryptodisk UUID probe. - (probe_cryptodisk_uuid): New function. - (probe_abstraction): Likewise. - (probe): Use new functions. - * util/import_gcry.py: Create Makefile.utilgcry.def. - Add modname member. - -2011-07-07 Vladimir Serbinenko - - Lazy device scanning. - - * Makefile.util.def (libgrubkern.a): Add grub-core/kern/emu/raid.c. - (grub-setup): Remove util/raid.c. - * grub-core/Makefile.core.def (kernel): Add kern/emu/raid.c on emu. - * grub-core/disk/lvm.c (scan_depth): New variable. - (grub_lvm_iterate): Rescan if necessary. - (find_lv): New function based on grub_lvm_open. - (grub_lvm_open): Use find_lv. Rescan on error. - (is_node_readable): New function. - (is_lv_readable): Likewise. - (grub_lvm_scan_device): Skip already found disks. - (do_lvm_scan): New function. Move grub_lvm_scan_device inside of it. - Stop if searched device is found and readable. - * grub-core/disk/raid.c (inscnt): New variable. - (scan_depth): Likewise. - (scan_devices): New function based on grub_raid_register. Abort if - looked for device is found. - (grub_raid_iterate): Rescan if needed. - (find_array): NEw function based on -grub_raid_open. - (grub_raid_open): Use find_array and rescan. - (insert_array): Set became_readable_at. - * grub-core/kern/disk.c (grub_disk_dev_iterate): Iterate though "pull. - * grub-core/kern/emu/getroot.c (grub_util_open_dm) [HAVE_DEVICE_MAPPER]: - New function. - (grub_util_is_lvm) [HAVE_DEVICE_MAPPER]: Use grub_util_open_dm. - (grub_util_pull_device): New function. - (grub_util_get_grub_dev): Call grub_util_pull_device. - * util/raid.c: Moved to .. - * grub-core/kern/emu/raid.c: ... here. - (grub_util_raid_getmembers): New parameter "bootable". - All users updated. Support 1.x. - * include/grub/ata.h (grub_ata_dev): Change iterate prototype. - All users updated. - * include/grub/disk.h (grub_disk_pull_t): New enum. - (grub_disk_dev): Change iterate prototype. - All users updated. - * include/grub/emu/getroot.h (grub_util_raid_getmembers) [__linux__]: - New proto. - * include/grub/emu/hostdisk.h (grub_util_pull_device): Likewise. - * include/grub/lvm.h (grub_lvm_lv): New members fullname and compatname. - * include/grub/raid.h (grub_raid_array): New member became_readable_at. - * include/grub/scsi.h (grub_scsi_dev): Change iterate prototype. - All users updated. - * include/grub/util/raid.h: Removed. - -2011-07-06 Vladimir Serbinenko - - * po/POTFILES.in: Regenerate. - -2011-07-06 Vladimir Serbinenko - - Unify sparc init with other ieee1275. - - * grub-core/Makefile.core.def (kernel): Use kern/ieee1275/init.c - instead of kern/sparc64/ieee1275/init.c. - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options) - [__sparc__]: Set GRUB_IEEE1275_FLAG_NO_PARTITION_0. - * grub-core/kern/ieee1275/init.c [__sparc__]: Include - grub/machine/kernel.h. - (grub_ieee1275_original_stack) [__sparc__]: New variable. - (grub_claim_heap) [__sparc__]: Use sparc version. - (grub_machine_init): Moved args parsing to - (grub_parse_cmdline): ...this. - * grub-core/kern/sparc64/ieee1275/init.c: Removed. - * include/grub/offsets.h (GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP): - New definition. - (GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN): Likewise. - - Move BOOTP to separate file. - - * grub-core/Makefile.core.def (net): Add net/bootp.c. - * grub-core/net/net.c: Move all BOOTP functions to - * grub-core/net/bootp.c: ... here. - - Use frame interface on PXE. - - * grub-core/Makefile.core.def (pxecmd): Removed. - (pxe): Use net/drivers/i386/pc/pxe.c rather than net/i386/pc/pxe.c. - * grub-core/commands/i386/pc/pxecmd.c: Removed. - * grub-core/i386/pc/pxe.c: Moved from here ... - * grub-core/net/i386/pc/pxe.c: ... here. Rewritten. - * grub-core/net/net.c (grub_net_open_real): Handle old pxe syntax. - * include/grub/i386/pc/pxe.h (grub_pxe_unload): Removed. - - EFI network support. - - * grub-core/Makefile.core.def (efinet): New module. - * grub-core/disk/efi/efidisk.c (compare_device_paths): Moved from - here... - * grub-core/kern/efi/efi.c (grub_efi_compare_device_paths): ... here. - All users updated. - * grub-core/kern/efi/init.c (grub_efi_net_config): New variable. - (grub_machine_get_bootlocation): Call grub_efi_net_config if needed. - * grub-core/kern/x86_64/efi/callwrap.S (efi_wrap_7): New function. - * grub-core/net/drivers/efi/efinet.c: New file. - * include/grub/efi/efi.h (grub_efi_compare_device_paths): New proto. - (grub_efi_net_config): New extern var. - - Various cleanups and bugfixes. - - * grub-core/disk/efi/efidisk.c (grub_efidisk_open): Fix off-by-one - error. - (grub_efidisk_get_device_name): Unify similar codepaths. Accept whole - disk declared as partition. - * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Fix memory - leak on failure. - * grub-core/kern/dl.c (grub_dl_load_file): Fix memory leak. - * grub-core/kern/mm.c (grub_debug_malloc): Don't use unsupported %zx. - (grub_debug_zalloc): Likewise. - (grub_debug_realloc): Likewise. - (grub_debug_memalign): Likewise. - * grub-core/net/arp.c (grub_net_arp_receive): IPv4 is 4-byte wide. - Check that target is IPv4. - * grub-core/net/drivers/ieee1275/ofnet.c (grub_ofnet_findcards): Use - local-mac-address as fallback. - * grub-core/net/ethernet.c (grub_net_recv_ethernet_packet): Prevent - memory leak. - * grub-core/net/ip.c (ipchksum): Rename to ... - (grub_net_ip_chksum): ... this. All users updated. - (grub_net_recv_ip_packets): Special handling for DHCP. - * util/grub-mkimage.c (generate_image): Zero-out aout header. - - Unify prefix handling - - * grub-core/kern/efi/init.c (grub_efi_set_prefix): Revamped into ... - (grub_machine_get_bootlocation): ... this. - * grub-core/kern/emu/main.c (grub_machine_set_prefix): Revamped into ... - (grub_machine_get_bootlocation): ... this. - (grub_prefix): New variable. - (prefix): Removed. - (root_dev): New variable. - (dir): Likewise. - (main): Use new variables. - * grub-core/kern/i386/coreboot/init.c (grub_machine_set_prefix): - Revamped into ... - (grub_machine_get_bootlocation): ... this. - * grub-core/kern/i386/efi/init.c (grub_machine_set_prefix): Removed. - * grub-core/kern/i386/pc/init.c (make_install_device): Revamped into ... - (grub_machine_get_bootlocation): ... this. - (grub_machine_set_prefix): Removed. - * grub-core/kern/ia64/efi/init.c (grub_machine_set_prefix): Removed. - * grub-core/kern/ieee1275/init.c (grub_machine_set_prefix): - Revamped into ... - (grub_machine_get_bootlocation): ... this. - * grub-core/kern/main.c (grub_set_root_dev): Revamped into ... - (grub_set_prefix_and_root): ... this. All users updated. - * grub-core/kern/mips/init.c (grub_machine_set_prefix): - Revamped into ... - (grub_machine_get_bootlocation): ... this. - * include/grub/kernel.h (grub_machine_set_prefix): Removed. - (grub_machine_get_bootlocation): New proto. - * include/grub/i386/pc/kernel.h (grub_pc_net_config): New var. - - Less intrusive and more reliable seek on network implementation. - - * grub-core/kern/file.c (grub_file_net_seek): Removed. - (grub_file_seek): Don't call grub_file_net_seek. - * grub-core/net/net.c (grub_net_fs_read): Renamed to ... - (grub_net_fs_read_real): .. this. - (grub_net_seek_real): Use net->offset. - (grub_net_fs_read): Seek if necessary. - - Unify IEEE1275 netwotk config with the other platforms. - - * grub-core/kern/ieee1275/init.c (grub_ieee1275_net_config): - New variable. - (grub_machine_get_bootlocation): Support network. - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): - Support type and device parsing. - (grub_ieee1275_get_device_type): New function. - * grub-core/net/drivers/ieee1275/ofnet.c (grub_getbootp_real): Revamped - into ... - (grub_ieee1275_net_config_real): ... this. - (grub_ofnet_probecards): Removed. - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Remove ofnet.h. - * include/grub/ieee1275/ofnet.h: Removed. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_net_config): NEw - extern var. - (grub_ieee1275_get_device_type): New function. - - Unify network device closing across platforms and make more robust. - - * grub-core/kern/ieee1275/init.c (grub_machine_fini): Don't call - grub_grubnet_fini. - * grub-core/net/ethernet.c (send_ethernet_packet): Open card if it isn't - already. - * grub-core/net/net.c (grub_net_network_level_interface_register): - Update num_ifaces. - (grub_net_card_unregister): Close all interfaces. - (receive_packets): Don't poll if no iterfaces are registered. - Open if necessary. - (grub_net_fini_hw): New function. - (grub_net_restore_hw): Likewise. - (fini_hnd): New variable. - (GRUB_MOD_INIT): Register preboot hook. - (GRUB_MOD_FINI): Run and unregister preboot hook. - - Poll network cards when idle. - - * grub-core/kern/term.c (grub_net_poll_cards_idle): New variable. - (grub_checkkey): Call grub_net_poll_cards_idle if it's not NULL. - * grub-core/net/net.c (receive_packets): Save last poll time. - (grub_net_poll_cards_idle_real): New function. - (GRUB_MOD_INIT): Register grub_net_poll_cards_idle. - (GRUB_MOD_FINI): Unregister grub_net_poll_cards_idle. - * include/grub/kernel.h (grub_poll_cards_idle): New extern variable. - - Rename ofnet interfaces. - - * grub-core/net/drivers/ieee1275/ofnet.c (find_alias): New function. - (grub_ofnet_findcards): Use ofnet_%s names. - - * util/grub-mknetdir.in: Support for EFI and IEEE1275. - - Cleanup socket opening. - - * grub-core/net/net.c (grub_net_fs_open): Rewritten. - (grub_net_fs_close): Likewise. - (grub_net_fs_read_real): Use eof member. - * include/grub/net/udp.h (+grub_net_udp_open): New proto. - (+grub_net_udp_close): New inline function. - - * include/grub/net/tftp.h: Moved to the top of ... - * grub-core/net/tftp.c: ... here. - * include/grub/net/ip.h: Moved mostly to the top of ... - * grub-core/net/ip.c: ... here. - * include/grub/net/ethernet.h: Moved mostly to the top of ... - * grub-core/net/ethernet.c: ... here. - - * grub-core/kern/device.c (grub_device_close): Free device->net->server. - - * grub-core/commands/probe.c (grub_cmd_probe): Use protocol name for - FS name. - - * include/grub/net/ip.h (ipv4_ini): Removed. - (ipv4_fini): Likewise. - - * include/grub/net/ip.h (grub_net_recv_ip_packets): New proto. - (grub_net_send_ip_packets): Likewise. - -2011-07-05 Vladimir Serbinenko - - * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_init): Use new - grub_read_cmos prototype. - -2011-07-05 Vladimir Serbinenko - - VGA text support in qemu-mips - - * grub-core/Makefile.core.def (kernel): Add term/i386/pc/vga_text.c, - term/i386/vga_common.c and kern/vga_init.c on qemu-mips. - * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Init vga - text. - * grub-core/kern/i386/qemu/init.c: Renamed to ... - * grub-core/kern/vga_init.c: ... this. - * grub-core/kern/vga_init.c (VGA_ADDR) [__mips__]: Adjust. - (grub_qemu_init_cirrus) [__mips__]: Skip PCI and adjust the I/O base. - * grub-core/term/i386/pc/vga_text.c (VGA_TEXT_SCREEN) [__mips__]: - Adjust. - * include/grub/vga.h [GRUB_MACHINE_MIPS_QEMU_MIPS]: Declare - GRUB_MACHINE_PCI_IO_BASE. - -2011-07-05 Vladimir Serbinenko - - MIPS qemu flash support. - - * grub-core/boot/mips/startup_raw.S [GRUB_MACHINE_MIPS_QEMU_MIPS]: Check - magic. - * grub-core/kern/mips/qemu_mips/init.c (probe_mem): New function. - (grub_machine_init): Probe memory if its size isn't known. - * util/grub-mkimage.c (image_targets): Add flash targets. - (generate_image): Handle flash targets. - -2011-07-05 Vladimir Serbinenko - - MIPS qemu at_keyboard support. - - * gentpl.py (videoinkernel): Add qemu-mips. - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add necessary headers. - * grub-core/Makefile.core.def (kernel): Add at_keyboard and layout. - * grub-core/kern/mips/qemu_mips/init.c (grub_machine_init): Init new - modules. - * grub-core/term/at_keyboard.c (grub_keyboard_controller_init) - [GRUB_MACHINE_MIPS_QEMU_MIPS]: Don't consider original set. - * grub-core/term/serial.c (grub_serial_register) - [GRUB_MACHINE_MIPS_QEMU_MIPS]: Make com0 explicitly active. - -2011-07-05 Vladimir Serbinenko - - CMOS support on sparc. - - * gentpl.py (cmos): Add powerpc and sparc. - * grub-core/Makefile.core.def (datetime): Add lib/ieee1275/cmos.c on - powerpc and sparc. - * grub-core/lib/cmos_datetime.c (grub_get_datetime) - [__powerpc__ || __sparc__]: Rename to grub_get_datetime_cmos. - (grub_set_datetime) [__powerpc__ || __sparc__]: Likewise to - grub_set_datetime_cmos. - * grub-core/lib/ieee1275/cmos.c: New file. - * grub-core/lib/ieee1275/datetime.c (no_ieee1275_rtc): New vaiable. - (find_rtc): Set no_ieee1275_rtc on error. - (grub_get_datetime): Call grub_get_datetime_cmos on error. - (grub_set_datetime): Call grub_set_datetime_cmos on error. - * include/grub/cmos.h (grub_cmos_read): Return grub_err_t since it may - fail. Move value to argument. All users updated - (grub_cmos_write): Likewise. - (grub_cmos_read) [__powerpc__ || __sparc__]: Rewritten. - (grub_cmos_write) [__powerpc__ || __sparc__]: Likewise. - * include/grub/datetime.h [__powerpc__ || __sparc__]: Declare - grub_get_datetime_cmos and grub_set_datetime_cmos. - -2011-07-02 Grégoire Sutre - - * util/grub-mkconfig.in: Use @PACKAGE@ instead of hardcoded name when - sourcing grub-mkconfig_lib. - * util/update-grub_lib.in: Likewise. - * util/grub.d/00_header.in: Likewise. - * util/grub.d/10_hurd.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - -2011-06-28 Colin Watson - - * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Use - default_bg_color rather than black. - (grub_gfxterm_fullscreen): Likewise. - (grub_gfxterm_background_color_cmd): Save new background color in - default_bg_color. - -2011-06-27 Vladimir Serbinenko - - * grub-core/Makefile.core.def (chain): Fix coreboot filename. - -2011-06-27 Vladimir Serbinenko - - * grub-core/disk/pata.c (grub_pata_initialize) [QEMU_MIPS]: Fix a - mismerge. - -2011-06-27 Vladimir Serbinenko - - Chainloading on coreboot support. - - * grub-core/Makefile.core.def (chain): Add coreboot. - * grub-core/loader/i386/coreboot/chainloader.c: New file. - -2011-06-27 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c (grub_bsd_load): Handle relocator failure - if it happens. - -2011-06-27 Vladimir Serbinenko - - Implement time command. - - * grub-core/Makefile.core.def (time): New module. - * grub-core/commands/time.c: New file. - * grub-core/script/parser.y: Remove "time" keyword. - * grub-core/script/yylex.l: Likewise. - -2011-06-27 Vladimir Serbinenko - - * include/grub/loader.h (grub_loader_unregister_preboot_hook): Export. - -2011-06-27 Vladimir Serbinenko - - * grub-core/lib/relocator.c (malloc_in_range): Fix a memory corruption - when handling leftovers. - -2011-06-27 Vladimir Serbinenko - - * util/ieee1275/grub-ofpathname.c (main): Handle --help and --version - so that help2man doesn't fail. - -2011-06-27 Vladimir Serbinenko - - * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer) Use right - type in pointers on sparc64. - (get_card_packet): Likewise. - -2011-06-27 Colin Watson - - * grub-core/commands/videoinfo.c (hook): Indicate current video mode - with `*'. - (grub_cmd_videoinfo): Fetch current video mode. - -2011-06-27 Vladimir Serbinenko - - * grub-core/disk/scsi.c (grub_scsi_read): Limit SCSI reads to 32K - because of underlying system restrictions. - -2011-06-27 Vladimir Serbinenko - - * util/grub-mkrescue.in: Rename "ata" to "pata" and add ahci when - necessary. - -2011-06-27 Vladimir Serbinenko - - Coreboot video support. - - * grub-core/Makefile.core.def (vga): Extend to coreboot and multiboot. - (vbe): Likewise. - * grub-core/kern/i386/coreboot/startup.S: Include int.S. - * grub-core/kern/i386/pc/startup.S (grub_bios_interrupt): Moved from - here ... - * grub-core/kern/i386/int.S: ... here. - * grub-core/video/i386/pc/vbe.c: Updated includes. - * grub-core/video/i386/pc/vga.c: Likewise. - * include/grub/i386/coreboot/memory.h - (GRUB_MEMORY_MACHINE_SCRATCH_ADDR): New definition. - (GRUB_MEMORY_MACHINE_SCRATCH_SEG): Likewise. - (GRUB_MEMORY_MACHINE_SCRATCH_SIZE): Likewise. - * include/grub/i386/pc/int.h (GRUB_CPU_INT_FLAGS_DEFAULT) [!PCBIOS]: - Disable interrupts. - * include/grub/i386/pc/vga.h: Removed. All users updated. - -2011-06-27 Vladimir Serbinenko - - * grub-core/disk/ahci.c (grub_ahci_readwrite_real): Use proper - definitions for dprintf. - * grub-core/disk/pata.c (grub_pata_readwrite): Likewise. - -2011-06-27 Vladimir Serbinenko - - * grub-core/net/drivers/ieee1275/ofnet.c (send_card_buffer): Fix - prototype. - (get_card_packet): Likewise. - -2011-06-26 Yves Blusseau - - Display the path of the file when file is not found - - * grub-core/fs/fat.c: Display the filename when file is not found. - * grub-core/fs/fshelp.c: Likewise. - * grub-core/fs/hfs.c: Likewise. - * grub-core/fs/jfs.c: Likewise. - * grub-core/fs/minix.c: Likewise. - * grub-core/fs/ufs.c: Likewise. - * grub-core/fs/btrfs.c: Likewise. - * grub-core/commands/i386/pc/play.c: Likewise. - -2011-06-26 Szymon Janc - - * grub-core/commands/cmp.c (grub_cmd_cmp): Remove unnecessary NULL - pointer checks before calling grub_free(). - * grub-core/commands/wildcard.c (match_devices): Likewise. - * grub-core/commands/wildcard.c (match_files): Likewise. - * grub-core/fs/cpio.c (grub_cpio_dir): Likewise. - * grub-core/fs/cpio.c (grub_cpio_open): Likewise. - * grub-core/fs/udf.c (grub_udf_read_block): Likewise. - * grub-core/fs/xfs.c (grub_xfs_read_block): Likewise. - * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Likewise. - * grub-core/normal/cmdline.c (grub_cmdline_get): Likewise. - * grub-core/script/yylex.l (grub_lexer_unput): Likewise. - * grub-core/video/readers/jpeg.c (grub_video_reader_jpeg): Likewise. - * grub-core/video/readers/png.c (grub_png_output_byte): Likewise. - -2011-06-25 Patrick - - * grub-core/kern/main.c (grub_load_normal_mode): Correct the comment. - -2011-06-25 Vladimir Serbinenko - - * grub-core/net/i386/pc/pxe.c (grub_pxe_recv): Fix declaration. - (grub_pxe_send): Likewise. - (GRUB_MOD_INIT): Fix types. - -2011-06-24 Szymon Janc - - * grub-core/io/xzio.c: Fix code style issues - -2011-06-24 Vladimir Serbinenko -2011-06-24 Manoel Rebelo Abranches - - Network infrastructure. - The ARP protocol was made by Paulo Pinatti - - * include/grub/net/arp.h: New file. - * include/grub/net/device.h: Likewise. - * include/grub/net/ethernet.h: Likewise. - * include/grub/net/ip.h: Likewise. - * include/grub/net/netbuff.h: Likewise. - * include/grub/net/tftp.h: Likewise. - * include/grub/net/udp.h: Likewise. - * include/grub/ieee1275/ofnet.h: Likewise. - * include/grub/emu/export.h: Likewise. - * include/grub/net.h: Likewise. - * grub-core/net/arp.c: Likewise. - * grub-core/net/ethernet.c: Likewise. - * grub-core/net/ip.c: Likewise. - * grub-core/net/udp.c: Likewise. - * grub-core/net/tftp.c: Likewise. - * grub-core/net/netbuff.c: Likewise. - * grub-core/net/net.c: Likewise. - * grub-core/net/drivers/emu/emunet.c: Likewise. - * grub-core/net/drivers/ieee1275/ofnet.c: Likewise. - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add net.h, ofnet.h and - export.h. - * grub-core/Makefile.core.def (net): New module. - (tftp): Likewise. - (ofnet): Likewise. - (emunet): Likewise. - * grub-core/commands/ls.c (grub_ls_list_devices) [!GRUB_UTIL]: List - network protocols. - * grub-core/kern/device.c (grub_net_open) : New variable. - (grub_device_open): Handle network device. - (grub_device_close): Likewise. - * grub-core/kern/file.c (grub_file_net_seek) : New variable. - (grub_grubnet_fini): Likewise. - (grub_file_seek): Seek in network device. - * grub-core/kern/fs.c (grub_fs_probe): Handle network devices. - * grub-core/kern/ieee1275/init.c (grub_machine_set_prefix): Handle - network root. - (grub_machine_fini): Call grub_grubnet_fini. - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_parse_args): Handle - network. - (grub_ieee1275_get_aliasdevname): New function. - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_get_mbi_size): - Add unofficial Solaris network info. - (grub_multiboot_make_mbi): Likewise. - * grub-core/fs/i386/pc/pxe.c: Moved from here ... - * grub-core/net/i386/pc/pxe.c: ...here. Adapted for new design. - * include/grub/device.h (grub_fs): Removed. - * include/grub/err.h (grub_err_t): Add network-related values. - * include/grub/i386/pc/pxe.h: Removed bootp parts. - * include/grub/ieee1275/ieee1275.h (grub_ofnetcard_data): New struct. - (grub_ieee1275_get_aliasdevname): New proto. - * include/grub/net.h: Rewritten. - -2011-06-24 Vladimir Serbinenko - - * grub-core/disk/raid.c (insert_array): Ensure uniqueness of readable - names. - -2011-06-24 Vladimir Serbinenko - - * grub-core/commands/wildcard.c (match_files): Add a useful dprintf. - (wildcard_expand): Don't stop on nonregexp parts after regexp ones since - it truncates the output. - Reported by: Ximin Luo. - -2011-06-24 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Skip . and .. - -2011-06-24 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Load - partmap before abstraction. - -2011-06-24 Alexander Kurtz - - * util/grub-mkconfig_lib.in: Add missing quotes. - -2011-06-24 Vladimir Serbinenko - - * grub-core/kern/emu/getroot.c (grub_guess_root_device): Revert to - old method if mountinfo would return /dev/root and /dev/root doesn't - exist. - -2011-06-24 Vladimir Serbinenko - - ZFS zlib support - - * grub-core/fs/zfs/zfs.c (zlib_decompress): New function. - (decomp_table): Add zlib entries. - (zio_read): USe 8 bits for compression function rather than 3. - * include/grub/zfs/zio.h (zio_compress): Add zlib values. - -2011-06-24 Vladimir Serbinenko - - * grub-core/disk/ahci.c: Add missing license statements. - * grub-core/fs/romfs.c: Likewise. - * grub-core/lib/ia64/setjmp.S: Likewise. - * grub-core/loader/i386/pc/freedos.c: Likewise. - * grub-core/loader/ia64/efi/linux.c: Likewise. - * grub-core/video/colors.c: Likewise. - * include/grub/dl.h (GRUB_MOD_DEP): New macro. - -2011-06-23 Vladimir Serbinenko - - AHCI support. - - * grub-core/Makefile.core.def (ata_pthru): Removed. - (ahci): New module. - (pata): Likewise. - * grub-core/bus/usb/ohci.c (GRUB_MOD_FINI): Unregister preboot hook - on unload. - * grub-core/commands/hdparm.c (grub_hdparm_do_ata_cmd): Use ATA - readwrite. - (grub_hdparm_do_check_powermode_cmd): Likewise. - (grub_hdparm_do_smart_cmd): Likewise. - (grub_hdparm_set_val_cmd): Likewise. - (grub_cmd_hdparm): Likewise. Check thta we have an ATA device. - * grub-core/disk/ahci.c: New file. - * grub-core/disk/ata.c: Factor out the low-level part into ... - * grub-core/disk/pata.c: ... here. - * grub-core/disk/ata_pthru.c: Contents moved to ... - * grub-core/disk/pata.c: ... here. - * grub-core/disk/scsi.c (grub_scsi_names): New array. - (grub_scsi_iterate): Use grub_scsi_names. - (grub_scsi_open): Likewise. - * grub-core/kern/disk.c (grub_disk_ata_pass_through): Removed. - * include/grub/ata.h (grub_ata_commands): Add DMA commands. - (grub_ata_regs_t): New struct. - (grub_disk_ata_pass_through_parms): Likewise. - (grub_ata_device): Renamed to ... - (grub_ata): ... this. - (grub_ata_dev): New struct. - Removed all low-level inline functions. - * include/grub/scsi.h: Add PATA and AHCI subsystems. - (grub_scsi_dev): Removed 'name' and 'id'. Added 'id' parameter to - iterate hooks and open. All users updated. - * util/grub-install.in: Handle AHCI disk module. - -2011-06-23 Szymon Janc - - Add support for DRI and RSTn markers in JPEG files. - - * grub-core/video/readers/jpeg.c (JPEG_MARKER_DRI): New define. - (JPEG_MARKER_RST0): Likewise. - (JPEG_MARKER_RST1): Likewise. - (JPEG_MARKER_RST2): Likewise. - (JPEG_MARKER_RST3): Likewise. - (JPEG_MARKER_RST4): Likewise. - (JPEG_MARKER_RST5): Likewise. - (JPEG_MARKER_RST6): Likewise. - (JPEG_MARKER_RST7): Likewise. - (grub_jpeg_data): New fields dri, r1, bitmap_ptr. - (grub_jpeg_decode_dri): New function. - (grub_jpeg_decode_sos): Move image data related part into - grub_jpeg_decode_data function. - (grub_jpeg_decode_data): New function. - (grub_jpeg_reset): New function. - (grub_jpeg_decode_jpeg): Handle new markers. - -2011-06-23 Vladimir Serbinenko - - * util/ieee1275/ofpath.c (check_sas): Close fd. - (main): Free of_path. - Reported by: David Volgyes . - -2011-06-23 Vladimir Serbinenko - - * util/grub-mkpasswd-pbkdf2.c (main): Don't double-close. - Reported by: David Volgyes . - -2011-06-23 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Close - file after stat. - Reported by: David Volgyes . - -2011-06-23 Vladimir Serbinenko - - * util/raid.c (grub_util_raid_getmembers): Close fd before returning. - - Reported by: David Volgyes . - -2011-06-23 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (rs_recover) [STANDALONE]: - Prevent memory leak. - -2011-06-23 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (rs_recover): Prevent memory leak. - (main): Close file. - Reported by: David Volgyes . - -2011-06-23 Vladimir Serbinenko - - * grub-core/loader/i386/xnu.c (grub_cpu_xnu_fill_devprop): Don't attempt - to continue if allocation is failed. - - Reported by: David Volgyes . - -2011-06-23 David Volgyes - - * grub-core/bus/usb/ohci.c (grub_ohci_pci_iter): Avoid NULL-pointer - dereference. - -2011-06-23 Vladimir Serbinenko - - Fix spurious warning. - - * grub-core/partmap/acorn.c (grub_acorn_boot_block): Make a union. - (acorn_partition_map_find): Use .bin member. - -2011-06-23 Vladimir Serbinenko - - * grub-core/kern/emu/getroot.c (grub_guess_root_device): Don't accept - /dev/root as a valid device. - -2011-06-23 Jim Meyering - - Avoid NULL deref in grub_device_open. - - * grub-core/kern/device.c (grub_device_open): Don't dereference - a NULL pointer upon failed grub_env_get. - -2011-06-23 Vladimir Serbinenko - - Support non-512B sectors and agglomerate reads. - - * Makefile.util.def (libgrubmods.a): Add grub-core/commands/testload.c. - * grub-core/disk/efi/efidisk.c (grub_efidisk_data): Remove disk_io. - (disk_io_guid): Removed. - (make_devices): Locate solely by BlockIO. - (grub_efidisk_open): Fill log_sector_size and total_sectors. - (grub_efidisk_read): Use read_blocks. - (grub_efidisk_write): Use write_blocks. - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_open): Fill - log_sector_size. - (get_safe_sectors): Handle non-512B sectors. - (grub_biosdisk_read): Remove special CDROM handling. Handle non-512B - sectors. - (grub_biosdisk_write): Handle non-512B sectors. - * grub-core/disk/scsi.c (grub_scsi_open): Fill log_sector_size. - (grub_scsi_read): Remove special non-512B block handling (now handled - one level up). - * grub-core/kern/disk.c (grub_disk_open): Fill default log_sector_size - and do sanity checks. - (grub_disk_adjust_range): Handle non-512B sectors. - (transform_sector): New function. - (grub_disk_read_small): Likewise. - (grub_disk_read): Rewritten. - (grub_disk_write): Handle non-512B sectors. - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_open): Fill - log_sector_size. - (open_device): Use log_sector_size. - (grub_util_biosdisk_read): Likewise. - (grub_util_biosdisk_write): Likewise. - * grub-core/partmap/msdos.c (grub_partition_msdos_iterate): Handle - non-512B sectors. - (pc_partition_map_embed): Likewise. - * include/grub/disk.h (grub_disk): New field log_sector_size. - (GRUB_DISK_CACHE_SIZE): Redefined from GRUB_DISK_CACHE_BITS. - (GRUB_DISK_CACHE_BITS): Increased to 6. - * util/grub-fstest.c (fstest): New command testload. - (argp_parser): Likewise. - -2011-06-16 Robert Millan - - Detect `ataraid' devices on GNU/kFreeBSD. Fix for ATA devices using - `ata' driver on kernel of FreeBSD 9. - - * util/deviceiter.c [__FreeBSD_kernel__] (get_ada_disk_name) - (get_ataraid_disk_name): New functions. - [__FreeBSD_kernel__] (grub_util_iterate_devices): Scan for ataraid - (/dev/ar[0-9]+) and ada (/dev/ada[0-9]+) devices using - get_ataraid_disk_name() and get_ada_disk_name(). - -2011-06-13 Colin Watson - - * docs/man/grub-mklayout.h2m (DESCRIPTION): Add a reference to the - input format. - -2011-05-29 Colin Watson - - * docs/grub.texi (Obtaining and Building GRUB): Substitute - `ftp.gnu.org' for `alpha.gnu.org'. - -2011-05-27 Colin Watson - - * grub-core/kern/emu/hostdisk.c (linux_find_partition): Handle - partitions under /dev/disk/by-id/. - -2011-05-27 Colin Watson - - * grub-core/kern/emu/hostdisk.c (linux_find_partition): Give up - after ten consecutive open failures. Scanning all the way up to - 10000 is excessive and can cause serious performance problems in - some configurations. - Fixes Ubuntu bug #787461. - -2011-05-21 Vladimir Serbinenko - - * grub-core/disk/arc/arcdisk.c (reopen): Close old handle before - opening new one. - -2011-05-21 Colin Watson -2011-05-21 Vladimir Serbinenko - - Don't stat devices unless we have to. - - * grub-core/kern/emu/getroot.c (grub_find_device): Recognize - dir == /dev/mapper. - (grub_guess_root_device): Use already known os_dev if possible. - * grub-core/kern/emu/hostdisk.c - (convert_system_partition_to_system_disk): Scan only in /dev/mapper - if device is known to be a dm one. - -2011-05-20 Colin Watson - - * util/grub-mkconfig.in: Export GRUB_CMDLINE_LINUX_XEN_REPLACE and - GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT. - Reported by: Pawel Tecza. - -2011-05-19 Vladimir Serbinenko - - * grub-core/Makefile.core.def (lsacpi): Fix ia64 mismerge. - (lsefisystab): Likewise. - (lssal): Likewise. - (lsefimmap): Likewise. - (hdparm): Enable on qemu-mips. - (setjmp): Add ia64 nodist. - (serial): Simplify tags. - -2011-05-18 Colin Watson - - * Makefile.util.def (grub-ofpathname): Install manual page. - -2011-05-18 Colin Watson - - * grub-core/fs/squash4.c: Add missing GRUB_MOD_LICENSE. - -2011-05-18 Colin Watson - - * .bzrignore: Add grub-core/modinfo.sh and a number of test files. - -2011-05-18 Vladimir Serbinenko - - * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Downgrade a printf - into dprintf. - -2011-05-18 Vladimir Serbinenko - - Use full 64-bit division. - - * grub-core/kern/misc.c (grub_divmod64_full): Renamed to ... - (grub_divmod64): ... this. - * include/grub/misc.h (grub_divmod64): Removed. All users switch to full - version. - -2011-05-18 Colin Watson - - * util/grub-mkrescue.in: Use portable `.' rather than non-portable - `source'. - -2011-05-18 Colin Watson - - * grub-core/genmod.sh.in: Use 'set -e' rather than '#! /bin/sh -e', - to avoid accidents when debugging with 'sh -x'. - * grub-core/gensyminfo.sh.in: Likewise. - * tests/example_scripted_test.in: Likewise. - * tests/grub_cmd_regexp.in: Likewise. - * tests/grub_script_blanklines.in: Likewise. - * tests/grub_script_dollar.in: Likewise. - * tests/grub_script_expansion.in: Likewise. - * tests/grub_script_final_semicolon.in: Likewise. - * tests/partmap_test.in: Likewise. - * tests/util/grub-shell-tester.in: Likewise. - * tests/util/grub-shell.in: Likewise. - -2011-05-18 Colin Watson - - Move gfxmenu color handling to video, so that gfxterm can use it - too. - - * grub-core/gfxmenu/named_colors.c: Move to ... - * grub-core/video/colors.c: ... here. Rename - grub_gui_get_named_color to grub_video_get_named_color. - * grub-core/gfxmenu/gui_string_util.c (my_isxdigit): Move to ... - * grub-core/video/colors.c (my_isxdigit): ... here. - * grub-core/gfxmenu/gui_string_util.c (parse_hex_color_component): - Move to ... - * grub-core/video/colors.c (parse_hex_color_component): ... here. - * grub-core/gfxmenu/gui_string_util.c (grub_gui_parse_color): Move - to ... - * grub-core/video/colors.c (grub_video_parse_color): ... here. - - * include/grub/gui.h (grub_gui_color_t): Move to ... - * include/grub/video.h (grub_video_rgba_color_t): ... here. - * include/grub/gui.h (grub_gui_color_rgb): Move to ... - * include/grub/video.h (grub_video_rgba_color_rgb): ... here. - * include/grub/gui.h (grub_gui_map_color): Move to ... - * include/grub/video.h (grub_video_map_rgba_color): ... here. - * include/grub/gui_string_util.h (grub_gui_get_named_color): Move - to ... - * include/grub/video.h (grub_video_get_named_color): ... here. - * include/grub/gui_string_util.h (grub_gui_parse_color): Move to ... - * include/grub/video.h (grub_video_parse_color): ... here. - - * grub-core/Makefile.core.def (kernel) [videoinkernel]: Add - video/colors.c. - (gfxmenu): Remove gfxmenu/named_colors.c. - (video) [videomodules]: Add video/colors.c. - - Add a background_color command. - - * grub-core/term/gfxterm.c (grub_gfxterm_background_color_cmd): New - function. - (GRUB_MOD_INIT): Register background_color command. - (GRUB_MOD_FINI): Unregister background_color command. - (redraw_screen_rect): Allow blend/replace of text layer to be - controlled independently from whether there is a background bitmap. - (grub_gfxterm_background_image_cmd): Change blend_text_bg when - changing bitmap. - -2011-05-18 Vladimir Serbinenko - - Patch BPB in ntldr and chainloader --bpb. - - * grub-core/fs/fat.c: Include grub/fat.h. - (grub_fat_bpb): Moved to ... - * include/grub/fat.h (grub_fat_bpb): ... here. New file. - * grub-core/loader/i386/pc/chainloader.c: Include grub/fat.h and - grub/ntfs.h. - * include/grub/i386/pc/chainloader.h (grub_chainloader_flags_t): - Moved from here... - * grub-core/loader/i386/pc/chainloader.c (grub_chainloader_flags_t): ... - here. - * grub-core/loader/i386/pc/chainloader.c (grub_chainloader_patch_bpb): - New function. - (grub_chainloader_cmd): Patch BPB if --bpb is given. - (GRUB_MOD_INIT): Show --bpb. - * grub-core/loader/i386/pc/ntldr.c (grub_cmd_ntldr): Patch BPB. - * grub-core/normal/main.c (features): New variable. - (GRUB_MOD_INIT): Set feature_* variables. - * include/grub/i386/pc/chainloader.h (grub_chainloader_patch_bpb): New - proto. - * include/grub/ntfs.h (grub_ntfs_bpb): New field bios_drive. - -2011-05-18 Vladimir Serbinenko - - * grub-core/Makefile.core.def (ieee1275_fb): Use enable=powerpc_ieee1275 - for cleanness. - -2011-05-18 Vladimir Serbinenko - - FreeDOS direct loading support. - - * docs/grub.texi (Supported OS): Add FreeDOS. - * grub-core/Makefile.core.def (freedos): New module. - * grub-core/lib/i386/relocator.c (grub_relocator16_ebx): New extern - variable. - (grub_relocator16_boot): Handle %ebx. - * grub-core/lib/i386/relocator16.S: Likewise. - * grub-core/loader/i386/pc/freedos.c: New file. - -2011-05-18 Vladimir Serbinenko - - Long Linux command line support. - - * grub-core/loader/i386/linux.c (GRUB_LINUX_CL_END_OFFSET): Removed. - (maximal_cmdline_size): New variable. - (allocate_pages): Use maximal_cmdline_size. - (grub_cmd_linux): Set and use maximal_cmdline_size. - * grub-core/loader/i386/pc/linux.c (GRUB_LINUX_CL_END_OFFSET): Removed. - (allocate_pages): Use maximal_cmdline_size. - (grub_cmd_linux): Set and use maximal_cmdline_size. - * include/grub/i386/linux.h (GRUB_LINUX_SETUP_MOVE_SIZE): Removed. - (linux_kernel_header): Add fields kernel_alignment, relocatable, pad - and cmdline_size. - -2011-05-18 Vladimir Serbinenko -2011-05-18 Colin Watson - - Improve devmapper support - - * grub-core/kern/emu/getroot.c (grub_util_is_dmraid): Removed. - (grub_util_is_lvm): New function. - (grub_util_get_dev_abstraction): Assume dmraid if not lvm rather - than lvm if not dmraid. - Handle mapped md nodes. - * grub-core/kern/emu/hostdisk.c (device_is_mapped): Rename to ... - (grub_util_device_is_mapped): ... this. Make always available. All users - updated. - (grub_util_get_dm_node_linear_info) [HAVE_DEVICE_MAPPER]: New function. - (convert_system_partition_to_system_disk): Handle lvm, mpath and - dmraid nodes. - * include/grub/emu/misc.h (grub_util_device_is_mapped): New proto. - -2011-05-18 Vladimir Serbinenko - - Unify grub-mkrescue (except powerpc) and grrub-mknetdir across platforms - - * grub-core/Makefile.am (platform_DATA): Add modinfo.sh. - * grub-core/modinfo.sh.in: New file. - * grub-core/Makefile.core.def (modinfo.sh): New script. - * util/grub-mknetdir.in: Use modinfo.sh. - * util/grub-mkrescue.in: Likewise. - -2011-05-17 Vladimir Serbinenko - - * grub-core/kern/ia64/dl_helper.c (grub_ia64_dl_get_tramp_got_size): - Fix potential usage of Elf32 instead of Elf64 when compiling on - 32-bit architecture. Add endianness macros while on it. - -2011-05-17 Vladimir Serbinenko - - Use mipsel- rather than mips- in directories involving mipsel ports to - allow both endiannesses coexist. - - * configure.ac: proparate target_cpu=mipsel rather than resetting to - mips. All conditions adjusted. - * tests/util/grub-shell-tester.in: Remove gratuitious target_cpu - variable. - * util/grub-install.in: Adjust conditions to take renaming into account. - * util/grub-mkimage.c (image_targets): Likewise. New target - mips-qemu_mips-elf for bigendian mips. - -2011-05-17 Vladimir Serbinenko - - Avoid unnecessary copying on MIPS. - - * grub-core/boot/decompressor/none.c (grub_decompress_core): Exit - early if src == dest. - * util/grub-mkimage.c (generate_image): Arange for src == dest if - compression is none. - -2011-05-17 Vladimir Serbinenko - - Reduce memory footprint on SGI by putting modules before the kernel - as opposed to after. - - * grub-core/Makefile.core.def (kernel): Increase linking address. - (none_decompress): Likewise. - (xz_decompress): Likewise. - * grub-core/boot/mips/startup_raw.S: Use prewritten uncompression - address. - * grub-core/kern/mips/arc/init.c (grub_machine_init): Handle memory - layout change. - (grub_arch_modules_addr): New function. - * grub-core/kern/mips/init.c (grub_arch_modules_addr): Moved from here... - * grub-core/kern/mips/loongson/init.c (grub_arch_modules_addr): .. here - * grub-core/kern/mips/qemu_mips/init.c (grub_arch_modules_addr): ... and - here. - * grub-core/kern/mips/startup.S (total_size): Rename to ... - (grub_total_modules_size): ... this. Make global. - [GRUB_MACHINE_ARC]: Don't attempt to move modules out of the bss. - * include/grub/offsets.h (GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR): - New definition. - (GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR): Likewise. - (GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_ADDR): Likewise. - (GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR): Likewise. - (GRUB_KERNEL_MIPS_ARC_LINK_ADDR): Increased. - * util/grub-mkimage.c (image_target_desc): New flag - PLATFORM_FLAGS_MODULES_BEFORE_KERNEL. - (image_targets): Set PLATFORM_FLAGS_MODULES_BEFORE_KERNEL on mips-arc. - (generate_image): Handle images with modules before kernel. - -2011-05-17 Vladimir Serbinenko - - Prevent potential loss of memory map by overwrite on qemu-mips. - - * grub-core/boot/mips/startup_raw.S [GRUB_MACHINE_MIPS_QEMU_MIPS]: - Save ram size in $s4. - * grub-core/kern/mips/qemu_mips/init.c (RAMSIZE): Removed. - All users changed to grub_arch_memsize. - * grub-core/kern/mips/startup.S (grub_arch_machine): Restrict to - Loongson. - [GRUB_MACHINE_MIPS_QEMU_MIPS]: Save grub_arch_memsize. - * grub-core/loader/mips/linux.c (grub_linux_boot): Pass memory size. - * include/grub/mips/qemu_mips/memory.h (grub_arch_memsize): New - external variable. - -2011-05-17 Colin Watson - - * .bzrignore: Remove grub-dumpbios. - -2011-05-17 Colin Watson - - * util/grub.d/20_linux_xen.in: Honour GRUB_CMDLINE_LINUX_XEN_REPLACE - and GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT, which replace - GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT (complementing the - existing options which append). - * docs/grub.texi (Simple configuration): Document new options. - Reported by: Ian Jackson. Fixes Debian bug #617538. - -2011-05-17 Colin Watson - - * util/grub-fstest.c (cmd_cat): New function. - (fstest): Handle CMD_CAT. - (options): Add cat. - (argp_parser): Handle cat. - -2011-05-17 Colin Watson - - * Makefile.util.def (grub-bin2h): Don't install. - * docs/man/grub-bin2h.h2m: Remove. - -2011-05-17 Vladimir Serbinenko - - * grub-core/kern/mips/startup.S (grub_arch_cpuclock): Move to the right - place. - -2011-05-17 Vladimir Serbinenko - - Reenable qemu-mips port. - - * configure.ac: Handle --target=qemu-mips and --target=qemu_mips. - Fix small arc bug while on it. - * gentpl.py: Handle qemu_mips. - * grub-core/Makefile.am: Likewise. - * grub-core/Makefile.core.def: Likewise. - * grub-core/disk/ata.c [GRUB_MACHINE_MIPS_QEMU_MIPS]: Remove - inappropriate includes. - (grub_ata_pciinit) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Removed. - (grub_ata_initialize): [GRUB_MACHINE_MIPS_QEMU_MIPS]: Rewritten. - * grub-core/kern/main.c (grub_modules_get_end) - [GRUB_MACHINE_MIPS_QEMU_MIPS]: Enable. - * grub-core/kern/mips/qemu-mips: Moved to .. - * grub-core/kern/mips/qemu_mips: ... this. - * grub-core/kern/mips/qemu_mips/init.c (grub_get_rtc): Removed. - (grub_machine_init): Call terminfo_init and serial_init. - * grub-core/kern/mips/startup.S: Change MIPS_LOONGSON to MACHINE. - * grub-core/loader/mips/linux.c (params) [GRUB_MACHINE_MIPS_QEMU_MIPS]: - New variable. - (grub_linux_boot) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Handle the qemu-mips - parameter passing. - (grub_linux_unload) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Free params. - (grub_cmd_linux) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Handle params. - (grub_cmd_initrd) [GRUB_MACHINE_MIPS_QEMU_MIPS]: Likewise. - * include/grub/mips/qemu_mips/cmos.h: New file. - * include/grub/mips/qemu-mips/kernel.h: Don't include cpu/kernel.h. - * include/grub/mips/qemu-mips/memory.h (grub_machine_mmap_iterate): - Removed. - * include/grub/mips/qemu-mips/serial.h (GRUB_MACHINE_SERIAL_PORTS): - Use correct mips-style address. - * include/grub/mips/qemu-mips/time.h: Include cpu/time.h. - (GRUB_TICKS_PER_SECOND): Removed. - (grub_get_rtc): Likewise. - (grub_cpu_idle): Likewise. - * include/grub/offsets.h (GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR): - New definition. - (GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_COMPRESSED_SIZE): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_UNCOMPRESSED_SIZE): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_PREFIX_END): Likewise. - (GRUB_KERNEL_MIPS_QEMU_MIPS_MOD_ALIGN): Likewise. - * util/grub-mkimage.c (image_targets): Add mipsel-qemu_mips-elf. - -2011-05-17 Vladimir Serbinenko - - SGI ARCS port. - - * Makefile.util.def (libgrubmods.a): Add dvh.c. - * conf/Makefile.common (CCASFLAGS_PLATFORM): Add -mips3 on all mips - platforms. - * configure.ac: New target mips-arc. - * gentpl.py: Likewise. - * grub-core/Makefile.am: Likewise. - * grub-core/Makefile.core.def: Likewise. - (xz_decompress): Remove -D GRUB_MACHINE_LINK_ADDR. - (none_decompress): Likewise. - (lsdev): New module. - (datetime): Use lib/arc/datetime.c on ARC. - (part_dvh): New module. - * grub-core/commands/arc/lsdev.c: New file. - * grub-core/disk/arc/arcdisk.c: Likewise. - * grub-core/kern/mips/arc/init.c: Likewise. - * grub-core/kern/mips/cache_flush.S: Don't flush non 4-byte - aligned addresses. - * grub-core/kern/mips/dl.c (grub_arch_dl_check_header): Fix bigendian - support. - (grub_arch_dl_relocate_symbols): Likewise. - * grub-core/kern/mips/loongson/init.c (grub_get_rtc): Moved from here... - * grub-core/kern/mips/init.c (grub_get_rtc): ... here. - * grub-core/kern/mips/startup.S (grub_arch_cpuclock): Have on all - platforms. - * grub-core/lib/arc/datetime.c: New file. - * grub-core/loader/mips/linux.c: Always include time.h. Don't include - pci.h on non-loongson. - (envp_off) [!GRUB_MACHINE_MIPS_LOONGSON]: Remove. - (grub_linux_boot): Set unused registers to 0. - (grub_cmd_linux) [!GRUB_MACHINE_MIPS_LOONGSON]: Remove envp. - * grub-core/mmap/mips/loongson/uppermem.c: Moved from here ... - * grub-core/mmap/mips/uppermem.c: ...here. - * grub-core/partmap/dvh.c: New file. - * grub-core/term/arc/console.c: Likewise. - * grub-core/term/terminfo.c (ANSI_C0_STR): New const. - (grub_terminfo_set_current): Add terminal "arc". - (grub_terminfo_readkey): Support ARC sequences. - * include/grub/arc/arc.h: New file. - * include/grub/arc/console.h: Likewise. - * include/grub/disk.h (grub_disk_dev_id): Add - GRUB_DISK_DEVICE_ARCDISK_ID. - * include/grub/mips/arc/kernel.h: New file. - * include/grub/mips/arc/memory.h: Likewise. - * include/grub/mips/arc/time.h: Likewise. - * include/grub/mips/loongson/kernel.h (grub_halt): Moved from here ... - * include/grub/mips/kernel.h (grub_halt): ... here. - * include/grub/mips/loongson.h (GRUB_CPU_REGISTER_WRAP): Moved from - here... - * include/grub/mips/mips.h (GRUB_CPU_REGISTER_WRAP): ... here. - (GRUB_CPU_LOONGSON_COP0_TIMER_COUNT): Moved from here ... - * include/grub/mips/mips.h (GRUB_CPU_LOONGSON_COP0_TIMER_COUNT): .. here - * include/grub/mips/loongson/kernel.h (grub_reboot): Removed redundant - proto. - * include/grub/mips/loongson/memory.h (GRUB_ARCH_LOWMEMVSTART): Moved - from here ... - * include/grub/mips/memory.h (GRUB_ARCH_LOWMEMVSTART): ... here. - (GRUB_ARCH_LOWMEMPSTART): Moved from here ... - * include/grub/mips/memory.h (GRUB_ARCH_LOWMEMPSTART): ... here. - (GRUB_ARCH_LOWMEMMAXSIZE): Moved from here ... - * include/grub/mips/memory.h (GRUB_ARCH_LOWMEMMAXSIZE): ... here. - (GRUB_ARCH_HIGHMEMPSTART): Moved from here ... - * include/grub/mips/memory.h (GRUB_ARCH_HIGHMEMPSTART): ... here. - (grub_phys_addr_t): Moved from here ... - * include/grub/mips/memory.h (grub_phys_addr_t): ... here. - (grub_vtop): Moved from here ... - * include/grub/mips/memory.h (grub_vtop): ... here. - (grub_map_memory): Moved from here ... - * include/grub/mips/memory.h (grub_map_memory): ... here. - (grub_unmap_memory): Moved from here ... - * include/grub/mips/memory.h (grub_unmap_memory): ... here. - (grub_machine_mmap_iterate): Moved from here ... - * include/grub/mips/memory.h (grub_machine_mmap_iterate): ... here. - (grub_mmap_get_lower): Moved from here ... - * include/grub/mips/memory.h (grub_mmap_get_lower): ... here. - (grub_mmap_get_upper): Moved from here ... - * include/grub/mips/memory.h (grub_mmap_get_upper): ... here. - * include/grub/mips/loongson/time.h (grub_arch_cpuclock): Moved from - here ... - * include/grub/mips/time.h (grub_arch_cpuclock): ... here. - * include/grub/mips/loongson/time.h (grub_get_rtc): Moved from - here ... - * include/grub/mips/time.h (grub_get_rtc): ... here. - * include/grub/mips/loongson/time.h (grub_arch_cpuclock): Moved from - here ... - * include/grub/mips/time.h (grub_arch_cpuclock): ... here. - * include/grub/mips/loongson/time.h (grub_cpu_idle): Moved from - here ... - * include/grub/mips/time.h (grub_cpu_idle): ... here. - * include/grub/offsets.h (GRUB_KERNEL_MIPS_ARC_LINK_ADDR): New - definition. - (GRUB_KERNEL_MIPS_ARC_LINK_ALIGN): Likewise. - (GRUB_KERNEL_MIPS_ARC_COMPRESSED_SIZE): Likewise. - (GRUB_KERNEL_MIPS_ARC_UNCOMPRESSED_SIZE): Likewise. - (GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE): Likewise. - (GRUB_KERNEL_MIPS_ARC_PREFIX): Likewise. - (GRUB_KERNEL_MIPS_ARC_PREFIX_END): Likewise. - (GRUB_KERNEL_MIPS_ARC_MOD_ALIGN): Likewise. - (GRUB_MACHINE_LINK_ADDR): Likewise. - * include/grub/terminfo.h (GRUB_TERMINFO_READKEY_MAX_LEN): Increased - to 6. - * util/grub-install.in: Run dvhtool on ARC. - * util/grub-mkimage.c (image_targets): Add mips-arc. - (generate_image): Handle ECOFF output for mips-arc. - -2011-05-16 Vladimir Serbinenko - - * grub-core/bus/pci.c (grub_memalign_dma32): Always allocate in 64-byte - blocks. - -2011-05-16 Vladimir Serbinenko - - * grub-core/bus/usb/usbhub.c (attach_root_port): Wait 10ms - after enabling port. - -2011-05-16 Vladimir Serbinenko - - Skip incorrect USB devices. - - * grub-core/bus/usb/usb.c (grub_usb_device_initialize): Fail if - configcnt == 0. - * include/grub/usb.h (grub_usb_err_t): New enum value - GRUB_USB_ERR_BADDEVICE. - -2011-05-16 Vladimir Serbinenko - - Fuloong video init support. - - * include/grub/vga.h (grub_vga_write_arx): inb monochrome address as - well. - (grub_vga_read_arx): New function. - * grub-core/video/sis315pro.c (GRUB_SIS315PRO_MMIO_SPACE): New - definition. - (framebuffer): New members io, mmioptr and mmiobase. - (read_sis_cmd): New function. - (write_sis_cmd): Likewise. - (grub_video_sis315pro_setup): Do the initialisation. Use 640x480 - rather than 640x400. - * grub-core/video/sis315_init.c: New file. - -2011-05-15 Vladimir Serbinenko - - * grub-core/bus/cs5536.c: Don't include grub/machine/kernel.h on - non-loongson. - * grub-core/kern/mips/dl.c (grub_arch_dl_init_linker): Fix argument - to grub_dl_register_symbol. - -2011-05-15 Vladimir Serbinenko - - Fix compilation errors. - - * grub-core/term/ns8250.c (serial_get_divisor): Declare 'port' as - potentially unused. - * grub-core/loader/i386/linux.c (grub_linux_setup_video): - Handle GRUB_VIDEO_DRIVER_SIS315PRO. - * grub-core/bus/cs5536.c (grub_cs5536_init_geode): Restrict DIVIL init - to loongson machines. - -2011-05-15 Vladimir Serbinenko - - Several FS mtime support. - - * grub-core/fs/affs.c (grub_affs_time): New struct. - (grub_affs_file): New field mtime. - (grub_fshelp_node): Changed 'block' and 'parent' to more appropriate - type. Removed 'size'. New field 'di'. All users updated. - (grub_affs_mount): Simplify checsum checking. - (grub_affs_iterate_dir): New helper grub_affs_create_node. - (grub_affs_dir): Handle mtime. - * grub-core/fs/cpio.c (grub_cpio_find_file): Handle mtime. - (grub_cpio_dir): Likewise. - * grub-core/fs/hfs.c (grub_hfs_dirrec): New fields 'ctime' and 'mtime'. - (grub_hfs_filerec): New field mtime. - (grub_hfs_dir): Handle mtime. - (grub_hfs_mtime): New function. - (grub_hfs_fs): Register grub_hfs_mtime. - * grub-core/fs/iso9660.c (grub_iso9660_date2): New struct. - (grub_iso9660_dir): New field mtime. - (grub_fshelp_node): New field dirent. - (iso9660_to_unixtime): New function. - (iso9660_to_unixtime2): Likewise. - (grub_iso9660_read_symlink): Use node->dirent. - (grub_iso9660_iterate_dir): Likewise. - (grub_iso9660_dir): Set mtime. - (grub_iso9660_mtime): New function. - (grub_iso9660_fs): Register grub_iso9660_mtime. - * grub-core/fs/jfs.c (grub_jfs_time): New struct. - (grub_jfs_inode): New fields atime, ctime and mtime. - (grub_jfs_dir): Set mtime. - * grub-core/fs/minix.c (grub_minix_dir): Likewise. - * grub-core/fs/ntfs.c (list_file): Set mtime. - (grub_ntfs_dir): Likewise. - * grub-core/fs/reiserfs.c (grub_fshelp_node): New field 'mtime'. - (grub_reiserfs_iterate_dir): Set mtime. - (grub_reiserfs_dir): Likewise. - * grub-core/fs/sfs.c (grub_sfs_obj): New field mtime. - (grub_fshelp_node): Likewise. - (grub_sfs_iterate_dir): Set mtime. - (grub_sfs_dir): Likewise. - * grub-core/fs/udf.c (grub_udf_dir): Set mtime. - * grub-core/fs/xfs.c (grub_xfs_time): New struct. - (grub_xfs_inode): New fields atime, mtime, ctime. - (grub_xfs_dir): Set mtime. - * include/grub/datetime.h (grub_datetime2unixtime): New function. - * include/grub/hfs.h (grub_hfs_sblock): New fields ctime and mtime. - * include/grub/ntfs.h (grub_fshelp_node): New field mtime. - - Support UDF symlinks. - - * grub-core/fs/udf.c (grub_udf_iterate_dir): Handle symlinks. - (grub_ufs_read_symlink): New function. All users updated. - - Check amiga partmap checksum. - - * grub-core/partmap/amiga.c (grub_amiga_rdsk): Pad to 128 bytes. - (grub_amiga_partition): Likewise. - (amiga_partition_map_checksum): New function. - (amiga_partition_map_iterate): Check checksum. - -2011-05-15 Vladimir Serbinenko - - ROMFS support. - - * Makefile.util.def (libgrubmods.a): Add romfs. - * grub-core/Makefile.core.def (romfs): New module. - * grub-core/fs/romfs.c: New file. - -2011-05-15 Vladimir Serbinenko - - Squashfs v4 support. - - * Makefile.util.def (libgrubmods.a): Add squash4. - * grub-core/Makefile.core.def (squash4): New module. - * grub-core/fs/squash4.c: New file. - * grub-core/io/gzio.c (grub_gzio): New members disk_input_off, - disk_input_start, disk_input. - (get_byte): Handle disk_input. - (grub_zlib_disk_read): New function. - * include/grub/deflate.h (grub_zlib_disk_read): New proto. - -2011-05-15 Vladimir Serbinenko -2011-05-15 Feiran Zheng - - * Makefile.util.def (libgrubmods.a): Add minix3. - * grub-core/Makefile.core.def (minix3): New module. - * grub-core/fs/minix.c (GRUB_MINIX_MAGIC) [MODE_MINIX3]: New value. - (GRUB_MINIX_BSIZE): Removed. - (GRUB_MINIX_INODE_DIR_BLOCKS): New definition. All users updated. - (grub_minix_ino_t): New type. - (grub_minix_le_to_cpu_ino): New macro. - (GRUB_MINIX_ZONE2SECT): New definition. All users updated. - (grub_minix_sblock) [MODE_MINIX3]: Change for minix3. - (grub_minix_data): New field block_size. - (grub_minix_read_file): Handle 64-bit correctly. - * grub-core/fs/minix3.c: New file. - -2011-05-15 Tristan Gingold -2011-05-15 Robert Millan -2011-05-15 Vladimir Serbinenko - - IA64 support. - - * Makefile.util.def (libgrubmods.a): Add grub-core/kern/ia64/dl_helper.c - * configure.ac: Add ia64-efi target. - Probe for __ia64_trampoline, __udivsi3, __umoddi3, __udivdi3, - __divsi3, __modsi3, __umodsi3, __moddi3 and __divdi3 symbols. - * gentpl.py: Add ia64_efi platform. - Rename x86_efi to efi and Add ia64-efi. All users updated. - * grub-core/Makefile.am: Set KERNEL_HEADER_FILES for ia64-efi. - * grub-core/Makefile.core.def (kernel.img): Add compile flags for ia64. - Remove kern/generic/rtc_get_time_ms.c on EFI. - Add kern/ia64/efi/startup.S, kern/ia64/efi/init.c, kern/ia64/dl.c, - kern/ia64/dl_helper.c on ia64-efi. - Add kern/emu/cache.c on emu. - (linux): Use on loader/ia64/efi/linux.c on ia64. - * grub-core/gensymlist.sh (grub_register_exported_symbols): Check - whether symbol is a function. - * grub-core/kern/dl.c [GRUB_MACHINE_EMU]: Include sys/mman.h. - (grub_symbol): New field 'isfunc'. - (grub_dl_resolve_symbol): Return whole symbol rather than just address. - (grub_dl_register_symbol): New argument 'isfunc'. All users updated. - (grub_dl_load_segments): Place all sections into the same region. - [__ia64__]: Create trampolines and got. - [GRUB_MACHINE_EMU]: Call mprotect. - (grub_dl_resolve_symbols): Resolve symbol type as well. - [__ia64__]: Create function descriptors. - * grub-core/kern/efi/efi.c (grub_get_rtc): Renamed to ... - (grub_rtc_get_time_ms): ... this. Expressions simplified. - (grub_get_rtc): New function. - * grub-core/kern/emu/cache.c [__ia64__]: New file. - * grub-core/kern/emu/cache.S: Renamed to ... - * grub-core/kern/emu/cache_s.S: ... this. - [__ia64__]: Add a nop. - * grub-core/kern/emu/full.c (grub_arch_dl_get_tramp_got_size) - [__ia64__]: New function. - * grub-core/kern/emu/lite.c [__ia64__]: Include ../ia64/dl.c. - * grub-core/kern/ia64/dl.c: New file. - * grub-core/kern/ia64/dl_helper.c: Likewise. - * grub-core/kern/ia64/efi/init.c: New file. - * grub-core/kern/ia64/efi/startup.S: Likewise. - * grub-core/lib/efi/halt.c [__ia64__]: Don't try acpi. - * grub-core/lib/ia64/longjmp.S: New file (from glibc). - * grub-core/lib/ia64/setjmp.S: Likewise (from glibc). - * grub-core/lib/setjmp.S [__ia64__]: Include ./ia64/setjmp.S. - * grub-core/loader/ia64/efi/linux.c: New file. - * include/grub/dl.h (GRUB_MOD_NAME): Redefined using C rather than asm. - (GRUB_MOD_DEP): Likewise. - (grub_dl) [__ia64__]: New fields got and tramp. - (grub_dl): New field 'base'. - (grub_dl_register_symbol): New argument isfunc. All users updated. - (GRUB_IA64_DL_TRAMP_ALIGN): New definition. - (GRUB_IA64_DL_TRAMP_SIZE): Likewise. - (GRUB_IA64_DL_GOT_ALIGN): Likewise. - (grub_ia64_dl_get_tramp_got_size): New proto. - (GRUB_ARCH_DL_TRAMP_ALIGN) [__ia64__]: Likewise - (GRUB_ARCH_DL_GOT_ALIGN) [__ia64__]: Likewise - (grub_arch_dl_get_tramp_got_size) [__ia64__]: Likewise - * include/grub/efi/api.h: Skip call wrappers on ia64. - * include/grub/efi/pe32.h (GRUB_PE32_MACHINE_IA64): New definition. - * include/grub/efi/time.h (GRUB_TICKS_PER_SECOND): Change to 1000. - * include/grub/elf.h (ELF_ST_INFO): New definition. - * include/grub/ia64/efi/kernel.h: New file. - * include/grub/ia64/efi/memory.h: Likewise. - * include/grub/ia64/efi/time.h: Likewise. - * include/grub/ia64/kernel.h: Likewise. - * include/grub/ia64/setjmp.h: Likewise (from glibc). - * include/grub/ia64/time.h: New file. - * include/grub/ia64/types.h: Likewise. - * include/grub/libgcc.h (__udivsi3, __umodsi3, __umoddi3, __udivdi3, - __moddi3, __divdi3, __divsi3, __modsi3, __ia64_trampoline): - New protos. - * include/grub/offsets.h (GRUB_KERNEL_IA64_EFI_PREFIX): New definition. - (GRUB_KERNEL_IA64_EFI_PREFIX_END): Likewise. - * include/grub/types.h (PRIxGRUB_ADDR): Likewise. - * util/grub-mkimage.c (image_target_desc): New field pe_target. - All users updated. - (EFI64_HEADER_SIZE): New definition. All users updated. - (image_targets): Add ia64-efi. - * util/grub-mkimagexx.c (relocate_symbols): New arguments jumpers and - jumpers_addr. All users updated. - Create function descriptors. - (count_funcs): New function. - (unaligned_uint32): New struct. - (MASK20): New definition. - (MASK19): Likewise. - (MASKF21): Likewise. - (add_value_to_slot_20b): New function. - (add_value_to_slot_21_real): Likewise. - (add_value_to_slot_21): Likewise. - (ia64_kernel_trampoline): New struct. - (nopm): New variable. - (jump): Likewise. - (make_trampoline): New function. - (relocate_addresses): Handle ia64. - (make_reloc_section): Likewise. - (load_image): Likewise. - -2011-05-15 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Silence spurious - warning. Move variables before code while on it. - -2011-05-15 Vladimir Serbinenko - - Fuloong support. - - * configure.ac: Rename yeeloong platform to loongson. All users updated. - * grub-core/Makefile.core.def (fwstart_fuloong): New image. - * grub-core/boot/mips/loongson/fuloong.S: New file. - * grub-core/boot/mips/loongson/fwstart.S: Wait for CS5536 to come up. - Explicitly init CS5536. - [FULOONG]: Don't use serial until CS5536 is available. - Set GPIO based on dumps. - (serial_hw_init) [FULOONG]: Handle CS5536 parts. - [FULOONG]: Handle GPIO and memory controller differences. - Parse machine type in $a2. - * grub-core/boot/mips/startup_raw.S: Determine and save the - architecture. - * grub-core/bus/cs5536.c (gpiodump): Move to fwstart.S. - (grub_cs5536_init_geode): Remove gpio part. Conditionalise DIVIL - init on architecture type. - * grub-core/kern/mips/loongson/init.c (grub_machine_init): Init - SIS315E. Don't init at_keyboard on fuloong. - (grub_halt): Support Fuloong. - * grub-core/kern/mips/startup.S [LOONGSON]: Save $s7. - * grub-core/loader/mips/linux.c (LOONGSON_MACHTYPE): Removed. - (loongson_machtypes): New array. - (grub_cmd_linux) [GRUB_MACHINE_MIPS_LOONGSON]: Pass the right machine - type. - * grub-core/term/ns8250.c (serial_get_divisor): New parameter port and - config. All users updated. Handle CS5536 serial. - * grub-core/term/serial.c (grub_serial_register): Conditionalise - default port on machine type. Register serial as inactive. - * grub-core/video/sis315pro.c: New file. - * include/grub/cs5536.h (GRUB_CS5536_MSR_MAILBOX_CONFIG_ENABLED): New - definition. - (GRUB_CS5536_MSR_MAILBOX_CONFIG): Likewise. - (GRUB_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1): Likewise. - (GRUB_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3): Likewise. - (GRUB_CS5536_MSR_DIVIL_UART1_CONF): Likewise. - (GRUB_CS5536_MSR_DIVIL_UART2_CONF): Likewise. - * include/grub/mips/loongson.h (GRUB_CPU_LOONGSON_SHUTDOWN_GPIO): Rename - to ... - (GRUB_CPU_YEELOONG_SHUTDOWN_GPIO): ... this. - * include/grub/mips/loongson/kernel.h (GRUB_ARCH_MACHINE_YEELOONG): New - definition. - (GRUB_ARCH_MACHINE_FULOONG): Likewise. - (grub_arch_machine): New extern var. - * include/grub/mips/loongson/serial.h - (GRUB_MACHINE_SERIAL_DIVISOR_115200): Renamed to ... - (GRUB_MACHINE_SERIAL_PORT0_DIVISOR_115200): ... this. - (GRUB_MACHINE_SERIAL_PORT): Renamed to ... - (GRUB_MACHINE_SERIAL_PORT0): ... this. - (GRUB_MACHINE_SERIAL_PORT2_DIVISOR_115200): New definition. - (GRUB_MACHINE_SERIAL_PORT1): Likewise. - (GRUB_MACHINE_SERIAL_PORT2): Likewise. - (GRUB_MACHINE_SERIAL_PORTS): Include ports 1 and 2. - * include/grub/term.h (grub_term_register_input_inactive): New inline - function. - (grub_term_register_output_inactive): Likewise. - * include/grub/video.h (grub_video_driver_id): New value - GRUB_VIDEO_DRIVER_SIS315PRO. - * util/grub-mkimage.c (image_target_desc): Rename name to dirname. - New field "names". All users updated. - New field value IMAGE_FULOONG_FLASH. - (generate_image): USe separate fwstart hashes for yeeloong and fuloong. - -2011-05-14 Jordan Uggla - - * docs/grub.texi (Invoking grub-install): Fix additional outdated claims - and add some clarification. - -2011-05-14 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Autoload gzio since it's needed on some - platforms if kernel is compressed. - -2011-05-14 Vladimir Serbinenko - - * grub-core/kern/mm.c (grub_memalign): Disable auto-unloadding of - unused modules since currently referrence counter isn't reliable and - there isn't much memory to recover there anyway. - -2011-05-14 Vladimir Serbinenko - - * grub-core/kern/dl.c (grub_dl_load_file): Decrease ref counter - rather than resetting it to allow modules to reference themselves - in init. - -2011-05-14 Vladimir Serbinenko - - * grub-core/kern/dl.c (grub_dl_unload): Don't decrease reference - counter on dependencies since grub_dl_unref already handles this. - -2011-05-14 Vladimir Serbinenko - - * grub-core/font/font_cmd.c (loadfont_command): Set grub_errno - on error if not already done. - -2011-05-14 Vladimir Serbinenko - - Fix few potential memory misusage. - - * grub-core/font/font.c (load_font_index): Don't free char_index to - avoid double free. - (grub_font_load): Zero-fill font at alloc for safety. - Close file on error. - (free_font): Free bmp_idx. - -2011-05-14 Vladimir Serbinenko - - * docs/grub.texi (Installation): Fix several outdated claims. - -2011-05-14 Vladimir Serbinenko - - Handle module_license on windows. - - * util/grub-pe2elf.c (MODLICENSE_SECTION): New definition. All following - sections shifted. - (insert_string): Make argument const char * instead of char *. - (write_section_data): Handle long section names. - Handle module_license. - -2011-05-14 Vladimir Serbinenko - - * grub-core/commands/menuentry.c (grub_cmd_menuentry): Correctly - handle class-free menuentries. - (grub_normal_add_menu_entry): Add a check to be sure. - -2011-05-14 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c (set1_e0_mapping): Fix swap between - PgUp and PgDown. - -2011-05-13 Vladimir Serbinenko - - * configure.ac: Bump version to 1.99. - -2011-05-13 Vladimir Serbinenko - - Give ATA device a bit more time on first try in order to allow disks - to spin up. - - * grub-core/disk/ata.c (grub_atapi_identify): Use GRUB_ATA_TOUT_DEV_INIT - if dev->present is 1. Reset dev->present on failure. - (grub_ata_device_initialize): Set dev->present to 1. - * include/grub/ata.h (GRUB_ATA_TOUT_DEV_INIT): New value. - (grub_ata_device): New member 'present'. - -2011-05-13 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Update hash. - -2011-05-13 Vladimir Serbinenko - - Flush caches on DMA memory. - - * grub-core/kern/mips/cache.S (grub_arch_sync_dma_caches): New function. - * grub-core/bus/pci.c (grub_memalign_dma32): Flush caches. - (grub_dma_free): Likewise. - * include/grub/cache.h (grub_arch_sync_dma_caches): New declaration. - -2011-05-13 Vladimir Serbinenko - - * grub-core/boot/mips/yeeloong/fwstart.S: Add explicit set mips3 - to avoid asm treating ld and sd as macros. - -2011-05-13 Vladimir Serbinenko - - * grub-core/boot/mips/startup_raw.S: Flush cache after loading - decompressor. - -2011-05-13 Vladimir Serbinenko - - * grub-core/boot/mips/startup_raw.S: Use jalr rather than bal to call - grub_decompress_core since later would fail if grub_decompress_core - is too far. - -2011-05-13 Vladimir Serbinenko - - * grub-core/kern/mips/dl.c (grub_arch_dl_relocate_symbols): Handle - R_MIPS_JALR since it's used by newer compiler. - -2011-05-10 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Correctly handle the Linux in root. - -2011-05-09 Vladimir Serbinenko - - * grub-core/loader/efi/chainloader.c (grub_chainloader_unload): Set - file_path to 0 for surety. - (grub_chainloader_boot): Set exit_data to NULL. - Unset the loader once done. - (grub_cmd_chainloader): Fix confusing error message if file is empty. - -2011-05-09 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c (fetch_key): Make a printf on - unknown key into a dprintf. - -2011-05-09 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (linux_find_partition): Don't abort - on first non-existant partition. - -2011-05-09 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (open_device): Set data->fd to -1 if - openning fails. - Reported by: Mark Korenberg. - -2011-05-09 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (linux_find_partition): Prevent possible - overflow. - -2011-05-09 Vladimir Serbinenko - - * util/grub-mkimage.c (main): Explicitely flush and sync the output - before closing to ensure that it will be readable by grub-setup. - -2011-05-05 Vladimir Serbinenko - - * grub-core/loader/efi/appleloader.c (MAKE_PIWG_PATH): New macro. - (devpath_1): Use MAKE_PIWG_PATH. - (devpath_2): Likewise. - (devpath_3): Likewise. - (devpath_4): Likewise. - (devpath_5): Likewise. - (devpath_6): Likewise. - - The appleldr.mod was checked that to be binary identical to previous - version. - -2011-05-05 Zach - - Support 2010 Macbooks. - - * grub-core/loader/efi/appleloader.c (devpath_6): New variable. - (devs): Add devpath_6. - -2011-05-05 Vladimir Serbinenko - - * util/grub-mkpasswd-pbkdf2.c (main): Use /dev/urandom and not - /dev/random. /dev/urandom is good enough for our purposes (salting). - -2011-05-05 Vladimir Serbinenko - - * util/grub-mkrescue.in (process_input_dir): Include efiemu??.o. - -2011-05-05 Vladimir Serbinenko - - * grub-core/lib/legacy_parse.c (grub_legacy_parse): Correctly handle - hexadecimal. - -2011-05-05 Vladimir Serbinenko - - * grub-core/efiemu/main.c (grub_efiemu_load_file): Return grub_errno - and not 0 on failure. - -2011-05-03 Colin Watson - - * grub-core/fs/i386/pc/pxe.c (grub_pxefs_dir): Return - GRUB_ERR_BAD_FS rather than GRUB_ERR_IO if the disk is not a pxe - disk; otherwise grub_fs_probe will not fall back to the next - filesystem. - (grub_pxefs_open): Likewise, for consistency. - Reported and tested by: Ezekiel Grave. - -2011-05-03 Colin Watson - - * tests/partmap_test.in: Don't hardcode path to parted. - Reported by: Peter Hjalmarsson. Fixes Savannah bug #33150. - -2011-05-01 Colin Watson - - * docs/grub.texi (GRUB only offers a rescue shell): Suggest the use - of `ls' to find out which devices are available. - -2011-04-25 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_linux_boot): Supply target rather - than source address for efi mmap buffer. - -2011-04-25 Vladimir Serbinenko - - * grub-core/partmap/amiga.c (amiga_partition_map_iterate): Fix a - wrong action on non-detecting the magic. - -2011-04-25 Vladimir Serbinenko - - * grub-core/gnulib/regex.c: Remove GRUB_MOD_LICENSE since it's - already supplied by another part of the module (fixes compilation on - FreeBSD). - -2011-04-25 Vladimir Serbinenko - - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Make mdraid UUID - match the one used by mdadm. - -2011-04-21 Colin Watson - - * po/README: Add instructions for creating po/LINGUAS. - -2011-04-21 Colin Watson - - Add "SEE ALSO" sections to most man pages. Fixes Debian bug - #551428. - - * docs/man/grub-editenv.h2m (SEE ALSO): New section. - * docs/man/grub-emu.h2m (SEE ALSO): Likewise. - * docs/man/grub-fstest.h2m (SEE ALSO): Likewise. - * docs/man/grub-install.h2m (SEE ALSO): Likewise. - * docs/man/grub-macho2img.h2m (SEE ALSO): Likewise. - * docs/man/grub-menulst2cfg.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkconfig.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkdevicemap.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkfont.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkimage.h2m (SEE ALSO): Likewise. - * docs/man/grub-mklayout.h2m (SEE ALSO): Likewise. - * docs/man/grub-mknetdir.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkpasswd-pbkdf2.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkrelpath.h2m (SEE ALSO): Likewise. - * docs/man/grub-mkrescue.h2m (SEE ALSO): Likewise. - * docs/man/grub-ofpathname.h2m (SEE ALSO): Likewise. - * docs/man/grub-pe2elf.h2m (SEE ALSO): Likewise. - * docs/man/grub-probe.h2m (SEE ALSO): Likewise. - * docs/man/grub-reboot.h2m (SEE ALSO): Likewise. - * docs/man/grub-script-check.h2m (SEE ALSO): Likewise. - * docs/man/grub-set-default.h2m (SEE ALSO): Likewise. - * docs/man/grub-setup.h2m (SEE ALSO): Likewise. - -2011-04-21 Colin Watson - - * grub-core/kern/emu/getroot.c - (grub_find_root_device_from_mountinfo): Remove non-virtual-device - test that was incorrectly reintroduced in r3214. - Reported by: Ian Dall. Fixes Savannah bug #33133. - -2011-04-21 Colin Watson - - Fix stack pointer handling in 16-bit relocator. - - * grub-core/lib/i386/relocator16.S (grub_relocator16_start): Move - grub_relocator16_sp to %esp rather than %ss, and zero-extend it. - Fixes Ubuntu bug #683904. - -2011-04-20 Vladimir Serbinenko - - * configure.ac: Bump version to 1.99~rc2. - -2011-04-20 Vladimir Serbinenko - - * include/grub/dl.h [ASM_FILE]: Adapt for assembly. - * grub-core/lib/i386/setjmp.S: Add missing GRUB_MOD_LICENSE. - * grub-core/lib/x86_64/setjmp.S: Likewise. - * grub-core/lib/mips/setjmp.S: Likewise. - * grub-core/lib/powerpc/setjmp.S: Likewise. - * grub-core/lib/sparc64/setjmp.S: Likewise. - -2011-04-20 Vladimir Serbinenko - - * grub-core/lib/efi/datetime.c: Add missing GRUB_MOD_LICENSE. - * grub-core/lib/efi/datetime.c: Likewise. - -2011-04-19 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_flush): - New function. - (grub_util_biosdisk_close): Use grub_util_biosdisk_flush. - * include/grub/emu/hostdisk.h (grub_util_biosdisk_flush): New proto. - * util/grub-setup.c (setup): Use grub_util_biosdisk_flush. - -2011-04-19 Vladimir Serbinenko - - * grub-core/term/gfxterm.c (grub_gfxterm_fullscreen): Preserve previous - bitmap. - (grub_gfxterm_term_init): Likewise. - -2011-04-19 Vladimir Serbinenko - - Take into account the decorations the computing menu entry width. - - * grub-core/gfxmenu/widget-box.c (get_border_width): New function. - (grub_gfxmenu_create_box): Register get_border_width. - * grub-core/gfxmenu/gui_list.c (draw_menu): Use get_border_width - if available. - * include/grub/gfxwidgets.h (grub_gfxmenu_box): New member - get_border_width. - -2011-04-18 Endres Puschner - - * grub-core/gfxmenu/icon_manager.c (grub_gfxmenu_icon_manager_get_icon): - Don't skip first class. - -2011-04-18 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_read_logical): Support huge - chunks. - * include/grub/err.h (grub_err_t): New enum value GRUB_ERR_BUG. - -2011-04-18 Vladimir Serbinenko - - Complete 64-bit division support. - - * grub-core/kern/misc.c (grub_divmod64): Rename to ... - (grub_divmod64_full): ... this. Support 64-bit divisor and reminder. - * include/grub/misc.h (grub_divmod64): Rename to ... - (grub_divmod64_full): ... this. - (grub_divmod64): New inline function. - -2011-04-18 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Add forgotten comma. - -2011-04-18 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Update fwstart.img hash after - performing the necessary test. - -2011-04-17 Vladimir Serbinenko - - * Makefile.am (multiboot.elf): Add -Wl,--build-id=none. - (kfreebsd.elf): Likewise. - (pc-chainloader.elf): Likewise. - (ntldr.elf): Likewise. - -2011-04-17 Vladimir Serbinenko - - Identify RAID by its UUID rather than (guessed) name. - - * grub-core/disk/raid.c (ascii2hex): New function. - (grub_raid_open): Accept mduuid/%s specification. - * grub-core/kern/emu/getroot.c (get_mdadm_name): Revamped into ... - (get_mdadm_uuid): ... this. - (grub_util_get_grub_dev): Use mduuid/%s if UUID is available. - -2011-04-16 Vladimir Serbinenko - - * grub-core/gfxmenu/gui_image.c (rescale_image): Don't attempt to scale - to negative size. - -2011-04-13 Colin Watson - - * util/grub.d/10_linux.in: Add rootflags=subvol= if / is on a - btrfs subvolume. - * util/grub.d/20_linux_xen.in: Likewise. - -2011-04-13 Colin Watson - - Rewrite /proc/self/mountinfo handling to cope with bind-mounts and - move-mounts appearing out of order. Fixes Ubuntu bug #738345. - - * grub-core/kern/emu/getroot.c (find_root_device_from_mountinfo): - Build a list of relevant visible mounts using the mnt_id and - parent_mnt_id fields, and then scan that list at the end. - -2011-04-12 Colin Watson - - * docs/grub.texi (normal): New section. - (normal_exit): New section. - (Embedded configuration): Add reference to normal. - (GRUB only offers a rescue shell): Likewise. - * docs/grub-dev.texi (Error Handling): Fix typo. - -2011-04-12 Colin Watson - - * NEWS: Drop obsolete entry about probe-only btrfs support. - -2011-04-12 Colin Watson - - * util/import_gcry.py: Fix typo. - -2011-04-11 Vladimir Serbinenko - - * NEWS: Add btrfs support. - -2011-04-11 Vladimir Serbinenko -2011-04-11 Colin Watson - - BtrFS support. Written by me (Vladimir) with important bugfixes and - even more important testing by Colin. - - * Makefile.util.def (libgrubmods.a): Add crc.c and gzio.c - * grub-core/Makefile.core.def (btrfs): Add crc.c. - * grub-core/fs/btrfs.c: Stub replaced with real implementation. - * grub-core/io/gzio.c (grub_gzio): New fields mem_input_size, - mem_input_off and mem_input. All users updated to accept in-RAM input. - (gzio_seek): New function. - (test_zlib_header): Likewise. - (grub_gzio_read): Likewise. - (grub_zlib_decompress): Likewise. - * grub-core/kern/emu/getroot.c (grub_find_root_device_from_mountinfo): - Accept partial and non-virtual mounts. - (grub_guess_root_device): Do rescanning after device_from_mountinfo to - avoid receiving /dev/dm-X as device. - * grub-core/kern/emu/misc.c (grub_make_system_path_relative_to_its_root): - Handle bind and partial mounts. - * grub-core/lib/crc.c: New file. - * include/grub/deflate.h: Likewise. - * include/grub/emu/misc.h (grub_find_root_device_from_mountinfo): New - proto. - * include/grub/lib/crc.h: New file. - -2011-04-11 Vladimir Serbinenko - - Implement automatic module license checking according to new GNU - guidelines. - - * grub-core/kern/dl.c (grub_dl_check_license): New function. - (grub_dl_load_core): Use grub_dl_check_license. - * include/grub/dl.h (GRUB_MOD_SECTION): New macro. - (GRUB_MOD_LICENSE): Likewise. - (GRUB_MOD_DUAL_LICENSE): Likewise. - All modules updated. - -2011-04-11 Colin Watson - - * grub-core/fs/btrfs.c (grub_btrfs_fs) [GRUB_UTIL]: Set - reserved_first_sector to 1. btrfs reserves plenty of space for boot - loaders. - Reported by: Gene Cumm. Fixes Ubuntu bug #757446. - -2011-04-11 Vladimir Serbinenko - - * util/grub-fstest.c (cmd_cmp): Check that sizes match. - -2011-04-11 Vladimir Serbinenko - - * util/grub-fstest.c (read_file): Report GRUB error if file opening - failed. - -2011-04-11 Vladimir Serbinenko - - * grub-core/kern/file.c (grub_file_open): Don't take into account the - parenthesis in the middle of the filename. - -2011-04-10 Vladimir Serbinenko - - * grub-core/loader/mips/linux.c (grub_cmd_initrd): Use correct limits - rather than trying to put initrd way too high. - Reported by: Ryan Lortie - -2011-04-10 Vladimir Serbinenko - - * grub-core/boot/mips/yeeloong/fwstart.S (no_cs5536): Put back - improperly removed string. - -2011-04-10 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_data): New member - is_disk. - (grub_util_biosdisk_open): Don't apply ioctl on non-disk devices. - (open_device) Likewise. - (grub_util_biosdisk_close): Likewise. - Reported by: Mark Korenberg. - -2011-04-10 Alexander Kurtz - - * util/grub-mkconfig_lib.in: Add missing quotes. - -2011-04-10 Colin Watson - - * grub-core/gnulib/argp-parse.c (__argp_input): Don't crash if pstate - is NULL. - -2011-04-10 Vladimir Serbinenko - - Dynamically count the number of lines for the lower banner. - - * grub-core/normal/menu_entry.c (per_term_screen): New member - num_entries. - (print_down): Use num_entries. - (update_screen): Likewise. - (grub_menu_entry_run): Set num_entries. - * grub-core/normal/menu_text.c (menu_viewer_data): New member - num_entries. - (grub_print_message_indented): Move real part to ... - (grub_print_message_indented_real): ... here. Additional argument - dry_run. - (draw_border): Additional argument num_entries. - (print_message): Additional argument dry_run. - (print_entries): Receive menu viewer data. - (grub_menu_init_page): New argment num_entries. - (menu_text_set_chosen_entry): Use num_entries. - (grub_menu_try_text): Likewise. - * grub-core/normal/term.c (print_ucs4_terminal): New argument dry_run. - All users updated. - (grub_ucs4_count_lines): New function. - * include/grub/term.h (grub_term_cursor_x): Moved from here .. - * grub-core/normal/menu_text.c (grub_term_cursor_x): ... to here. - * include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): Removed. - (grub_term_border_height): Likewise. - (grub_term_num_entries): Likewise. - -2011-04-10 Vladimir Serbinenko - - * grub-core/boot/mips/yeeloong/fwstart.S: Fix address to error message. - Remove now unused string. - -2011-04-09 Colin Watson - - * docs/grub-dev.texi (Finding your way around): Update for 1.99 - build system. - (Getting started): GRUB is developed in Bazaar now, not Subversion. - - (Comment): Fix typo. - (Getting started): General copy-editing. - (Typical Development Experience): Likewise. - (Error Handling): Likewise. - (Video API): Likewise. - -2011-04-09 Colin Watson - - * docs/grub-dev.texi: Replace MoinMoin syntax with Texinfo syntax - throughout. - -2011-04-08 Vladimir Serbinenko - - * util/grub-mkimage.c (main): Handle special naming of yeeloong - directory. - -2011-04-08 Colin Watson - - * docs/grub-dev.texi: Fix spelling of "developer" throughout. - * grub-core/fs/i386/pc/pxe.c (parse_dhcp_vendor): Fix spelling of - "development". - -2011-04-08 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (run): Use grub_memcpy rather than - grub_strcpy since the lines aren't necessarily 0-terminated. - -2011-04-08 Vladimir Serbinenko - - * grub-core/lib/legacy_parse.c (legacy_commands): Find doesn't set - root on legacy. - -2011-04-08 Vladimir Serbinenko - - * grub-core/commands/probe.c (options): Argument to set isn't optional. - (GRUB_MOD_INIT): DEVICE isn't optional. - -2011-04-08 Vladimir Serbinenko - - * grub-core/normal/term.c (print_ucs4_terminal): Don't try to put the - word on new line if it's too long anyway. Fixes a hang. - -2011-04-08 Vladimir Serbinenko - - * include/grub/util/raid.h (grub_util_raid_getmembers): Make argument - const. - * util/grub-setup.c (main): Reuse md device name if available. - * util/raid.c (grub_util_raid_getmembers): Receive device name and - not GRUB name as argument. - Based on patch by: Florian Wagner . - -2011-04-08 Vladimir Serbinenko - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): - Place mbi on low memory for better compatibility. - -2011-04-08 Vladimir Serbinenko - - * include/grub/efiemu/efiemu.h: Use grub_memory_hook_t type. - -2011-04-08 Vladimir Serbinenko -2011-04-08 Colin Watson - - * autogen.sh: Ensure that collate and ctype locale is C. - * conf/Makefile.common: Likewise. - -2011-04-08 Vladimir Serbinenko - - * grub-core/normal/menu.c: Add missing include. - -2011-04-08 Vladimir Serbinenko - - * grub-core/disk/raid.c [GRUB_UTIL]: Add missing include. - -2011-04-08 Martin Zuther - - * util/grub-mkconfig.in: Ignore emacsen backup. - -2011-04-08 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (open_device): Sync on close and not - on open. - (grub_util_biosdisk_close): Likewise. - -2011-04-08 Vladimir Serbinenko - - * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Add missing - const attribute and use grub_isdigit. - -2011-04-06 Andrey - - * grub-core/video/fb/video_fb.c (grub_video_fb_setup): Silence older - gcc warning. - -2011-04-06 Vladimir Serbinenko - - * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align): Add few - useful grub_dprintf's. - -2011-04-06 Vladimir Serbinenko - - * include/grub/fs.h (grub_dirhook_info): Use unsigned for 1-bit fields. - -2011-04-06 Vladimir Serbinenko - - * util/grub.d/00_header.in: Don't use LANG unless unifont is available. - -2011-04-06 Vladimir Serbinenko - - Output errors if theme loading failed. - - * grub-core/gfxmenu/gfxmenu.c (grub_gfxmenu_try): Move the call to - grub_gfxterm_fullscreen on error paths to ... - * grub-core/normal/menu.c (menu_init): ...here. Wait after showing - theme loading error. - -2011-04-06 Vladimir Serbinenko - - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): Let a bit more - space for older compilers. - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. - -2011-04-06 Vladimir Serbinenko - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Detect spares - and report them as not RAID members since they are useless for GRUB. - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. - -2011-04-02 Vladimir Serbinenko - - Increase LVM implementation robustness in order not to crash on - configurations like pvmove. Previously code assumed that in some places - only lvs or only pvs are used whereas it seems that they are used - interchangeably. - - * grub-core/disk/lvm.c (read_node): New function. - (read_lv): Use read_node. - (grub_lvm_scan_device): Use only first mirror on pvmove'd lvs. - Match volumes only at the end when all lvs are found. Take both - pvs (first) and lvs (second) into account. - * include/grub/lvm.h (grub_lvm_segment): Merge fields stripe_* and - mirror_* into node_*. All users updated. - (grub_lvm_stripe): Merge this ... - (grub_lvm_mirror): ... and this ... - (grub_lvm_node): ... into this. All users updated. - -2011-04-02 Vladimir Serbinenko - - * grub-core/disk/lvm.c (grub_lvm_scan_device): Print errors on the end - of function to allow further scanning for LVMs. - -2011-04-02 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_read): Don't close - on failed seek as it breaks open fd reusage. - -2011-04-02 Vladimir Serbinenko - - * util/grub-install.in: Add a recommendation to use --recheck before - reporting bugs. - -2011-04-02 Vladimir Serbinenko - - * docs/grub.texi (Vendor power-on buttons): Explain how the numbers - are obtained. - -2011-04-02 Vladimir Serbinenko - - GRUB developper manual based on existing Internals section and - contributions by the various authors with active copyright assignment. - - * docs/Makefile.am (info_TEXINFOS): Add grub-dev.texi. - * docs/font_char_metrics.png: New file. - * docs/font_char_metrics.txt: Likewise. - * docs/grub-dev.texi: Likewise. - * docs/grub.texi (Internals): Move from here ... - * docs/grub-dev.texi: ... here. - -2011-04-01 Colin Watson - - Store the loopback device as data on loopback grub_disk structures, - rather than the file it points to. This fixes use of freed memory - if an existing loopback device is replaced. - - * grub-core/disk/loopback.c (grub_loopback_open): Store dev in - disk->data, not dev->file. - (grub_loopback_read): Adjust file assignment to match. - Fixes Ubuntu bug #742967. - -2011-04-01 Colin Watson - - * grub-core/disk/loopback.c (grub_cmd_loopback): Fix a memory leak - when replacing an existing device. - -2011-04-01 Vladimir Serbinenko - - Fix incorrect types in jfs.c. This enables >2TiB disks and fixes some - memory corruptions. - - * grub-core/fs/jfs.c (struct grub_jfs_diropen): Interpret bytes as - unsigned. - (grub_jfs_lookup_symlink): Make ino a grub_uint32_t rather than int. - (grub_jfs_blkno): Use 64-bit quantities for block sectors. - (grub_jfs_read_inode): Likewise. - (grub_jfs_opendir): Likewise. Remove now useless casts. - (grub_jfs_getent): Likewise. - Make ino a grub_uint32_t rather than int. - (grub_jfs_mount): Ensure that blksize and log2_blksize are consistent. - (grub_jfs_read_file): Use 64-bit quantities when necessary. Replace - division and module with bit operations. - (grub_jfs_find_file): Make ino a grub_uint32_t. - (grub_jfs_lookup_symlink): Likewise. Use 64-bit quantities - -2011-04-01 Colin Watson - - * grub-core/normal/menu_entry.c (run): Quieten uninitialised - warning. (This was in fact always initialised before use, but GCC - wasn't smart enough to prove that.) - * grub-core/script/lexer.c (grub_script_lexer_yywrap): Likewise. - -2011-03-31 Vladimir Serbinenko - - * grub-core/kern/x86_64/efi/callwrap.S (efi_wrap_0): Preserve 16-byte - stack alignment. - (efi_wrap_1): Likewise. - (efi_wrap_2): Likewise. - (efi_wrap_3): Likewise. - (efi_wrap_4): Likewise. - (efi_wrap_5): Likewise. - (efi_wrap_6): Likewise. - (efi_wrap_10): Likewise. - Based on information by: Red Hat/Peter Jones. - -2011-03-31 Colin Watson - - * grub-core/mmap/efi/mmap.c (grub_mmap_unregister): Remove - set-but-not-used variable. - -2011-03-31 Colin Watson - - * docs/grub.texi (Simple configuration): Be more explicit about - GRUB_DEFAULT, and add an example. - Reported by: Leslie Rhorer. - -2011-03-30 Colin Watson - - * docs/grub.texi (Commands): Link to "GRUB only offers a rescue - shell". - -2011-03-30 Alexey Shvetsov - - * util/grub.d/10_linux.in: Add gentoo-specific config filename. - * util/grub.d/20_linux_xen.in: Likewise. - -2011-03-30 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Try alternative config filenames where - we parse config file. - * util/grub.d/20_linux_xen.in: Likewise. - -2011-03-30 Alexey Shvetsov - - * util/grub.d/10_linux.in: Add gentoo-specific Linux and initrd names. - * util/grub.d/20_linux_xen.in: Likewise. - -2011-03-30 Vladimir Serbinenko - - * grub-core/disk/raid.c (insert_array): Add few potentially - useful grub_util_info. - (grub_raid_register): Likewise. - -2011-03-30 Vladimir Serbinenko - - * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev) [__linux__]: - Preserve partition number in mdadm code path. - -2011-03-30 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Add - few potentially useful grub_util_info. - -2011-03-30 Vladimir Serbinenko - - * grub-core/disk/lvm.c (grub_lvm_scan_device): Remove spurious \n. - -2011-03-30 Colin Watson - - * docs/grub.texi (default): Use @example rather than nested - itemized lists to avoid breaking gendocs. - -2011-03-30 Colin Watson - - * docs/grub.texi (Future): Update. - -2011-03-30 Colin Watson - - * docs/grub.texi (Environment): New chapter. - (Changes from GRUB Legacy): Link to "Environment block" section for - details of limitations. - (Simple configuration): Likewise. Link to documentation of gfxmode - and gfxpayload variables from GRUB_GFXMODE and GRUB_GFXPAYLOAD - respectively. - (Shell-like scripting): Note that normal variables are stored in the - environment. - (gettext): Link to documentation of lang and locale_dir. - (list_env): New section. - (load_env): New section. - (save_env): New section. - - (Reporting bugs): Fix typo. - -2011-03-30 Vladimir Serbinenko - - * docs/grub.texi: Correctly use "terminal_input" and not "terminal" in - the example. - -2011-03-30 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c (set_scancodes) - [!GRUB_MACHINE_MIPS_YEELOONG && !GRUB_MACHINE_QEMU]: Use scancode set 1. - -2011-03-30 Colin Watson - - * docs/grub.texi (Menu-specific commands): Remove some semantics - that were true in GRUB Legacy but not in GRUB 2. - (submenu): New section. - (false): New section. - (read): New section. - (true): New section. - -2011-03-30 Colin Watson - - * docs/grub.texi (Changes from GRUB Legacy): Minor proofreading. - -2011-03-30 Colin Watson - - * docs/grub.texi (Simple configuration): Explain some of the - current limitations of grub-mkconfig. - Reported by: Leslie Rhorer. - -2011-03-29 Vladimir Serbinenko - - Old macs search for boot.efi rather than for bootia32.efi. - - * util/grub-install.in: Copy bootia32.efi to boot.efi. - * util/grub-mkrescue.in: Likewise. - Suggested by: Peter Jones. - -2011-03-29 Vladimir Serbinenko - - * util/grub.d/20_linux_xen.in: Accept old-style xen kernels. - -2011-03-29 Vladimir Serbinenko - - * include/grub/lvm.h (grub_lvm_lv): New field 'visible'. - (grub_lvm_segment): New fields 'type', 'mirror_count' and 'mirrors'. - (grub_lvm_mirror): New struct. - * grub-core/disk/lvm.c (grub_lvm_checkvalue): Commented out. - (grub_lvm_iterate): Iterate only visible volumes. - (grub_lvm_read): Factor out to .. - (read_lv): ... this. Support mirrors. - (grub_lvm_read): New wrapper function. - (grub_lvm_scan_device): Parse mirrors. Skip everything that isn't - stripped or mirrored. - -2011-03-29 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Skip vmlinux-* on x86 platforms. - -2011-03-29 Colin Watson - - * docs/grub.texi (loopback): New section. - -2011-03-29 Colin Watson - - * grub-core/disk/loopback.c (GRUB_MOD_INIT): Stop documenting - removed -p option. - -2011-03-29 Colin Watson - - * docs/grub.texi (BIOS installation): New section, partly based on - previous text in other sections. - (Installing GRUB using grub-install): Replace BIOS discussion with a - cross-reference. - (Images): Likewise. - -2011-03-29 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (find_partition_start) - [HAVE_DIOCGDINFO]: Add safety checks. - -2011-03-29 Vladimir Serbinenko - - * util/grub.d/10_kfreebsd.in: Allow ufs.ko to be missing as it's - per default compiled in kernel and prior to 8.0 isn't shipped at all. - -2011-03-29 Colin Watson - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): If - real_sb->size is zero (e.g. RAID-0), get the disk size from - real_sb->data_size instead. - Fixes Ubuntu bug #743136. - -2011-03-29 Vladimir Serbinenko - - * grub-core/normal/misc.c (grub_normal_print_device_info): Use correct - printf clauses for printing size and start. - -2011-03-29 Vladimir Serbinenko - - * grub-core/fs/ext2.c (grub_ext2_read_inode): Fix an overflow. - Reported and tested by: Timothy Nikkel. - -2011-03-29 Vladimir Serbinenko - - * grub-core/term/gfxterm.c (dirty_region_add): Move core part to ... - (dirty_region_add_real): ... this. - (dirty_region_add): Don't discard margin refresh when performing - scheduled repaint. - -2011-03-29 Vladimir Serbinenko - - * grub-core/lib/relocator.c (allocate_regstart) - [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Avoid grub_dprintf since not all - terminals are capabple of malloc-free operation. - (allocate_inreg) [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Likewise. - (malloc_in_range) [!DEBUG_RELOCATOR_NOMEM_DPRINTF]: Likewise. - -2011-03-29 Mario Limonciello - - * util/grub-setup.c: Copy the partition table zone if floppy support - is disabled, even if no partition table is found. - - Otherwise, the BIOS on Dell Latitude E series laptops will freeze - during POST if an invalid partition table is contained in the PBR - of the active partition when GRUB is installed to a partition. - -2011-03-28 Colin Watson - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Remove stale - comment. - -2011-03-28 Colin Watson - - * grub-core/disk/raid.c (grub_raid_register): Adjust debug message - to be specific about what kind of RAID device we're scanning for. - -2011-03-26 Seth Goldberg - - * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): Don't - return freed string. - -2011-03-26 Vladimir Serbinenko - - * grub-core/fs/iso9660.c (grub_iso9660_label): Rtrim the label. - -2011-03-26 Vladimir Serbinenko - - Use libgeom on FreeBSD to detect partitions. - - * Makefile.util.def (grub-mkimage): Add LIBGEOM to ldadd. - (grub-mkrelpath): Likewise. - (grub-script-check): Likewise. - (grub-editenv): Likewise. - (grub-mkpasswd-pbkdf2): Likewise. - (grub-fstest): Likewise. - (grub-mkfont): Likewise. - (grub-mkdevicemap): Likewise. - (grub-probe): Likewise. - (grub-setup): Likewise. - (grub-ofpathname): Likewise. - (grub-mklayout): Likewise. - (example_unit_test): Likewise. - (grub-menulst2cfg): Likewise. - * grub-core/Makefile.core.def (grub-emu): Likewise. - (grub-emu-lite): Likewise. - * configure.ac: Check for -lgeom on FreeBSD and set LIBGEOM. - * grub-core/kern/emu/hostdisk.c [FreeBSD]: Include libgeom.h. Don't - define HAVE_DIOCGDINFO. - (follow_geom_up) [FreeBSD]: New function. - (find_partition_start) [FreeBSD]: Rewritten using follow_geom_up. - (convert_system_partition_to_system_disk) [FreeBSD]: Likewise. - (grub_util_biosdisk_get_grub_dev) [FreeBSD]: Use FreeBSD path - unconditionally of HAVE_DIOCGDINFO. - -2011-03-26 Vladimir Serbinenko - - Fix FreeBSD compilation problem. - - * grub-core/kern/emu/hostdisk.c (MAJOR) [FreeBSD]: New definition. - (FLOPPY_MAJOR) [FreeBSD]: Likewise. - -2011-03-24 Colin Watson - - * grub-core/video/fb/video_fb.c (grub_video_fb_get_info_and_fini): - Switch back to page zero before loading a kernel, since some kernel - drivers expect that. - Thanks to: Felix Kuehling. - -2011-03-24 Vladimir Serbinenko - - * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_addr) - [DEBUG_RELOCATOR]: Reuse grub_mm_check. - (grub_relocator_alloc_chunk_align) [DEBUG_RELOCATOR]: Likewise. - -2011-03-24 Vladimir Serbinenko - - * include/grub/mm.h (GRUB_MM_CHECK): Rename to ... - (grub_mm_check): ... this. MAke a function-like macro and use GRUB_FILE. - -2011-03-24 Vladimir Serbinenko - - * grub-core/lib/relocator.c (allocate_inreg): Avoid dprintf unless - DEBUG_RELOCATOR is defined since gfxterm can't cope with output when - malloc is disabled. - -2011-03-24 Vladimir Serbinenko - - * grub-core/loader/i386/bsdXX.c (grub_freebsd_load_elfmodule): Account - for modules headers when counting the needed allocation size. - -2011-03-23 Vladimir Serbinenko - - * grub-core/term/gfxterm.c (calculate_normal_character_width): Return 8 - if no ASCII character is found to prevent crash. - -2011-03-23 Alexander Kurtz - - * grub-core/video/bitmap.c (match_extension): Ignore case. - -2011-03-23 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (init_line): Fix off-by-one error. - -2011-03-23 Vladimir Serbinenko - - * grub-core/script/parser.y: Declare "time" as valid argument. - -2011-03-23 Peter Jones - - Fix incorrect assert failure reporting. - - * grub-core/tests/example_functional_test.c (example_test): Add - a failure comment. - * grub-core/tests/lib/test.c (add_failure): Renamed to ... - (failure_start): ...this. Check that malloc succeeded. - Don't call xvasprintf. Return failure struct. - (failure_append_vtext): New function. - (failure_append_text): Likewise. - (add_failure): Likewise. - (grub_test_assert_helper): Likewise. - * include/grub/test.h (grub_test_assert_helper): New declaration. - (grub_test_assert): Macro rewritten. - -2011-03-23 Vladimir Serbinenko - - * grub-core/normal/main.c (GRUB_MOD_INIT): Export pager variable. - -2011-03-23 Vladimir Serbinenko - - * grub-core/lib/i386/pc/biosnum.c: Add missing include. - -2011-03-23 Vladimir Serbinenko - - * grub-core/disk/usbms.c (grub_usbms_reset): Transform USB-style error - into GRUB-style one. - -2011-03-23 Vladimir Serbinenko - - * grub-core/bus/usb/usbtrans.c (grub_usb_control_msg): Return usb-style - error and not grub_errno. - * grub-core/bus/usb/usbhub.c (grub_usb_add_hub): Likewise. - -2011-03-23 Vladimir Serbinenko - - * grub-core/bus/usb/uhci.c (grub_uhci_detect_dev): Return - GRUB_USB_SPEED_NONE in case of failure and not the error code. - -2011-03-23 Vladimir Serbinenko - - * grub-core/efiemu/i386/pc/cfgtables.c - (grub_machine_efiemu_init_tables): Make declaration a prototype. - * grub-core/loader/xnu.c (grub_xnu_lock): Likewise. - (grub_xnu_unlock): Likewise. - * grub-core/normal/cmdline.c (grub_cmdline_get/cl_set_pos_all): Likewise. - -2011-03-23 Vladimir Serbinenko - - * grub-core/bus/usb/usb.c (attach_hooks): Make static. - * grub-core/bus/usb/usbhub.c (hubs): Likewise. - * grub-core/commands/hashsum.c (aliases): Likewise. - * grub-core/commands/setpci.c (pci_registers): Likewise. - * grub-core/disk/usbms.c (attach_hook): Likewise. - * grub-core/fs/zfs/zfs.c (decomp_table): Likewise. - (zio_checksum_table): Likewise. - * grub-core/gettext/gettext.c (grub_gettext_msg_list): Likewise. - * grub-core/gfxmenu/gfxmenu.c (cached_view): Likewise. - * grub-core/lib/legacy_parse.c (legacy_commands): Likewise. - * grub-core/lib/relocator.c (leftovers): Likewise. - (extra_blocks): Likewise. - * grub-core/loader/i386/bsd.c (relocator): Likewise. - * grub-core/loader/i386/multiboot_mbi.c (modules): Likewise. - (modules_last): Likewise. - * grub-core/loader/i386/xnu.c (table_aliases): Likewise. - (devices): Likewise. - * grub-core/loader/multiboot_mbi2.c (modules): Likewise. - (modules_last): Likewise. - * grub-core/normal/auth.c (users): Likewise. - * grub-core/normal/context.c (initial_menu): Likewise. - (current_menu): Likewise. - * grub-core/normal/crypto.c (crypto_specs): Likewise. - * grub-core/term/serial.c (grub_serial_ports): Likewise. - (grub_serial_terminfo_input_template): Likewise. - (grub_serial_terminfo_output_template): Likewise. - (grub_serial_terminfo_input): Likewise. - (grub_serial_terminfo_output): Likewise. - (registered): Likewise. - * grub-core/term/usb_keyboard.c (attach_hook): Likewise. - -2011-03-23 Vladimir Serbinenko - - * grub-core/video/bochs.c (grub_video_bochs_setup): Use - grub_video_mode_type_t. - * grub-core/video/cirrus.c (grub_video_cirrus_setup): Likewise. - * grub-core/video/i386/pc/vbe.c (grub_video_vbe_setup): Likewise. - * grub-core/video/i386/pc/vga.c (grub_video_vga_setup): Likewise. - -2011-03-23 Vladimir Serbinenko - - * util/grub-install.in: Correct the x86-64 name as x86_64. - -2011-03-11 Colin Watson - - * grub-core/boot/i386/pc/lnxboot.S (real_code_2): Ensure that the - initial chunk read from the kernel always includes GRUB's multiboot - header, which is now outside the first sector. - -2011-03-09 Colin Watson - - * grub-core/loader/i386/linux.c (find_efi_mmap_size): Page-align - cached mmap_size, so that this works correctly when called multiple - times. - Reported by: Daniel Kahn Gillmor. Should fix Debian bug #616638. - -2011-03-09 Colin Watson - - * docs/grub.texi (Simple configuration): Tidy up formatting. - -2011-03-07 Szymon Janc - - * grub-core/fs/zfs/zfs.c (zap_leaf_lookup): - Set-but-not-used variable removed. - -2011-02-12 Vladimir Serbinenko - - Workaround yet another IEEE1275 bug. - - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New enum value - GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS. - * grub-core/kern/ieee1275/mmap.c (grub_machine_mmap_iterate): Ignore - adress_cells and size:cells if GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS - is set. - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set - GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS on powermacs. - -2011-02-12 Vladimir Serbinenko - - * grub-core/partmap/msdos.c (pc_partition_map_embed): Fix off by one - error. - -2011-02-11 Colin Watson - - * util/grub.d/20_linux_xen.in: Bail out early if linux_list is - empty, since in that case we can only generate either nothing or a - syntactically invalid configuration file. - Reported by: Michal Suchanek. Fixes Debian bug #612898. - -2011-02-09 Colin Watson - - * docs/grub.texi (Kernel): Add reference to grub-mkrescue. - (Making a GRUB bootable CD-ROM): Likewise. - (Invoking grub-mkrescue): New section. - Reported by: Yann Dirson. Fixes Debian bug #612585. - -2011-02-09 Colin Watson - - * util/grub-install.in: Remove unnecessary brackets from tr - arguments. - * util/grub.d/10_hurd.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - Reported by: Jamie Heilman. Fixes Debian bug #612564. - -2011-02-08 Colin Watson - - * include/grub/file.h (not_easly_seekable): Rename to ... - (not_easily_seekable): ... this. Update all users. - -2011-01-28 Colin Watson - - * docs/grub.texi (Making a GRUB bootable CD-ROM): Update to describe - grub-mkrescue. - -2011-01-24 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Refuse to create the images - bigger than the actual flash (512K) in Loongson machines. 512K is also - the biggest chip supported by them. - -2011-01-22 Vladimir Serbinenko - - * grub-core/kern/emu/getroot.c: Include config-util.h explicitly. - -2011-01-22 Anthony DeRobertis - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Check - super_offset field. - -2011-01-22 Vladimir Serbinenko - - * util/grub-install.in: Ignore install device on platforms - where it doesn't make sense. Always use UUIDs except on pc, efi and - sparc64. - Reported by: Daniel Kahn Gillmor. - -2011-01-22 Vladimir Serbinenko - - * grub-core/bus/bonito.c (write_bases): Fix direction of the shift. - -2011-01-22 Vladimir Serbinenko - - * grub-core/partmap/bsdlabel.c: Include grub/emu/misc.h and not grub/util/misc.h. - (iterate_real): Don't rely on partition being non-NULL. - -2011-01-22 Vladimir Serbinenko - - * grub-core/script/argv.c (round_up_exp): unsigned is 32-bit on all - supported platforms. Put a compile time assert for this rather than - generate a warning with 32-bit shift. - -2011-01-22 Vladimir Serbinenko - - * grub-core/disk/scsi.c (grub_scsi_read): Fix binary and check and make - logical expression more readable. - -2011-01-22 Vladimir Serbinenko - - * grub-core/disk/raid.c (insert_array): Ensure uniqueness of p->number - even if some elements have a name. - Reported by: Alexander GQ Gerasiov. - -2011-01-22 Colin Watson - - * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Consider a - path unreadable if `grub-probe -t abstraction' fails, for example if - memberlist fails on an LVM volume group. - Reported by: Darius Jahandarie. - -2011-01-22 Colin Watson - - * docs/grub.texi (Simple configuration): Document - GRUB_PRELOAD_MODULES. - -2011-01-17 Colin Watson - - * .bzrignore: Remove nonexistent grub-pbkdf2. - -2011-01-16 Vladimir Serbinenko - - * configure.ac: Bump version to 1.99~rc1. - -2011-01-15 Vladimir Serbinenko - - * util/grub-mkimage.c (generate_image): Check fwstart.img checksum - for safety. - -2011-01-14 Vladimir Serbinenko - - * grub-core/kern/mips/yeeloong/init.c (grub_machine_init): Init boot - module. - -2011-01-14 Vladimir Serbinenko - - * grub-core/Makefile.core.def (fwstart): Add lost LDFLAGS. - -2011-01-13 Vladimir Serbinenko - - * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Quote bootpath and - diskdevid. - -2011-01-13 Vladimir Serbinenko - - Fix compilation on cygwin. - - * conf/Makefile.common (STRIPFLAGS_KERNEL): Add -F elf32-i386 and - -R .drectve on cygwin. - * conf/i386-pc-cygwin-img-ld.sc: Merge rdata and pdata into data. - * configure.ac: Use $(top_builddir) in TARGET_OBJ2ELF. - (COND_CYGWIN): New condition. - * grub-core/Makefile.am (%.mod): Set TARGET_OBJ2ELF. - * grub-core/genmod.sh.in: Use ${TARGET_OBJ2ELF} and - not @TARGET_OBJ2ELF@. - * util/grub-pe2elf.c (write_symbol_table): Use pe_symtab->type and not - type to determine whether aux is to be used. - -2011-01-12 Vladimir Serbinenko - - * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath): Use the - realpath'ed device string. - Handle floppy (somewhat). - Issue error in unknown case rather than garbage. - Reported by: Axel Beckert. - -2011-01-12 Vladimir Serbinenko - - * util/grub.d/00_header.in (load_video): Handle the case when no video - drivers available. - Thanks to: Axel Beckert. - -2011-01-12 Vladimir Serbinenko - - * util/grub-mkfont.c (write_font_pf2): Use appropriate type for data - variable. Fixes problem on big endian platforms. - -2011-01-12 Vladimir Serbinenko - - * grub-core/Makefile.core.def (ieee1275_fb): Disable on sparc. - It doesn't work well there. - -2011-01-12 Vladimir Serbinenko - - * grub-core/normal/context.c (grub_env_context_close): Silence spurious - warning. - * grub-core/normal/menu.c (grub_menu_execute_entry): Likewise. - * grub-core/partmap/msdos.c (pc_partition_map_embed): Use unsigned - counter. - -2011-01-12 Vladimir Serbinenko - - Use alias->path rather than buggy "canon". - - * grub-core/disk/ieee1275/ofdisk.c (ofdisk_hash_add_real): New function. - (ofdisk_hash_add): New argument curcan. All users updated. - -2011-01-11 Colin Watson - - * configure.ac: Fall back to `true' if `makeinfo' does not exist. - -2011-01-11 Vladimir Serbinenko - - * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32): Apply - loadmask before doing any calculations. Use correct type for offset. - (grub_linux_load64): Likewise. - -2011-01-11 Colin Watson - - * util/grub-mklayout.c (console_grub_equivalences_shift): Terminate - with NULL. - (console_grub_equivalences_unshift): Likewise. - Reported by: Daniel Dehennin. - -2011-01-11 Vladimir Serbinenko - - * grub-core/fs/i386/pc/pxe.c (set_mac_env): Export variable. - (set_env_limn_ro): Likewise. - (GRUB_MOD_INIT): Likewise. - * grub-core/hook/datehook.c (GRUB_MOD_INIT): Likewise. Change to - ARRAY_SIZE while on it. - (GRUB_MOD_FINI): Change to ARRAY_SIZE. - * grub-core/normal/context.c (grub_env_export): Move from here ... - * grub-core/kern/env.c (grub_env_export): ... here. - * grub-core/normal/context.c (grub_cmd_export): Skip exporting root and - prefix. - * grub-core/kern/main.c (grub_main): Export root and prefix. - * include/grub/env.h (grub_env_export): Export. - Reported by: Seth Goldberg. - -2011-01-11 Vladimir Serbinenko - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): - Take into account space used by ELF sections and multiboot palette. - Reported by: Grégoire Sutre. - -2011-01-11 Vladimir Serbinenko - - * BUGS: New file. - -2011-01-10 Vladimir Serbinenko - - Pass more appropriate video id to Linux. - - * grub-core/loader/i386/linux.c (grub_linux_setup_video): Use - grub_video_get_driver_id and variable gfxpayloadforcelfb to - fill have_vga. - (grub_linux_boot): Rely on grub_linux_setup_video to fill have_vga and - shift params->lfb_size. - * include/grub/i386/linux.h: Make an enume out of have_vga values. - -2011-01-10 Vladimir Serbinenko - - * util/grub-menulst2cfg.c: Add missing include of misc.h. - -2011-01-10 Vladimir Serbinenko - - * grub-core/fs/zfs/zfsinfo.c (grub_cmd_zfs_bootfs): Use comma as - separator and pass bootpath/devid even if only one of them is available. - Reported by: Seth Goldberg. - -2011-01-10 Vladimir Serbinenko - - Don't use post-4G memory on EFI even if 64-bit since some non-compliant - implementations bug on them. - - * grub-core/kern/efi/mm.c (grub_efi_allocate_pages): Skip post-4G - memory. - (filter_memory_map): Likewise. - -2011-01-10 Vladimir Serbinenko - - * util/grub-kbdcomp.in: Add missing prefix and exec_prefix variables. - Reported by: nebuchadnezzar. - -2011-01-10 Vladimir Serbinenko - - * util/grub-kbdcomp.in: Add missing transform and bindir variables. - Reported by: nebuchadnezzar. - -2011-01-10 Vladimir Serbinenko - - Submenu default support. - - * grub-core/normal/menu.c (grub_menu_execute_entry): New parameter - auto_boot. All users updated. - Declared static. - Handle chosen and default with submenus. - (grub_menu_execute_with_fallback): Declared static. - Don't notify failure if autobooted. Upper level does it. - (menuentry_eq): New function. - (get_entry_number): Use menuentry_eq. - (show_menu): New parameter "autobooted". All users updated. - (grub_show_menu): Likewise. - * include/grub/normal.h (grub_show_menu): Likewise. - * include/grub/menu.h (grub_menu_execute_entry): Removed. - (grub_menu_execute_with_fallback): Likewise. - -2011-01-10 Vladimir Serbinenko - - * util/grub-mklayout.c (usage): Update help text. - -2011-01-10 Vladimir Serbinenko - - * grub-core/commands/legacycfg.c (legacy_file): Trim the line. - -2011-01-10 Vladimir Serbinenko - - * util/grub-menulst2cfg.c (main): Trim the line. - -2011-01-10 Vladimir Serbinenko - - * grub-core/kern/i386/pc/init.c (grub_get_conv_memsize): Removed. - (grub_machine_init): Don't check amount of low memory as reportedly - INT 12h can be broken and if low memory is too low we wouldn't have - gotten into grub_machine_init anyway. - -2011-01-10 Vladimir Serbinenko - - * grub-core/kern/i386/pc/mmap.c (grub_get_conv_memsize): New function. - (grub_machine_mmap_iterate): Take low memory into account - -2011-01-10 Vladimir Serbinenko - - * grub-core/fs/btrfs.c (grub_btrfs_mount): Transform out of range into - badfs. - Reported by: TiCPU. - -2011-01-10 Vladimir Serbinenko - - * grub-core/disk/raid.c (insert_array): Display RAID name in duplicate - members errors. - -2011-01-09 Grégoire Sutre - - * util/grub.d/10_netbsd.in (netbsd_load_fs_module): New function. - (netbsd_entry): Use netbsd_load_fs_module() to load filesystem module. - -2011-01-09 Grégoire Sutre - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Handle - openbsd and netbsd types being in part_bsd module. - -2011-01-08 Vladimir Serbinenko - - * config.h.in (_LARGEFILE_SOURCE): Add missing define. - (_FILE_OFFSET_BITS): Likewise. - Reported by: Seth Goldberg. - -2011-01-08 Grégoire Sutre - - * configure.ac: Check for libdevmapper header. - -2011-01-08 Vladimir Serbinenko - - * grub-core/fs/zfs/zfs.c (dmu_read): Use void * for some pointers to - avoid aliasing. - (fzap_lookup): Likewise. - (dnode_get): Likewise. - (make_mdn): Likewise. - (zfs_mount): Likewise. - (fzap_iterate): Use temporary pointer to avoid aliasing. - (grub_zfs_read): Likewise. - * grub-core/loader/i386/xnu.c (grub_xnu_boot): Likewise. - * grub-core/loader/xnu.c (grub_cmd_xnu_kernel): Use void * for some - pointers to avoid aliasing. - (grub_cmd_xnu_kernel64): Likewise. - (grub_xnu_load_driver): Likewise. - -2011-01-08 Vladimir Serbinenko - - * grub-core/commands/terminal.c (grub_cmd_terminal_input): Silence - aliasing warning. - (grub_cmd_terminal_output): Likewise. - Reported and tested by: Grégoire Sutre. - -2011-01-08 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c (grub_keyboard_getkey): Silence spurious - warning. - Reported and tested by: Grégoire Sutre. - -2011-01-08 Vladimir Serbinenko - - * configure.ac: Do CPU substitution even if it's specified explicitly. - Reported and tested by: Alain Greppin. - -2011-01-08 Vladimir Serbinenko - - * grub-core/Makefile.am (rs_decoder.S): Force compilation with -Os. - Reported and tested by: Alain Greppin. - -2011-01-08 Vladimir Serbinenko - - Satisfy some bison versions need for inttypes.h. - - * grub-core/lib/posix_wrap/inttypes.h: New file. - * grub-core/lib/posix_wrap/sys/types.h (int8_t): New type. - (int16_t): Likewise. - (int32_t): Likewise. - (int64_t): Likewise. - Reported and tested by: Alain Greppin. - -2011-01-08 Vladimir Serbinenko - - * grub-core/loader/i386/bsdXX.c (grub_netbsd_load_elf_meta): - Silence spurious warning. - Reported and tested by: Alain Greppin. - -2011-01-07 Szymon Janc - - * docs/grub.texi (Support automatic decompression): Update with xz - decompression support. - -2011-01-07 Szymon Janc - - Improve loaders' kernel command line handling. - - * grub-core/lib/cmdline.c: New file. - * include/grub/lib/cmdline.h: Likewise. - * grub-core/loader/i386/linux.c (grub_cmd_linux): Use - grub_create_loader_cmdline to create kernel command line. - * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Likewise. - * grub-core/loader/powerpc/ieee1275/linux.c (grub_cmd_linux): Likewise. - * grub-core/loader/sparc64/ieee1275/linux.c (grub_cmd_linux): Likewise. - * grub-core/Makefile.core.def (linux16): Add lib/cmdline.c on i386_pc. - (linux): Add lib/cmdline.c on common. - -2011-01-07 Vladimir Serbinenko - - * grub-core/fs/xfs.c (grub_xfs_iterate_dir): Take into account that - inopos might be unaligned. - -2011-01-07 Vladimir Serbinenko - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Add missing - endian transformations. - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. - Based on report by: Doug Nazar. - -2011-01-07 Doug Nazar - - * grub-core/disk/raid5_recover.c (grub_raid5_recover): Add missing - array->members[i].start_sector. - * grub-core/disk/raid6_recover.c (grub_raid6_recover): Likewise. - -2011-01-07 Vladimir Serbinenko - - * util/grub-setup.c (setup): Handle NetBSD and OpenBSD disklabels. - Reported and tested by: Grégoire Sutre. - -2011-01-06 Colin Watson - - * tests/util/grub-shell.in: Set serial terminfo type to `dumb', to - avoid causing test failures by clearing the screen. - -2011-01-06 Colin Watson - - * grub-core/kern/emu/getroot.c (find_root_device_from_mountinfo): - Fix prefix check to handle the case where dir ends with a slash - (most significantly, "/" itself). - Reported by: Michael Vogt. - -2011-01-05 Vladimir Serbinenko - - Run terminfo_cls on initing terminfo output to clear the screen and - move the cursor to (0,0). - - * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_init_output): - Call grub_terminfo_output_init. - * grub-core/term/serial.c (grub_serial_term_output): Set .init. - * grub-core/term/terminfo.c (grub_terminfo_output_init): New function. - * include/grub/terminfo.h (grub_terminfo_output_init): New declaration. - -2011-01-05 Vladimir Serbinenko - - * util/grub-install.in: Determine ofpathname, nvsetenv and efibootmgr - only when needed. - -2011-01-05 Vladimir Serbinenko - - * grub-core/term/terminfo.c (grub_terminfo_readkey): Handle keys with - CTRL. - -2011-01-05 Vladimir Serbinenko - - The E820 type 5 is BADRAM, not EXEC_CODE. - - * grub-core/loader/i386/bsd.c (GRUB_E820_EXEC_CODE): Removed. - (GRUB_E820_BADRAM): New define. - * grub-core/loader/i386/linux.c (grub_linux_boot): Translate code - into reserved. Propagate BADRAM. - * grub-core/loader/i386/bsd.c (GRUB_E820_EXEC_CODE): Removed. - (GRUB_E820_BADRAM): New define. - -2011-01-04 Vladimir Serbinenko - - * grub-core/lib/efi/relocator.c (grub_relocator_firmware_fill_events): - Ignore the memory post-4G. - (grub_relocator_firmware_alloc_region): Additional debug statement. - -2011-01-04 Vladimir Serbinenko - - * grub-core/kern/emu/getroot.c (grub_util_get_grub_dev): Check md/%s - names. - Reported by: David Pravec. - -2011-01-04 Vladimir Serbinenko - - * grub-core/disk/i386/pc/biosdisk.c (GRUB_MOD_INIT): Workaround buggy - BIOSes. - -2011-01-04 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (grub_reed_solomon_add_redundancy): - Prevent overflow. - (grub_reed_solomon_recover): Likewise. - -2011-01-04 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (main) [TEST]: Reactivate normal test. - -2011-01-04 Vladimir Serbinenko - - * grub-core/lib/reed_solomon.c (scratch) [! STANDALONE]: Remove leftover - variable. - -2011-01-04 Colin Watson - - * grub-core/commands/legacycfg.c (GRUB_MOD_INIT): Fix typo in - descriptions of extract_legacy_entries_source and - extract_legacy_entries_configfile. - Reported by: Seung Soo, Ha. - -2011-01-03 Colin Watson - - * grub-core/bus/pci.c (grub_pci_iterate): Skip remaining functions - on devices that do not implement function 0. - -2011-01-03 Dave Vasilevsky - - * grub-core/fs/hfsplus.c: Make parent unsigned. - (grub_hfsplus_cmp_catkey): Don't compare using subtraction, it - overflows. - (grub_hfsplus_cmp_extkey): Likewise - -2011-01-03 Vladimir Serbinenko - - * util/grub-install.in: Correctly use bootloader_id and not - GRUB_DISTRIBUTOR on efibootmgr line. - -2011-01-03 Vladimir Serbinenko - - * util/grub-mkfont.c (main): Report errors in FT_New_Face. - -2010-12-31 Ian Campbell - - * util/grub.d/20_linux_xen.in (linux_entry): Correctly capitalize - Xen and reorder menu item wording to make it clearer that this entry - will launch Xen. Print separate messages when loading Xen and - Linux. - -2010-12-31 Vladimir Serbinenko - - * grub-core/partmap/amiga.c (GRUB_AMIGA_PART_MAGIC): New define. - (amiga_partition_map_iterate): Check "PART" magic to avoid a very long - loop in case of incorrect amiga partmap. - -2010-12-31 Vladimir Serbinenko - - * grub-core/partmap/amiga.c (GRUB_AMIGA_RDSK_MAGIC): New define. - (amiga_partition_map_iterate): Use grub_memcmp instead of grub_strcmp. - Reported by:EHeM. - -2010-12-31 Vladimir Serbinenko - - * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Silence - spurious warning. - Reported by: crocket - -2010-12-27 Vladimir Serbinenko - - * grub-core/loader/xnu.c (grub_cmd_xnu_kernel) [! GRUB_MACHINE_EFI]: - Preload EFIemu. - (grub_cmd_xnu_kernel64) [! GRUB_MACHINE_EFI]: Likewise. - -2010-12-27 Vladimir Serbinenko - - * grub-core/loader/xnu.c (grub_cmd_xnu_kext): Abort if no kernel - is loaded - (grub_cmd_xnu_kextdir): Likewise. - (grub_cmd_xnu_splash): Likewise. - -2010-12-27 Vladimir Serbinenko - - Avoid using Reed-Solomon with 0 redundancy. - - * grub-core/kern/i386/pc/startup.S: Remove 0-data check. - * grub-core/lib/reed_solomon.c (decode_block): Do not proceed on 0 data - or 0 redundancy. - (grub_reed_solomon_add_redundancy): Do not proceed with 0 redundancy. - (grub_reed_solomon_recover): Likewise. - -2010-12-27 Vladimir Serbinenko - - Don't use disk subsystem in freebsd_boot. - - * grub-core/loader/i386/bsd.c (freebsd_bootdev): New variable. - (freebsd_biosdev): Likewise. - (grub_freebsd_boot): Use freebsd_bootdev and freebsd_biosdev. - (grub_cmd_freebsd): Set freebsd_bootdev and freebsd_biosdev. - -2010-12-26 Vladimir Serbinenko - - Handling of files of unknown size is currently limited. They can't be - used e.g. for initrd or modules. Moreover gzip handling of not - easily seekable files is buggy. Disable unknown file size for now. May - be inefficient but works. - - * grub-core/io/gzio.c (test_header): Always retrieve the file size. - * grub-core/io/xzio.c (grub_xzio_open): Likewise. - -2010-12-25 Mirko Parthey - - * grub-core/boot/i386/pc/boot.S: Fix %es:%bx pointing to nowhere on - floppy probe. - -2010-12-25 Jeroen Dekkers - - * grub-core/disk/raid.c (insert_array): Don't add spurious members. - -2010-12-25 Shea Levy - - * grub-core/genmod.sh.in: Use @OBJCOPY@ rather than objcopy. - -2010-12-25 Vladimir Serbinenko - - * util/grub.d/30_os-prober.in: Don't emit drivemap directive for - Windows Server 2008. - Reported by: Devin Giddings. - -2010-12-25 Vladimir Serbinenko - - * grub-core/commands/acpihalt.c (grub_acpi_halt): Sleep for 1.5 before - writing an error message because of async power management. - * grub-core/kern/mips/yeeloong/init.c (grub_halt): Likewise. - (grub_reboot): Likewise. - -2010-12-23 Jordan Uggla - - * tests/util/grub-shell.in: Suppress "ACPI shutdown failed" error to - keep unit tests from failing when they shouldn't. - -2010-12-21 Colin Watson - - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_RAW_SIZE): The - previous patch increased the size of the RS code by 20 bytes (at - least with gcc-4.4), so increase this by 20 bytes to match. - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): Likewise. - -2010-12-21 Colin Watson - - * grub-core/lib/reed_solomon.c (gauss_solve): Fix size of standalone - scratch area. Make sure to initialise chosen in standalone mode as - well as non-standalone. - Reported by: Robert Hooker and Andy Whitcroft. - Tested by: Andy Whitcroft. - -2010-12-21 Colin Watson - - * grub-core/commands/echo.c (grub_cmd_echo): Make UTF-8-clean by - constructing a new unescaped string and passing it to grub_xputs in - one go, rather than passing characters to grub_printf one at a time. - -2010-12-21 Colin Watson - - * grub-core/fs/udf.c (read_string): Pacify GCC warning by - initialising utf16. - -2010-12-21 Colin Watson - - * util/grub-mkconfig_lib.in (gettext_quoted): Add clarifying - comment. Add an extra layer of quotation, requiring the output of - this function to be used in a printf format string. - (gettext_printf): New function. - * util/grub.d/10_hurd.in: Use gettext_printf where appropriate. - Extract translatable strings from here-documents and use a temporary - variable instead, so that xgettext can find them. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - - * po/grub.d.sed: New file. - * po/Makefile.in.in ($(DOMAIN).pot-update): Extract gettext_printf - arguments. Set c-format flags on all strings extracted from - util/grub.d/ (xgettext refuses to include these itself for strings - it extracted from a shell file, but these really are c-format). - -2010-12-20 Vladimir Serbinenko - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_add_module): - Avoid next pointing to nowhere. - -2010-12-19 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_mount): Read data->bblock.rootblock - rather than assuming than rootblock is exactly in the middle. - (grub_affs_label): Likewise. - -2010-12-19 Vladimir Serbinenko - - * grub-core/fs/affs.c (grub_affs_fs) [GRUB_UTIL]: Explicitly set - reserved_first_sector to 0. - * grub-core/fs/cpio.c (grub_cpio_fs) [GRUB_UTIL]: Likewise. - * grub-core/fs/sfs.c (grub_sfs_fs) [GRUB_UTIL]: Likewise. - * grub-core/fs/xfs.c (grub_xfs_fs) [GRUB_UTIL]: Likewise. - -2010-12-19 Vladimir Serbinenko - - Fix handling of UTF-16 UDF labels. - - * grub-core/fs/udf.c (grub_udf_iterate_dir): Move string-parsing part - (read_string): .. here. - (grub_udf_label): Use read_string. - -2010-12-19 BVK Chaitanya - - * grub-core/normal/menu_entry.c (run): Execute commands from menu - editor under argument scope. - Reported by: Jordan Uggla - -2010-12-18 Vladimir Serbinenko - - * util/grub-mkfont.c (main): Handle errors from FT_Set_Pixel_Sizes. - -2010-12-18 Colin Watson - - * grub-core/normal/term.c (print_more): Make \r or \n scroll one - line, and other keys scroll an entire page (previous handling was - for \r and \n to scroll a page and other keys to scroll two lines). - -2010-12-18 Vladimir Serbinenko - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_make_mbi): - Set ptrdest to correct get_physical_target_address rather than - incorrect get_virtual_current_address. - -2010-12-18 kashyap garimella - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_load): Use - correct cat to grub_uint8_t * rather than grub_uint32_t *. - -2010-12-10 Colin Watson - - * .bzrignore: Ignore grub-core/rs_decoder.S. - -2010-12-10 Colin Watson - - * grub-core/gettext/gettext.c (grub_gettext_init_ext): Factor out - .mo/.mo.gz opening sequence to ... - (grub_mofile_open_lang): ... here. - (grub_gettext_init_ext): If opening ll_CC fails, try ll. - * util/grub.d/00_header.in (grub_lang): Include country part of - locale. - Reported by: Mario Limonciello. - -2010-12-09 Robert Millan - - * NEWS: Document addition of ZFS support. - -2010-12-04 Colin Watson - - * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Use `>> 1' - rather than `/ 2', as the latter requires -Wa,--divide which would - require bumping our minimum binutils version. - -2010-12-03 BVK Chaitanya - - * util/grub-script-check.c (main): Print script line number on - error. - -2010-12-01 Robert Millan - - * grub-core/fs/zfs/zfs.c: New file. - * grub-core/fs/zfs/zfs_fletcher.c: Likewise. - * grub-core/fs/zfs/zfs_lzjb.c: Likewise. - * grub-core/fs/zfs/zfs_sha256.c: Likewise. - * grub-core/fs/zfs/zfsinfo.c: Likewise. - - * include/grub/zfs/dmu.h: Likewise. - * include/grub/zfs/dmu_objset.h: Likewise. - * include/grub/zfs/dnode.h: Likewise. - * include/grub/zfs/dsl_dataset.h: Likewise. - * include/grub/zfs/dsl_dir.h: Likewise. - * include/grub/zfs/sa_impl.h: Likewise. - * include/grub/zfs/spa.h: Likewise. - * include/grub/zfs/uberblock_impl.h: Likewise. - * include/grub/zfs/vdev_impl.h: Likewise. - * include/grub/zfs/zap_impl.h: Likewise. - * include/grub/zfs/zap_leaf.h: Likewise. - * include/grub/zfs/zfs.h: Likewise. - * include/grub/zfs/zfs_acl.h: Likewise. - * include/grub/zfs/zfs_znode.h: Likewise. - * include/grub/zfs/zil.h: Likewise. - * include/grub/zfs/zio.h: Likewise. - * include/grub/zfs/zio_checksum.h: Likewise. - - * Makefile.util.def: Build ZFS into libgrubmods. - * grub-core/Makefile.core.def: Build zfs.mod. - -2010-11-30 Szymon Janc - - * grub-core/commands/regexp.c (grub_cmd_regexp): Remove unused - variable. - * grub-core/commands/wildcard.c (match_files): Likewise. - -2010-11-30 Robert Millan - - * grub-core/loader/i386/bsd.c - (grub_cmd_freebsd_loadenv, grub_cmd_freebsd_module_elf): Check - whether kernel is loaded using grub_loader_is_loaded(), rather - than `kernel_type', which may still be `KERNEL_TYPE_NONE' under - certain error conditions. - -2010-11-30 Robert Millan - - * grub-core/commands/echo.c: Include `'. - (grub_cmd_echo): Call grub_refresh() after printing a message. - -2010-11-26 Vladimir Serbinenko - - Avoid using tricks for initialising endian variables. - - * grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot): - Make const. - (GRUB_MOD_INIT): Don't byte-swap. - * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): - Use grub_cpu_to_le16_compile_time and grub_cpu_to_le32_compile_time. - * include/grub/types.h (grub_swap_bytes16_compile_time): New macro. - (grub_swap_bytes32_compile_time): Likewise. - (grub_cpu_to_le32_compile_time): Likewise. - (grub_cpu_to_le16_compile_time): Likewise. - -2010-11-26 Vladimir Serbinenko - - * util/grub-setup.c (setup): Stop recommending --force. People who - understand the dangers of blocklists are able to find this option - anyway and the ones who don't shouldn't use it anyway. - -2010-11-26 Robert Millan - - * grub-core/term/i386/pc/vga_text.c (VGA_TEXT_SCREEN): Beautify. - Update all users. - -2010-11-26 Colin Watson - - Fix LVM-on-RAID probing. - - * util/grub-probe.c (probe): Remember which disk was detected as - RAID (perhaps an LVM physical volume). Use that disk's raidname - rather than that of the top-level disk. - -2010-11-25 BVK Chaitanya - - Fix cmdline argument quotes for setparams command of menuentry - definitions. - - * grub-core/commands/menuentry.c (setparams_prefix): Use single - quotes for arguments. - * grub-core/lib/legacy_parse.c (grub_legacy_escape): Use - grub_strchrsub function instead. - - * include/grub/misc.h (grub_strchrsub): New function. - -2010-11-24 Colin Watson - - * util/deviceiter.c (grub_util_iterate_devices): Save a bit of - effort by skipping "." and ".." entries up-front. - Suggested by: Michael Lazarev. - -2010-11-24 Colin Watson - - * grub-core/Makefile.core.def (xz_decompress): Move -lgcc from - ldflags to ldadd, to fix link line ordering. - (none_decompress): Likewise. - -2010-11-24 Colin Watson - - * grub-core/Makefile.core.def (kernel): Add kern/emu/cache.S for emu - platforms. - (grub-emu-lite): Remove kern/emu/cache.S. - -2010-11-23 Colin Watson - - * util/deviceiter.c (compare_devices): If the by-id link for a - device couldn't be resolved, fall back to sorting by the by-id link - rather than segfaulting. - Reported and tested by: Daniel Mierswa. - -2010-11-23 Colin Watson - - * Makefile.util.def (grub-menulst2cfg): List libraries in ldadd, not - ldflags, to fix link line ordering. - -2010-11-23 Colin Watson - - * grub-core/Makefile.am (gentrigtables): Put -lm after $<; some - linkers are picky about this. - -2010-11-23 Colin Watson - - * grub-core/Makefile.am (command.lst): Adjust sed expression - ordering so that extended and priority commands aren't treated as - ordinary commands. - -2010-11-23 Colin Watson - - * include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_BIOS_BOOT): - Remove byte-swapping function calls, which are not valid in - structure initialisers. - * grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot): Make - non-const. - (GRUB_MOD_INIT): Byte-swap data1, data2, and data3 fields of - grub_gpt_partition_type_bios_boot. - -2010-11-22 Colin Watson - - Fix test program build on GNU/kFreeBSD. - - * Makefile.util.def (example_unit_test): Add `$(LIBZFS) - $(LIBNVPAIR)' library dependencies. - -2010-11-22 Colin Watson - - * util/grub-install.in: Fix parsing of --grub-mkrelpath= option. - -2010-11-22 Colin Watson - - * util/grub-install.in: Remove excessive quoting that broke - installations to RAID devices. - -2010-11-19 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_cmd_linux): Pass correctly the - bootloader version instead of 0. - -2010-11-19 Vladimir Serbinenko - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Fix spurious - warning. - -2010-11-19 Vladimir Serbinenko - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Don't try to - retrieve the metadat sector if size isn't known. - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. - -2010-11-18 Robert Millan - - * grub-core/fs/btrfs.c (grub_btrfs_mount): Replace grub_strncmp() - with grub_memcmp(). - -2010-11-18 Vladimir Serbinenko - - * grub-core/normal/menu_entry.c (print_up): Fix displacement of up - arrow. - Reported by: Jordan Uggla. - -2010-11-16 Vladimir Serbinenko - - Make better UTF compliant. - - * grub-core/normal/charset.c (grub_utf8_to_utf16): Handle 6- and 7-byte - sequences as incorrect. - (grub_is_valid_utf8): Likewise. - (grub_utf8_to_ucs4): Likewise. - (grub_ucs4_to_utf8): Handle codepoints outside of BMP. - (grub_ucs4_to_utf8_alloc): Likewise. - * include/grub/charset.h (grub_utf16_to_utf8): Likewise. - -2010-11-16 Vladimir Serbinenko - - Make legacy_source behave like source. - - * grub-core/commands/legacycfg.c (legacy_file): Don't call - grub_show_menu. - (grub_cmd_legacy_source): Call grub_show_menu if needed. - -2010-11-16 Colin Watson - - * conf/Makefile.common (CFLAGS_GNULIB): Add -Wno-unused-parameter. - (-Wunused implies -Wunused-parameter, but not vice versa). - -2010-11-16 Colin Watson - - * configure.ac: Make error messages less confusing by testing for - -Wtrampolines rather than -Wno-trampolines (since -Wno-* is always - accepted, but produces a diagnostic if something else is wrong). - -2010-11-15 Vladimir Serbinenko - - * grub-core/term/at_keyboard.c (grub_keyboard_controller_read) - [GRUB_MACHINE_MIPS_YEELOONG || GRUB_MACHINE_QEMU]: ifdef-ed out - (now unused). - (grub_keyboard_controller_init) - [GRUB_MACHINE_MIPS_YEELOONG || GRUB_MACHINE_QEMU]: Don't attempt to - read the initial state since controller isn't inited yet. - -2010-11-15 Vladimir Serbinenko - - * grub-core/lib/relocator.c (malloc_in_range): Take into account that - allocate_regbeg may need to create new chunk header. - -2010-11-14 Vladimir Serbinenko - - Fix quoting in legacy parser. - - * grub-core/lib/legacy_parse.c (grub_legacy_escape): Correctly handle - single quotes. - (grub_legacy_parse): Likewise. - Reported by: Jordan Uggla. - Tested by: Jordan Uggla. - -2010-11-14 Vladimir Serbinenko - - Don't add -lgcc on i386 and x86_64. - - * configure.ac (LIBS): Don't add -lgcc on i386 and x86_64. - * conf/Makefile.common (LDADD_KERNEL): Likewise. - * grub-core/Makefile.core.def (kernel): Use LDADD_KERNEL. - -2010-11-14 Vladimir Serbinenko - - * configure.ac: Add -Wno-trampolines when supported. - -2010-11-14 Modestas Vainius - - * grub-core/kern/emu/getroot.c (grub_util_is_dmraid): Recognise ddf1_ - fakeraid. - -2010-11-14 Giuseppe Caizzone - - Add generic logical block size support for UDF. - - * grub-core/fs/udf.c (GRUB_UDF_LOG2_BLKSIZE): Removed. - (GRUB_UDF_BLKSZ): Removed. - (struct grub_udf_data): New field "lbshift" to hold the logical block - size of the file system in log2 format. All users updated. - (sblocklist): Change type to unsigned. - (grub_udf_mount): Change type of "sblklist" to unsigned. - Move AVDP search before VRS recognition, because the latter requires - knowledge of the logical block size, which is detected during the - former. - Detect and validate logical block size during AVDP search, adding - support for block sizes 512, 1024 and 4096. - Make VRS recognition independent of block size. - -2010-11-14 Giuseppe Caizzone - - Properly handle deleted files on UDF. - - * grub-core/fs/udf.c (grub_udf_iterate_dir): Skip directory entries - whose "characteristics" field has the bit GRUB_UDF_FID_CHAR_DELETED - set. - -2010-11-14 Giuseppe Caizzone - - Support reading files larger than 2 GiB. - - * grub-core/fs/udf.c (grub_udf_iterate_dir): Change type of variable - "offset" to grub_off_t. - (grub_udf_read_file): Likewise for parameter "pos". - -2010-11-14 Vladimir Serbinenko - - * docs/grub.texi (Changes from GRUB Legacy): Note when save_env is - unavailable. - (Simple configuration): Refer to Changes from GRUB Legacy about - save_env availability. - -2010-11-14 Vladimir Serbinenko - - * util/grub-install.in: Ignore empty partition table detection - instead of trying to include part_ module. - -2010-11-14 Vladimir Serbinenko - - * grub-core/disk/lvm.c (GRUB_MOD_FINI): Reset the vg_list. Fixes - LVM on RAID support. - -2010-11-14 Vladimir Serbinenko - - Properly define WORDS_BIGENDIAN in wrapped environments. - - * grub-core/lib/libgcrypt_wrap/cipher_wrap.h (WORDS_BIGENDIAN): New - definition. - * grub-core/lib/posix_wrap/sys/types.h (WORDS_BIGENDIAN): Likewise. - - Reported by: Manoel Rebelo Abranches. - Tested by: Manoel Rebelo Abranches. - -2010-11-13 Vladimir Serbinenko - - * util/grub-mkconfig.in: Fix quoting. - -2010-11-13 Vladimir Serbinenko - - Support big ext2 files. - - * grub-core/fs/ext2.c (grub_ext2_inode): Rename dir_acl to size_high. - (grub_ext2_read_block): Support triple indirect blocks. - (grub_ext2_read_file): Use 64-bit types and read size_high. - (grub_ext2_open): Read size_high. - Reported by: Ximin Luo. - Tested by: Manoel Rebelo Abranches. - -2010-11-13 Vladimir Serbinenko - - * util/grub-install.in: Handle filenames containing spaces. - Reported by: Jordan Uggla. - Tested by: Jordan Uggla. - -2010-11-13 Vladimir Serbinenko - - * util/grub-mkconfig.in (grub_script_check): New variable. - Use grub_script_check instead of grub-script-check. - Reported by: Barry Jackson. - -2010-11-13 Vladimir Serbinenko - - * docs/grub.texi (menu): Correct the order. - Reported by: D. Hugh Redelmeier. - -2010-11-12 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S (multiboot_trampoline): Add missing - jump. - -2010-11-08 Manoel Rebelo Abranches - - * include/grub/elfload.h (grub_elf32_size): New parameter. - All users updated. - Return maximum segments alignment. - (grub_elf64_size): Likewise. - * kern/elf.c (grub_elf32_size): New parameter. All users updated. - Return maximum segments alignment. - (grub_elf64_size): Likewise. - * grub-core/loader/powerpc/ieee1275/linux.c: - (grub_linux_claimmap_iterate): New function. Uses the - "available" property in the "memory" node for memory allocation - for kernel in the PowerPC loader. - (grub_linux_load32): Correctly find linux entry point offset. - (grub_linux_load64): Likewise. - -2010-11-07 Robert Millan - - On mips-yeeloong, build with -march=loongson2f when this flag is - available (GCC >= 4.4). - * conf/Makefile.common [COND_mips_yeeloong] (CFLAGS_PLATFORM): Remove - `-march=mips3'. - * configure.ac: For mips-yeeloong, add -march=loongson2f if available, - or otherwise add -march=mips3. - -2010-11-07 BVK Chaitanya - - Suppress shell expansion on echo '*' and echo "*" like cases. - Reported by: Jordan Uggla. - - * grub-core/script/execute.c (grub_script_arglist_to_argv): Escape - string arguments before shell expansion. - * tests/grub_cmd_echo.in: New testcases. - -2010-11-07 Robert Millan - - * conf/mips-qemu-mips.rmk: Remove stale file from previous - transition. - -2010-11-07 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c - (convert_system_partition_to_system_disk): Handle devices like "sdaa1". - -2010-11-06 Vladimir Serbinenko - - * include/grub/emu/misc.h: Don't include grub/util/libzfs.h. - * include/grub/emu/misc.h (grub_get_libzfs_handle): Move from here ... - * include/grub/util/libzfs.h (grub_get_libzfs_handle): ... here. - -2010-11-06 Vladimir Serbinenko - - * grub-core/fs/ntfs.c (grub_ntfs_uuid): Make uppercase. - -2010-11-06 Vladimir Serbinenko - - * util/grub-install.in: Replace useless recomendation to pass - --modules with a recomendation to report a bug. - -2010-11-06 Vladimir Serbinenko - - Properly register serial terminfo. - Reported by: Jordan Uggla - - * grub-core/term/serial.c (grub_serial_terminfo_input_template): New - const. - (grub_serial_terminfo_output_template): Likewise. - (grub_cmd_serial): Register "serial" with terminfo. - (GRUB_MOD_INIT(serial)): Fill grub_serial_terminfo_input and - grub_serial_terminfo_output. - -2010-11-05 Robert Millan - - * util/grub-mkconfig.in: Remove gfxterm.mod probe (no longer - needed). - -2010-11-05 Robert Millan - - On Yeeloong, pass machine type information to Linux. - - * grub-core/loader/mips/linux.c [GRUB_MACHINE_MIPS_YEELOONG] - (LOONGSON_MACHTYPE): New macro, set to - "machtype=lemote-yeeloong-2f-8.9inches". - [LOONGSON_MACHTYPE] (grub_cmd_linux): Pass LOONGSON_MACHTYPE as - additional argument to Linux. - -2010-11-04 Robert Millan - - * util/deviceiter.c (grub_util_iterate_devices): Increase SCSI - limit to 48 (to cope with Sun Fire X4500), and IDE limit to 96 - (its SATA disks are detected as slaveless IDE master drives on - kFreeBSD). - Reported by Carsten Aulbert. - -2010-11-02 Colin Watson - - * util/bin2h.c (main): Fix spelling error in generated output. - -2010-11-01 Grégoire Sutre - - * grub-core/partmap/bsdlabel.c (iterate_real): Fix an integer overflow. - -2010-11-01 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (grub_cmd_linux): Autoload vbe.mod if - vga= option is supplied. - -2010-11-01 Vladimir Serbinenko - - * util/grub.d/10_hurd.in: Don't call savedefault on recovery entries. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - -2010-11-01 Vladimir Serbinenko - - * grub-core/lib/arg.c (grub_arg_parse): Avoid interpreting direct - argument as an argument to no-argument option. - -2010-11-01 Vladimir Serbinenko - - * util/grub.d/10_linux.in: Add missing load_video with explicit - GRUB_GFXPAYLOAD_LINUX. - -2010-11-01 Vladimir Serbinenko - - * Makefile.am (libgrub.pp): Propagate the libgrub.a split. - -2010-11-01 Vladimir Serbinenko - - * grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Do not put - elements with invlid index. - * grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise. - * grub-core/disk/raid.c (insert_array): Automatically reallocate - members. - * include/grub/raid.h (grub_raid_member): New struct. - (grub_raid_array): Transform devices and start_sector into usage of - grub_raid_member. All users updated - (allocated_devs): New member. - -2010-11-01 Vladimir Serbinenko - - * docs/man/grub-set-default.h2m: Clarify that only saved default entry - is modified - -2010-10-29 BVK Chaitanya - - NetBSD build fix for getline function conflict from gnulib. - - * Makefile.util.def (libgrubkern.a): New library for grub kernel - components that depend on gnulib headers. - (libgrubmods.a): Renamed from earlier libgrub.a. - * conf/Makefile.common: Remove gnulib from *_LIBRARY flags. - -2010-10-26 Vladimir Serbinenko - - * util/grub-setup.c (setup): Refuse to do a cross-disk embeddingless - install rather than creating a broken install. - -2010-10-26 Vladimir Serbinenko - - * util/grub-setup.c (argp): Remove misleading example of installing to - a partition. - -2010-10-26 Vladimir Serbinenko - - * util/grub-setup.c (setup): Clarify the error message. - -2010-10-26 Vladimir Serbinenko - - * include/grub/types.h (grub_target_off_t): Removed no longer used type. - -2010-10-23 Vladimir Serbinenko - - * grub-core/kern/emu/misc.c - (grub_make_system_path_relative_to_its_root) - [HAVE_LIBZFS && HAVE_LIBNVPAIR]: Fix mountpoint return on ZFS. - -2010-10-23 Vladimir Serbinenko - - * grub-core/kern/emu/misc.c - (grub_make_system_path_relative_to_its_root): Revert r2882. - -2010-10-22 Vladimir Serbinenko - - * grub-core/lib/relocator.c (grub_relocator_subchunk): Remove now - useless field head. All users updated. - (free_subchunk): Correct handling of IN_REGION subchunk. - -2010-10-22 Colin Watson - - * docs/grub.texi (Installing GRUB using grub-install): Proofread. - (Supported kernels): Likewise. - -2010-10-18 Grégoire Sutre - - Make mktemp invocations portable. - - * grub-core/genmod.sh.in: Use mktemp with an explicit template, and - exit if mktemp fails. - * tests/grub_script_blockarg.in: Likewise. - * tests/partmap_test.in: Likewise. - * tests/util/grub-shell-tester.in: Likewise. - * tests/util/grub-shell.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - * Makefile.am: Likewise, and chain shell commands with `&&' - instead of ';'. - * util/grub-mkrescue.in: Use the same explicit template as above, and - exit if mktemp fails. - -2010-10-18 BVK Chaitanya - - * util/grub.d/10_linux.in: Fix built-in initramfs image mode for - Linux kernel, reported by Dennis Schridde. - -2010-10-17 Szymon Janc - - * grub-core/normal/auth.c (grub_auth_check_authentication): - Set-but-not-used variable removed. - -2010-10-17 Vladimir Serbinenko - - * docs/grub.texi (GNU/Linux): Document APM unavailability with - 32-bit linux protocol. - -2010-10-17 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S (grub_console_setcursor): Check - cursor shape for sanity. - -2010-10-17 Vladimir Serbinenko - - * docs/grub.texi (Installation): Document buggy BIOS install. - -2010-10-17 Vladimir Serbinenko - - * docs/grub.texi (Installation): Indent. - -2010-10-17 Vladimir Serbinenko - - * util/grub-setup.c (setup): New parameter allow_floppy. - (arguments): New member allow_floppy. - (argp_parser): Handle --allow-floppy. - (main): Pass allow_floppy. - * util/grub-install.in: New option --allow-floppy passed though to - grub-setup. - -2010-10-17 Vladimir Serbinenko - - * util/grub-install.in: Handle partitionless disks. - -2010-10-17 Vladimir Serbinenko - - * util/grub-setup.c (setup): Don't clean blocklists before readability - verfification. - -2010-10-16 Vladimir Serbinenko - - * docs/grub.texi (Installation): Document embedding zone. Remove - obsolete grub-install example. - -2010-10-16 Szymon Janc - - * grub-core/commands/legacycfg.c (grub_cmd_legacy_kernel): - Set-but-not-used variable ifdef'ed. - * grub-core/lib/legacy_parse.c (grub_legacy_parse): Likewise. - * grub-core/bus/usb/ohci.c (grub_ohci_pci_iter): Set-but-not-used - variable removed. - * grub-core/disk/lvm.c (grub_lvm_scan_device): Likewise. - * grub-core/fs/jfs.c (grub_jfs_find_file): Likewise. - * grub-core/fs/minix.c (grub_minix_dir): Likewise. - * grub-core/fs/sfs.c (grub_sfs_read_extent): Likewise. - * grub-core/fs/ufs.c (grub_ufs_dir): Likewise. - * grub-core/gfxmenu/gui_list.c (grub_gui_list_new): Likewise. - * grub-core/gfxmenu/view.c (redraw_menu_visit): Likewise. - * grub-core/gfxmenu/widget-box.c (draw): Likewise. - * grub-core/lib/relocator.c (malloc_in_range): Likewise. - * grub-core/loader/i386/bsdXX.c (grub_netbsd_load_elf_meta): Likewise. - * grub-core/loader/i386/bsd_pagetable.c (fill_bsd64_pagetable): - Likewise. - -2010-10-16 Vladimir Serbinenko - - * grub-core/commands/acpihalt.c (skip_ext_op): Skip index field op. - * include/grub/acpi.h (GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP): New - enum value. - -2010-10-16 Vladimir Serbinenko - - * grub-core/commands/acpihalt.c (get_sleep_type): Accept \_S5_ as - synonym to _S5_. Needed for some DSDTs. - -2010-10-16 Vladimir Serbinenko - - Userspace ACPI parser debugging. - - * grub-core/commands/acpihalt.c [GRUB_DSDT_TEST]: Include userspace - headers and add relevant defines. Don't include standard headers. - (main) [GRUB_DSDT_TEST]: New function. - * include/grub/acpi.h [GRUB_DSDT_TEST]: Don't include standard headers. - Don't declare functions. - -2010-10-16 Vladimir Serbinenko - - Remove dead grub_efi_mm_fini. - - * grub-core/kern/efi/mm.c (allocated_page): Removed. - (ALLOCATED_PAGES_SIZE): Likewise. - (MAX_ALLOCATED_PAGES): Likewise. - (allocated_pages): Likewise. - (grub_efi_allocate_pages): Don't record allocated pages. - (grub_efi_free_pages): Likewise. - (grub_efi_mm_init): Likewise. - (grub_efi_mm_fini): Removed. - -2010-10-16 Vladimir Serbinenko - - * grub-core/kern/efi/mm.c (BYTES_TO_PAGES): Round up instead of down. - (grub_efi_mm_init): Take into account the memory map size increase. - -2010-10-16 Vladimir Serbinenko - - * grub-core/term/ns8250.c (do_real_config): Set port->broken to 0. - (serial_hw_put): Wait based on real time rather than port reads. Don't - roken ports. - * include/grub/serial.h (grub_serial_port): New field broken. - -2010-10-16 Robert Millan - - * grub-core/kern/emu/misc.c - (grub_make_system_path_relative_to_its_root): Fix premature return - when processing non-root ZFS filesystems. - Reported by Sergio Talens-Oliag. - -2010-10-15 Robert Millan - - * util/grub.d/10_linux.in (list): Expand "vmlinu[zx]" instances to - guarantee compressed ones are processed first. - -2010-10-14 Vladimir Serbinenko - - * grub-core/efiemu/main.c (grub_efiemu_prepare): Handle errors from - grub_efiemu_autocore. - -2010-10-14 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S (bypass_table): Use 0x1b explicitly - rather than 0x1b. - (grub_console_getkey): Use correct jae opcode rather than ja. - -2010-10-12 Robert Millan - - * util/grub-mkconfig.in: Merge `GRUB_DISABLE_LINUX_RECOVERY' and - `GRUB_DISABLE_NETBSD_RECOVERY' into a single `GRUB_DISABLE_RECOVERY' - variable. All references updated. - - * util/grub.d/10_kfreebsd.in: Support recovery boot entries. - -2010-10-08 Vladimir Serbinenko - - Correctly distinguish mdraid flavours. - - * grub-core/disk/raid.c (grub_raid_getname) [GRUB_UTIL]: New function. - (insert_array): New argument raid. - * include/grub/disk.h (grub_disk_dev) [GRUB_UTIL]: New member raidname. - * include/grub/raid.h (grub_raid_array) [GRUB_UTIL]: New member driver. - * util/grub-probe.c (probe): PRint raidname instead of plainly "mdraid". - -2010-10-09 Vladimir Serbinenko - - * grub-core/kern/i386/pc/startup.S (grub_console_getkey): Fix incorrect - handling of special keys. - -2010-10-02 Aleš Nesrsta - - * include/grub/scsi.h (grub_make_scsi_id): Fix incorrect usgae of - GRUB_SCSI_ID_BUS_SHIFT instead of GRUB_SCSI_ID_LUN_SHIFT. - -2010-10-02 Aleš Nesrsta - - * grub-core/bus/usb/ohci.c (GRUB_OHCI_TDS): Increase. - * grub-core/bus/usb/uhci.c (N_TD): New definition. All previous implicit - users updated. - * grub-core/bus/usb/usbtrans.c (grub_usb_bulk_setup_readwrite): - Use right endpoint when querying descriptor. - -2010-10-01 Vladimir Serbinenko - - Clear out 0x80 color bit on EFI. - Tested by: decoder - Reported by: decoder and meta tech. - - * grub-core/term/efi/console.c (grub_console_standard_color): Removed. - (grub_console_setcolorstate): Clear out 0x80 bit. - Use GRUB_TERM_DEFAULT_STANDARD_COLOR. - (grub_console_output): Use GRUB_TERM_DEFAULT_NORMAL_COLOR. - Use GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR. - -2010-10-01 Vladimir Serbinenko - - * grub-core/loader/i386/linux.c (DEFAULT_VIDEO_MODE) [GRUB_MACHINE_EFI]: - Set to "auto". - -2010-09-30 Vladimir Serbinenko - - * grub-core/gettext/gettext.c (grub_gettext_init_ext): Avoid using - mo_file after freeing. - -2010-09-30 Vladimir Serbinenko - - * grub-core/normal/term.c (read_terminal_list): Free in a right order. - -2010-09-30 Vladimir Serbinenko - - * grub-core/script/execute.c (grub_script_execute_sourcecode): Set - flags. - -2010-09-30 Vladimir Serbinenko - - * util/grub-setup.c (main) [GRUB_MACHINE_IEEE1275]: Propagate argp - usage. - -2010-09-30 Vladimir Serbinenko - - Put terminfo into core on ieee1275 and yeeloong (needed for console). - - * gentpl.py: New groups terminfoinkernel and terminfomodule. - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Include extcmd.h, arg.h - and terminfo.h when needed. - * grub-core/Makefile.core.def (kernel): Include term/terminfo.c, - term/tparm.c, commands/extcmd.c, lib/arg.c on terminfokernel. - (terminfo): Enable only on terminfokernel. - (extcmd): Likewise. - * include/grub/extcmd.h: Add missing EXPORT_FUNC. - * include/grub/lib/arg.h: Likewise. - * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Fix - incorrect usage of ->. - -2010-09-29 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi] - [GRUB_MACHINE_EFI && __i386__]: Fix typo. - -2010-09-29 Vladimir Serbinenko - - Fix coreboot compilation. - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_get_mbi_size): - Take VBE info into account even if only text is supported. - (fill_vbe_info): Take into account the case when only VGA text - is supported. - * include/grub/multiboot.h (GRUB_MACHINE_HAS_VBE): Set to zero - on coreboot, multiboot and qemu. - -2010-09-29 Vladimir Serbinenko - - * grub-core/lib/relocator.c (malloc_in_range): Trim too verbose - debug messages. - (grub_relocator_prepare_relocs): Set movers_chunk.srcv. - -2010-09-29 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c (grub_cmd_netbsd): Provide default serial - parameters. - -2010-09-29 Vladimir Serbinenko - - * grub-core/lib/arg.c (grub_arg_parse): Fix treating of all commands as - if they were BSD-style. - -2010-09-29 Vladimir Serbinenko - - * grub-core/boot/i386/pc/lnxboot.S: Replace - GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE with - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART. - -2010-09-29 Vladimir Serbinenko - - Write embedding zone using Reed-Solomon. - - * Makefile.util.def (grub-setup): Add grub-core/lib/reed_solomon.c. - * grub-core/Makefile.am (rs_decoder.S): New target. - (kern/i386/pc/startup.S): Depend on rs_decoder.S. - * grub-core/kern/i386/pc/startup.S (reed_solomon_redundancy): New field. - (multiboot): Move to RS part. - (post_reed_solomon): New label. - (grub_boot_drive): Move to non-RS part since it's modified in memory - on boot. - Include rs_decoder.S. - * grub-core/lib/reed_solomon.c: New file. - * include/grub/offsets.h (GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY): - New definition. - (GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE): Removed. - (GRUB_KERNEL_I386_PC_RAW_SIZE): Updated. - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART): New definition. - * include/grub/partition.h (grub_partition_map): Change prototype of - embed to allow returning additional sectors. - * include/grub/reed_solomon.h: New file. - * util/grub-setup.c (setup): Handle Reed-Solomon. - -2010-09-28 Colin Watson - - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix - i386 and x86-64 definedness tests. - -2010-09-27 Yves Blusseau - - Fix generation of kernel_syms.lst - - * grub-core/Makefile.am (kernel_syms.lst): Fix value and position of - ASM_PREFIX - -2010-09-26 Robert Millan - - Support degraded ZFS arrays in "grub-probe -t device" resolution. - - * grub-core/kern/emu/getroot.c (find_root_device_from_libzfs): When - the pool is an array of devices, iterate through it and return the - first device that passes a stat() test (instead of blindly returning - the first one). - -2010-09-26 Robert Millan - - Build fixes for GNU/kFreeBSD. - - * Makefile.util.def: Add `$(LIBZFS) $(LIBNVPAIR)' library dependencies - to programs that require ZFS conversion. - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): Support - kernels that don't have FLOPPY_MAJOR. - -2010-09-25 BVK Chaitanya - - * grub-core/kern/emu/full.c (grub_emu_post_init): Fix typo. - -2010-09-25 BVK Chaitanya - - Fix grub-emu build. - - * grub-core/kern/emu/main.c: Remove #include . - * grub-core/kern/emu/full.c: Split grub_mdraid_{init,fini} into - mdraid09 and mdraid1x. - -2010-09-24 Colin Watson - - Re-enable grub-extras. - - * autogen.sh: Create symlinks to ${GRUB_CONTRIB} if necessary to - avoid confusing Automake. Run autogen only twice, once for the top - level and once for grub-core. Add Makefile.util.def and - Makefile.core.def from extra modules to the appropriate autogen - invocations. If Makefile.common exists in an extra module, include - it in both Makefile.util.am and grub-core/Makefile.core.am; - similarly, include any Makefile.util.common file in Makefile.util.am - and any Makefile.core.common file in grub-core/Makefile.core.am. - * conf/Makefile.common ($(top_srcdir)/grub-core/Makefile.core.am): - Depend on $(top_srcdir)/grub-core/Makefile.gcry.def. - ($(top_srcdir)/grub-core/Makefile.gcry.def): Remove. - * grub-core/Makefile.am: Remove inclusion of Makefile.gcry.am. - - * gentpl.py (gvar_add): Turn GVARS into a set. - (global_variable_initializers): Sort global variables on output. - (vars_init): New function. - (first_time): Likewise. - (library): Ensure that non-global variable initialisations are - emitted before the first time we emit code for a library block. - Append to variables rather than setting them. Only emit - noinst_LIBRARIES, BUILT_SOURCES, and CLEANFILES the first time for - each conditional path. - (program): installdir() emits an Autogen macro, so must be passed to - var_add rather than gvar_add. - (data): Likewise. - (script): Likewise. - (rules): New function, centralising handling for different target - types. Set up Guile association lists for first_time and vars_init, - and send most output to a diversion so that variable initialisations - can be emitted first. - (module_rules): Use new rules function. - (kernel_rules): Likewise. - (image_rules): Likewise. - (library_rules): Likewise. - (program_rules): Likewise. - (script_rules): Likewise. - (data_rules): Likewise. - - * configure.ac: Add AC_PROG_LN_S, for the benefit of ntldr-img. - - * .bzrignore: Add contrib and grub-core/contrib. Remove - grub-core/Makefile.gcry.am. - -2010-09-24 Yves Blusseau - - * grub-core/lib/LzFind.c: Add missing include. - * grub-core/lib/LzmaEnc.c: Likewise. - * grub-core/script/lexer.c: Likewise. - * grub-core/script/yylex.l: Likewise. - * util/grub-macho2img.c: Likewise. - * util/grub-menulst2cfg.c: Likewise. - * util/grub-mklayout.c: Likewise. - * util/grub-mkpasswd-pbkdf2.c - * util/grub-mkrelpath.c: Likewise. - * util/resolve.c: Likewise. - -2010-09-24 BVK Chaitanya - - * Makefile.util.def (example_unit_test): Add - grub-core/gnulib/libgnu.a. - -2010-09-23 Grégoire Sutre - - * grub-core/commands/acpihalt.c (get_sleep_type): Initialize prev. - -2010-09-23 Vladimir Serbinenko - - Support xz compression on yeeloong. - - * Makefile.util.def (grub-mkimage): Add $(LIBLZMA). - * configure.ac: Check for LZMA. - * grub-core/Makefile.core.def (xz_decompress): New target. - (none_decompress): Likewise. - * grub-core/boot/decompressor/minilib.c: New file. - * grub-core/boot/decompressor/none.c: Likewise. - * grub-core/boot/decompressor/xz.c: Likewise. - * grub-core/kern/mips/cache.S: Change to noreorder nomacro. - * grub-core/kern/mips/cache_flush.S: Likewise. - * grub-core/kern/i386/pc/lzma_decode.S: Remove dead code. - * grub-core/kern/mips/startup.S: Move first stage to ... - * grub-core/boot/mips/startup_raw.S: ...here. Change to noreorder - nomacro. - * grub-core/kern/mips/startup.S: Change to noreorder nomacro. - * grub-core/lib/mips/relocator_asm.S: Change to noreorder nomacro. - * grub-core/lib/xzembed/xz_dec_bcj.c [GRUB_EMBED_DECOMPRESSOR]: - Allocate statically. - * grub-core/lib/xzembed/xz_dec_lzma2.c [GRUB_EMBED_DECOMPRESSOR]: - Allocate statically or use scratch. Don't check CRC32. - * grub-core/lib/xzembed/xz_dec_stream.c [GRUB_EMBED_DECOMPRESSOR]: - Allocate statically. Don't check CRC32. - * include/grub/decompressor.h: New file. - * include/grub/offsets.h (GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE): - Removed. - (GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE): New field. - (GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE): Adjusted. - (GRUB_KERNEL_MIPS_YEELOONG_PREFIX): Likewise. - (GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END): Likewise. - (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE): New define. - * util/grub-mkimage.c (grub_compression_t): New type. - (PLATFORM_FLAGS_DECOMPRESSORS): New flag. - (image_target_desc): New field default_compression. - (image_targets): Adjust yeeloong targets. - (compress_kernel_xz) [HAVE_LIBLZMA]: New function. - (compress_kernel): New parameter comp. - (generate_image): Likewise. Handle new compression case. - (options): New option --compression - (help): Likewise. - (main): Handle new option. - -2010-09-22 Grégoire Sutre - - * grub-core/kern/emu/hostdisk.c [__NetBSD__]: Define FLOPPY_MAJOR. - -2010-09-22 Colin Watson - - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix - typo in __i386__ conditional. - -2010-09-22 Vladimir Serbinenko - - * grub-core/loader/multiboot_mbi2.c (GRUB_MACHINE_EFI): Add missing - include. - -2010-09-22 Vladimir Serbinenko - - Implement EFI and ACPI multiboot2 extensions. - - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_load): Declare - new tags as supported. - (acpiv2_size): New function. - (grub_multiboot_get_mbi_size): Take new tags into account. - (grub_multiboot_make_mbi): Add new tags. - * include/grub/multiboot.h (GRUB_MACHINE_HAS_ACPI): New definition. - -2010-09-21 Aleš Nesrsta - - * grub-core/bus/usb/serial/common.c (grub_usbserial_attach): - Added missing configuration of USB device. - -2010-09-21 Colin Watson - - * grub-core/normal/menu_entry.c (run): Make sure we always return - a value. - -2010-09-21 Colin Watson - - * grub-core/commands/efi/lsefimmap.c (grub_cmd_lsefimmap): - NumberOfPages is UINT64 according to the UEFI specification, not - UINTN. Fix printf format. - -2010-09-21 Colin Watson - - * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Change type of - `err' to grub_usb_err_t. - Reported and tested by: KESHAV P.R. - -2010-09-21 Colin Watson - - * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): Make - tpart non-const, so that we can assign to it. (Since this is a - typedef, the constness refers to the pointer rather than what it - points to.) - -2010-09-21 Colin Watson - - * conf/Makefile.common (CPPFLAGS_GNULIB): Add - $(top_srcdir)/grub-core/gnulib as well as - $(top_builddir)/grub-core/gnulib. - Reported by: KESHAV P.R. - -2010-09-21 Colin Watson - - * util/grub-install.in: Fix the bootloader ID option to be - consistently --bootloader-id, not --bootloader_id. - Reported by: KESHAV P.R. - -2010-09-21 Colin Watson - - * grub-core/commands/hashsum.c (GRUB_MOD_INIT): Make "Compute or - check hash checksum." consistently translatable. - -2010-09-21 Yves Blusseau - - * conf/Makefile.common (CPPFLAGS_GNULIB): Replace $(top_srcdir) with - $(top_builddir). - -2010-09-21 Colin Watson - - * grub-core/commands/hashsum.c (aliases): Add sha1sum alias. - (GRUB_MOD_INIT): Register sha1sum command. - (GRUB_MOD_FINI): Unregister sha1sum command. - -2010-09-21 Yves Blusseau - - Keep boot and grub directory names in sync with utils scripts - - * configure.ac: Define GRUB_BOOT_DIR_NAME and GRUB_DIR_NAME macros. - * config.h.in: Add previous macros. - * include/grub/emu/misc.h (DEFAULT_DIRECTORY): Use previous macros. - * util/grub-install.in: Use $bootdir and $grubdir variables. - -2010-09-21 Colin Watson - - * grub-core/kern/emu/hostdisk.c (find_system_device): Only try to - convert partition names to disk names if the new `convert' parameter - is set. - (grub_util_biosdisk_get_grub_dev): If opening the disk device - returns GRUB_ERR_UNKNOWN_DEVICE, treat the partition device as a - disk in its own right. This can happen with Xen disk images. - -2010-09-21 Yves Blusseau - - * util/grub-editenv.c: Update strings to avoid warnings when generating - grub.pot file. - * util/grub-setup.c: Likewise. - -2010-09-21 Vladimir Serbinenko - - * configure.ac: Change version to 1.99~beta0. - -2010-09-21 Vladimir Serbinenko - - * grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): - Add BADRAM. - * grub-core/loader/multiboot_mbi2.c (grub_fill_multiboot_mmap): - Likewise. - * include/multiboot.h: Resynced with specification. - * include/multiboot2.h: Likewise. - -2010-09-21 Colin Watson - - Fix po directory handling. - - * configure.ac: Create po/Makefile.in rather than po/Makefile. - * grub-core/gnulib/Makefile.am: Import gettext module. - * m4/gnulib-cache.m4: Likewise. - * m4/gnulib-comp.m4: Likewise. - * m4/gettext.m4: New file, from gnulib. - * m4/glibc2.m4: Likewise. - * m4/iconv.m4: Likewise. - * m4/intdiv0.m4: Likewise. - * m4/intl.m4: Likewise. - * m4/intldir.m4: Likewise. - * m4/intlmacosx.m4: Likewise. - * m4/intmax.m4: Likewise. - * m4/inttypes-pri.m4: Likewise. - * m4/lcmessage.m4: Likewise. - * m4/lib-ld.m4: Likewise. - * m4/lib-link.m4: Likewise. - * m4/lib-prefix.m4: Likewise. - * m4/lock.m4: Likewise. - * m4/nls.m4: Likewise. - * m4/po.m4: Likewise. - * m4/printf-posix.m4: Likewise. - * m4/progtest.m4: Likewise. - * m4/threadlib.m4: Likewise. - * m4/uintmax_t.m4: Likewise. - * m4/visibility.m4: Likewise. - * po/Makefile.am: Remove. - * po/Makefile.in.in: New file, from gettext. - ($(DOMAIN).pot-update): Support POTFILES-shell. - * po/Makevars: New file. - * po/POTFILES-shell: Rename to ... - * po/POTFILES-shell.in: ... this. Update. - * po/POTFILES: Rename to ... - * po/POTFILES.in: ... this. Update. - * po/Rules-quot: New file, from gettext. - * po/boldquot.sed: Likewise. - * po/en@boldquot.header: Likewise. - * po/en@quot.header: Likewise. - * po/insert-header.sin: Likewise. - * po/quot.sed: Likewise. - * po/remove-potcdate.sin: Likewise. - -2010-09-20 Vladimir Serbinenko - - * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Use UUID when possible. - -2010-09-20 Vladimir Serbinenko - - * util/grub.d/20_linux_xen.in: Use submenus. - -2010-09-20 Vladimir Serbinenko - - Support submenus. - - * grub-core/commands/menuentry.c (grub_normal_add_menu_entry): New - parameter submenu. All users updated. - * grub-core/normal/main.c (free_menu): Rename to ... - (grub_normal_free_menu): ... this. Made global. - * grub-core/normal/menu.c (grub_menu_execute_entry): Open new context - if requested. - * grub-core/normal/menu_entry.c (screen): New field submenu. - (make_screen): Set submenu. - (run): Open new context if requested. - * include/grub/menu.h (grub_menu_entry): New field submenu. - * include/grub/normal.h (grub_normal_free_menu): New proto. - -2010-09-20 Vladimir Serbinenko - - Menu entries extractor. - - * grub-core/commands/configfile.c (grub_cmd_source): Implement extractor - variants. - (GRUB_MOD_INIT): Register new variants. - (GRUB_MOD_FINI): Unregister new variants. - * grub-core/commands/legacycfg.c (grub_cmd_legacy_configfile): Merge - into grub_cmd_legacy_source. - (grub_cmd_legacy_source): Implement extractor variants. - (GRUB_MOD_INIT): Register new variants. - (GRUB_MOD_FINI): Unregister new variants. - * grub-core/commands/menuentry.c (grub_menu_init): Declare menuentry - as an extractor. - * grub-core/commands/search_wrap.c (GRUB_MOD_INIT): Declare - search as an extractor. - * grub-core/commands/test.c (GRUB_MOD_INIT): Declare - test as an extractor. - * grub-core/kern/corecmd.c (grub_register_core_commands): Declare set - as an extractor. - * grub-core/normal/context.c (grub_env_context_open): Reorganised. - (grub_env_new_context): New function. - (grub_env_context_open): Likewise. - (grub_env_extractor_open): Likewise. - (grub_env_extractor_close): Likewise. - * grub-core/script/execute.c (grub_script_execute_cmdline): Handle - grub_extractor_level. - * include/grub/command.h (GRUB_COMMAND_FLAG_EXTRACTOR): New flag. - * include/grub/env.h (grub_env_extractor_open): New proto. - (grub_env_extractor_close): Likewise. - * include/grub/normal.h (grub_extractor_level): New external variable. - -2010-09-20 Vladimir Serbinenko - - Make cutmem accept a region specification. - Suggested by: Samuel Thibault - - * grub-core/mmap/mmap.c (parsemem): New function. - (grub_cmd_cutmem): Handle new arguments. - -2010-09-20 Vladimir Serbinenko - - New command cutmem. - - * grub-core/mmap/mmap.c (grub_cmd_cutmem): New function. - (GRUB_MOD_INIT): Register new command. - (GRUB_MOD_FINI): Unregister new command. - -2010-09-20 Vladimir Serbinenko - - Support some annoying BSD and Minix subpartitions. - - * Makefile.util.def (libgrub.a): Add grub-core/partmap/bsdlabel.c. - * grub-core/disk/efi/efidisk.c (grub_efidisk_get_device_name): - Properly handle concatenation. - * grub-core/kern/device.c (grub_device_iterate): Likewise. - * grub-core/normal/completion.c (iterate_partition): Likewise. - * grub-core/kern/disk.c (grub_disk_open): Make disk->name not - contain partition. All users updated. - * grub-core/partmap/bsdlabel.c (grub_netbsdlabel_partition_map): New - struct. - (grub_openbsdlabel_partition_map): Likewise. - (bsdlabel_partition_map_iterate): Rename to .. - (iterate_real): ... this. New arguments sector, freebsd and pmap. - (bsdlabel_partition_map_iterate): New function. - (netopenbsdlabel_partition_map_iterate): Likewise. - (netbsdlabel_partition_map_iterate): Likewise. - (openbsdlabel_partition_map_iterate): Likewise. - (GRUB_MOD_INIT): Register new partmaps. - (GRUB_MOD_FINI): Unregister new partmaps. - * grub-core/partmap/msdos.c (pc_partition_map_iterate): Rename to ... - (grub_partition_msdos_iterate): ... this. All users updated. - Don't support embedding other than in a minix partition. - * include/grub/msdos_partition.h (grub_partition_msdos_iterate): New - proto. - * include/grub/partition.h (grub_partition): New field msdostype. - * util/grub-install.in: Handle openbsd and netbsd types being in - part_bsd module. - -2010-09-20 Vladimir Serbinenko - - Split mdraid.mod into mdraid09.mod and mdraid1x.mod. - - * Makefile.util.def (libgrub.a): Add grub-core/disk/mdraid1x_linux.c. - * grub-core/Makefile.core.def (mdraid): Renamed to ... - (mdraid09): ... this. - (mdraid1x): New module. - * grub-core/disk/mdraid_linux.c: Move 1.x parts ... - * grub-core/disk/mdraid1x_linux.c: ...here. All users updated. - -2010-09-20 Vladimir Serbinenko - - * grub-core/kern/emu/misc.c (asprintf): Use vsnprintf instead of - vsprintf. - -2010-09-20 Colin Watson - - * grub-core/commands/efi/lsefimmap.c: Correct header. - * NEWS: Update. - -2010-09-20 Colin Watson - - * util/grub-editenv.c (argp_parser): Don't pass translated strings - as printf format strings; the translations might contain '%' which - could cause a crash. - (main): Likewise. - * util/grub-fstest.c (argp_parser): Likewise. - * util/grub-setup.c (argp_parser): Likewise. - (main): Likewise. - -2010-09-20 Vladimir Serbinenko - - Use argp in grub-fstest. - - * util/grub-fstest.c: Don't include getopt.h. - Include argp.h. - (root): New variable. - (args_count): Likewise. - (nparm): Likewise. - (num_disks): Likewise. - (images): Likewise. - (cmd): Likewise. - (debug_str): Likewise. - (args): Likewise. - (options): Transformed to argp. - (usage): Removed. - (main): Split argument parsing into ... - (argp_parser): ... this. Changed to argp format. - (argp): New variable. - (main): Use argp_parse. - -2010-09-20 Tristan Gingold -2010-09-20 Robert Millan -2010-09-20 Vladimir Serbinenko - - * grub-core/commands/efi/lsefimmap.c: New file. - * grub-core/Makefile.core.def (lsefimmap): New module. - * include/grub/efi/api.h (PRIxGRUB_EFI_UINTN_T): New definition. - -2010-09-20 Vladimir Serbinenko - - Pause the execution (10s max) if any errors are displayed so the user - has a chance to see them. - - * grub-core/kern/err.c (grub_err_printed_errors): New variable. - (grub_print_error): Increment grub_err_printed_errors. - * grub-core/normal/menu.c (grub_menu_execute_entry): Pause the - execution if any errors were displayed. - (show_menu): Remove old code for pause. - * grub-core/normal/menu_entry.c (run): Likewise. - * grub-core/normal/term.c (grub_normal_char_counter): Removed. All - users updated. - (grub_normal_get_char_counter): Likewise. - * include/grub/err.h (grub_err_printed_errors): New external variable. - * include/grub/normal.h (grub_normal_get_char_counter): Removed. - -2010-09-20 Vladimir Serbinenko - - Support multiboot VBE info. - - * grub-core/loader/i386/multiboot_mbi.c (grub_multiboot_get_mbi_size): - Take VBE info into account. - (fill_vbe_info) [GRUB_MACHINE_HAS_VBE]: New function. - (retrieve_video_parameters) [GRUB_MACHINE_HAS_VBE]: - Call fill_vbe_info when appropriate. - (grub_multiboot_make_mbi): Account for the size occupied by VBE info. - * grub-core/loader/multiboot_mbi2.c (grub_multiboot_load): Declare tags - as supported. - (grub_multiboot_get_mbi_size): Take new tags into account. - (fill_vbe_tag) [GRUB_MACHINE_HAS_VBE]: New function. - (retrieve_video_parameters) [GRUB_MACHINE_HAS_VBE]: - Call fill_vbe_tag when appropriate. - (grub_multiboot_make_mbi): Properly align tags. - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_pm_interface): New - function. - * include/grub/i386/pc/vbe.h (grub_vbe_bios_get_pm_interface): New - proto. - * include/grub/multiboot.h (GRUB_MACHINE_HAS_VBE): New definition. - -2010-09-20 Vladimir Serbinenko - - Suport manual terminal geometry specification. - - * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): - Save state in grub_ofconsole_terminfo_output. - (grub_ofconsole_term): Use grub_terminfo_getwh. - (grub_ofconsole_getwh): Removed. - * grub-core/term/serial.c (grub_serial_getwh): Removed. - (grub_serial_term): Use grub_terminfo_getwh. - * grub-core/term/terminfo.c (grub_terminfo_getwh): New function. - (options): New struct. - (OPTION_*): New enum. - (grub_cmd_terminfo): Transform into extcmd and handle new parameters. - * include/grub/terminfo.h (grub_terminfo_output_state): New fields - width and height. - (grub_terminfo_getwh): New proto. - * grub-core/lib/legacy_parse.c (grub_legacy_parse): Handle --lines. - -2010-09-20 Vladimir Serbinenko - - Handle legacy "terminal" command. - - * grub-core/lib/legacy_parse.c (legacy_command): New flags FLAG_TITLE - and FLAG_TERMINAL. - (legacy_commands): Add terminal and title. - (grub_legacy_parse): Handle terminal. Simplify title handling. - -2010-09-20 Vladimir Serbinenko - - * grub-core/lib/arg.c (grub_arg_show_help): Correctly handle - parameters overflow. - -2010-09-20 Colin Watson - - * .bzrignore: Add grub-core/gnulib/sys, widthspec.bin, and - widthspec.h. - - * docs/grub.texi (Shell-like scripting): Document `!'. - (Network): Simplify using new i386-pc-pxe format. Mention - grub-mknetdir. - - * NEWS: Update. - -2010-09-20 Colin Watson - - * Makefile.am (SUBDIRS): Restore "."; it's important to force - ordering, so that e.g. ascii.h is built before grub-core/font/font.c - when needed. - -2010-09-20 Colin Watson - - * grub-core/commands/efi/lsefisystab.c: Correct header. - * grub-core/commands/efi/lssal.c: Likewise. - * grub-core/commands/testload.c: Likewise. - -2010-09-20 Colin Watson - - * util/grub-mkrescue.in: Add explicit root argument to --set to - prevent the UUID being interpreted as an argument to --set (matches - previous change to prepare_grub_to_access_device). - -2010-09-20 Colin Watson - - * kern/emu/hostdisk.c: Include and - on FreeBSD. Define HAVE_DIOCGDINFO on NetBSD and FreeBSD to reduce - the verbosity of later #ifs. - (find_partition_start): Define this function on FreeBSD too. - (device_is_wholedisk) [__FreeBSD__ || __FreeBSD_kernel__]: New - function. - (grub_util_biosdisk_get_grub_dev): Use partition-start-sector logic - on FreeBSD. - -2010-09-20 Yves Blusseau - - * util/grub-editenv.c: Use argp instead of getopt. - -2010-09-20 Yves Blusseau - - * util/grub-setup.c: Use argp instead of getopt. - -2010-09-20 Yves Blusseau - - Use gnulib-tool to create gnulib source files. - - * Add gnulib files generated by gnulib-tool in build-aux, m4 and - grub-core/gnulib directories - * .bzignore: Add **/.deps and autogenerated gnulib files - * configure.ac: Assign auxiliary directory to build-aux, add invocation - of gnulib macros, add grub-core/gnulib/Makefile - * Makefile.am: Add gnulib directory in SUBDIRS (removing unnecessary .), - include m4 directory to aclocal. - * Makefile.util.def: Remove direct compilation of gnulib source files - and use the new grub-core/gnulib/libgnu.a. - * build-aux/config.rpath: move config.rpath from top directory to - build-aux - * conf/Makefile.common: Remove the macro _GL_UNUSED already defined - in gnulib headers - * conf/Makefile.extra-dist: Add m4/gnulib-cache.m4 - * grub-core/Makefile.core.def: Remove unnecessary extra_dist - * grub-core/lib/posix_wrap/localcharset.h (locale_charset): Update - header. - * grub-core/lib/posix_wrap/langinfo.h (nl_langinfo): Return static - string. - -2010-09-20 Yves Blusseau - - * .bzrignore: Add grub-kbdcomp, grub-menulst2cfg, *.marker, - grub-core/genmod.sh and grub-core/gensyminfo.sh - -2010-09-20 BVK Chaitanya - - Add a test for echo command options. - - * tests/grub_cmd_echo.in: New test. - * Makefile.util.def: Rules for new test. - -2010-09-20 Szymon Janc - - Remove crc.mod and move crc command to hashsum.mod. - Remove lib/crc.c - users updated to use gcrypt implementation. - - * grub-core/commands/crc.c: Removed. - * grub-core/Makefile.core.def (crc): Module removed. - * grub-core/commands/hashsum.c (aliases[]): Add crc alias. - * grub-core/commands/hashsum.c (GRUB_MOD_INIT): Register crc command. - * grub-core/commands/hashsum.c (GRUB_MOD_FINI): Unregister crc command. - * grub-core/lib/crc.c: Removed. - * include/grub/lib/crc.h: Removed. - * Makefile.util.def (crc): Remove lib/crc.c - * grub-core/Makefile.core.def (libgrub.a): Remove grub-core/lib/crc.c. - * util/grub-fstest.c (cmd_crd): Use libgcrypt crc implementation. - * Makefile.util.def (libgrub.a): Add grub-core/lib/libgcrypt-grub/cipher/crc.c. - * Makefile.util.def (grub-fstest): Add CFLAGS_GCRY to cflags. - * Makefile.util.def (grub-fstest): Add CPPFLAGS_GCRY to cppflags. - * grub-core/efiemu/prepare.c (grub_efiemu_crc): Use libgcrypt crc implementation. - -2010-09-20 Vladimir Serbinenko - - * grub-core/boot/i386/pc/boot.S: Ignore %dl if it's not in a sane range. - -2010-09-19 Vladimir Serbinenko - - Split config.h for util and core. - - * acinclude.m4 (HAVE_ASM_USCORE): Transformed into a variable. - (ADDR32): Likewise. - (DATA32): Likewise. - (BSS_START_SYMBOL): Likewise. - (END_SYMBOL): Likewise. - (NEED_ENABLE_EXECUTE_STACK): Likewise. All users updated. - (grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK): Removed. - * config.h.in: New file. - * configure.ac: Use config-util.h as config define file. - Rename MACHINE into GRUB_MACHINE. All users updated. - (NEED_REGISTER_FRAME_INFO): Transformed into a variable. All users - updated. - (NESTED_FUNC_ATTR): Likewise. - Substitue new variables. - (COND_HAVE_ASM_USCORE): New conditional. - * grub-core/Makefile.am (ASM_PREFIX): New variable. - (kernel_syms.lst): Use ASM_PREFIX. - * grub-core/kern/emu/console.c: Include config-util.h. - * grub-core/kern/emu/misc.c: Likewise. - * grub-core/kern/emu/mm.c: Likewise. - * include/grub/emu/misc.h: Likewise. - * include/grub/libgcc.h: Likewise. - -2010-09-19 Vladimir Serbinenko - - * grub-core/term/efi/console.c (efi_codes): Fix GRUB_TERM_KEY_* - constants usage. - * grub-core/kern/emu/console.c (grub_ncurses_getkey): - Fix GRUB_TERM_KEY_* constants usage. - * grub-core/kern/emu/misc.c (asprintf): Fix vasprintf usage. - -2010-09-19 Vladimir Serbinenko - - * grub-core/bus/usb/ohci.c (grub_ohci_cancel_transfer): Use %p to - print pointer. - * grub-core/bus/usb/uhci.c: Remove empty define. - (grub_uhci_check_transfer): Add missing cast. - * grub-core/bus/usb/usbhub.c (poll_nonroot_hub): Use %p to - print pointer. - * grub-core/term/usb_keyboard.c (grub_usb_keyboard_getkey): Use - PRIuGRUB_SIZE. - * include/grub/types.h (PRIuGRUB_SIZE): New definition. - -2010-09-19 Vladimir Serbinenko - - * grub-core/Makefile.core.def (legacycfg): Add - lib/i386/pc/vesa_modes_table.c on emu. - -2010-09-19 BVK Chaitanya - - Reduce number of temporary files generated by build system. - - * grub-core/gencmdlist.sh: Removed. - * grub-core/genfslist.sh: Removed. - * grub-core/genhandlerlist.sh: Removed. - * grub-core/genmodsrc.sh: Removed. - * grub-core/genpartmaplist.sh: Removed. - * grub-core/genparttoollist.sh: Removed. - * grub-core/gentermiinallist.sh: Removed. - * grub-core/genvideolist.sh: Removed. - - * grub-core/genmod.sh.in: New file. - * grub-core/gensyminfo.sh.in: New file. - - * conf/Makefile.common (CPPFLAGS_*_LIST): New marker flags. - * conf/Makefile.extra-dist: Update with new files. - * gentpl.py: Remove rules related to unnecessary temporary files. - * grub-core/Makefile.am (syminfo.lst): New replacement for def-* - and und-* files. - * grub-core/Makefile.core.def: New rules for gensyminfo.sh and - genmod.sh scripts. - * grub-core/bus/usb/uhci.c: Remove empty #define. - * grub-core/genmoddep.awk: Updated with new syminfo format. - * util/bash-completion.d/Makefile.am: Add config.log to - CLEANFILES. - -2010-09-19 Yves Blusseau - - * Makefile.util.def: Add forgotten $(LIBINTL) library. - -2010-09-19 BVK Chaitanya - - * util/grub-mkconfig.in: Check the config script for syntax errors - before saving. - -2010-09-19 Colin Watson -2010-09-19 Vladimir Serbinenko - - * Makefile.util.def (grub-install): Use util/grub-install.in on all - platforms. - * util/grub-install.in: Add EFI and IEEE1275 support. - * util/i386/efi/grub-install.in: Removed. - * util/ieee1275/grub-install.in: Likewise. - -2010-09-19 Vladimir Serbinenko - - * grub-core/commands/i386/cmostest.c (+parse_args): New function. - (grub_cmd_cmosclean): Likewise. - (GRUB_MOD_INIT): Register command cmosclean. - * util/grub-mkconfig.in: Export GRUB_BUTTON_CMOS_CLEAN. - * util/grub.d/00_header.in: Handle GRUB_BUTTON_CMOS_CLEAN. - -2010-09-18 Carles Pina i Estany -2010-09-18 Aleš Nesrsta -2010-09-18 Vladimir Serbinenko - - Add keyboard layouts support. - - * Makefile.util.def (grub-mklayout): New file. - (grub-kbdcomp): New script. - * grub-core/Makefile.am (KERNEL_HEADER_FILES) [COND_mips_yeeloong]: - Add keyboard_layouts.h. - * grub-core/Makefile.core.def (kernel): Add commands/keylayouts.c and - commands/boot.c on yeeloong. - (keylayouts): New module. - * grub-core/bus/usb/ohci.c - * grub-core/bus/usb/uhci.c - * grub-core/bus/usb/usbhub.c (rescan): New variable. - (grub_usb_add_hub): Poll interrupt pipe for device handling. - (attach_root_port): Likewise. - (poll_nonroot_hub): Likewise. - (grub_usb_poll_devices): Likewise. - (detach_device): Close transfer. - * grub-core/bus/usb/usbtrans.c (grub_usb_execute_and_wait_transfer): New - function. - (grub_usb_bulk_setup_readwrite): Likewise. - (grub_usb_bulk_finish_readwrite): Likewise. - * grub-core/commands/keylayouts.c: New file. - * grub-core/commands/keystatus.c (grub_getkeystatus): New function. - * grub-core/commands/menuentry.c (hotkey_aliases): All several new - aliases. - * grub-core/term/at_keyboard.c: Restructured to use keylayouts and - support scancode 2. - * grub-core/term/usb_keyboard.c: Restructured to use keylayouts. - * include/grub/keyboard_layouts.h: New file. - * util/grub-mklayout.c: New file. - * util/grub-kbdcomp.in: Likewise. - -2010-09-18 Vladimir Serbinenko - - Unify memory types. - - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Include memory.h. - * grub-core/commands/lsmmap.c (grub_cmd_lsmmap): Output user-readable - types. - * grub-core/kern/i386/multiboot_mmap.c (grub_lower_mem): Removed. - (grub_upper_mem): Likewise. - * grub-core/kern/ieee1275/init.c (grub_upper_mem): Likewise. - * include/grub/memory.h (grub_memory_type_t): New enum. - All users updated. - -2010-09-18 Vladimir Serbinenko - - * grub-core/Makefile.core.def (lsapm): New module. - * grub-core/commands/i386/pc/lsapm.c: New file. - * grub-core/loader/i386/multiboot_mbi.c (make_mbi) [GRUB_MACHINE_PCBIOS]: Pass APM info. - * grub-core/loader/multiboot_mbi2.c (make_mbi) [GRUB_MACHINE_PCBIOS]: - Likewise. - * include/grub/i386/pc/apm.h: New file. - * include/multiboot.h (multiboot_apm_info): New struct. - -2010-09-18 Vladimir Serbinenko - - GRUB-legacy configuration file support. - - * Makefile.util.def (grub-menulst2cfg): New util. - * docs/man/grub-menulst2cfg.h2m: New file. - * grub-core/Makefile.core.def (legacycfg): New module. - * grub-core/commands/legacycfg.c: New file. - * grub-core/commands/menuentry.c (append_menu_entry): Rename to ... - (grub_normal_add_menu_entry): ... this. - * grub-core/commands/password.c (grub_cmd_password): Split main part to ... - (grub_normal_set_password): ...this. - * grub-core/commands/videoinfo.c (grub_cmd_videoinfo): Support MODE. - * grub-core/loader/i386/linux.c (linux_vesafb_res): Move to .., - * grub-core/lib/i386/pc/vesa_modes_table.c: ... here. - * grub-core/lib/legacy_parse.c: New file. - * grub-core/normal/auth.c (grub_cmd_authenticate): New command. - * include/grub/i386/pc/vesa_modes_table.h: New file. - * include/grub/legacy_parse.h: Likewise. - * include/grub/normal.h (grub_normal_add_menu_entry): New proto. - * util/grub-menulst2cfg.c: New file. - -2010-09-17 Colin Watson - - * grub-core/kern/emu/hostdisk.c - (convert_system_partition_to_system_disk): Initialise node. - -2010-09-17 Colin Watson - - * grub-core/kern/emu/hostdisk.c - (convert_system_partition_to_system_disk): Fix devmapper memory pool - leak. - Reported and based on patch by: Modestas Vainius. - -2010-09-17 Colin Watson - - Fix DM-RAID probing with recent versions of device-mapper udev - rules. - - * grub-core/kern/emu/hostdisk.c (read_device_map): Don't - canonicalise device paths under /dev/mapper/. - (convert_system_partition_to_system_disk): Compare the - uncanonicalised path to /dev/mapper/ rather than the canonicalised - path, since device nodes under /dev/mapper/ are often symlinks. - -2010-09-17 Yves Blusseau - - * .bzrignore: *.d removed (old rule), add *.image and symlist.h. - -2010-09-16 Yves Blusseau - - * configure.ac: Avoid some annoying error messages if freetype-config - program is not found. - -2010-09-16 Colin Watson - - Support RAID on virtio devices, and others. - - * grub-core/kern/emu/getroot.c [__MINGW32__] (find_root_device): - Rename to ... - [__MINGW32__] (grub_find_device): ... this. - [! __MINGW32__ && ! __CYGWIN__] (find_root_device): Rename to ... - [! __MINGW32__ && ! __CYGWIN__] (grub_find_device): ... this. Use a - reasonable default if dir is NULL. - [! __MINGW32__ && __CYGWIN__] (find_cygwin_root_device): Rename to - ... - [! __MINGW32__ && __CYGWIN__] (grub_find_device): ... this. - (grub_guess_root_device): Update callers. - * include/grub/emu/getroot.h (grub_find_device): Add prototype. - - * util/raid.c (grub_util_getdiskname): Remove. - (grub_util_raid_getmembers): Use grub_find_device rather than - grub_util_getdiskname. - -2010-09-16 Colin Watson - - * docs/grub.texi (serial): Remove obsolete comment about GRUB - needing to be compiled with serial support. - (ls): Indicate that multiple files are accepted. - * grub-core/commands/ls.c (GRUB_MOD_INIT): Update help text to - indicate that multiple files are accepted. - -2010-09-16 Colin Watson - - * .bzrignore: Add *.1, *.8, grub-shell, grub-shell-tester, - libgrub_a_init.c, and util/bash-completion.d/grub. - -2010-09-15 Vladimir Serbinenko - - * util/grub-setup.c (setup): Fix incorrect container semantics. - -2010-09-15 Vladimir Serbinenko - - * grub-core/commands/parttool.c (grub_cmd_parttool): Fix a variable - misusage. - Reported by: J. Nick Terry - -2010-09-15 Vladimir Serbinenko - - Move embedding routines to partmap sources files. - - * grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot) - [GRUB_UTIL]: New variable. - (gpt_partition_map_iterate): Set part.parent. - (gpt_partition_map_embed) [GRUB_UTIL]: New function. - (grub_gpt_partition_map) [GRUB_UTIL]: Set .embed. - * grub-core/partmap/msdos.c (pc_partition_map_embed) [GRUB_UTIL]: - New function. - (grub_msdos_partition_map) [GRUB_UTIL]: Set .embed. - * include/grub/partition.h (grub_embed_type_t) [GRUB_UTIL]: New type. - (grub_partition_map) [GRUB_UTIL]: New field embed. - * util/grub-setup.c (grub_gpt_partition_type_bios_boot): Removed. - (setup): Use ->embed. - -2010-09-15 Vladimir Serbinenko - - * grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): New - function. - * include/grub/emu/hostdisk.h (grub_util_biosdisk_is_floppy): New proto. - * util/grub-setup.c (setup): Use grub_util_biosdisk_is_floppy. - -2010-09-15 Yves Blusseau - - Add function to get completions from usage. - - * util/bash-completion.d/grub-completion.bash.in: Add function to get - completions from usage. Use LC_ALL=C to get options properly. - -2010-09-15 Vladimir Serbinenko - - * grub-core/gnulib/basename-lgpl.c: Imported. - * grub-core/gnulib/basename.c: Likewise. - * grub-core/gnulib/dirname-lgpl.c: Likewise. - * grub-core/gnulib/dirname.c: Likewise. - * grub-core/gnulib/dirname.h: Likewise. - * grub-core/gnulib/stripslash.c: Likewise. - -2010-09-15 Vladimir Serbinenko - - * grub-core/gnulib/error.c: Resynced. - * grub-core/gnulib/getopt.c: Likewise. - * grub-core/gnulib/getopt_int.h: Likewise. - * grub-core/gnulib/regex.h: Likewise. - * grub-core/gnulib/regex_internal.c: Likewise. - * grub-core/gnulib/regex_internal.h: Likewise. - -2010-09-15 Szymon Janc - - * grub-core/lib/xzembed/xz_dec_stream.c (dec_main): Fix index and block - CRC calculations and validity checks. - * grub-core/lib/xzembed/xz_dec_stream.c (dec_index): Fix index CRC - calculations. - -2010-09-15 Szymon Janc - - * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_end): Fix memory leak. - -2010-09-14 Vladimir Serbinenko - - Fix incorrect echo options handling. - Reported by: Yves Blusseau. - - * include/grub/command.h (grub_command_flags_t): New flags - GRUB_COMMAND_ACCEPT_DASH and GRUB_COMMAND_OPTIONS_AT_START. - * grub-core/lib/arg.c (grub_arg_parse): Handle new flags. - * grub-core/commands/echo.c (GRUB_MOD_INIT): Use new flags. - -2010-09-14 Vladimir Serbinenko - - * include/grub/command.h (GRUB_COMMAND_FLAG_CMDLINE): Removed. All - users updated. - (GRUB_COMMAND_FLAG_MENU): Likewise. - (GRUB_COMMAND_FLAG_BOTH): Likewise. - (GRUB_COMMAND_FLAG_TITLE): Removed. - (GRUB_COMMAND_FLAG_NO_ECHO): Likewise. - (GRUB_COMMAND_FLAG_EXTCMD): Moved into enum. - (GRUB_COMMAND_FLAG_DYNCMD): Likewise. - (GRUB_COMMAND_FLAG_BLOCKS): Likewise. - (grub_command_flags_t): New enum. All users updated. - -2010-09-14 Seth Goldberg - - Fix solaris compilation. - - * grub-core/Makefile.core.def (kernel): Include gnulib/error.c on emu. - (grub-emu): Add LIBZFS and LIBNVPAIR to ldadd. - (grub-emu-list): Likewise. - -2010-09-14 Vladimir Serbinenko - - Remove deprecated root command. - - * grub-core/commands/minicmd.c (grub_mini_cmd_root): Removed. All users - updated. - -2010-09-14 Vladimir Serbinenko - - * util/i386/pc/grub-setup.c: Merge this ... - * util/sparc64/ieee1275/grub-setup.c: ... and this ... - * util/grub-setup.c: ... into this. - * include/grub/sparc64/ieee1275/boot.h (grub_boot_blocklist) [ASM_FILE]: - New struct. - -2010-09-14 Vladimir Serbinenko - - * grub-core/fs/ext2.c (grub_ext2_open): Use return error value when - possible. - -2010-09-14 Vladimir Serbinenko - - * grub-core/partmap/sun.c (sun_partition_map_iterate): Don't needlesly - allocate p. - -2010-09-14 Vladimir Serbinenko - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Add - explicit root argument to set to prevent UUID to be interpreted as - argument to set. - -2010-09-14 Vladimir Serbinenko - - * grub-core/kern/sparc64/ieee1275/crt0.S: Align stack. - -2010-09-14 Vladimir Serbinenko - - Don't export grub_gate_a20. - - * grub-core/kern/i386/pc/init.c: Remove leftovers. - * grub-core/kern/i386/pc/startup.S (FUNCTION(grub_gate_a20)): Rename - to ... - (grub_gate_a20): ... this. All users updated. - * include/grub/i386/pc/init.h: Removed. All users updated. - -2010-09-14 Vladimir Serbinenko - - Create euro.pf2 which supports most European languages. - - * Makefile.am (grubdata_DATA): Add euro.pf2. - (euro.pf2): New target. - (CLEANFILES): Add euro.pf2. - -2010-09-14 Vladimir Serbinenko - - * configure.ac: Disable emu-usb by default to prevent inadvertent - device takeover. - -2010-09-13 Vladimir Serbinenko - - Disable usbserial on grub-emu since our libusb code isn't good enough - yet. - - * grub-core/Makefile.core.def (usbserial_common): Disable on emu. - (usbserial_pl2303): Likewise. - (usbserial_ftdi): Likewise. - -2010-09-13 Vladimir Serbinenko - - * include/grub/disk.h (grub_disk): Remove has_partitions. - All users updated. - * disk/loopback.c (grub_loopback): Remove has_partitions. - All users updated. - (options): Remove partitions. All users updated. - * util/grub-fstest.c (fstest): Don't pass "-p" to loopback. - * util/i386/pc/grub-setup.c (setup): copy partition table only when - actual partition table is found. - -2010-09-13 Vladimir Serbinenko - - Remove readability checks (too many false negatives). - - * util/grub-install.in: Remove readability checks. - * util/grub-mkconfig.in: Likewise. - * util/grub.d/10_hurd.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Revert to old - way. - -2010-09-13 Vladimir Serbinenko - - Enable acpi shutdown on all ACPI platforms. - - * grub-core/Makefile.core.def (halt): Inlude commands/acpihalt.c - on coreboo, multiboot and EFI. - * grub-core/commands/acpihalt.c (get_sleep_type): Add missing casts. - (grub_acpi_halt): Likewise. - * grub-core/commands/i386/pc/halt.c (grub_halt): Call grub_acpi_halt. - (grub_cmd_halt): Don't call grub_acpi_halt directly. - * grub-core/lib/efi/halt.c (grub_halt): Call grub_acpi_halt. - * grub-core/lib/i386/halt.c (grub_halt) - [GRUB_MACHINE_COREBOOT || GRUB_MACHINE_MULTIBOOT]: Likewise. - -2010-09-13 Vladimir Serbinenko - - * grub-core/commands/iorw.c (grub_cmd_read): Declare buf in smallest - context. - -2010-09-13 Vladimir Serbinenko - - * grub-core/video/efi_gop.c: Fix over-80-chars line. - * grub-core/video/efi_uga.c: Likewise. - -2010-09-13 Vladimir Serbinenko - - Filter devaliases and never open same device twice. - - * grub-core/disk/ieee1275/ofdisk.c (last_devpath): New variable. - (last_ihandle): Likewise. - (ofdisk_hash_ent): New member shortest. - (ofdisk_hash_add): Add canonical path too. - (scan): New function. - (grub_ofdisk_iterate): Iterate over hashed entries. - (compute_dev_path): Don't add :0. - (grub_ofdisk_open): Don't really open the disk. - (grub_ofdisk_close): Avoid closing unrelated disk. - (grub_ofdisk_read): Implement reopen logic. - * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_canonicalise_devname): - New function. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_canonicalise_devname): - New proto. - -2010-09-13 Vladimir Serbinenko - - Fix sparc64. - - * configure.ac (GRUB_KERNEL_MACHINE_LINK_ADDR): Removed. - * grub-core/Makefile.core.def (kernel): Make ldflags just use the - right address. Add sparc64_ieee1275_ldflags. - * grub-core/loader/sparc64/ieee1275/linux.c: Remove leftover include. - * util/grub-mkimagexx.c (locate_sections): Correct grub_host_to_target32 - to grub_host_to_target_addr - (load_image): Likewise. - -2010-09-13 Vladimir Serbinenko - - * grub-core/normal/completion.c (complete_file): Handle device - containing slash. - Fix based on patch by Doug Nazar. - -2010-09-13 Vladimir Serbinenko - - grub-mknetdir script. - - * Makefile.util.def (grub-mknetdir): New module. - * tests/util/grub-shell.in: Support boot=net - * util/grub-mknetdir.in: New file. - -2010-09-13 Vladimir Serbinenko - - videoinfo on non-vbe. - - * grub-core/Makefile.core.def (vbeinfo): Removed. - (vbetest): Removed. - (videoinfo): New module. - * grub-core/commands/i386/pc/vbeinfo.c: Removed. - * grub-core/commands/i386/pc/vbetest.c: Removed. - * grub-core/commands/videoinfo.c: New file. - * grub-core/commands/videotest.c (grub_cmd_videotest): Support mode - specification. - (grub_cmd_videotest) [GRUB_MACHINE_PCBIOS]: Load vbe.mod when invoked - as vbetest. - (GRUB_MOD_INIT) [GRUB_MACHINE_PCBIOS]: New command vbetest. - (GRUB_MOD_FINI) [GRUB_MACHINE_PCBIOS]: Unregister vbetest. - * grub-core/video/efi_gop.c (grub_video_gop_fill_mode_info): Fill - mode_number. New parameter mode. All users updated. - (grub_video_gop_iterate): New function. - (grub_video_efi_gop): New member iterate. - * grub-core/video/i386/pc/vbe.c (framebuffer): Removed leftover fields. - (grub_vbe_set_video_mode): Remove setting useless fields. - (vbe2videoinfo): New function. - (grub_video_vbe_iterate): Likewise. - (grub_video_vbe_setup): Use vbe2videoinfo. - (grub_video_vbe_print_adapter_specific_info): New function. - (grub_video_vbe_adapter): New fields iterate and - print_adapter_specific_info. - * include/grub/video.h (GRUB_VIDEO_MODE_*): Transform into enum. - All users updated. - (grub_video_mode_info): New field mode_number. - (grub_video_adapter): New fields iterate and - print_adapter_specific_info. - -2010-09-13 Tristan Gingold -2010-09-13 Robert Millan -2010-09-13 Vladimir Serbinenko - - * grub-core/commands/efi/lsefisystab.c: New file. - * grub-core/commands/efi/lssal.c: Likewise. - * grub-core/Makefile.core.def (lsacpi): New module. - (lsefisystab): Likewise. - * include/grub/efi/api.h (GRUB_EFI_SAL_TABLE_GUID): New definition. - (GRUB_EFI_HCDP_TABLE_GUID): Likewise. - (grub_efi_sal_system_table): New struct. - (grub_efi_sal_system_table_entrypoint_descriptor): Likewise. - (grub_efi_sal_system_table_memory_descriptor): Likewise. - (grub_efi_sal_system_table_platform_features): Likewise. - (grub_efi_sal_system_table_translation_register_descriptor): Likewise. - (grub_efi_sal_system_table_purge_translation_coherence): Likewise. - (grub_efi_sal_system_table_ap_wakeup): Likewise. - * include/grub/types.h (PRIuGRUB_UINT64_T): New definition. - -2010-09-13 Vladimir Serbinenko - - Support explicit user claim that a device is BIOS-visible. - - * grub-core/kern/emu/getroot.c (grub_util_get_dev_abstraction): - Return GRUB_DEV_ABSTRACTION_NONE if device is in device.map. - * grub-core/kern/emu/hostdisk.c - (convert_system_partition_to_system_disk): Support mdX. - (find_system_device): New parameter add. All users updated. - (grub_util_biosdisk_is_present): New function. - * include/grub/emu/hostdisk.h (grub_util_biosdisk_is_present): New - proto. - -2010-09-13 Vladimir Serbinenko - - Search hints support. - - * commands/search.c (FUNC_NAME): New arguments hints and nhints. - All users updated. - -2010-09-13 Yves Blusseau - - Bash completion script for util commands - - * Makefile.am: Add util/bash-completion.d directory - * configure.ac: Likewise. - * util/bash-completion.d/Makefile.am: New file. - * util/bash-completion.d/grub-completion.bash.in: Likewise. - -2010-09-12 Vladimir Serbinenko - - * grub-core/normal/term.c (put_glyphs_terminal): Correct sign. - (print_backlog): set backlog_ucs4 and backlog_glyphs. - Reported by: Yves Blusseau. - -2010-09-12 Vladimir Serbinenko - - * grub-core/normal/misc.c (grub_normal_print_device_info): Show - partition size and offset. - -2010-09-12 Vladimir Serbinenko - - * grub-core/commands/wildcard.c (make_regex): Escape brackets. - -2010-09-12 Vladimir Serbinenko - - * grub-core/commands/ls.c (grub_cmd_ls): Accept multiple files. - -2010-09-12 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_vprintf): Use va_copy when necessary. - (grub_xvasprintf): Likewise. - -2010-09-12 Vladimir Serbinenko - - * grub-core/kern/emu/main.c (main): Call hostfs_init only after init_all. - -2010-09-12 Vladimir Serbinenko - - * grub-core/commands/menuentry.c (append_menu_entry): Don't rely on - args ending with NULL. - -2010-09-12 Vladimir Serbinenko - - * grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_reset): Preserve context - pointer. - -2010-09-11 Szymon Janc - - * grub-core/commands/lsacpi.c (grub_cmd_lsacpi): Fix prototype. - -2010-09-11 Vladimir Serbinenko - - Shutdown using ACPI. - - * grub-core/Makefile.core.def (halt): Add commands/acpihalt.c on i386-pc. - * grub-core/commands/acpihalt.c: New file. - * grub-core/commands/i386/pc/halt.c (grub_cmd_halt): Call grub_acpi_halt. - * include/grub/acpi.h (grub_acpi_fadt): New member pm1a. - (grub_acpi_halt): New proto. - (GRUB_ACPI_SLP_EN): New const. - (GRUB_ACPI_SLP_TYP_OFFSET): Likewise. - (GRUB_ACPI_OPCODE_*): New enum. - (GRUB_ACPI_EXTOPCODE_*): Likewise. - -2010-09-11 Tristan Gingold -2010-09-11 Robert Millan -2010-09-11 Vladimir Serbinenko - - * commands/lsacpi.c: New file. - * grub-core/Makefile.core.def (lsacpi): New module. - * include/grub/acpi.h (GRUB_ACPI_FADT_SIGNATURE): New definition. - (GRUB_ACPI_MADT_SIGNATURE): Likewise. - (grub_acpi_madt_entry_header): New struct. - (grub_acpi_madt): Likewise. - (grub_acpi_madt_entry_interrupt_override): Likewise. - (grub_acpi_madt_entry_sapic): Likewise. - (grub_acpi_madt_entry_lsapic): Likewise. - (grub_acpi_madt_entry_platform_int_source): Likewise. - * include/grub/types.h (PRIxGRUB_UINT32_T): New definition. - (PRIuGRUB_UINT32_T): Likewise. - (PRIxGRUB_UINT64_T): Likewise. - -2010-09-11 Vladimir Serbinenko - - Implement loading palette on ieee1275_fb. - - * grub-core/video/ieee1275.c (stdout_ihandle): New variable. - (have_setcolors): Likewise. - (grub_video_ieee1275_init): Fill stdout_ihandle and have_setcolors. - (grub_video_ieee1275_setup): Use grub_video_ieee1275_set_palette. - (grub_video_ieee1275_set_palette): Implement. - -2010-09-11 Vladimir Serbinenko -2010-09-11 Colin Watson - - * util/grub-install.in (grub_partition): New variable. - Set prefix_drive on EFI and PC to (,$grub_partition) as last resort. - * util/i386/pc/grub-setup.c (setup): Don't touch prefix. - Fixes a bug reported by Yves Blusseau. - -2010-09-11 Vladimir Serbinenko - - Fix emu on mipsel. - - * conf/Makefile.common (CFLAGS_PLATFORM): Add -mflush-func - =grub_cpu_flush_cache on all mips and not only yeeloong. - * configure.ac (COND_mips): New conditional. - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add libgcc on all - platforms. - * grub-core/kern/emu/cache.S (__mips__): Use _flush_cache. - * grub-core/kern/emu/full.c (grub_arch_dl_init_linker) - [GRUB_LINKER_HAVE_INIT]: New function. - (grub_emu_post_init): Likewise. - * grub-core/kern/emu/lite.c (grub_emu_post_init): Likewise. - * grub-core/kern/emu/main.c: Use grub_emu_post_init. - * include/grub/cache.h (_mips): Include mips/cache.h. - * include/grub/disk.h [GRUB_UTIL || GRUB_MACHINE_EMU]: Add missing - LVM and RAID prototypes. - * include/grub/emu/misc.h (grub_emu_post_init): New proto. - * include/grub/mips/time.h (grub_cpu_idle) [GRUB_MACHINE_EMU]: New - function. - -2010-09-10 Colin Watson - - * util/grub-install.in: Don't try to verify core.img until after - running grub-mkimage to create it. - -2010-09-10 Robert Millan - - * util/grub.d/10_hurd.in: Add misc readability checks. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - -2010-09-10 Colin Watson - - * util/grub-install.in: ${imgext} won't be defined here until the - install branch is merged. For the meantime, only verify core.img on - i386-pc and sparc64-ieee1275 platforms. - -2010-09-10 Robert Millan - - Solaris support in grub_find_zpool_from_dir(). Thanks - Seth Goldberg for referring to getextmntent() facility. - - * configure.ac: Check for getextmntent(), `sys/mnttab.h' and - `sys/mkdev.h'. - * grub-core/kern/emu/misc.c [HAVE_SYS_MNTTAB_H]: Include - `'. - [HAVE_SYS_MKDEV_H]: Include `'. - [HAVE_GETEXTMNTENT] (grub_find_zpool_from_dir): Add getextmntent() - method for finding zpool name. - -2010-09-10 Colin Watson - - grub-fstest needs the host and hostfs modules while other utilities - actively require those modules to be absent, so grub-fstest needs - its own initialisation and finalisation code. - - * Makefile.am (grub_fstest.pp): New target. - (grub_fstest_init.lst): Likewise. - (grub_fstest_init.c): Likewise. - * Makefile.util.def (grub-fstest): Add grub_fstest_init.c. - -2010-09-10 Robert Millan - - * configure.ac: Check for `struct statfs.f_fstypename' and - `struct statfs.f_mntfromname'. - - * grub-core/kern/emu/misc.c (grub_find_zpool_from_dir): Conditionalize - kFreeBSD-specific code. - -2010-09-10 Robert Millan - - * util/grub.d/10_kfreebsd.in: Fix ${kfreebsd_device} initialization - on ZFS. Now non-main filesystems are supported as / too. - -2010-09-09 Colin Watson - - * Makefile.util.def (libgrub.a): Move grub-core/kern/emu/hostfs.c - and grub-core/disk/host.c to ... - (grub-fstest): ... here. Having the host disk implementation - present confuses grub-probe and other utility programs. - - * util/grub-mkconfig.in: Only verify readability of grub.cfg.new - when writing to a file, not when writing to stdout. - -2010-09-09 BVK Chaitanya - - * tests/partmap_test.in: New test for partitions. - * Makefile.util.def: Rules for new test. - -2010-09-09 Robert Millan - - * util/grub-probe.c (probe): Fix a pair of unhandled error - conditions. - -2010-09-09 Robert Millan - - Basic Btrfs support (detection and UUID). - - * grub-core/fs/btrfs.c: New file. - * Makefile.util.def (library): Register btrfs.c. - * grub-core/Makefile.core.def: Likewise. - -2010-09-08 Robert Millan - - * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Improve - with (optional) parameters to specify device and relative path. - * util/grub-install.in: Use is_path_readable_by_grub() to - verify readability of a few critical files. - * util/grub-mkconfig.in: Use is_path_readable_by_grub() to - verify readability of grub.cfg.new. - -2010-09-08 Vladimir Serbinenko - - Split minix.mod into minix.mod and minix2.mod. - - * Makefile.util.def (libgrub.a): Add grub-core/fs/minix2.c. - * grub-core/Makefile.core.def (minix2): New module. - * grub-core/fs/minix.c: Use definitions instead of runtime version - checking. - * grub-core/fs/minix2.c: New file. - -2010-09-08 Yves Blusseau - - Add new --boot-directory option to replace --root-directory - - * util/grub-install.in: Add new --boot-directory option - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - -2010-09-08 Yves Blusseau - - * util/grub-mkconfig.in: Use new variable. - -2010-09-08 Yves Blusseau - - * configure.ac: Define some useful variables. - -2010-09-08 Vladimir Serbinenko - - * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set - GRUB_IEEE1275_FLAG_HAS_CURSORONOFF when appropriate. - * grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_setcursor): - Use terminfo and don't use cursor-on/cursor-off unless it's known - to work. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New element - GRUB_IEEE1275_FLAG_HAS_CURSORONOFF. - -2010-09-08 Colin Watson - - * grub-core/kern/efi/init.c (grub_efi_set_prefix): If the prefix - starts with "(,", fill the drive containing the loaded image in - between those two characters, but expect that a full partition - specification including partition map names will follow. - -2010-09-08 Robert Millan - - * configure.ac: Remove `--enable-grub-fstest' option. - * Makefile.util.def (grub-fstest): Remove COND_GRUB_FSTEST condition. - - * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Use - `grub-fstest' instead of `grub-probe' for readability verification. - * util/grub-probe.c (probe): Remove readability verification kludge. - -2010-09-08 Robert Millan - - * util/grub-mkconfig.in: Pass `--device ${GRUB_DEVICE}' when - initializing `GRUB_FS'. - -2010-09-08 BVK Chaitanya - - Not command (!) support to GRUB script. - - * tests/grub_script_not.in: New test. - * Makefile.util.def: Rules for new test. - - * grub-core/script/execute.c (grub_script_execute_cmdline): Handle - ! command as a special case. - * grub-core/script/yylex.l (GRUB_PARSER_TOKEN_NOT): Removed. - -2010-09-07 BVK Chaitanya - - * grub-core/commands/wildcard.c (wildcard_expand): Fix wrong - grub_free. - -2010-09-07 BVK Chaitanya - - * docs/grub.texi (Shell-like scripting): Fix @dots to @dots{}. - -2010-09-07 BVK Chaitanya - - * docs/grub.texi (Shell-like scripting): Documentation for break, - continue, shift and return commands. - -2010-09-06 Vladimir Serbinenko - - Rename CD-ROM to cd on BIOS. - - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_get_drive): Recognise - "cd". - (grub_biosdisk_call_hook): Call with "cd" instead of arbitrary hdX. - -2010-09-05 Vladimir Serbinenko - - * grub-core/kern/emu/main.c (main): Reinit LVM and RAID. - * util/grub-probe.c (main): Likewise. - * util/i386/pc/grub-setup.c (main): Likewise. - * util/sparc64/ieee1275/grub-setup.c (main): Likewise. - Reported and debugged by: alexxy - -2010-09-05 Vladimir Serbinenko - - * grub-core/disk/lvm.c (grub_lvm_scan_device) [GRUB_UTIL]: Output more - diagnostic info. - -2010-09-05 Jo Shields - - * util/grub.d/30_os-prober.in: Add missing classes. - -2010-09-05 Vladimir Serbinenko - - * docs/grub.texi (Theme file format): Document new position format. - -2010-09-05 Vladimir Serbinenko - - * docs/grub.texi (Theme file format): Replace Box_slice_names.png with - a table. Use @code instead of @verbatim. - -2010-09-05 Colin D Bennett - - Gfxmenu documentation. - - * docs/grub.texi (Theme file format): New chapter. - -2010-09-05 Szymon Janc - - * grub-core/Makefile.core.def (xzio): New module. - * grub-core/io/xzio.c: New file. - * grub-core/lib/xzembed/xz.h: New file (from xembed). - * grub-core/lib/xzembed/xz_config.h: Likewise. - * grub-core/lib/xzembed/xz_dec_bcj.c: Likewise. - * grub-core/lib/xzembed/xz_dec_lzma2.c: Likewise. - * grub-core/lib/xzembed/xz_dec_stream.c: Likewise. - * grub-core/lib/xzembed/xz_lzma2.h: Likewise. - * grub-core/lib/xzembed/xz_private.h: Likewise. - * grub-core/lib/xzembed/xz_stream.h: Likewise. - * include/grub/file.h (grub_file_filter_id): New compression filter - GRUB_FILE_FILTER_XZIO. - -2010-09-05 Vladimir Serbinenko - - * include/grub/file.h (GRUB_FILE_SIZE_UNKNOWN): New definition. - * grub-core/disk/loopback.c (grub_loopback_open): Handle unknown file - size. - -2010-09-05 Vladimir Serbinenko - - * include/grub/err.h (grub_err_t): Replace GRUB_ERR_BAD_GZIP_DATA with - GRUB_ERR_BAD_COMPRESSED_DATA. All users updated. - -2010-09-05 Vladimir Serbinenko - - Uncompressed checksum support. - - * grub-core/commands/hashsum.c (options): Add option --uncompress. - (check_list): New parameter uncompress. - (grub_cmd_hashsum): Handle --uncompress. - -2010-09-05 Vladimir Serbinenko - - Reintroduce testload. - - * grub-core/commands/minicmd.c (grub_rescue_cmd_testload) [0]: Moved - from here ... - * grub-core/commands/testload.c (grub_cmd_testload): ... here. - (GRUB_MOD_INIT): New function. - (GRUB_MOD_FINI): Likewise. - * grub-core/Makefile.core.def (testload): New module. - -2010-09-05 Szymon Janc - - * grub-core/lib/posix_wrap/sys/types.h (bool): Transform into an enum. - (uint8_t): New type. - (uint16_t): Likewise. - (uint32_t): Likewise. - (uint64_t): Likewise. - -2010-09-05 Szymon Janc - - * include/grub/crypto.h (GRUB_MD_CRC32): New definition. - -2010-09-05 Vladimir Serbinenko - - * grub-core/io/gzio.c (grub_gzio_open): Removed "transparent" parameter. - Made static. - (grub_gzfile_open): Removed. All users updated. - (GRUB_MOD_INIT): New function. - (GRUB_MOD_FINI): Likewise. - * grub-core/kern/file.c (grub_file_filters_all): New variable. - (grub_file_filters_enabled): Likewise. - (grub_file_open): Handle filters. - * grub-core/loader/i386/bsd.c (GRUB_MOD_INIT): Load gzio. - * grub-core/normal/main.c (GRUB_MOD_INIT): Likewise. - * include/grub/file.h (grub_file_filter_id_t): New type. - (grub_file_filter_t): Likewise. - (grub_file_filters_all): New extern variable. - (grub_file_filters_enabled): Likewise. - (grub_file_filter_register): New inline function. - (grub_file_filter_unregister): Likewise. - (grub_file_filter_disable): Likewise. - (grub_file_filter_disable_compression): Likewise. - * include/grub/gzio.h: Removed. - -2010-09-04 BVK Chaitanya - - Filename expansion support for wildcards in GRUB script. - - * tests/grub_script_expansion.in: New test. - * Makefile.util.def: Rule for new test. - - * grub-core/commands/wildcard.c: New file, implements filename - expansion support for GRUB script. - * grub-core/Makefile.core.def: Rule update for regexp.mod. - * grub-core/script/argv.c: Cosmetic changes. - * grub-core/script/execute.c (grub_script_arglist_to_argv): - Refactored to perform wildcard expansion on arguments. - * include/grub/script_sh.h (grub_script_wildcard_translator): New - struct. - - * tests/util/grub-shell.in: Fix quoting for read input. - -2010-09-04 BVK Chaitanya - - Support for updating environment variables with matched substrings - of regexp. - - * tests/grub_cmd_regexp.in: New test. - * Makefile.util.def: Rule for new test. - - * grub-core/commands/regexp.c: New option -s to update environment - variables with regexp matches. - -2010-09-04 Szymon Janc - - * include/grub/file.h (grub_file): New member not_easly_seekable. - (grub_file_seekable): New inline function. - * grub-core/io/gzio.c (test_header): Don't test end magic if file isn't - easily seekable. - (grub_gzio_open): Set not_easly_seekable. - * grub-core/fs/i386/pc/pxe.c (grub_pxefs_open): Set not_easily_seekable. - * grub-core/io/bufio.c (grub_bufio_open): Propagate not_easily_seekable. - -2010-09-04 BVK Chaitanya - - Support for options to appear multiple times on cmdline. - - * include/grub/lib/arg.h (grub_arg_list_alloc): New prototype. - * grub-core/commands/extcmd.c: Support for repeatable option. - * grub-core/lib/arg.c (grub_arg_list_alloc): New function for - repeatable option support. - - Refactor menuentry into a regular command. - - * grub-core/commands/menuentry.c: New file, menuentry command - implementation. - * grub-core/Makefile.core.def: Rule update for normal.mod. - * grub-core/normal/main.c: Moved menuentry creation to - grub-core/commands/menuentry.c. - * grub-core/normal/menu.c (grub_menu_execute_entry): Removed. - (grub_menu_execute_entry_real): Removed. - * grub-core/script/execute.c (grub_script_execute_sourcecode): New - function. - (grub_script_execute_menuentry): Removed. - * grub-core/script/parser.y (menuentry): Removed. - * grub-core/script/script.c (grub_script_create_cmdmenu): Removed. - * grub-core/script/yylex.l (menuentry): Removed. - * include/grub/menu.h (grub_menu_init): New prototype. - (grub_menu_fini): New prototype. - * include/grub/normal.h (grub_normal_add_menu_entry): Removed. - * include/grub/script_sh.h (grub_script_cmd_menuentry): Removed. - (grub_script_execute_sourcecode): New prototype. - -2010-09-04 BVK Chaitanya - - "return" command for GRUB script functions. - - * tests/grub_script_return.in: New test. - * Makefile.util.def: Rules for new test. - - * grub-core/script/execute.c (grub_script_return): New function. - * grub-core/script/main.c: Register/unregister return commaond. - * include/grub/script_sh.h (grub_script_return): New prototype. - -2010-09-04 BVK Chaitanya - - "setparams" command to update positional parameters. - - * tests/grub_script_setparams.in: New test. - * Makefile.util.def: Rules for new test. - - * grub-core/script/argv.c (grub_script_argv_make): New function. - * grub-core/script/execute.c (replace_scope): New function. - (grub_script_setparams): New function. - * grub-core/script/lexer.c: Remove unused variables. - * grub-core/script/main.c: Register/unregister setparams command. - * include/grub/script_sh.h (grub_script_argv_make): New prototype. - (grub_script_setparams): New prototype. - -2010-09-04 BVK Chaitanya - - * grub-core/normal/completion.c (grub_normal_do_completion): Fix - grub_free order. - -2010-09-04 BVK Chaitanya - - Support for passing block of commands as an argument to extcmds. - - * Makefile.util.def: Rules for new test. - * tests/grub_script_blockarg.in: New test. - * grub-core/tests/test_blockarg.c: New file, block argument - command used in the test. - - * include/grub/extcmd.h (grub_extcmd_context): New struct. - (grub_register_extcmd_prio): New function prototype. - (grub_extcmd_dispatcher): New function prototype. - * include/grub/command.h (GRUB_COMMAND_FLAG_BLOCKS): New command - type. - * include/grub/script_sh.h (struct grub_script): New members - `children', `next_siblings' and `refcnt' for block arguments and - reference counting. - (GRUB_SCRIPT_ARG_TYPE_BLOCK): New argument type. - (grub_script_arg): New member `script' for block argument. - (grub_script_argv): New member `script' for block argument. - (grub_parser_param): New member `scripts' for block argument. - (grub_script_mem_free): New extern function prototype. - (grub_script_ref): New function prototype. - (grub_script_unref): New function prototype. - - * grub-core/normal/dyncmd.c (grub_dyncmd_dispatcher): Moved to - extcmd form to support block arguments. - * grub-core/script/argv.c: Block arguments support. - * grub-core/script/execute.c: Likewise. - * grub-core/script/lexer.c: Likewise. - * grub-core/script/main.c: Likewise. - * grub-core/script/script.c: Likewise. - * grub-core/script/parser.y: Likewise. New `block' and `block0' - non-terminals. - - * grub-core/commands/acpi.c: Update extcmd implementations with - grub_extcmd_context_t. - * grub-core/commands/cat.c: Likewise. - * grub-core/commands/echo.c: Likewise. - * grub-core/commands/extcmd.c: Likewise. - * grub-core/commands/hashsum.c: Likewise. - * grub-core/commands/hdparm.c: Likewise. - * grub-core/commands/help.c: Likewise. - * grub-core/commands/hexdump.c: Likewise. - * grub-core/commands/i386/cpuid.c: Likewise. - * grub-core/commands/i386/pc/drivemap.c: Likewise. - * grub-core/commands/i386/pc/halt.c: Likewise. - * grub-core/commands/i386/pc/sendkey.c: Likewise. - * grub-core/commands/iorw.c: Likewise. - * grub-core/commands/keystatus.c: Likewise. - * grub-core/commands/loadenv.c: Likewise. - * grub-core/commands/ls.c: Likewise. - * grub-core/commands/lspci.c: Likewise. - * grub-core/commands/memrw.c: Likewise. - * grub-core/commands/probe.c: Likewise. - * grub-core/commands/search_wrap.c: Likewise. - * grub-core/commands/setpci.c: Likewise. - * grub-core/commands/sleep.c: Likewise. - * grub-core/disk/loopback.c: Likewise. - * grub-core/hello/hello.c: Likewise. - * grub-core/loader/i386/bsd.c: Likewise. - * grub-core/loader/xnu.c: Likewise. - * grub-core/term/gfxterm.c: Likewise. - * grub-core/term/serial.c: Likewise. - * grub-core/tests/lib/functional_test.c: Likewise. - -2010-09-04 BVK Chaitanya - - Multi-line quoted strings support. - - * grub-core/script/lexer.c (append_newline): Removed. - (grub_script_lexer_yywrap): Refactored. - (grub_script_lexer_init): Refactored. - * grub-core/script/yylex.l (yywrap): New function. - (grub_lexer_resplit): New function. - (grub_lexer_unput): New function. - * include/grub/script_sh.h (grub_lexer_param): New members, unput - and resplit. - * tests/grub_script_echo1.in: Added few more testcases. - -2010-09-04 Vladimir Serbinenko - - * grub-core/kern/misc.c: Don't add abort alias in utils. - Reported by: echoline. - -2010-09-03 BVK Chaitanya - - Add missing files into "make dist" tarball for other platforms. - - * gentpl.py (script): Use dist_noinst_DATA instead of EXTRA_DIST. - * conf/Makefile.common (dist_noinst_DATA): New variable. - * conf/Makefile.extra-dist: Added missing make dist files. - * grub-core/Makefile.core.def: Likewise. - -2010-09-03 Vladimir Serbinenko - - Compress grub_prefix. - - * grub-core/boot/i386/pc/lnxboot.S: Use - GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE. - * grub-core/kern/i386/pc/startup.S: Move grub_prefix to compressed part. - * include/grub/offsets.h: Rename GRUB_MACHINE_DATA_END to - GRUB_MACHINE_PREFIX_END. All users updated. - (GRUB_KERNEL_I386_PC_PREFIX): Set to GRUB_KERNEL_I386_PC_RAW_SIZE. - (GRUB_KERNEL_I386_PC_PREFIX_END): Set to GRUB_KERNEL_I386_PC_PREFIX - + 0x40. - (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. - * util/grub-mkimage.c (image_target_desc): Change data_end to - prefix_end. All users updated. - -2010-09-03 Vladimir Serbinenko - - * grub-core/loader/i386/bsd.c (grub_freebsd_boot): Set %ebp to sane - value. - (grub_openbsd_boot): Likewise. - (grub_netbsd_boot): Likewise. - * grub-core/loader/i386/xnu.c (grub_xnu_boot_resume): Likewise. - (grub_xnu_boot): Likewise. - -2010-09-02 Vladimir Serbinenko - - * configure.ac: Clean LIBS variable after tests. - -2010-09-02 Colin Watson - - * INSTALL: Document that libdevmapper needs to be 1.02.34 or later. - -2010-09-02 Vladimir Serbinenko - - * configure.ac: Check for dm_log_with_errno_init in libdevmapper and - echo if libdevmapper will be used. - -2010-09-02 Ian Turner - - * grub-core/fs/i386/pc/pxe.c (grub_pxefs_read): Keep the blocksize - constant for the same file. - -2010-09-02 Vladimir Serbinenko - - * grub-core/kern/i386/multiboot_mmap.c: Remove leftover include. - -2010-09-02 Colin Watson - - * .bzrignore: Add *.pp, **/.dirstamp, grub-core/*.module, and - grub-core/*.pp. - -2010-09-02 Colin Watson - - Zero %ebp and %edi when entering Linux's 32-bit entry point, as - required by the boot protocol. - - * include/grub/i386/relocator.h (struct grub_relocator32_state): Add - ebp and edi members. - * grub-core/lib/i386/relocator.c (grub_relocator_boot): Handle - state.ebp and state.edi. - * grub-core/lib/i386/relocator32.S (grub_relocator32_start): Set - %ebp and %edi according to grub_relocator32_ebp and - grub_relocator32_edi respectively. - * grub-core/loader/i386/linux.c (grub_linux_boot): Zero state.ebp - and state.edi. - -2010-09-02 Vladimir Serbinenko - - Add i386-pc-pxe image target. - - * util/grub-mkimage.c (image_target_desc): New enum value - IMAGE_I386_PC_PXE. - (image_targets): New target i386-pc-pxe. - (generate_image): Handle i386-pc-pxe image. - -2010-09-02 Vladimir Serbinenko - - Fix grub_pxe_scan. - - * grub-core/fs/i386/pc/pxe.c (grub_pxe_pxenv): Put correct type bangpxe. - (grub_pxe_scan): Fix types and pxe_rm_entry computation. - All users updated. - * include/grub/i386/pc/pxe.h (grub_pxe_bangpxe): New struct. - (grub_pxe_pxenv): Correct type. - -2010-09-01 Colin Watson - - * NEWS: Document most of the important changes since 1.98. - -2010-09-01 Colin Watson - - * util/grub-mkrescue.in (usage): Tidy up usage output (and hence - generated manual page) a little. - -2010-09-01 Colin Watson - - * docs/grub.texi: Add myself as an author. - -2010-09-01 Vladimir Serbinenko - - * Makefile.util.def (libgrub.a): Add missing sunpc. - Reported by: Seth Goldberg. - -2010-08-30 Vladimir Serbinenko - - Interrupt wrapping and code simplifications. - - * Makefile.util.def (grub-mkrescue): Use x86 tg instead of - x86_noieee1275 which are functionaly equivalent in this case. - (grub-install): Make source on each platform explicit. Enable on - all noemu. - * gentpl.py (x86_efi_pc): Removed group. - (x86_noefi): Likewise. - (i386_noefi): Likewise. - (x86_noieee1275): Likewise. - (i386_noieee1275): Likewise. - (i386_noefi_noieee1275): Likewise. - (i386_pc_qemu_coreboot): Likewise. - (i386_coreboot_multiboot): Likewise. - (i386_pc_coreboot_multiboot_qemu): Likewise. - (x86_noefi_mips): Likewise. - (noieee1275): Likewise. - (ieee1275_mips): Likewise. - (noemu_noieee1275): Likewise. - (cmos): New group. - (usb): Likewise. - (videoinkernel): Likewise. - (videomodules): Likewise. - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Remove - include/grub/elf.h, include/grub/elfload.h, include/grub/net.h, - include/grub/reader.h, include/grub/symbol.h, include/grub/types.h, - include/grub/loader.h, include/grub/msdos_partition.h, - include/grub/machine/biosdisk.h, include/grub/machine/boot.h, - include/grub/machine/console.h, include/grub/machine/vga.h, - include/grub/machine/vbe.h, include/grub/machine/init.h, - include/grub/machine/kernel.h, include/grub/cpu/time.h, - include/grub/cpu/types.h, include/grub/gzio.h and include/grub/menu.h - (KERNEL_HEADER_FILES) [i386-pc]: Add include/grub/machine/int.h. - (KERNEL_HEADER_FILES) [i386-ieee1275]: Add include/grub/i386/pit.h - * grub-core/Makefile.core.def (kernel): Explicit the source for - startup. Explicit the platforms using kern/generic/rtc_get_time_ms.c. - Split ieee1275_mips. Remove kern/i386/halt.c. Remove kern/i386/misc.S. - Enable kern/i386/pit.c on all x86. Remove kern/i386/ieee1275/init.c. - Use videoinkernel tag. - (usb): Enable on all usb. - (usbserial_common): Likewise. - (usbserial_pl2303): Likewise. - (usbserial_ftdi): Likewise. - (uhci): Enable on all x86. - (ohci): Enable on all pci. - (cmostest): Enable on all CMOS. - (acpi): Include commands/acpi.c on all platforms. - (halt): Add relevant lib/*/halt.c. - (hdparm): Enable on all pci. - (lspci): Likewise. - (usbtest): Enable on all usb. - (ata): Enable on all pci. - (ata_pthru): Likewise. - (usbms): Enable on all usb. - (usb_keyboard): Likewise. - (font): Use tag videomodules. - (bufio): Likewise. - (datetime): Use tag cmos. Enable on all noemu. - (mmap): Use tags common and x86. - (gfxterm): Use tag videomodules. - (bitmap): Likewise. - (bitmap_scale): Likewise. - (video_fb): Likewise. - (video): Likewise. - * grub-core/bus/usb/ohci.c (grub_ohci_td): Make link_td a pointer and - adjust padding accordingly. All users updated. - (grub_ohci_transaction): Fix bad format specification. - (GRUB_MOD_INIT): Add asserts for struct size. - * grub-core/bus/usb/uhci.c (grub_uhci_pci_iter): Add explicit casts. - (grub_alloc_td): Likewise. - (grub_free_queue): Likewise. - (grub_uhci_transfer): Likewise. - (grub_uhci_transaction): Fix bad format specification. - * grub-core/bus/usb/usbtrans.c (grub_usb_control_msg): Likewise. - (grub_usb_bulk_readwrite): Likewise. - * grub-core/kern/i386/misc.S (grub_stop): Moved from here ... - * grub-core/commands/i386/pc/halt.c (stop): ...here. Transformed into C. - Made static. - * grub-core/lib/i386/halt.c (stop): ... and here. Transformed into C. - Made static. - * grub-core/kern/i386/pc/startup.S (grub_halt): Moved from here ... - * grub-core/commands/i386/pc/halt.c (grub_halt): ...here. - Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_biosdisk_rw_int13_extensions): - Moved from here ... - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_rw_int13_extensions): - ... here. Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S (grub_biosdisk_rw_standard): - Moved from here ... - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_rw_standard): - ... here. Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S - (grub_biosdisk_check_int13_extensions): Moved from here ... - * grub-core/disk/i386/pc/biosdisk.c - (grub_biosdisk_check_int13_extensions): ... here. Transformed into C. - Made static. - * grub-core/kern/i386/pc/startup.S - (grub_biosdisk_get_cdinfo_int13_extensions): Moved from here ... - * grub-core/disk/i386/pc/biosdisk.c - (grub_biosdisk_get_cdinfo_int13_extensions): ... here. - Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S - (grub_biosdisk_get_diskinfo_int13_extensions): Moved from here ... - * grub-core/disk/i386/pc/biosdisk.c - (grub_biosdisk_get_diskinfo_int13_extensions): ... here. - Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S - (grub_biosdisk_get_diskinfo_standard): Moved from here ... - * grub-core/disk/i386/pc/biosdisk.c - (grub_biosdisk_get_diskinfo_standard): ... here. - Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S - (grub_biosdisk_get_num_floppies): Moved from here ... - * grub-core/disk/i386/pc/biosdisk.c - (grub_biosdisk_get_num_floppies): ... here. - Transformed into C. Made static. - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_get_diskinfo_real): - New function. - * grub-core/kern/i386/pc/startup.S (grub_pxe_scan): Moved from here ... - * grub-core/fs/i386/pc/pxe.c (grub_pxe_scan): ... here. - Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S (grub_rm_entry): Moved from here ... - * grub-core/fs/i386/pc/pxe.c (grub_rm_entry): ... here. - Transformed into C. Made static. - * grub-core/kern/i386/ieee1275/init.c: Removed. - * grub-core/kern/i386/misc.S: Likewise. - * grub-core/kern/i386/pc/startup.S (grub_get_memsize): - Splitted from here ... - * grub-core/kern/i386/pc/init.c (grub_get_conv_memsize): ... here. - Transformed into C. Made static. All users updated. - * grub-core/kern/i386/pc/mmap.c (grub_get_ext_memsize): ... and here. - Transformed into C. Made static. All users updated. - * grub-core/kern/i386/pc/startup.S (grub_get_eisa_mmap): - Moved from here... - * grub-core/kern/i386/pc/mmap.c (grub_get_eisa_mmap): ... here. - Transformed into C. Made static. All users updated. - * grub-core/kern/i386/pc/startup.S (grub_get_mmap_entry): - Moved from here... - * grub-core/kern/i386/pc/mmap.c (grub_get_mmap_entry): ... here. - Transformed into C. Made static. All users updated. - * grub-core/kern/i386/pc/startup.S (grub_stop_floppy): - Removed (replaced by C version). - * grub-core/kern/i386/pc/startup.S (grub_vga_set_mode): - Moved from here... - * grub-core/video/i386/pc/vga.c (grub_vga_set_mode): ...here. - Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_controller_info): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_controller_info): - ... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_mode_info): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_mode_info): - ... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_mode): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_mode): - ... here. Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_mode): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_mode): - ... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S - (grub_vbe_bios_getset_dac_palette_width):Moved from here... - * grub-core/video/i386/pc/vbe.c - (grub_vbe_bios_getset_dac_palette_width):... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_memory_window): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_memory_window): - ... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_memory_window): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_memory_window): - ... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_scanline_length): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_scanline_length): - ... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_scanline_length): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_scanline_length): - ... here. Transformed into C. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_display_start): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_display_start): - ... here. Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_get_display_start): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_get_display_start): - ... here. Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S (grub_vbe_bios_set_palette_data): - Moved from here... - * grub-core/video/i386/pc/vbe.c (grub_vbe_bios_set_palette_data): - ... here. Transformed into C. Made static. - * grub-core/kern/i386/pc/startup.S (grub_pxe_call): Receive - pxe_rm_entry as third argument. - (grub_bios_interrupt): New function. - * grub-core/kern/i386/qemu/mmap.c: Remove useless include. - * grub-core/kern/i386/qemu/startup.S (codestart): Do cli;hlt instead - of calling grub_stop. - * grub-core/kern/efi/efi.c (grub_halt): Moved from here ... - * grub-core/lib/efi/halt.c (grub_halt): ...here. - * grub-core/kern/emu/main.c (grub_halt): Moved from here ... - * grub-core/lib/emu/halt.c (grub_halt): ... here. - * grub-core/lib/i386/halt.c: Moved from here ... - * grub-core/lib/i386/halt.c: ... here. - * grub-core/kern/ieee1275/openfw.c (grub_halt): Moved from here ... - * grub-core/lib/ieee1275/halt.c (grub_halt): ... here. - * grub-core/loader/i386/pc/linux.c (grub_linux16_boot): Call - grub_stop_floppy. - * grub-core/loader/i386/xnu.c (guessfsb) [IEEE1275]: Enable. - * include/grub/i386/coreboot/init.h: Removed. - * include/grub/i386/multiboot/init.h: Likewise. - * include/grub/i386/pc/biosdisk.h: Removed all function prototypes. - * include/grub/i386/pc/init.h: Likewise except grub_gate_a20. - * include/grub/i386/pc/int.h: New file. - * include/grub/i386/pc/pxe.h (GRUB_PXE_SIGNATURE): New definition. - (grub_pxe_scan): Removed. - (grub_pxe_call): Update prototype. - * include/grub/i386/pc/vbe.h: Removed EXPORT_FUNC and useless - prototypes. - * include/grub/i386/pc/vga.h (grub_vga_set_mode): Removed. - * include/grub/i386/qemu/init.h: Removed. - * include/grub/mips/yeeloong/kernel.h (grub_reboot): Add missing - noreturn. - (grub_halt): Likewise. - * include/grub/misc.h (grub_halt): Removed EXPORT_FUNC. - (grub_reboot): Likewise. - * grub-core/kern/i386/coreboot/init.c (grub_stop_floppy): Moved from here... - * include/grub/i386/floppy.h (grub_stop_floppy): ...here. Inlined. - * grub-core/kern/i386/pc/startup.S (grub_hard_stop): Removed. - -2010-08-30 Robert Millan - - * NEWS: Document addition of ZFS support in `grub-install' and - `grub-mkconfig'. - -2010-08-30 BVK Chaitanya - - * conf/Makefile.common (CPPFLAGS_DEFAULT): Remove leading / from - dprintf output. - -2010-08-30 Vladimir Serbinenko - - Remove leftover embedding of font objects. - - * include/grub/kernel.h (OBJ_TYPE_FONT): Removed. - * util/grub-install.in (font): Removed. - * util/grub-mkimage.c (generate_image): Remove font support. All users - updated. - -2010-08-30 Vladimir Serbinenko - - Remove leftover embedding of font objects. - - * include/grub/kernel.h (OBJ_TYPE_FONT): Removed. - * util/grub-install.in (font): Removed. - * util/grub-mkimage.c (generate_image): Remove font support. All users - updated. - -2010-08-30 Vladimir Serbinenko - - * docs/grub.texi (Network): Fix reference to pxe_blksize. - Reported by: Ian Turner - -2010-08-30 Vladimir Serbinenko - - * grub-core/normal/menu.c (grub_wait_after_message): Add a 10 second - timeout to avoid indefinite boot stalling. - -2010-08-30 Vladimir Serbinenko - - * grub-core/normal/color.c (grub_env_write_color_normal): Fix a warning. - (grub_env_write_color_highlight): Likewise. - -2010-08-30 Vladimir Serbinenko - - * grub-core/normal/term.c (print_more): Return to normal and not - to standard state after printing "---MORE---". - -2010-08-30 Vladimir Serbinenko - - * grub-core/term/i386/vga_common.c (grub_console_setcolorstate): - Mask out the bit 0x80 since it has other meaning that specifiing color. - -2010-08-29 Vladimir Serbinenko - - New relocator. Allows for more kernel support and more straightforward - loader writing. - - * Makefile.am (BOOTTARGET): New variable. - (QEMU32): Likewise. - (linux.init.x86_64): New target. - (linux.init.i386): Likewise. - (multiboot.elf): Likewise. - (kfreebsd.elf): Likewise. - (kfreebsd.aout): Likewise. - (pc-chainloader.elf): Likewise. - (pc-chainloader.bin): Likewise. - (ntldr.elf): Likewise. - (ntldr.bin): Likewise. - (multiboot2.elf): Likewise. - (kfreebsd.init.x86_64): Likewise. - (kfreebsd.init.i386): Likewise. - (knetbsd.init.i386): Likewise. - (kopenbsd.init.i386): Likewise. - (knetbsd.init.x86_64): Likewise. - (kopenbsd.init.x86_64): Likewise. - (linux-initramfs.i386): Likewise. - (linux-initramfs.x86_64): Likewise. - (kfreebsd-mfsroot.i386.img): Likewise. - (knetbsd.image.i386): Likewise. - (kopenbsd.image.i386): Likewise. - (kopenbsd.image.x86_64): Likewise. - (knetbsd.miniroot-image.i386.img): Likewise. - (kfreebsd-mfsroot.x86_64.img): Likewise. - (knetbsd.image.x86_64): Likewise. - (knetbsd.miniroot-image.x86_64.img): Likewise. - (kfreebsd-mfsroot.i386.gz): Likewise. - (bootcheck-kfreebsd-i386): Likewise. - (kfreebsd-mfsroot.x86_64.gz): Likewise. - (bootcheck-kfreebsd-x86_64): Likewise. - (knetbsd.miniroot-image.i386.gz): Likewise. - (bootcheck-knetbsd-i386): Likewise. - (bootcheck-kopenbsd-i386): Likewise. - (bootcheck-kopenbsd-x86_64): Likewise. - (knetbsd.miniroot-image.x86_64.gz): Likewise. - (bootcheck-knetbsd-x86_64): Likewise. - (bootcheck-linux-i386): Likewise. - (bootcheck-linux-x86_64): Likewise. - (bootcheck-linux16-i386): Likewise. - (bootcheck-linux16-x86_64): Likewise. - (bootcheck-multiboot): Likewise. - (bootcheck-multiboot2): Likewise. - (bootcheck-kfreebsd-aout): Likewise. - (bootcheck-pc-chainloader): Likewise. - (bootcheck-ntldr): Likewise. - (CLEANFILES): Add new targets. - (BOOTCHECKS): New variable. - (.PHONY): Add bootchecks. - (SUCCESSFUL_BOOT_STRING): New variable. - (BOOTCHECK_TIMEOUT): Likewise. - (bootcheck): New target - * Makefile.util.def (grub-mkrescue): Enable on i386-multiboot. - * configure.ac: Correct efiemu excuse. - * docs/grub.texi (Supported kernels): New chapter. - * grub-core/Makefile.am (KERNEL_HEADER_FILES): Add - include/grub/mm_private.h. Simplify inclusion of - include/grub/boot.h, include/grub/loader.h - and include/grub/msdos_partition.h - (KERNEL_HEADER_FILES) [i386_coreboot]: - Remove include/grub/machine/loader.h. Add include/grub/i386/pit.h. - (KERNEL_HEADER_FILES) [i386_multiboot]: Likewise. - (KERNEL_HEADER_FILES) [i386_qemu]: Likewise. - (KERNEL_HEADER_FILES) [i386_ieee1275]: Remove - include/grub/machine/loader.h. - (KERNEL_HEADER_FILES) [x86_64-efi]: Likewise. - * grub-core/Makefile.core.def (kernel): Remove kern/i386/loader.S from - extra_dist. - (pci.mod): Enable on i386-multiboot. - (acpi.mod): Enable on i386-multiboot and i386-coreboot. - (efiemu.mod): Enable on i386-coreboot, i386-ieee1275, i386-multiboot and - i386-qemu. - (relocator.mod): Rewritten. - (aout.mod): Enable on all x86. - (bsd.mod): Likewise. - (ntldr.mod): New module. - (linux.mod): Use loader/i386/linux.c on all x86. - (xnu.mod): Enable on all x86. - (vga_text.mod): disable on EFI and QEMU. - * grub-core/efiemu/i386/coredetect.c: Remove useless include. - * grub-core/efiemu/i386/pc/cfgtables.c: Likewise. - * grub-core/efiemu/loadcore.c: Likewise. - * grub-core/efiemu/main.c: Likewise. - (grub_efiemu_exit_boot_services): Removed. - (grub_efiemu_finish_boot_services): Likewise. - * grub-core/efiemu/mm.c (grub_efiemu_finish_boot_services): New - function. - * grub-core/efiemu/i386/nocfgtables.c: New file. - * grub-core/kern/dl.c (grub_dl_unload_all): Removed. - * grub-core/kern/efi/efi.c (grub_efi_exit_boot_services): Removed. - (grub_efi_finish_boot_services): Moved from here ... - * grub-core/kern/efi/mm.c (grub_efi_finish_boot_services): ...here. - Fille finish memory map and related data. - (finish_mmap_buf): New variable. - (grub_efi_uintn_t finish_mmap_size): Likewise. - (grub_efi_uintn_t finish_key): Likewise. - (grub_efi_uintn_t finish_desc_size): Likewise. - (grub_efi_uint32_t finish_desc_version): Likewise. - (grub_efi_is_finished): Likewise. - (grub_efi_get_memory_map): Use saved memory map if EFI is already - finished. - * grub-core/kern/elf.c (grub_elf32_phdr_iterate): Make global. - (grub_elf64_phdr_iterate): Likewise. - * grub-core/kern/i386/coreboot/init.c (grub_os_area_addr): Removed. - (grub_os_area_size): Likewise. - (grub_machine_init): Don't reserve os area. - * grub-core/kern/i386/coreboot/startup.S: Don't include loader.S. - * grub-core/kern/i386/ieee1275/startup.S: Likewise. - * grub-core/kern/i386/loader.S: Removed. - * grub-core/kern/i386/pc/init.c (grub_os_area_addr): Removed. - (grub_os_area_size): Likewise. - (grub_machine_init): Don't reserve os area. - * grub-core/kern/i386/pc/startup.S (grub_chainloader_real_boot): - Don't call grub_dl_unload_all. - Don't include loader.S. - * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_iterate): - Declare the memory after _end as available. - * grub-core/kern/mm.c (GRUB_MM_FREE_MAGIC): Moved from here... - * include/grub/mm_private.h (GRUB_MM_FREE_MAGIC): ... here. - (GRUB_MM_ALLOC_MAGIC): Moved from here... - * include/grub/mm_private.h (GRUB_MM_ALLOC_MAGIC): ... here. - * grub-core/kern/mm.c (grub_mm_header): Moved from here... - * include/grub/mm_private.h (grub_mm_header): ... here. - * grub-core/kern/mm.c (GRUB_MM_ALIGN): Moved from here... - * include/grub/mm_private.h (GRUB_MM_ALIGN): ... here. - * grub-core/kern/mm.c (grub_mm_region): Moved from here ... - (grub_mm_region): ..here. Removed addr. Added pre_size. - All users updated. - * grub-core/kern/mm.c (base): Renamed to ... - (grub_mm_base): ... this. Made global. - (grub_real_malloc): Alloc from end of region. - (grub_memalign): Don't attempt to malloc if grub_mm_base is NULL. - * grub-core/kern/powerpc/cache.S (grub_arch_sync_caches): Move to ... - * grub-core/kern/powerpc/cache_flush.S: ... here. - * grub-core/lib/efi/relocator.c: New file. - * grub-core/lib/i386/relocator.c: Rewritten. - * grub-core/lib/i386/relocator16.S: New file. - * grub-core/lib/i386/relocator32.S: Likewise. - * grub-core/lib/i386/relocator64.S: Likewise. - * grub-core/lib/i386/relocator_asm.S: Rewritten. - * grub-core/lib/i386/relocator_common.S: New file. - * grub-core/lib/ieee1275/relocator.c: Likewise. - * grub-core/lib/mips/relocator.c: Rewritten. - * grub-core/lib/mips/relocator_asm.S: Renamed variables and minor - stylistic adjustments. - * grub-core/lib/powerpc/relocator.c: New file. - * grub-core/lib/powerpc/relocator_asm.S: Likewise. - * grub-core/lib/relocator.c: Rewritten. - * grub-core/lib/x86_64/relocator_asm.S: New file. - * grub-core/loader/aout.c (grub_aout_load): Make load_addr a void *. - * grub-core/loader/i386/bsd.c (NETBSD_DEFAULT_VIDEO_MODE): New const. - (bsd_tag): New struct. - (tags): New variable. - (tags_last): Likewise. - (netbsd_module): New struct. - (netbsd_mods): New variable. - (netbsd_mods_last): Likewise. - (openbsd_opts): New parameter "serial". - (OPENBSD_SERIAL_ARG): New definition. - (netbsd_opts): New parameter "serial". - (NETBSD_SERIAL_ARG): New definition. - (grub_freebsd_add_meta): Reorganised into ... - (grub_bsd_add_meta): ...this. All users updated. - (grub_freebsd_add_mmap): Reorganised into ... - (generate_e820_mmap): ...this... - (grub_bsd_add_mmap): ...and this. All users updated. - (grub_freebsd_list_modules): Use tags. - (grub_netbsd_add_meta_module): New function. - (grub_netbsd_list_modules): Likewise. - (grub_freebsd_boot): Use relocator and finish EFI. - (grub_openbsd_boot): Likewise. - (grub_netbsd_setup_video): New function. - (grub_netbsd_add_modules): Likewise. - (grub_netbsd_boot): Use grub_netbsd_add_modules, relocator, netbsd_tags - and finish EFI. - (grub_bsd_unload): Unload tags. - (grub_bsd_load_aout): Use relocator. - (grub_bsd_elf32_size_hook): New function. - (grub_bsd_elf32_hook): Use relocator. - (grub_bsd_elf64_size_hook): New function. - (grub_bsd_elf64_hook): Use relocator. - (grub_bsd_load_elf): Use relocator and call grub_openbsd_find_ramdisk. - (grub_bsd_load): Zero-out openbsd_ramdisk. - (grub_bsd_load): Use relocator. - (grub_cmd_openbsd): Support serial. - (grub_cmd_netbsd): Support modules. - (grub_cmd_freebsd_module): Use relocator. - (grub_netbsd_module_load): New function. - (grub_cmd_netbsd_module): Likewise. - (grub_cmd_openbsd_ramdisk): Likewise. - (GRUB_MOD_INIT): Register knetbsd_module, knetbsd_module_elf and - kopenbsd_ramdisk. - (GRUB_MOD_FINI): Unregister new commands. - * grub-core/loader/i386/bsdXX.c (load): Remove useless checks. - (grub_freebsd_load_elfmodule_obj): Use relocator. - (grub_freebsd_load_elfmodule): Likewise. - (grub_freebsd_load_elf_meta): Likewise. - (grub_netbsd_load_elf_meta): New function. - (grub_openbsd_find_ramdisk): Likewise. - * grub-core/loader/i386/bsd_helper.S: Removed. - * grub-core/loader/i386/bsd_pagetable.c: Support relocator. - * grub-core/loader/i386/bsd_trampoline.S: Removed. - * grub-core/loader/i386/efi/linux.c: Likewise. - * grub-core/loader/i386/ieee1275/linux.c: Likewise. - * grub-core/loader/i386/linux.c (HAS_VGA_TEXT): New const. - (DEFAULT_VIDEO_MODE): Likewise. - (real_mode_target): New variable. - (prot_mode_target): Likewise. - (initrd_mem_target): Likewise. - (relocator): Likewise. - (efi_mmap_buf): Likewise. - (efi_mmap_size): Likewise. - (find_efi_mmap_size): Moved from grub-core/loader/i386/efi/linux.c. - (free_pages): Use relocator. - (allocate_pages): Account for efi_mmap and use relocator. Return error. - (grub_linux_setup_video): Return error. - (grub_linux_trampoline_start): Removed. - (grub_linux_trampoline_end): Likewise. - (grub_linux_boot): Use relocator and DEFAULT_VIDEO_MODE. Pass console - andd video parameters depending on firmware. - [GRUB_MACHINE_IEEE1275]: Pass OFW parameters. - [GRUB_MACHINE_EFI]: Pass EFI parameters. - (grub_cmd_linux) [GRUB_MACHINE_EFI]: Likewise. - (grub_cmd_initrd): Use relocator. - * grub-core/loader/i386/linux_trampoline.S: Removed. - * grub-core/loader/i386/multiboot_mbi.c (elf_sec_num): New variable. - (elf_sec_entsize): Likewise. - (elf_sec_shstrndx): Likewise. - (elf_sections): Likewise. - (grub_multiboot_load): Use relocator. - (grub_multiboot_get_mbi_size): Account for sections. - (grub_multiboot_make_mbi): Use relocator and support sections. - (grub_multiboot_add_elfsyms): New function. - (grub_multiboot_free_mbi): Free sections. - * grub-core/loader/i386/pc/linux.c (relocator): New variable. - (grub_linux_real_target): Likewise. - (grub_linux_real_chunk): Likewise. - (grub_linux16_prot_size): Likewise. - (grub_linux16_boot): Use relocator. - (grub_linux_unload): Unload relocator. - (grub_cmd_linux): Use relocator. - (grub_cmd_initrd): Likewise. - * grub-core/loader/i386/pc/ntldr.c: New file. - * grub-core/loader/i386/xnu.c (guessfsb) [GRUB_MACHINE_IEEE1275]: - Don't try to guess CPU frequency. - (grub_xnu_set_video): Stretch bitmap. - (grub_xnu_boot): Use relocator. - * grub-core/loader/mips/linux.c (grub_linux_boot): Use relocator. - (grub_linux_unload): Free relocator. - (grub_linux_load32): Use relocator. - (grub_linux_load64): Likewise. - (grub_cmd_initrd): Likewise. - * grub-core/loader/multiboot.c (grub_multiboot_boot): Use relocator. - (grub_multiboot_unload): Unload relocator. - (grub_cmd_multiboot): Use relocator. - (grub_cmd_module): Likewise. - * grub-core/loader/multiboot_elfxx.c (grub_multiboot_load_elfXX): - Use relocator and support sections. - * grub-core/loader/multiboot_mbi2.c(elf_sec_num): New variable. - (elf_sec_entsize): Likewise. - (elf_sec_shstrndx): Likewise. - (elf_sections): Likewise. - (grub_multiboot_load): Use relocator. - (grub_multiboot_get_mbi_size): Account for sections. - (grub_multiboot_make_mbi): Use relocator and support sections. - (grub_multiboot_add_elfsyms): New function. - * grub-core/loader/powerpc/ieee1275/linux.c: Remove useless include. - * grub-core/loader/sparc64/ieee1275/linux.c: Likewise. - * grub-core/loader/xnu.c (grub_xnu_heap_malloc): Use relocator. - Prototype changed. All users updated. - (grub_xnu_align_heap): Simplified. - (grub_xnu_writetree_toheap): Likewise. - (grub_xnu_unload): Unload relocator. - (grub_cmd_xnu_kernel): Use relocator. - (grub_cmd_xnu_kernel64): Likewise. - (grub_xnu_register_memory): Simplified. - * grub-core/loader/xnu_resume.c (grub_xnu_resume): Use relocator. - * grub-core/term/efi/console.c (grub_console_putchar): Abort if - EFI is finished. - (grub_console_checkkey): Likewise. - (grub_console_getkey): Likewise. - (grub_console_getwh): Likewise. - (grub_console_getxy): Likewise. - (grub_console_gotoxy): Likewise. - (grub_console_cls): Likewise. - (grub_console_setcolorstate): Likewise. - (grub_console_setcursor): Likewise. - * grub-core/term/ns8250.c (grub_ns8250_hw_get_port): New function. - * grub-core/tests/boot/kbsd.init-i386.S: New file. - * grub-core/tests/boot/kbsd.init-x86_64.S: Likewise. - * grub-core/tests/boot/kbsd.spec.txt: Likewise. - * grub-core/tests/boot/kernel-8086.S: Likewise. - * grub-core/tests/boot/kernel-i386.S: Likewise. - * grub-core/tests/boot/kfreebsd-aout.cfg: Likewise. - * grub-core/tests/boot/kfreebsd.cfg: Likewise. - * grub-core/tests/boot/kfreebsd.init-i386.S: Likewise. - * grub-core/tests/boot/kfreebsd.init-x86_64.S: Likewise. - * grub-core/tests/boot/knetbsd.cfg: Likewise. - * grub-core/tests/boot/kopenbsd.cfg: Likewise. - * grub-core/tests/boot/kopenbsdlabel.txt: Likewise. - * grub-core/tests/boot/linux.cfg: Likewise. - * grub-core/tests/boot/linux.init-i386.S: Likewise. - * grub-core/tests/boot/linux.init-x86_64.S: Likewise. - * grub-core/tests/boot/linux16.cfg: Likewise. - * grub-core/tests/boot/multiboot.cfg: Likewise. - * grub-core/tests/boot/multiboot2.cfg: Likewise. - * grub-core/tests/boot/ntldr.cfg: Likewise. - * grub-core/tests/boot/pc-chainloader.cfg: Likewise. - * include/grub/aout.h (grub_aout_load): Make load_addr a void *. - * include/grub/autoefi.h (grub_autoefi_finish_boot_services): - New definition. - * include/grub/dl.h (grub_dl_unload_all): Removed. - * include/grub/efi/efi.h (grub_efi_exit_boot_services): Likewise. - (grub_efi_finish_boot_services): Change prototype. - (grub_efi_is_finished): New variable. - * include/grub/efiemu/efiemu.h (grub_efiemu_finish_boot_services): - Changed prototype. - (grub_efiemu_finish_boot_services): Removed. - (grub_machine_efiemu_init_tables): New prototype. - * include/grub/elfload.h (grub_elf32_phdr_iterate): Likewise. - (grub_elf64_phdr_iterate): Likewise. - * include/grub/i386/bsd.h: Include relocator.h. - (freebsd_tag_header): New struct. - (grub_openbsd_bios_mmap): Removed. - (grub_unix_real_boot): Removed. - (grub_freebsd_load_elfmodule32): Changed prototype. - (grub_freebsd_load_elfmodule_obj64): Likewise. - (grub_freebsd_load_elf_meta32): Likewise. - (grub_freebsd_load_elf_meta64): Likewise. - (grub_freebsd_add_meta): Removed. - (grub_netbsd_load_elf_meta32): New prototype. - (grub_netbsd_load_elf_meta64): Likewise. - (grub_bsd_add_meta): Likewise. - (grub_openbsd_ramdisk_descriptor): New struct. - (grub_openbsd_find_ramdisk32): New prototype. - (grub_openbsd_find_ramdisk64): Likewise. - * include/grub/i386/coreboot/loader.h: Removed. - * include/grub/i386/efi/loader.h: Likewise. - * include/grub/i386/ieee1275/loader.h: Likewise. - * include/grub/i386/linux.h (linux_kernel_header): Change void * - to grub_uint32_t. - * include/grub/i386/loader.h: Removed. - * include/grub/i386/memory.h (GRUB_MEMORY_CPU_CR4_PAE_ON): Correct the - value. - (GRUB_MEMORY_CPU_CR4_PSE_ON): New definition. - (grub_phys_addr_t): New type. - (grub_vtop): New inline function. - (grub_map_memory): Likewise. - (grub_unmap_memory): Likewise. - * include/grub/i386/multiboot/loader.h: Removed. - * include/grub/i386/netbsd_bootinfo.h (NETBSD_BTINFO_BOOTDISK): Removed. - (NETBSD_BTINFO_CONSOLE): New definition. - (NETBSD_BTINFO_SYMTAB): Likewise. - (NETBSD_BTINFO_MODULES): Likewise. - (NETBSD_BTINFO_FRAMEBUF): Likewise. - (grub_netbsd_bootinfo): New struct. - (grub_netbsd_btinfo_common): Use explicit bitsize. - (grub_netbsd_btinfo_mmap_entry): Removed. - (GRUB_NETBSD_MAX_BOOTPATH_LEN): New definition. - (grub_netbsd_btinfo_bootdisk): New struct. - (grub_netbsd_btinfo_symtab): Likewise. - (grub_netbsd_btinfo_serial): Likewise. - (grub_netbsd_btinfo_modules): Likewise. - (grub_netbsd_btinfo_framebuf): Likewise. - (GRUB_NETBSD_MAX_ROOTDEVICE_LEN): New definition. - * include/grub/i386/openbsd_bootarg.h (OPENBSD_BOOTARG_CONSOLE): - Likewise. - (grub_openbsd_bootargs): Use explicit bitsize. - (grub_openbsd_bootarg_console): New struct. - (GRUB_OPENBSD_COM_MAJOR): New definition. - (GRUB_OPENBSD_VGA_MAJOR): Likewise. - * include/grub/i386/pc/efiemu.h: Removed. - * include/grub/i386/pc/loader.h: Don't include cpu/loader.h. - * include/grub/i386/qemu/loader.h: Removed. - * include/grub/i386/relocator.h: Rewritten. - * include/grub/i386/xnu.h (grub_xnu_heap_will_be_at): Removed. - * include/grub/mips/memory.h: New file. - * include/grub/mips/multiboot.h: Rewritten. - * include/grub/mips/relocator.h: Rewritten. - * include/grub/mips/yeeloong/memory.h (grub_phys_addr_t): New type. - (grub_vtop): New function. - (grub_map_memory): Likewise. - (grub_unmap_memory): Likewise. - * include/grub/misc.h (ALIGN_DOWN): New definition. - * include/grub/mm.h (grub_mm_check_real): New proto. - (GRUB_MM_CHECK): New definition. - * include/grub/mm_private.h: New file. - * include/grub/multiboot.h (grub_multiboot_relocator): New variable. - (grub_multiboot_get_mbi_size): Removed. - (grub_multiboot_make_mbi): Change prottype. - (grub_multiboot_set_accepts_video): New proto. - (grub_multiboot_add_elfsyms): Likewise. - (grub_multiboot_payload_eip): New variable. - * include/grub/ns8250.h (grub_ns8250_hw_get_port) [!ASM_FILE]: - New prototype. - * include/grub/offsets.h (GRUB_KERNEL_I386_MULTIBOOT_PREFIX): - New definition. - (GRUB_KERNEL_I386_MULTIBOOT_DATA_END): Likewise. - (GRUB_KERNEL_I386_MULTIBOOT_MOD_ALIGN): Likewise. - * include/grub/powerpc/ieee1275/loader.h: Removed. - * include/grub/powerpc/memory.h: New file. - * include/grub/powerpc/relocator.h: Likewise. - * include/grub/relocator.h: Likewise. - * include/grub/relocator_private.h: Likewise. - * include/grub/sparc64/ieee1275/loader.h: Removed. - * include/grub/x86_64/memory.h: New file. - * include/grub/xnu.h (grub_xnu_writetree_toheap): Changed prototype. - (grub_xnu_heap_malloc): Likewise. - (grub_xnu_heap_real_start): Removed. - (grub_xnu_heap_start): Likewise. - (grub_xnu_relocator): New variable. - (grub_xnu_heap_target_start): Likewise. - * tests/util/grub-shell.in: Support non-pc. - * util/grub-mkimage.c (image_targets): Fix multiboot target. - -2010-08-29 Vladimir Serbinenko - - * grub-core/normal/charset.c (grub_utf8_to_ucs4_alloc): Avoid deadloop - on malloc error. - (grub_bidi_logical_to_visual): Check that malloc succeded. - * grub-core/normal/term.c (grub_puts_terminal): Fix fallback to dumb - puts. - (grub_xputs_normal): Likewise. - -2010-08-29 Vladimir Serbinenko - - * grub-core/Makefile.core.def (kernel): Add kern/mips/cache_flush.S to - extra_dist. - -2010-08-29 Vladimir Serbinenko - - * grub-core/efiemu/runtime/efiemu.sh: Removed. - -2010-08-29 Vladimir Serbinenko - - * Makefile.util.def (grub-ofpathname): Add missing ldadd. - -2010-08-29 Vladimir Serbinenko - - * grub-core/kern/misc.c (grub_real_dprintf): Always refresh after - dprintf. - -2010-08-29 BVK Chaitanya - - * Makefile.util.def: Use ldadd instead of ldflags for libraries. - -2010-08-28 Vladimir Serbinenko - - * grub-core/normal/term.c (print_more): Fix a memory leak. - (grub_puts_terminal): Revert to dumb puts if memory allocation fails. - (grub_xputs_normal): Likewise. - -2010-08-28 Vladimir Serbinenko - - * grub-core/script/lexer.c (grub_script_lexer_init): Don't look before - the begining of the string - -2010-08-28 Vladimir Serbinenko - - * grub-core/script/script.c (grub_script_parse): Free parsed on - failure. - -2010-08-28 Vladimir Serbinenko - - * grub-core/normal/completion.c (grub_normal_do_completion): Free argv - on failure. - -2010-08-28 Vladimir Serbinenko - - * grub-core/normal/cmdline.c (grub_cmdline_get): Free cl_terms on - return. - -2010-08-28 Vladimir Serbinenko - - * grub-core/term/gfxterm.c (grub_gfxterm_term_fini): Free the text buffer. - (scroll_up): Fix a memory leak. - -2010-08-28 Vladimir Serbinenko - - * grub-core/fs/nilfs2.c (grub_nilfs2_load_sb): Handle grub_disk_read - errors. - -2010-08-27 Vladimir Serbinenko - - Handle USB pendrives exposed as floppies. - - * grub-core/boot/i386/pc/boot.S: Check LBA even on what appears to be - floppy. - * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_open): Likewise. - Check for partitions on all devices. - -2010-08-25 Vladimir Serbinenko - - * grub-core/term/ieee1275/ofconsole.c (put): Correct prototype. - (readkey): Likewise. - -2010-08-25 BVK Chaitanya - - Multiple variable names support to "export" command. - - * normal/context.c (grub_cmd_export): "export" command supports - multiple variable names. - -2010-08-23 Samuel Thibault - - * util/grub.d/30_os-prober.in: Fix conversion from grub-probe - --target=drive output to Mach device name. - -2010-08-23 BVK Chaitanya - - New Automake based build system for GRUB. - - * ABOUT-NLS: New file. - * Makefile.am: New file. GRUB host utils' rules that doesn't fit - in Makefile.util.def file. - * Makefile.util.def: New file. Autogen build definitions file for - GRUB host utils. - * conf/Makefile.common: New file. Common variables for GRUB host - utils and target modules. - * conf/Makefile.extra-dist: New file. Extra files for make dist. - * docs/Makefile.am: New file. Automake file for docs. - * gentpl.py: New file. Python script to generate Autogen - template. - * grub-core/Makefile.am: New file. GRUB target modules' rules - that doesn't fit in Makefile.core.def file. - * grub-core/Makefile.core.def: New file. Autogen build - definitions file for GRUB target modules. - * grub-core/lib/setjmp.S: New file. Wrapper for target_cpu - specific setjmp.S file. - * po/Makefile.am: New file. - - * .bzrignore: New ignores. - * INSTALL: New requirements, without Ruby. - * acinclude.m4: Use TARGET_IMG_BASE_LDOPT variable instead. - * autogen.sh: Updated to invoke autogen as necessary. - * configure.ac: Separate *FLAGS with HOST_ and TARGET_ prefixes, - and defines for Automake conditionals. - * geninit.sh: Refactoring. - - * include/grub/dl.h: Allow build rules to define GRUB_MOD_* if - necessary. - * include/grub/emu/getroot.h (grub_make_system_path_relative_to_its_root): - New prototype. - - * include/grub/test.h: Fix functional test modules' naming. - * grub-core/tests/example_functional_test.c: Fix test module name. - - * util/misc.c: Hosted versions' of grub functions for libgrub.a - * tests/lib/unit_test.c: Remove hosted versions of grub functions. - * util/grub-editenv.c: Likewise. - * util/grub-fstest.c: Likewise. - * util/grub-mkdevicemap.c: Likewise. - * util/grub-mkfont.c: Likewise. - * util/grub-mkimage.c: Likewise. - * util/grub-mkpasswd-pbkdf2.c: Likewise. - * util/grub-probe.c: Likewise. - * util/grub-script-check.c: Likewise. - * util/i386/pc/grub-setup.c: Likewise. - * util/sparc64/ieee1275/grub-setup.c: Likewise. - - * tests/util/grub-shell.in: Fix override directory path. - * util/grub-mkrescue.in: Replace @pkglib_DATA@ with files. - * util/import_gcry.py: Create Makefile.gcry.def file instead. - - * util/lvm.c: Update #includes. - * util/raid.c: Likewise. - * util/resolve.c: Likewise. - * grub-core/bus/emu/pci.c: Likewise. - * grub-core/lib/posix_wrap/stdlib.h: Likewise. - * grub-core/lib/posix_wrap/string.h: Likewise. - * grub-core/kern/emu/main.c: Likewise. - - * grub-core/gensymlist.sh: New file. Script for generating kernel - symbols file. - * grub-core/genmoddep.awk: Support new kernel_syms.lst format. - - * grub-core/gentrigtables.c: Fix unused variable warnings. - - * Makefile.in: Removed. - * conf/any-emu.rmk: Removed. - * conf/common.rmk: Removed. - * conf/i386-coreboot.rmk: Removed. - * conf/i386-efi.rmk: Removed. - * conf/i386-ieee1275.rmk: Removed. - * conf/i386-multiboot.rmk: Removed. - * conf/i386-pc.rmk: Removed. - * conf/i386-qemu.rmk: Removed. - * conf/i386.rmk: Removed. - * conf/mips-yeeloong.rmk: Removed. - * conf/mips.rmk: Removed. - * conf/powerpc-ieee1275.rmk: Removed. - * conf/sparc64-ieee1275.rmk: Removed. - * conf/tests.rmk: Removed. - * conf/x86-efi.rmk: Removed. - * conf/x86_64-efi.rmk: Removed. - * gendistlist.sh: Removed. - * geninitheader.sh: Removed. - * genkernsyms.sh.in: Removed. - * genmk.rb: Removed. - * gensymlist.sh.in: Removed. - * mkinstalldirs: Removed. - * boot: Moved ... - * grub-core/boot: ... to here. - * bus: Moved ... - * grub-core/bus: ... to here. - * commands: Moved ... - * grub-core/commands: ... to here. - * disk: Moved ... - * grub-core/disk: ... to here. - * efiemu: Moved ... - * grub-core/efiemu: ... to here. - * font: Moved ... - * grub-core/font: ... to here. - * fs: Moved ... - * grub-core/fs: ... to here. - * gencmdlist.sh: Moved ... - * grub-core/gencmdlist.sh: ... to here. - * genemuinit.sh: Moved ... - * grub-core/genemuinit.sh: ... to here. - * genemuinitheader.sh: Moved ... - * grub-core/genemuinitheader.sh: ... to here. - * genfslist.sh: Moved ... - * grub-core/genfslist.sh: ... to here. - * genhandlerlist.sh: Moved ... - * grub-core/genhandlerlist.sh: ... to here. - * genmoddep.awk: Moved ... - * grub-core/genmoddep.awk: ... to here. - * genmodsrc.sh: Moved ... - * grub-core/genmodsrc.sh: ... to here. - * genpartmaplist.sh: Moved ... - * grub-core/genpartmaplist.sh: ... to here. - * genparttoollist.sh: Moved ... - * grub-core/genparttoollist.sh: ... to here. - * genterminallist.sh: Moved ... - * grub-core/genterminallist.sh: ... to here. - * gentrigtables.c: Moved ... - * grub-core/gentrigtables.c: ... to here. - * genvideolist.sh: Moved ... - * grub-core/genvideolist.sh: ... to here. - * gettext: Moved ... - * grub-core/gettext: ... to here. - * gfxmenu: Moved ... - * grub-core/gfxmenu: ... to here. - * gnulib: Moved ... - * grub-core/gnulib: ... to here. - * hello: Moved ... - * grub-core/hello: ... to here. - * hook: Moved ... - * grub-core/hook: ... to here. - * io: Moved ... - * grub-core/io: ... to here. - * kern: Moved ... - * grub-core/kern: ... to here. - * lib: Moved ... - * grub-core/lib: ... to here. - * loader: Moved ... - * grub-core/loader: ... to here. - * mmap: Moved ... - * grub-core/mmap: ... to here. - * normal: Moved ... - * grub-core/normal: ... to here. - * partmap: Moved ... - * grub-core/partmap: ... to here. - * parttool: Moved ... - * grub-core/parttool: ... to here. - * script: Moved ... - * grub-core/script: ... to here. - * term: Moved ... - * grub-core/term: ... to here - * tests/example_functional_test.c: Moved ... - * grub-core/tests/example_functional_test.c: ... to here. - * tests/lib/functional_test.c: Moved ... - * grub-core/tests/lib/functional_test.c: ... to here. - * tests/lib/test.c: Moved ... - * grub-core/tests/lib/test.c: ... to here. - * video: Moved ... - * grub-core/video: ... to here. - -2010-08-23 BVK Chaitanya - - Replace --enable-grub-emu-modules with grub-emu-lite. - - * kern/emu/cache.S: New file. Wrapper for $target_cpu specific - cache.S. - - * include/grub/emu/misc.h (grub_emu_init): New prototype. - * kern/emu/full.c: New file. For grub-emu specific initialization. - * kern/emu/lite.c: New file. For grub-emu-lite initialization. - * kern/emu/main.c: Call initialization function grub_emu_init. - - * Makefile.in: Include grub-emu-lite in install. - * commands/parttool.c: Use grub_no_autoload to differentiate - between grub-emu and grub-emu-lite. - * include/grub/misc.h: New variable grub_no_autoload. - - * conf/any-emu.rmk: New rules for grub-emu-lite. - * configure.ac: Remove --enable-grub-emu-modules. - * genmk.rb: Cleanup unnecessary rules. - * include/grub/dl.h: Remove GRUB_NO_MODULES macro. - - * normal/main.c: Don't load list files on grub-emu-lite. - * util/misc.c (grub_arch_sync_caches): Removed. - -2010-08-23 Colin Watson - - * kern/mips/startup.S (grub_prefix): Update comment to refer to - grub-mkimage rather than grub-mkelfimage. - * kern/powerpc/ieee1275/startup.S (grub_prefix): Likewise. - -2010-08-22 Vladimir Serbinenko - - * term/at_keyboard.c (grub_at_keyboard_getkey_noblock): Don't discard - a key after CapsLock or NumLock. It's just a qemu bug. - -2010-08-21 Vladimir Serbinenko - - * include/grub/usb.h (grub_usb_device): Add 'data' field back. It's - needed by libusb wrapper. - -2010-08-21 Samuel Thibault - - * docs/grub.texi (GNU/Hurd): Document booting GNU/Hurd. - -2010-08-21 Vladimir Serbinenko - - * loader/multiboot.c (grub_cmd_module): Don't unzip module if - --nounzip is passed. - -2010-08-20 Vladimir Serbinenko - - USB hotunplugging and USB serial support. - - * bus/usb/ohci.c (grub_ohci_transfer): Fill *actual and respect timeout. - * bus/usb/uhci.c (grub_free_queue): Compute *actual. - (grub_uhci_transfer): Respect timeout and set *actual. - * bus/usb/usb.c (grub_usb_device_initialize): Correctly skip fields of - non-standard length. - (grub_usb_device_attach): Autoload modules. - (GRUB_MOD_INIT): Set grub_term_poll_usb. - (GRUB_MOD_FINI): Unset grub_term_poll_usb. - * bus/usb/usbhub.c (grub_usb_hub): Replace speed with devices. All - users updated. - (grub_usb_add_hub): Fill nports and children. - (attach_root_port): Receive hub instead of controller. - All users updated. Fill hub->devices. - (grub_usb_root_hub): Allocate hub->devices. - (detach_device): New function. - (poll_nonroot_hub): Fill children and detach devices. - * bus/usb/usbtrans.c (grub_usb_bulk_readwrite): Accept timeout and - actual arguments. All users updated. - (grub_usb_bulk_read_extended): New function. - * bus/usb/serial/common.c: New file. - * bus/usb/serial/ftdi.c: Likewise. - * bus/usb/serial/pl2303.c: Likewise. - * commands/terminal.c (handle_command): Support wildcard. - * commands/usbtest.c: Output "Unknown" instead of empty string. - * conf/any-emu.rmk (pkglib_MODULES): Add usbserial_common.mod. - (usbserial_common_mod_SOURCES): New variable. - (usbserial_common_mod_CFLAGS): Likewise. - (usbserial_common_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add usbserial_pl2303.mod. - (usbserial_pl2303_mod_SOURCES): New variable. - (usbserial_pl2303_mod_CFLAGS): Likewise. - (usbserial_pl2303_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add usbserial_ftdi.mod. - (usbserial_ftdi_mod_SOURCES): New variable. - (usbserial_ftdi_mod_CFLAGS): Likewise. - (usbserial_ftdi_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add serial.mod. - (serial_mod_SOURCES): New variable. - (serial_mod_CFLAGS): Likewise. - (serial_mod_LDFLAGS): Likewise. - * conf/i386-pc.rmk: Likewise. - * conf/mips-yeeloong.rmk: Likewise. - * conf/i386.rmk (serial_mod_SOURCES): Add term/ns8250.c. - * conf/mips-yeeloong.rmk (kernel_img_SOURCES): Likewise. - * disk/usbms.c (first_available_slot): New variable. - (grub_usbms_attach): Don't reuse free slots due to potential cache - problems. - * include/grub/serial.h: Moved to .. - * include/grub/ns8250.h: ...this. - * include/grub/serial.h: New file. - * include/grub/term.h (grub_term_poll_usb): New variable. - * include/grub/terminfo.h (grub_terminfo_input_state): Pass term to - readkey. All users updated. - (grub_terminfo_output_state): Pass term to put. - * include/grub/usb.h (GRUB_USB_REQTYPE): New enum. - (grub_usb_controller_dev): Add timeout and actual arguments to - transfer. All users updated. - (grub_usb_interface): New field detach_data. - (grub_usb_device): New fields children and nports. - (grub_usb_ep_type_t): New type. - (grub_usb_get_ep_type): New function. - (grub_usb_bulk_read_extended): Likewise. - * include/grub/usbdesc.h (grub_usb_desc): New type. - * include/grub/usbserial.h: New file. - * include/grub/usbtrans.h (grub_usb_transaction): New field preceding. - * kern/term.c (grub_term_poll_usb): New variable. - (grub_getkey): Call grub_term_poll_usb if set. - (grub_checkkey): Likewise. - (grub_getkeystatus): Likewise. - * term/serial.c: Moved controller-specific parts to ... - * term/ns8250.c: ... here. - * term/serial.c: Mostly rewritten. - * term/usb_keyboard.c: Reorganised to use GET_REPORT only on attaching - according to spec. - -2010-08-20 Robert Millan - - Make kFreeBSD code more generic to support ext2fs as root, ufs as - a separate module and maybe other interesting combinations. - - * util/grub.d/10_kfreebsd.in (load_kfreebsd_module): New function. - (kfreebsd_entry): Use load_kfreebsd_module() to load modules. - (kfreebsd_entry): Add generic filesystem module load routine. - Map GRUB `ext2' to kFreeBSD `ext2fs'. - -2010-08-20 Colin Watson - - * commands/i386/pc/sendkey.c (keysym_table): Rename "numlock" to - "numcenter" (I misunderstood the purpose of this entry). - * docs/grub.texi (sendkey): Likewise. - -2010-08-20 Colin Watson - - * commands/i386/pc/sendkey.c (options): Remove "keep" from all - status flag options; simply omitting the option is equivalent and - simpler. Rename "wait" to "pause". Rename "sysreq" to "sysrq". - (keysym_table): Rename "num5numlock" to "numlock". - (grub_cmd_sendkey): Reinitialise `andmask' and `ormask', so that we - can uniformly say that only the last of multiple `sendkey' - invocations has any effect. - * docs/grub.texi (sendkey): New section. - -2010-08-19 Colin Watson - - * commands/i386/pc/sendkey.c (options): Fix three typos. - -2010-08-19 Vladimir Serbinenko - - Implement sendkey support. - - * commands/i386/pc/sendkey.c: New file. - * conf/i386-pc.rmk (pkglib_MODULES): Add sendkey.mod. - (sendkey_mod_SOURCES): New variable. - (sendkey_mod_CFLAGS): Likewise. - (sendkey_mod_LDFLAGS): Likewise. - -2010-08-18 Colin Watson - - * configure.ac: Move AM_INIT_AUTOMAKE after AC_CANONICAL_TARGET to - fix warnings from Autoconf. - -2010-08-18 Colin Watson - - * acinclude.m4 (grub_ASM_USCORE): Use a more accurate grep pattern, - to avoid false positives with some assemblers that output things - like "someprefix_func" as part of their output. - -2010-08-15 Robert Millan - - * kern/emu/misc.c (grub_get_libzfs_handle): Handle libzfs_init() - errors. - * kern/emu/getroot.c (find_root_device_from_libzfs): Handle - grub_get_libzfs_handle() errors. - -2010-08-14 Robert Millan - - * kern/emu/misc.c (grub_find_zpool_from_dir): Abort function if - filesystem is not ZFS. - -2010-08-12 BVK Chaitanya - - Fix for misspelled color names defaulting to black/black (bug - reported by Doug Nazar) - - * include/grub/normal.h (grub_parse_color_name_pair): Add return - status to prototype. - * normal/color.c (grub_parse_color_name_pair): Return failure - status. - (grub_env_write_color_normal): Ignore bad color names. - (grub_env_write_color_highlight): Likewise. - * normal/main.c (GRUB_MOD_INIT): Set default color names. - -2010-08-12 BVK Chaitanya - - "shift" command support to GRUB script. - - * include/grub/script_sh.h (grub_script_shift): New prototype. - * script/execute.c (grub_script_shift): New function. - * script/main.c (grub_script_init): Register shift command. - (grub_script_fini): Unregister shift command. - * util/grub-script-check.c (grub_script_cmd_shift): New function. - - * tests/grub_script_shift.in: New testcase. - * conf/tests.rmk: Rules for new testcase. - -2010-08-12 BVK Chaitanya - - "continue" command support to GRUB script. - - * script/execute.c (grub_script_execute_cmdwhile): Continue support. - (grub_script_break): Continue support. - * script/main.c (grub_script_init): Register continue command. - (grub_script_fini): Unregister continue command. - - * tests/grub_script_continue.in: New testcase. - * conf/tests.rmk: Rules for new testcase. - -2010-08-12 BVK Chaitanya - - "break" command support to GRUB script. - - * conf/common.rmk: Rule updates to grub-script-check. - * include/grub/misc.h (grub_min): New function. - * include/grub/script_sh.h (grub_script_init): New prototype. - (grub_script_fini): New prototype. - (grub_script_break): New prototype. - * script/main.c (grub_script_init): New function. - (grub_script_fini): New function. - * script/execute.c (grub_script_break): New function. - * normal/main.c: Calls to grub_script_{init,fini}. - * util/grub-script-check.c (grub_script_break): New function. - - * tests/grub_script_break.in: New testcase. - * conf/tests.rmk: Rules for new test case. - -2010-08-12 BVK Chaitanya - - Function parameters support to GRUB script. - - * script/yylex.l (VARIABLE): Regular expression update. - * script/function.c (grub_script_function_call): Moved ... - * script/execute.c (grub_script_function_call): ... to here. - (grub_script_execute_arglist_to_argv): Removed. - (grub_script_arglist_to_argv): New function. - * script/argv.c: New file. - (grub_script_argv_free): New function. - (grub_script_argv_next): Likewise. - (grub_script_argv_append): Likewise. - (grub_script_argv_split_append): Likewise. - * include/grub/script_sh.h (grub_script_argv): New struct. - (grub_script_argv_free): New function. - (grub_script_argv_next): Likewise. - (grub_script_argv_append): Likewise. - (grub_script_argv_split_append): Likewise. - - * conf/common.rmk (normal.mod): New source script/argv.c. - - * tests/grub_script_echo1.in: More tests. - * tests/grub_script_vars1.in: Likewise. - * tests/grub_script_functions.in: New test case. - * conf/tests.rmk: Rules for new testcase. - -2010-08-12 BVK Chaitanya - - Remove grub_script_cmdblock struct. - - * include/grub/script_sh.h: Remove grub_script_cmdblock. - * script/parser.y: Likewise. - * script/execute.c: Rename cmdblock suffix to cmdlist. - * script/script.c: Likewise. - * util/grub-script-check.c: Likewise. - -2010-08-11 Yves Blusseau - - * .bzrignore: add grub-macho2img - -2010-08-11 Vladimir Serbinenko - - * kern/i386/qemu/init.c (grub_qemu_init_cirrus): Fix compilation error. - -2010-08-11 Vladimir Serbinenko - - Remove the dump of sm712 initialisation sequence. - - * include/grub/pci.h (GRUB_PCI_CLASS_SUBCLASS_VGA): New const. - * include/grub/vga.h (GRUB_VGA_IO_ARX_READ): New register. - (GRUB_VGA_IO_MISC_WRITE): Likewise. - (GRUB_VGA_CR_*): Added many registers. - (GRUB_VGA_SR_*): Likewise. - (GRUB_VGA_GR_*): Likewise. - (grub_vga_write_arx): New function. - (grub_video_hw_config): New struct. - (grub_vga_set_geometry): New function. - * kern/i386/qemu/init.c (load_palette): Use grub_vga_write_arx and - GRUB_PCI_CLASS_SUBCLASS_VGA. - * video/cirrus.c (grub_video_cirrus_setup): Use grub_vga_set_geometry. - * video/sm712.c (grub_sm712_write_reg): New function - (grub_sm712_read_reg): Likewise. - (grub_sm712_sr_write): Likewise. - (grub_sm712_gr_write): Likewise. - (grub_sm712_cr_write): Likewise. - (grub_sm712_write_arx): Likewise. - (grub_sm712_cr_shadow_write): Likewise. - (grub_sm712_write_dda_lookup): Likewise. - (grub_video_sm712_setup): Initialise the video rather then - blindly replay the dump. - (main) [TEST]: Add a routine to be able to compile as standalone for - tests. - * video/sm712_init.c (sm712_init): Removed. - (sm712_sr_seq1): New array. - (sm712_sr_seq2): Likewise. - -2010-08-10 Vladimir Serbinenko - - * include/grub/vga.h: Add missing grub/pci.h include. - -2010-08-10 Yves Blusseau - - * util/grub-macho2img.c (main): fix typo - -2010-08-10 Vladimir Serbinenko - - * include/grub/vga.h (grub_vga_gr_write): Add GRUB_MACHINE_PCI_IO_BASE. - (grub_vga_gr_read): Likewise. - (grub_vga_cr_write): Likewise. - (grub_vga_cr_read): Likewise. - (grub_vga_sr_write): Likewise. - (grub_vga_sr_read): Likewise. - (grub_vga_palette_read): Likewise. - (grub_vga_palette_write): Likewise. - * video/sm712.c (GRUB_SM712_REG_BASE): New definition. - (grub_sm712_sr_read): New function. - (grub_video_sm712_setup): Use grub_vga_sr_write and grub_sm712_sr_read. - * video/sm712_init.c (sm712_init): Substract GRUB_MACHINE_PCI_IO_BASE. - -2010-08-09 Robert Millan - - * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Filter - out unused variables on non-ZFS build. - -2010-08-08 Robert Millan - - Fix path generation for sub-filesystems in ZFS. - - * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): Add - missing slash. - -2010-08-08 Robert Millan - - * util/grub-fstest.c (read_file, cmd_cmp): Improve error message. - -2010-08-08 Robert Millan - - * util/grub.d/10_kfreebsd.in: When files required for ZFS do not - exist, issue a proper error message (rely on `ls' for translated - strings). - -2010-08-08 Robert Millan - - Fix grub-probe invocation. - - * util/grub.d/10_kfreebsd.in: s/label/fs_label/g. - -2010-08-04 Robert Millan - - * configure.ac: Remove checks for getfsstat() and getmntany(). - Add checks for `' and `'. - * kern/emu/misc.c [HAVE_GETMNTANY]: Remove `'. - [HAVE_SYS_PARAM_H]: Include `'. - [HAVE_SYS_MOUNT_H]: Include `'. - [HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_mount_point_from_dir): Remove - function. - (grub_find_zpool_from_dir): Use statfs() instead of indirect matching - via find_mount_point_from_dir() and getfsstat() / getmntany(). - -2010-08-04 Robert Millan - - * include/grub/emu/misc.h (grub_find_mount_point_from_dir) - (grub_find_zpool_from_mount_point): Merge into ... - (grub_find_zpool_from_dir): ... this. - * kern/emu/misc.c: Likewise. - - * kern/emu/misc.c - (grub_make_system_path_relative_to_its_root): Replace - grub_find_mount_point_from_dir() / grub_find_zpool_from_mount_point() - with grub_find_zpool_from_dir(). - * kern/emu/getroot.c (find_root_device_from_libzfs): Likewise. - -2010-08-04 Robert Millan - - Support OpenSolaris in ZFS device resolution. - - * configure.ac: Check for getmntany(). - * kern/emu/misc.c [HAVE_GETMNTANY]: Include `'. - [HAVE_GETMNTANY] (grub_find_zpool_from_mount_point): Add OpenSolaris - support. - -2010-08-03 Robert Millan - - Fix grub-emu build. - - * include/grub/util/misc.h: Move `' to ... - * include/grub/emu/misc.h: ... here. - - * include/grub/util/misc.h (grub_get_libzfs_handle): Move function ... - * include/grub/emu/misc.h (grub_get_libzfs_handle): ... here. - - * util/misc.c: Remove `'. - [HAVE_LIBZFS] (libzfs_handle, fini_libzfs) - (grub_get_libzfs_handle): Move to ... - * kern/emu/misc.c [HAVE_LIBZFS] (__libzfs_handle, fini_libzfs) - (grub_get_libzfs_handle): ... here. - -2010-08-03 BVK Chaitanya - - * script/execute.c (grub_script_execute_cmdline): Check for NULL - as command name case. - -2010-08-02 Colin Watson - - * disk/raid.c (insert_array): Select unique numbers for named arrays - as well, for use as keys in the disk cache. - -2010-08-01 Robert Millan - - * util/grub.d/10_kfreebsd.in: Initialize ${kfreebsd_device} as the - kFreeBSD device name, except on ZFS where the filesystem label is - used. - (kfreebsd_entry): On ZFS root, load `opensolaris.ko', `zfs.ko' and - `/boot/zfs/zpool.cache'. - Set mountfrom kernel variable using ${kfreebsd_device}. - -2010-08-01 Robert Millan - - Make it even harder to use uninitialized `libzfs_handle' (and - make the interface a bit simpler). - - * include/grub/util/misc.h (grub_util_init_libzfs) - (libzfs_handle): Remove. - (grub_get_libzfs_handle): New prototype. - - * util/misc.c [HAVE_LIBZFS] (libzfs_handle): Add `static' - attribute. - (grub_util_init_libzfs): Remove. - (grub_get_libzfs_handle): New function. - - * kern/emu/getroot.c (find_root_device_from_libzfs): Use - grub_get_libzfs_handle() to obtain a libzfs handle instead of - accessing `libzfs_handle' directly. - -2010-08-01 Robert Millan - - * include/grub/emu/misc.h (grub_find_mount_point_from_dir) - (grub_find_zpool_from_mount_point): New function prototypes. - - * kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `' to ... - * kern/emu/misc.c [HAVE_GETFSSTAT]: ... here. - - * kern/emu/getroot.c (find_mount_point_from_dir): Move to ... - * kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove - `static' attribute. - - * kern/emu/getroot.c (find_root_device_from_libzfs): Split code for - finding zpool from mount point into ... - * kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this. - - * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When - requested path is part of a ZFS pool, use - grub_find_zpool_from_mount_point() to detect its filesystem name, - and generate a path with `/fsname@path' syntax. - -2010-08-01 Colin Watson - - * include/grub/util/libzfs.h (libzfs_init): Set argument list to - (void) rather than () so that this is a proper prototype. - -2010-08-01 Vladimir Serbinenko - - * lib/arg.c (grub_arg_show_help): Add the necessary spacing. - -2010-08-01 Vladimir Serbinenko - - * kern/emu/getroot.c (find_mount_point_from_dir): Compile only if - [HAVE_LIBZFS && HAVE_LIBNVPAIR] - -2010-08-01 Colin Watson - - * util/grub-mkrescue.in: Remove ${efi_dir} after building efi.img. - -2010-08-01 Colin Watson - - * script/yylex.l (NAME): Remove [:digit:], redundant with [:alnum:]. - -2010-08-01 Colin Watson - - * docs/grub.texi (Simple configuration): Document GRUB_CMDLINE_XEN - and GRUB_CMDLINE_XEN_DEFAULT. Recommend setting - GRUB_GFXPAYLOAD_LINUX=text rather than unsetting it in order to - disable gfxpayload. - (Shell-like scripting): Add real content. - (Serial terminal): Suggest `terminal_input serial; terminal_output - serial' rather than putting the two commands on separate lines, - since console input will be inoperative after the first command. - (menuentry): Document --class, --users, and --hotkey options. - (terminfo): Describe what `visually-ordered UTF-8' means (thanks, - Vladimir Serbinenko). - -2010-08-01 Vladimir Serbinenko -2010-08-01 Colin Watson - - * kern/misc.c (grub_memset): Optimise to reduce cache stalls. - -2010-08-01 Robert Millan - - * include/grub/emu/misc.h (grub_find_mount_point_from_dir) - (grub_find_zpool_from_mount_point): New function prototypes. - - * kern/emu/getroot.c [HAVE_GETFSSTAT]: Move `' to ... - * kern/emu/misc.c [HAVE_GETFSSTAT]: ... here. - - * kern/emu/getroot.c (find_mount_point_from_dir): Move to ... - * kern/emu/misc.c (grub_find_mount_point_from_dir): ... this. Remove - `static' attribute. - - * kern/emu/getroot.c (find_root_device_from_libzfs): Split code for - finding zpool from mount point into ... - * kern/emu/misc.c (grub_find_zpool_from_mount_point): ... this. - - * kern/emu/misc.c (grub_make_system_path_relative_to_its_root): When - requested path is part of a ZFS pool, use - grub_find_zpool_from_mount_point() to detect its filesystem name, - and generate a path with `/fsname@path' syntax. - -2010-08-01 Robert Millan - - Prevent accidental use of uninitialized libzfs_handle. - - * util/grub-probe.c (main): Move grub_util_init_libzfs() call to ... - * kern/emu/getroot.c (find_root_device_from_libzfs): ... here. - * util/misc.c (grub_util_init_libzfs): Make this function idempotent. - -2010-08-01 Colin Watson - - * util/grub.d/20_linux_xen.in: Don't use UUID for LVM root (matching - util/grub.d/10_linux.in). Fixes Debian bug #591093. - -2010-08-01 Robert Millan - - * kern/emu/getroot.c: Include `'. - -2010-07-31 Robert Millan - - * util/grub.d/10_kfreebsd.in: Make module handling more generic. - -2010-07-31 Robert Millan - - * kern/emu/misc.c: Add missing license header. - -2010-07-31 Robert Millan - - * configure.ac: Check for `libzfs.h' and `libnvpair.h'. - - * include/grub/util/libnvpair.h: Include `'. - [HAVE_LIBNVPAIR_H]: Include `' instead of - declaring libnvpair prototypes ourselves. - * include/grub/util/libzfs.h: Include `'. - [HAVE_LIBZFS_H]: Include `' instead of - declaring libzfs prototypes ourselves. - - (libzfs_handle): Moved to ... - * include/grub/util/misc.h (libzfs_handle): ... here. - Include `'. - -2010-07-30 Robert Millan - - * include/grub/emu/misc.h: Add missing license header. - -2010-07-30 Robert Millan - - Enable `grub-probe -t device' resolution on ZFS. - - * configure.ac: Check for getfsstat(), libzfs and libnvpair. - * include/grub/util/libnvpair.h: New file. - * include/grub/util/libzfs.h: New file. - - * kern/emu/getroot.c: Include `' and `'. - [HAVE_LIBZFS && HAVE_LIBNVPAIR]: Include `' and - `'. - [HAVE_GETFSSTAT]: Include `'. - - (find_mount_point_from_dir): New static function. - [HAVE_LIBZFS && HAVE_LIBNVPAIR] (find_root_device_from_libzfs): New - function. - [HAVE_LIBZFS && HAVE_LIBNVPAIR] (grub_guess_root_device): Use - find_root_device_from_libzfs() before ressorting to find_root_device(). - - * include/grub/util/misc.h (grub_util_init_libzfs): New function - prototype. - * util/misc.c: Include `'. - (grub_util_init_libzfs): New function. - [HAVE_LIBZFS] (libzfs_handle): New global variable. - [HAVE_LIBZFS] (fini_libzfs): New static function. - (grub_util_init_libzfs): New function. - * util/grub-probe.c (main): Call grub_util_init_libzfs(). - -2010-07-30 Robert Millan - - * include/grub/emu/misc.h (grub_make_system_path_relative_to_its_root) - (xmalloc, xrealloc, xstrdup, xasprintf): Add - `warn_unused_result' attribute. - * include/grub/misc.h (grub_strdup, grub_strndup, grub_strlen) - (grub_xasprintf, grub_xvasprintf): Likewise. - * include/grub/emu/misc.h (xasprintf): Remove duplicate prototype. - -2010-07-29 Robert Millan - - * util/grub-probe.c (PRINT_FS_LABEL): New enum value. - (probe): Handle `PRINT_FS_LABEL'. - (main): Handle `-t fs_label'. - -2010-07-29 Robert Millan - - * configure.ac: Remove grub-mkisofs checks. - -2010-07-28 Vladimir Serbinenko - - * util/ieee1275/grub-install.in: Don't use empty grub_device. - Reported by: Lennart Sorensen. - -2010-07-20 Vladimir Serbinenko - - * util/grub.d/00_header.in: Remove compatibility with terminal.mod - prior to terminal_input/terminal_output separation. It's been over 1.5 - years and those versions weren't widely deployed. - -2010-07-22 Colin Watson - - * disk/raid.c (insert_array): Don't count named arrays when looking - for unused array numbers. - Reported and tested by: Michael Guntsche. - -2010-07-20 Colin Watson - - * bus/usb/emu/usb.c (grub_usb_poll_devices): Add a dummy - implementation of this so that grub-emu links again, with a note - that this should support hotplugging in the future. - -2010-07-20 Colin Watson - - * kern/emu/getroot.c (grub_util_get_grub_dev): Use xasprintf. - -2010-07-20 Colin Watson - - * disk/loopback.c (grub_cmd_loopback): Don't leak a grub_file_t - handle on failure. - (grub_loopback_close): Remove empty function. - (grub_loopback_dev): Remove close method. - -2010-07-20 Colin Watson - - Disable EFI cursor when the EFI console becomes inactive. - - * term/efi/console.c (grub_efi_console_init): New function. - (grub_efi_console_fini): New function. - (grub_console_term_output): Register init and fini methods. - -2010-07-20 Vladimir Serbinenko - - * tests/util/grub-shell-tester.in: Remove bashism and declare as - sh script. - -2010-07-20 Vladimir Serbinenko - - * disk/loopback.c (grub_loopback): Replace filename with file. - (delete_loopback): Handle new semantics. - (grub_cmd_loopback): Likewise. - (grub_loopback_iterate): Likewise. - (grub_loopback_close): Likewise. - -2010-07-20 Vladimir Serbinenko - - * util/i386/efi/grub-install.in: Revert to platform-specific behaviour - with -p "". - Reported by: Tito Keitel. - -2010-07-20 Vladimir Serbinenko - - * docs/grub.texi (Naming convention): Document new naming convention. - -2010-07-20 Vadim Solomin -2010-07-20 Colin Watson - - Generate device.map in something closer to the old ordering. - - * util/deviceiter.c (struct device): New declaration. - (compare_file_names): Rename to ... - (compare_devices): ... this. Sort by kernel name in preference to - the stable by-id name, but keep the latter as a fallback comparison. - Update header comment. - (grub_util_iterate_devices) [__linux__]: Construct and sort an array - of `struct device' rather than of plain file names. - -2010-07-20 Thomas Frauendorfer - - * lib/i386/relocator_asm.S [! __x86_64__]: Don't try to disable amd64 - on i386. - -2010-07-20 Vladimir Serbinenko - - * commands/acpi.c (setup_common_tables): Use sizeof instead of - hardcoding size. - (setv1table): Likewise. - -2010-07-20 Colin Watson - - * disk/raid.c (insert_array): Use md/%s to name mdadm 1.x devices, - removing the homehost if present. - * kern/emu/getroot.c (get_mdadm_name) [__linux__]: New function. - (grub_util_get_grub_dev): Use md/%s to name mdadm 1.x devices, - removing the homehost if present. - (grub_util_get_grub_dev) [__linux__]: Get the array name from mdadm - if possible. - * util/i386/pc/grub-setup.c (main): Handle md/* devices. - - * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Add start_sector - parameter. Set its pointer target to 0. - * disk/mdraid_linux.c (grub_mdraid_detect): Add start_sector - parameter. Set its pointer target to 0 for 0.9 metadata, or to the - `data_offset' value from the superblock for 1.x metadata. - * disk/raid.c (grub_raid_read): Offset reads by the start sector of - data on the device. - (insert_array): Record the start sector of data on the device. - (grub_raid_register): Pass start_sector parameters to - grub_raid_list->detect and insert_array. - * include/grub/raid.h (struct grub_raid_array): Add start_sector - member. - (struct grub_raid): Add start_sector parameter to `detect'. - - * disk/mdraid_linux.c (struct grub_raid_super_1x): Remove - __attribute__ ((packed)), leaving a comment. - (grub_mdraid_detect): Split out 0.9 and 1.x detection to ... - (grub_mdraid_detect_09): ... here and ... - (grub_mdraid_detect_1x): ... here. - -2010-07-20 Peter Henn - - * disk/mdraid_linux.c (grub_mdraid_detect): Fix calculation of 1.x - chunk size and disk size, which are already given as sector counts - as distinct from the 0.90 units. Fetch the correct device number - from the role table instead of using the table index. - -2010-07-20 Felix Zielcke - - * disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Set array->name to NULL. - * disk/mdraid_linux.c (grub_raid_super_1x): New structure. - (WriteMostly1): New macro. - Set array->name to NULL for metadata format 0.90. Add support for - metadata 1.x. Fix some comments. - * disk/raid.c (): Add support for name based RAID arrays. Fix a - few comments. - * util/getroot.c (grub_util_get_grub_dev): Add support for - /dev/md/name style devices. - -2010-07-20 Colin Watson - - * .bzrignore: Ignore 20_linux_xen. - -2010-07-17 Colin Watson - - * util/import_unicode.py: Remove unnecessary imports. - -2010-07-17 Aleš Nesrsta - - Hotplugging and USB hub support. - - * bus/usb/ohci.c (grub_ohci_td): Add convenience fields. - (grub_ohci): Likewise. - (GRUB_OHCI_REG_CONTROL_BULK_ENABLE): New definition. - (GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE): Likewise. - (GRUB_OHCI_RESET_CONNECT_CHANGE): Likewise. - (GRUB_OHCI_CTRL_EDS): Likewise. - (GRUB_OHCI_BULK_EDS): Likewise. - (GRUB_OHCI_TDS): Likewise. - (GRUB_OHCI_ED_ADDR_MASK): Likewise. - (grub_ohci_ed_phys2virt): New function. - (grub_ohci_virt_to_phys): Likewise. - (grub_ohci_td_phys2virt): Likewise. - (grub_ohci_td_virt2phys): Likewise. - (grub_ohci_pci_iter): Allocate memory and don't wait for stable - attachment. - (grub_ohci_find_ed): New function. - (grub_ohci_alloc_td): Likewise. - (grub_ohci_free_td): Likewise. - (grub_ohci_free_tds): Likewise. - (grub_ohci_transfer): Use previously allocated memory. - (grub_ohci_portstatus): Reset status changed bit. - (grub_ohci_detect_dev): Supply status changed. - (grub_ohci_fini_hw): Free memory. - (grub_ohci_restore_hw): Reallocate memory. - * bus/usb/uhci.c (grub_uhci_portstatus): Don't reset on disable. - Reset status change. - (grub_uhci_detect_dev): Supply status_change. - * bus/usb/usb.c (attach_hooks): New var. - (grub_usb_device_attach): New function. - (grub_usb_register_attach_hook_class): Likewise. - (grub_usb_unregister_attach_hook_class): Likewise. - * bus/usb/usbhub.c (grub_usb_hub_add_dev): Handle errors correctly. - (grub_usb_add_hub): Reset connection changed bit. - (attach_root_port): New function. - (grub_usb_root_hub): Likewise. - (poll_nonroot_hub): Likewise. - (grub_usb_poll_devices): Likewise. - * commands/usbtest.c (grub_cmd_usbtest): Poll devices before listing. - * disk/usbms.c (grub_usbms_open): Use device hooks. - (grub_usbms_iterate) :Poll devices. - (grub_usbms_finddevs): Split into ... - (grub_usbms_attach): ... this ... - (grub_usbms_attach): ... and this. - * include/grub/usb.h (grub_usb_controller_dev): Supply status_changed - in detect_dev. - (grub_usb_interface): New fields attached and detach_hook. - (grub_usb_attach_hook_class): New type. - (grub_usb_attach_desc): New struct. - (grub_usb_register_attach_hook_class): New function. - (grub_usb_unregister_attach_hook_class): Likewise. - (grub_usb_poll_devices): Likewise. - (grub_usb_device_attach): Likewise. - * include/grub/usbtrans.h (GRUB_USB_HUB_FEATURE_C_CONNECTED): New const. - (GRUB_USB_HUB_STATUS_C_CONNECTED): Likewise. - -2010-07-17 Vladimir Serbinenko - - * include/grub/bsdlabel.h (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION): New definition. - * partmap/bsdlabel.c (bsdlabel_partition_map_iterate): Use FreeBSD - delta determination style. Works with most NetBSD partitions too. - -2010-07-17 Vladimir Serbinenko - - * kern/partition.c [GRUB_UTIL]: Add missing util/misc.h inclusion. - * partmap/bsdlabel.c [GRUB_UTIL]: Likewise. - -2010-07-17 Vladimir Serbinenko - - * disk/scsi.c (grub_scsi_open): Fix incorrect pointer dereference. - -2010-07-14 Anton Blanchard - - * loader/powerpc/ieee1275/linux.c (grub_cmd_linux): Do not reject - ET_DYN files. - -2010-07-14 Grégoire Sutre - - * Makefile.in: Use the substituted @USE_NLS@ instead of ENABLE_NLS. - -2010-07-14 Grégoire Sutre - - * kern/partition.c (grub_partition_check_containment): New function to - check that a partition is physically contained in a parent. Since - offsets are relative (and non-negative), this reduces to checking that - the partition ends before its parent. - (grub_partition_map_probe): Discard out-of-range sub-partitions. - (grub_partition_iterate): Likewise. - * include/grub/partition.h (grub_partition_map): Slightly more detailed - comments. - * partmap/bsdlabel.c (bsdlabel_partition_map_iterate): Discard - partitions that start before their parent, and add debug printfs. - -2010-07-13 Colin Watson - - * Makefile.in (.SUFFIX): Spell correctly, as ... - (.SUFFIXES): ... this. Fixes bug where `make foo' (where foo is a - bare module name without `.mod', e.g. `test') tried to invoke a - Modula-2 compiler. - -2010-07-13 Colin Watson - - * README: Point to the Info manual. - -2010-07-13 Jiro SEKIBA - - * fs/nilfs2.c: fix macro NILFS_2ND_SUPER_BLOCK to calculate - 2nd superblock position from partition size. - -2010-07-10 Colin Watson - - * Makefile.in (MAINTAINER_CLEANFILES): Remove - unicode/UnicodeData.txt, unicode/BidiMirroring.txt, and - unicode/ArabicShaping.txt again; these are inputs to autogen.sh, not - outputs. - -2010-07-10 Vladimir Serbinenko - - Restructure SCSI .id handling. - Reported and tested by: Aleš Nesrsta. - - * disk/ata.c (grub_atapi_close): Removed. All users updated. - (grub_atapi_dev): Changed .name to "ata". New field .id. - * disk/usbms.c (grub_usbms_close): Removed. All users updated. - (grub_usbms_dev): New field .id. - * disk/scsi.c (grub_scsi_iterate): Generate name. - (grub_scsi_open): Parse name. - * include/grub/scsi.h (grub_make_scsi_id): New function. - (grub_scsi_dev): Change iterate and open to number instead of naming - busses. All users updated. - (grub_scsi): Remove name. Add .bus. - -2010-07-10 Vladimir Serbinenko - - * commands/help.c (grub_cmd_help): Fix a typo. - -2010-07-10 Vladimir Serbinenko - - * normal/term.c (put_glyphs_terminal): Fix state->num_lines counting. - Reported and tested by: Colin Watson. - -2010-07-10 Vladimir Serbinenko - - * util/grub-mkrescue.in: Don't use tar GNU-ism since it's not necessary - in this context. - -2010-07-07 Vladimir Serbinenko - - * tests/util/grub-shell.in: Remove bashisms and declare as sh script. - -2010-07-07 Colin Watson - - * term/gfxterm.c (grub_gfxterm_background_image_cmd): Fix - indentation. - -2010-07-06 Colin Watson - - * conf/common.rmk (grub_probe_SOURCES): Add disk/raid5_recover.c - and disk/raid6_recover.c. - * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. - * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise. - -2010-07-06 Colin Watson - - * term/gfxterm.c (repaint_schedulded): Rename to ... - (repaint_scheduled): ... this. Update all callers. - (repaint_was_schedulded): Rename to ... - (repaint_was_scheduled): ... this. Update all callers. - -2010-07-06 Colin Watson - - * util/deviceiter.c (grub_util_iterate_devices): Skip MD devices, - which we expect to be handled by upper layers. - -2010-07-06 BVK Chaitanya - - * bus/usb/usbhub.c: #include time.h header. - -2010-07-06 Colin Watson - - * fs/reiserfs.c (grub_reiserfs_iterate_dir): Zero out first byte of - entry_name also for entries without stat blocks (e.g. ".."); fixes - corruption of the first entry in a directory. - -2010-07-06 Colin Watson - - * util/grub.d/00_header.in: Process GRUB_THEME and GRUB_BACKGROUND - after setting gfxterm as the active terminal. GRUB_BACKGROUND - doesn't work otherwise. - -2010-07-05 Colin Watson - - * docs/grub.texi (Features): Update list of supported file systems. - (GNU/Linux): Update for GRUB 2. - (Serial terminal): Remove mention of --disable-serial, which was a - GRUB Legacy configure option. Update instructions to use - `terminal_input' and `terminal_output' rather than `terminal'. - (Vendor power-on keys): Copy-edit. Add cross-references to `Simple - configuration' and `Installing GRUB using grub-install'. - (Menu entry editor): Update for GRUB 2. - (terminfo): Add vt100-color, ieee1275, and dumb terminal types. - Document new -a, -u, and -v options. - (initrd): New section. - (initrd16): New section. - (linux): New section. - (linux16): New section. - (search): The `var' argument to `--set' is optional. - (GRUB only offers a rescue shell): Go into a little more detail on - drive ordering. - -2010-07-05 Colin Watson - - * Makefile.in: Set LINGUAS to empty if ENABLE_NLS is undefined. - -2010-07-05 Colin Watson - - * Makefile.in (MAINTAINER_CLEANFILES): Add unicode/UnicodeData.txt, - unicode/BidiMirroring.txt, unicode/ArabicShaping.txt, and unidata.c. - -2010-07-05 Colin Watson - - * util/i386/pc/grub-setup.c (setup): Rename prefix to - install_prefix, in line with install_dos_part and install_bsd_part. - Add new prefix variable, which is copied to install_prefix after - comparing core.img in memory with the one read from disk in the - no-embedding case, and use that rather than overwriting - install_prefix immediately when installing to a partition. - Fixes Debian bug #586621; based on patches by Matt Kraai and M. Vefa - Bicakci. - -2010-07-04 Grégoire Sutre - - * configure.ac: Avoid == in test command, it's not portable. - * util/grub.d/30_os-prober.in: Likewise. - -2010-07-04 Colin Watson - - * kern/emu/getroot.c [__GNU__]: Include for munmap. - -2010-07-04 Grégoire Sutre - - * util/i386/pc/grub-setup.c (setup): Do not embed when there are - multiple (top-level) partmaps. - -2010-07-02 Vladimir Serbinenko - - * util/i386/efi/grub-install.in: Don't use empty grub_device. - Reported by: Tino Keitel. - -2010-07-02 Vladimir Serbinenko - - Bidi and diacritics support. - - * Makefile.in (widthspec.bin): New target. - (widthspec.h): Likewise. - (TARGET_CFLAGS): Add -DHAVE_UNIFONT_WIDTHSPEC=1 if font was available. - * autogen.sh: Generate unidata.c. - * commands/cat.c (grub_cmd_cat): Don't use grub_putchar. - * commands/ls.c (grub_ls_list_devices): Likewise. - (grub_ls_list_files): Likewise. - * commands/minicmd.c (grub_mini_cmd_cat): Likewise. - (grub_mini_cmd_lsmod): Likewise. - * commands/read.c: Likewise. - * kern/corecmd.c (grub_core_cmd_ls): Likewise. - * kern/rescue_reader.c (grub_rescue_read_line): Likewise. - * lib/arg.c (grub_arg_show_help): Likewise. - * lib/crypto.c (grub_password_get): Likewise. - * normal/auth.c (grub_username_get): Likewise. - * normal/misc.c (grub_normal_print_device_info): Likewise. - * commands/help.c (grub_cmd_help): Use grub_unicode_aglomerate_comb. - * conf/common.rmk (grub_mkfont_SOURCES): Add unidata.c. - (gfxmenu_mod_SOURCES): Add gfxmenu/font.c. - (normal/charset.c_DEPENDENCIES): New variable. - (normal_mod_SOURCES): Add normal/charset.c and unidata.c. - (pkglib_MODULES): Remove charset.mod. - (charset_mod_SOURCES): Removed. - (charset_mod_CFLAGS): Likewise. - (charset_mod_LDFLAGS): Likewise. - (pkglib_MODULES) [ieee1275]: Remove terminfo.mod. - * conf/powerpc-ieee1275.rmk (kernel_img_SOURCES): Add term/terminfo.c - and term/tparm.c. - * conf/sparc64-ieee1275.rmk (kernel_img_SOURCES): Likewise. - * conf/i386-ieee1275.rmk (kernel_img_SOURCES): Likewise. - (kernel_img_HEADERS): Add terminfo.h. - * font/font.c (ascii_glyph_lookup): Return NULL on failure. - Fill ->font. Reverse ascii bitmaps. - (grub_font_get_xheight): New function. - * font/font.c (grub_font_get_string_width): Moved from here ... - * gfxmenu/font.c (grub_font_get_string_width): ... here. - * font/font.c (grub_font_draw_string): Moved from here ... - * gfxmenu/font.c (grub_font_draw_string): ... here. - * font/font.c (grub_font_dup_glyph): New function. - (grub_font_blit_glyph): Likewise. - (grub_font_blit_glyph_mirror): Likewise. - (blit_comb): Likewise. - (grub_font_construct_dry_run): Likewise. - (grub_font_get_constructed_device_width): Likewise. - (grub_font_construct_glyph): Likewise. - * include/grub/charset.h (grub_ucs4_to_utf8): New proto. - * include/grub/misc.h (grub_utf8_to_ucs4): Moved from here ... - * include/grub/charset.h (grub_utf8_to_ucs4): ... here. - * include/grub/font.h (GRUB_FONT_CODE_CHAR_MASK): New constant. - (GRUB_FONT_CODE_RIGHT_JOINED): Likewise. - (GRUB_FONT_CODE_LEFT_JOINED): Likewise. - (grub_font_get_xheight): New proto. - (grub_font_get_constructed_device_width): Likewise. - (grub_font_construct_glyph): Likewise. - * include/grub/font.h (grub_font_get_string_width): Moved from here ... - * include/grub/gfxmenu_view.h (grub_font_get_string_width): ... here. - * include/grub/font.h (grub_font_draw_string): Moved from here ... - * include/grub/gfxmenu_view.h (grub_font_draw_string): ... here. - * include/grub/i386/vga_common.h (grub_console_putchar): Moved from here.. - * include/grub/i386/pc/console.h (grub_console_putchar): ... here. - * include/grub/i386/vga_common.h (grub_console_real_putchar): Removed. - (grub_console_getcharwidth): Likewise. - * include/grub/misc.h (grub_xputs): New proto. - (grub_puts): Inlined. - * include/grub/normal.h (grub_print_ucs4): Add margin specification. - (grub_normal_get_line_counter): Removed. - (grub_install_newline_hook): Likewise. - (grub_normal_get_char_counter): New proto. - (grub_normal_reset_more): Likewise. - (grub_xputs_normal): Likewise. - * include/grub/powerpc/ieee1275/console.h: Removed. - * include/grub/sparc64/ieee1275/console.h: Likewise. - * include/grub/term.h (GRUB_TERM_CODE_TYPE_MASK): New definition. - (GRUB_TERM_CODE_TYPE_ASCII): Likewise. - (GRUB_TERM_CODE_TYPE_CP437): Likewise. - (GRUB_TERM_CODE_TYPE_UTF8_LOGICAL): Likewise. - (GRUB_TERM_CODE_TYPE_UTF8_VISUAL): Likewise. - (GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS): Likewise. - (grub_term_input): Pass reference to self. All users updated. - (grub_term_output): Pass grub_unicode_glyph to putchar and getcharwidth. - Pass reference to self. New fields normal_color, highlight_color and - data. All users updated. - (grub_putchar): Removed. - (grub_putcode): Remove EXPORT_FUNC since it's not in kernel anymore. - (grub_unicode_estimate_width): New function. - (grub_term_getcharwidth): Add defaults. - (GRUB_TERM_DEFAULT_NORMAL_COLOR): New definition. - (GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR): Likewise. - (GRUB_TERM_DEFAULT_STANDARD_COLOR): Likewise. - (grub_cls): Remove EXPORT_FUNC. - (grub_setcolorstate): Inline. - (grub_newline_hook): Removed. - * include/grub/terminfo.h: Rewritten. All users updated. - * include/grub/unicode.h: New file. - * include/grub/video.h (grub_video_signed_rect): New type. - * kern/emu/console.c (grub_console_highlight_color): Removed. - (grub_console_normal_color): Likewise. - (grub_console_standard_color): Made static. - (grub_ncurses_putchar): Remove mapping. - (grub_ncurses_getcharwidth): Removed. - (grub_ncurses_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII. - (grub_ncurses_setcolor): Removed. - (grub_ncurses_getcolor): Likewise. - * kern/i386/pc/startup.S (grub_console_real_putchar): Renamed to ... - (grub_console_putchar): ... this. - (grub_console_putchar): Handle argument difference. - * kern/ieee1275/init.c (grub_machine_init): Split console_init into - console_init_early and console_init_lately. - * kern/sparc64/ieee1275/init.c (grub_machine_init): Likewise. - * kern/misc.c (grub_puts): Removed. - (grub_vprintf): Store UTF-8 string instead of outputting it directly. - (grub_vsnprintf_real): Remove str = NULL support. - * kern/misc.c (grub_utf8_to_ucs4): Move from here ... - * normal/charset.c (grub_utf8_to_ucs4): ... here. - * kern/term.c (grub_putcode): Renamed to ... - (grub_putcode_dumb): ... this. Pass grub_unicode_glyph instead of code. - (grub_putchar): Removed. - (grub_xputs_dumb): New function. - (grub_xputs): New variable. - * lib/charset.c: Move from here ... - * normal/charset.c: ... to here. - (grub_ucs4_to_utf8): New function. - (grub_ucs4_to_utf8_alloc): Use grub_ucs4_to_utf8. - (join_types): New variable. - (unpack_join): New function. - (bidi_types): New variable. - (unpack_bidi): New function. - (get_bidi_type): Likewise. - (get_join_type): Likewise. - (is_mirrored): Likewise. - (grub_unicode_get_comb_type): Likewise. - (grub_unicode_estimate_width) [HAVE_UNIFONT_WIDTHSPEC]: Likewise. - (is_type_after): Likewise. - (grub_unicode_aglomerate_comb): Likewise. - (bidi_line_wrap): Likewise. - (grub_bidi_line_logical_to_visual): Likewise. - (grub_bidi_logical_to_visual): Likewise. - (grub_unicode_mirror_code): Likewise. - (grub_unicode_shape_code): Likewise. - * normal/cmdline.c (grub_cmdline_get): Reset more counter. - Don't use grub_putchar. - * normal/main.c (grub_normal_init_page): Use grub_putcode. - (grub_normal_reader_init): Likewise. - (grub_xputs_saved): New variable. - (GRUB_MOD_INIT): Set grub_xputs. - (GRUB_MOD_FINI): Restore grub_xputs. - * normal/menu.c (grub_wait_after_message): Don't use grub_putchar. - (menu_init): Avoid printing gfxmenu error. - (show_menu): Use grub_normal_get_char_counter. - * normal/menu_entry.c (update_screen): Fix out-of-array. - (complete): Avoid NULL dereferencing. - * grub_menu_entry_run (grub_menu_entry_run): Don't use putchar. - * normal/menu_text.c (print_spaces): Removed. - (grub_print_ucs4): Likewise. - (grub_print_message_indented): Use grub_print_ucs4. - (print_message): Use grub_putcode. - (print_entry): Hanlde diacritics. - * normal/term.c (term_state): New type. - (grub_more_lines): Removed. - (term_states): New variable. - (grub_normal_line_counter): Renamed to .. - (grub_normal_char_counter): ...this. All users updated. - (grub_normal_get_line_counter): Renamed to ... - (grub_normal_get_char_counter): ... this. - (grub_normal_reset_more): New function. - (process_newline): Removed. - (print_more): New function. - (grub_install_newline_hook): Removed. - (map_code): New function. - (grub_puts_terminal): Use grub_print_ucs4. - (putglyph): New function. - (putcode_real): Likewise. - (grub_putcode): Use putcode_real. - (get_maxwidth): New function. - (get_startwidth): Likewise. - (print_ucs4_terminal): Likewise. - (find_term_state): Likewise. - (put_glyphs_terminal): Likewise. - (print_backlog): Likewise. - (print_ucs4_real): Likewise. - (grub_print_ucs4): Likewise. - (grub_xputs_normal): Likewise. - * term/efi/console.c (grub_console_putchar): Output diacritics. - (grub_console_getcharwidth): Removed. - (grub_console_term_output): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL. - * term/gfxterm.c (clear_char): Free chars. - (scroll_up): Avoid leaking memory. - (grub_gfxterm_putchar): Support diacritics. - (grub_video_term): Declare as GRUB_TERM_CODE_TYPE_UCS4_VISUAL. - * term/i386/pc/console.c (grub_console_term_output): Declare as - GRUB_TERM_CODE_TYPE_VGA. - * term/i386/pc/vga.c (grub_vga_term): Declare as - GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS. - * term/i386/pc/vga_text.c (grub_vga_text_term): Declare as - GRUB_TERM_CODE_TYPE_VGA. - * term/i386/vga_common.c (map_char): Removed. - (grub_console_putchar): Likewise. - (grub_console_getcharwidth): Likewise. - * term/ieee1275/ofconsole.c: Simplify using terminfo. - (colors): Reordered to match terminfo. - (grub_ofconsole_normal_color): Removed. - (grub_ofconsole_writeesc): Likewise. - (grub_ofconsole_highlight_color): Likewise. - (grub_ofconsole_getcharwidth): Likewise. - (grub_ofconsole_setcolorstate): Likewise. - (grub_ofconsole_setcolor): Likewise. - (grub_ofconsole_getcolor): Likewise. - (grub_ofconsole_readkey): Renamed to ... - (readkey): ... this. Remove escape sequence handling. Return -1 on no - key. - (grub_ofconsole_checkkey): Removed. - (grub_ofconsole_getkey): Likewise. - (grub_ofconsole_getxy): Likewise. - (grub_ofconsole_gotoxy): Likewise. - (grub_ofconsole_cls): Likewise. - (grub_ofconsole_refresh): Likewise. - (grub_ofconsole_terminfo_input): New struct. - (grub_ofconsole_terminfo_output): Likewise. - (grub_ofconsole_term_input): Use terminfo. - (grub_ofconsole_term_output): Likewise. - (grub_console_init): Split into ... - (grub_console_init_early): ...this and ... - (grub_console_init_lately): ...this. Use terminfo. - (grub_ofconsole_putchar): Renamed to ... - (put): ... this. Remove mapping. - (grub_ofconsole_term_output): Declare as GRUB_TERM_CODE_TYPE_ASCII. - * term/serial.c: Simplify using terminfo. - (xpos): Removed. - (ypos): Likewise. - (keep_track): Likewise. - (registered): Likewise. - (input_buf): Likewise. - (npending): Likewise. - (serial_translate_key_sequence): Likewise. - (fill_input_buf): Likewise. - (grub_serial_checkkey): Likewise. - (grub_serial_getkey): Likewise. - (grub_serial_getxy): Likewise. - (grub_serial_gotoxy): Likewise. - (grub_serial_putchar): Likewise. - (grub_serial_cls): Likewise. - (grub_serial_setcolorstate): Likewise. - (grub_serial_setcursor): Likewise. - (serial_hw_init): Use serial_hw_fetch. - (grub_serial_terminfo_input): New variable. - (grub_serial_terminfo_output): Likewise. - (grub_serial_term_input): Use terminfo. - (grub_serial_term_output): Likewise. - * term/terminfo.c (putstr): Use put. - (grub_terminfo_all_free): New function - (grub_terminfo_set_current): New types vt100-color, ieee1275 and dumb. - (grub_terminfo_output_register): New function. - (grub_terminfo_output_unregister): Likewise. - (grub_terminfo_getxy): Likewise. - (grub_terminfo_readkey): Likewise. - (grub_terminfo_checkkey): Likewise. - (grub_terminfo_getkey): Likewise. - (grub_terminfo_input_init): Likewise. - (print_terminfo): Likewise. - (grub_cmd_terminfo): Handle encoding. - (grub_terminfo_gotoxy): Track position. - (grub_terminfo_cls): Likewise. - (grub_terminfo_putchar): Likewise. - (grub_terminfo_setcolorstate): Handle colors - (grub_terminfo_cursor_on): This ... - (grub_terminfo_cursor_off): ... and this merged into ... - (grub_terminfo_setcursor): ... this. - * term/tparm.c (grub_terminfo_tparm): Avoid NULL dereferencing. - * unicode/ArabicShaping.txt: New file (imported from Unicode). - * unicode/BidiMirroring.txt: Likewise. - * unicode/UnicodeData.txt: Likewise. - * unicode/COPYING: Likewise. - * util/grub-editenv.c (grub_putchar): Removed. - (grub_xputs_real): New function. - (grub_xputs): New variable. - * util/grub-fstest.c (grub_putchar): Removed. - (grub_xputs_real): New function. - (grub_xputs): New variable. - * util/grub-mkdevicemap.c (grub_putchar): Removed. - (grub_xputs_real): New function. - (grub_xputs): New variable. - * util/grub-probe.c (grub_putchar): Removed. - (grub_xputs_real): New function. - (grub_xputs): New variable. - * util/grub-script-check.c (grub_putchar): Removed. - (grub_xputs_real): New function. - (grub_xputs): New variable. - * util/i386/pc/grub-setup.c (grub_putchar): Removed. - (grub_xputs_real): New function. - (grub_xputs): New variable. - * util/import_unicode.py: New file. - * util/grub-mkfont.c (ft_errmsgs): New array. - (grub_glyph_info): Make bitmap a pointer. - (file_formats): New type WIDTH_SPEC. - (grub_font_info): New members glyphs_unsorted, glyphs_sorted, num_glyphs. - (options): Add width-spec. - (help): Likewise. - (add_char): Renamed to ... - (add_glyph): ... this. - (add_glyph): Use index. Show freetype errors. Cut blank space at borders. - (glyph_replace): New type. - (subst_rightjoin), (subst_leftjoin), (subst_medijoin): New variables. - (add_char): New function. - (add_subst): Likewise. - (process_cursive): Likewise. - (add_font): Handle GSUB. - (write_font_width_spec): New function. - (main): Sort glyphs. - * commands/minicmd.c (grub_mini_cmd_clear): Moved from here ... - * normal/main.c (grub_mini_cmd_clear): ..here. All users updated. - * kern/term.c (grub_cls): Moved from here... - * normal/term.c (grub_cls): ... here. - -2010-07-02 Colin Watson - - * include/grub/types.h: Define the C99-style PRIxGRUB_SIZE macro, - suitable for using within the format argument of printf when - converting grub_size_t. - * disk/usbms.c (grub_usbms_transfer): Use PRIxGRUB_SIZE rather than - "x" to convert grub_size_t arguments. - -2010-07-02 Vladimir Serbinenko - - * gfxmenu/gui_list.c (draw_menu): Use viewport to simplify code and fix - too long captions. - (list_get_minimal_size): Take selection box into account. - -2010-07-02 Vladimir Serbinenko - - * font/font.c (grub_font_get_glyph_with_fallback): Avoid dereferencing - NULL font. - -2010-07-02 Colin Watson - - * util/deviceiter.c (grub_util_iterate_devices): Skip device-mapper - devices when iterating over /dev/disk/by-id; they will be handled - later if appropriate, which they aren't always (e.g. LVM). - -2010-07-02 Colin Watson - - * include/grub/misc.h (grub_reboot): Declare as noreturn. - * kern/efi/efi.c (grub_reboot): Don't return, even if reset_system - fails. - (grub_halt): Likewise. - * kern/ieee1275/openfw.c (grub_reboot): Don't return, even if - reset-all fails. - (grub_halt): Don't return, even if all of shut-down, power-off, and - poweroff fail. - -2010-07-02 Colin Watson - - * kern/efi/init.c (grub_efi_init): set_watchdog_timer takes four - arguments, not three. - -2010-07-02 Colin Watson - - * util/grub-mkconfig_lib.in (uses_abstraction): New function. - * util/grub.d/10_linux.in: Use it to check for LVM, so that - LVM-on-RAID is handled correctly. - -2010-07-02 Colin Watson - - * docs/grub.texi (Changes from GRUB Legacy): New section. - (Future): Fix typo. - -2010-07-02 Colin Watson - - * util/grub-mkconfig_lib.in (grub_file_is_not_garbage): Sometimes - grub.d/README accidentally ends up executable for one reason or - another. Ignore it. - -2010-07-02 Vladimir Serbinenko - - * partmap/gpt.c (MAX_SECTOR_LOG): New definition. - (gpt_partition_map_iterate): Support non-512B sectors. - -2010-07-02 Vladimir Serbinenko - - * kern/efi/init.c (grub_efi_init): Disable watchdog. - Tested by: Seth Goldberg. - -2010-07-02 Vladimir Serbinenko - - * loader/multiboot.c (grub_multiboot_boot) [GRUB_USE_MULTIBOOT2]: - Properly align mbi. - Reported by: Seth Goldberg. - -2010-07-01 Vladimir Serbinenko - - * util/grub-mkrescue.in: Avoid module duplication. - -2010-07-01 Sean Finney - - * util/grub.d/10_linux.in: Don't use UUID for LVM root. - -2010-07-01 Sean Finney - - * disk/lvm.c (grub_lvm_scan_device): Skip snapshots. - -2010-07-01 Vladimir Serbinenko - - * disk/lvm.c (grub_lvm_checkvalue): New function. - (grub_lvm_check_flag): Likewise. - -2010-07-01 Robert Millan - - * kern/emu/hostdisk.c (convert_system_partition_to_system_disk): - Support 'p' as partition separator on kernel of FreeBSD (used - with GPT labels). - (grub_util_biosdisk_get_grub_dev): Likewise. - -2010-07-01 Vladimir Serbinenko - - Yeeloong firmware port. - - * boot/mips/yeeloong/fwstart.S: New file. - * bus/cs5536.c (gpiodump): New const. - (set_io_space): New function. - (set_iod): Likewise. - (set_p2d): Likewise. - (grub_cs5536_init_geode): Likewise. - * commands/mips/yeeloong/lsspd.c: New file. - * conf/mips-qemu-mips.rmk (pkglib_MODULES): Add serial.mod. - (serial_mod_SOURCES): New variable. - (serial_mod_CFLAGS): Likewise. - (serial_mod_LDFLAGS): Likewise. - * conf/mips-yeeloong.rmk (kernel_img_SOURCES): Add term/serial.c, - term/terminfo.c and term/tparm.c. - (pkglib_IMAGES): Add fwstart.img. - (fwstart_img_SOURCES): New variable. - (fwstart_img_CFLAGS): Likewise. - (fwstart_img_ASFLAGS): Likewise. - (fwstart_img_LDFLAGS): Likewise. - (fwstart_img_FORMAT): Likewise. - (pkglib_MODULES): Add lsspd.mod. - (lsspd_mod_SOURCES): New variable. - (lsspd_mod_CFLAGS): Likewise. - (lsspd_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add halt.mod. - (halt_mod_SOURCES): New variable. - (halt_mod_CFLAGS): Likewise. - (halt_mod_LDFLAGS): Likewise. - * conf/mips.rmk (pkglib_MODULES): Remove serial.mod. - (serial_mod_SOURCES): Removed. - (serial_mod_CFLAGS): Likewise. - (serial_mod_LDFLAGS): Likewise. - * disk/ata.c (check_device): New function. - (grub_ata_device_initialize): Use check_device. - (grub_ata_iterate): Recheck devices. - (grub_ata_open): Likewise. - (grub_atapi_iterate): Likewise. - (grub_atapi_open): Likewise. - * include/grub/ata.h (GRUB_ATA_CH0_PORT1): New macro. - (GRUB_ATA_CH1_PORT1): Likewise. - (GRUB_ATA_CH0_PORT2): Likewise. - (GRUB_ATA_CH1_PORT2): Likewise. - * include/grub/mips/loongson.h: New file. - * include/grub/mips/yeeloong/ec.h: Likewise. - * include/grub/mips/yeeloong/serial.h (GRUB_MACHINE_SERIAL_PORT): New definition. - (GRUB_MACHINE_SERIAL_DIVISOR_115200): Likewise. - (GRUB_MACHINE_SERIAL_PORTS) [ASM_FILE]: Remove. - * include/grub/misc.h (grub_halt): Declare as noreturn. - * include/grub/serial.h (UART_ENABLE_FIFO): Renamed to ... - (UART_ENABLE_FIFO_TRIGGER14): ... this. All users updated. - (UART_ENABLE_FIFO_TRIGGER1): New definition. - (UART_ENABLE_DTRRTS): Likewise. - (UART_ENABLE_MODEM): Removed. - (UART_ENABLE_OUT2): New const. - * include/grub/term.h (grub_term_register_input_active): New function. - (grub_term_register_output_active): Likewise. - * kern/mips/startup.S [GRUB_MACHINE_MIPS_YEELOONG]: Handle 0xffffffff - argument. - * kern/mips/yeeloong/init.c (grub_get_rtc): Macroify. - (init_pci): New function. - (grub_machine_init): Execute platform init when firmware. Init serial. - (grub_halt): Implement. - (grub_exit): Likewise. - (grub_reboot): Likewise. - * term/serial.c (serial_hw_init): Update macros. - [GRUB_MACHINE_MIPS_YEELOONG]: Init on startup. - * util/grub-mkimage.c (image_target_desc): New id IMAGE_YEELOONG_FLASH. - (image_targets): New target mipsel-yeeloong-flash. - (generate_image): Support IMAGE_YEELOONG_FLASH. - * video/sm712.c (GRUB_SM712_TOTAL_MEMORY_SPACE): New definition. - (grub_video_sm712_setup): Init card. - (grub_video_sm712_set_palette): Removed. - * video/sm712_init.c: New file. - -2010-06-30 Colin Watson - - * Makefile.in (install-local): Temporarily prepend $(builddir) to - PATH when running help2man and then run it on the unadorned - executable names, rather than passing $(builddir)/* paths to - help2man. This avoids the build directory ending up in generated - manual pages. - -2010-06-29 Colin Watson - - * util/grub-mkconfig.in: Use 'set -e' rather than '#! /bin/sh -e', - to avoid accidents when debugging with 'sh -x'. - * util/grub-mkrescue.in: Likewise. - * util/grub.d/00_header.in: Likewise. - * util/grub.d/10_hurd.in: Likewise. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. - * util/grub.d/10_netbsd.in: Likewise. - * util/grub.d/10_windows.in: Likewise. - * util/grub.d/20_linux_xen.in: Likewise. - * util/grub.d/30_os-prober.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2010-06-29 Colin Watson - - * commands/cat.c (grub_cmd_cat): Fix buffer overrun if '\r' is the - last character in the buffer. - Reported by: Vladimir Serbinenko. - -2010-06-29 Robert Millan - - * docs/grub.texi (Simple configuration): Document ${GRUB_BADRAM}. - (Command-line and menu entry commands): Document `badram' command. - -2010-06-28 Robert Millan - - * util/grub-mkconfig.in: Export `GRUB_BADRAM' variable. - * util/grub.d/00_header.in: When `GRUB_BADRAM' is set, issue badram - command using ${GRUB_BADRAM} as parameter. - -2010-06-28 Colin Watson - - * docs/grub.texi (Device map): New section. - (Themes): New section (stub). - * Makefile.in (docs/grub.info): The info documentation now builds - without errors. Make sure it stays that way. - -2010-06-28 Vladimir Serbinenko - - Use normal parser for menu entries. - Reported by: Thomas Frauendorfer - - * include/grub/parser.h (grub_parser_execute): Don't export. - * normal/menu.c (grub_menu_execute_entry_real): New function. - (grub_menu_execute_entry): Use grub_menu_execute_entry_real. - -2010-06-28 Colin Watson - - * docs/grub.texi (Embedded configuration): New section (replacing - old "Preset Menu" stub). - (Images): New section. - (configfile): Note that any menu entries defined in `file' are shown - immediately. - -2010-06-28 Josh Triplett - - * mmap/i386/pc/mmap_helper.S: Set CF on return. - -2010-06-28 Colin Watson - - * util/grub-install.in: Add --debug-image= option. - -2010-06-28 Colin Watson - - Change grub-mkdevicemap to emit /dev/disk/by-id/ names where - possible on Linux. - - * util/deviceiter.c (check_device): Rename to ... - (check_device_readable_unique): ... this. Update all callers. - Maintain and check a list of which devices (by canonicalized name) - have already been seen. - (clear_seen_devices): New function. - (compare_file_names) [__linux__]: New function. - (grub_util_iterate_devices): Clear the list of seen devices on exit - and (just in case) on entry. - (grub_util_iterate_devices) [__linux__]: Iterate over non-partition - devices in /dev/disk/by-id/, in sorted order. Remove DM-RAID - seen-devices list, superseded by general code in check_device. - -2010-06-28 Colin Watson - - * commands/cat.c (options): New variable. - (grub_cmd_cat): Parse options. If the --dos option is given, print - DOS-style "\r\n" line endings as simple newlines (Debian bug - #586358). - (GRUB_MOD_INIT): Use extcmd. - (GRUB_MOD_FINI): Likewise. - * docs/grub.texi (cat): Document --dos. - -2010-06-28 Vladimir Serbinenko - - XEN with Linux grub-mkconfig support. - - * conf/common.rmk (grub-mkconfig_SCRIPTS) [linux]: Add 20_linux_xen. - * util/grub-mkconfig.in: Export GRUB_CMDLINE_XEN and - GRUB_CMDLINE_XEN_DEFAULT. - * util/grub.d/20_linux_xen.in: New file. - -2010-06-28 Vladimir Serbinenko - - Initialise VGA video on qemu ourselves. - - * boot/i386/qemu/boot.S: Don't call 0xc000. - * conf/i386-qemu.rmk (kern/i386/qemu/init.c_DEPENDENCIES): New variable. - (kernel_img_SOURCES): Add kern/i386/qemu/init.c and bus/pci.c. - (kernel_img_HEADERS): Add pci.h. - * conf/i386.rmk (pkglib_MODULES) [qemu]: Remove pci.mod. - * configure.ac: Force unifont on qemu and yeeloong. - * include/grub/i386/qemu/kernel.h (grub_qemu_init_cirrus): New proto. - (grub_vga_palette_write): Use correct register. - * kern/i386/coreboot/init.c (grub_machine_init) [GRUB_MACHINE_QEMU]: - Call grub_qemu_init_cirrus. - * kern/i386/qemu/init.c: New file. - * term/i386/pc/vga_text.c (inc_y): Never read outside the screen. - - * commands/videotest.c (grub_cmd_videotest): Handle double buffering. - -2010-06-26 Pavel Roskin - - * util/grub.d/10_linux.in: Add support for initrd images on Fedora - 13. - -2010-06-26 Colin Watson - - * docs/grub.texi (Simple configuration): Explain that - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY must be - set to `true' to disable their respective recovery entries, not - merely set. - -2010-06-26 Colin Watson - - Make the `source' command slightly faster. - - * normal/main.c (grub_normal_execute): Don't re-read list files when - nested. - -2010-06-23 Colin Watson - - * loader/i386/multiboot_mbi.c (retrieve_video_parameters): Set red - field position and mask size to red fields from mode_info, not - green. - * loader/multiboot_mbi2.c (retrieve_video_parameters): Likewise. - Remove redundant tag->common.framebuffer_type assignment. - Reported by: Seth Goldberg. - -2010-06-23 Colin Watson - - Sync up other versions of the Linux loader with Robert Millan's - change of 2010-01-09, "Make loader output a bit more user-friendly". - - * loader/i386/efi/linux.c (grub_linux_boot): Move debug info to - grub_dprintf(). - (grub_cmd_linux): Likewise. - (grub_cmd_initrd): Likewise. - * loader/i386/ieee1275/linux.c (grub_cmd_linux): Likewise. - * loader/i386/pc/linux.c (grub_cmd_linux): Likewise. - -2010-06-21 Colin Watson - - * kern/efi/mm.c (grub_efi_mm_init): Handle systems with memory maps - larger than MEMORY_MAP_SIZE. - -2010-06-21 BVK Chaitanya - - Fix parallel build. - - * conf/common.rmk: Add grub_script.tab.h as a grub-script-check - dependency. - * script/parser.y: #include grub_script.tab.h header. - -2010-06-20 Vladimir Serbinenko - - Support >3GiB and <16MiB RAM in i386-qemu. - - * kern/i386/qemu/mmap.c (QEMU_CMOS_MEMSIZE2_HIGH): New const. - (QEMU_CMOS_MEMSIZE2_LOW): Likewise. - (grub_lower_mem): Removed. - (grub_upper_mem): Likewise. - (mem_size): Made static. - (above_4g): New variable. - (grub_machine_mmap_init): Detect small mem_size and above_4g. - (grub_machine_mmap_iterate): Order in ascending order and add above_4g - support. - -2010-06-20 Vladimir Serbinenko - - Cirrus 5446 and Bochs video cards support. - - * conf/i386.rmk (pkglib_MODULES): Add video_cirrus.mod and - video_bochs.mod - (video_cirrus_mod_SOURCES): New variable. - (video_cirrus_mod_CFLAGS): Likewise. - (video_cirrus_mod_LDFLAGS): Likewise. - (video_bochs_mod_SOURCES): Likewise. - (video_bochs_mod_CFLAGS): Likewise. - (video_bochs_mod_LDFLAGS): Likewise. - * include/grub/vga.h: New file. - * include/grub/video_fb.h (grub_video_fb_doublebuf_blit_init): Removed. - (grub_video_fb_set_page_t): New type. - (grub_video_fb_setup): New prototype. - (grub_video_fb_swap_buffers): Likewise. - (grub_video_fb_get_info_and_fini): Likewise. - * term/i386/pc/vga_text.c (CRTC_ADDR_PORT): Moved to include/grub/vga.h. - (CRTC_DATA_PORT): Likewise. - (CRTC_CURSOR): Likewise. - (CRTC_CURSOR_ADDR_HIGH): Likewise. - (CRTC_CURSOR_ADDR_LOW): Likewise. - (CRTC_CURSOR_DISABLE): Likewise. - (update_cursor): Use grub_vga_cr_write. - (grub_vga_text_setcursor): Likewise. - * video/bochs.c: New file. - * video/fb/video_fb.c (render_target): Moved into framebuffer variable. - (palette): Likewise. - (palette_size): Likewise. - (framebuffer): New variable. - (grub_video_fb_init): Use 'framebuffer'. - (grub_video_fb_fini): Likewise. - (grub_video_fb_get_info): Likewise. - (grub_video_fb_get_palette): Likewise. - (grub_video_fb_set_palette): Likewise. - (grub_video_fb_set_viewport): Likewise. - (grub_video_fb_get_viewport): Likewise. - (grub_video_fb_map_color): Likewise. - (grub_video_fb_map_rgb): Likewise. - (grub_video_fb_map_rgba): Likewise. - (grub_video_fb_unmap_color): Likewise. - (grub_video_fb_unmap_color_int): Likewise. - (grub_video_fb_fill_rect): Likewise. - (grub_video_fb_blit_bitmap): Likewise. - (grub_video_fb_blit_render_target): Likewise. - (grub_video_fb_scroll): Likewise. - (grub_video_fb_create_render_target): Likewise. - (grub_video_fb_doublebuf_blit_init): Likewise. - (grub_video_fb_set_active_render_target): Handle doublebuffering. - (doublebuf_pageflipping_update_screen): New function. - (doublebuf_pageflipping_init): Likewise. - (grub_video_fb_setup): Likewise. - (grub_video_fb_swap_buffers): Likewise. - (grub_video_fb_get_info_and_fini): Likewise. - * video/i386/pc/vbe.c (framebuffer): Remove all doublebuffering fields. - All users updated. - (doublebuf_pageflipping_commit): Restructured into ... - (doublebuf_pageflipping_set_page): ... this. - (doublebuf_pageflipping_update_screen): Removed. - (doublebuf_pageflipping_init): Likewise. - (double_buffering_init): Likewise. - (grub_video_vbe_setup): Use grub_video_fb_setup. - (grub_video_vbe_swap_buffers): Removed. - (grub_video_vbe_set_active_render_target): Likewise. - (grub_video_vbe_get_active_render_target): Likewise. - (grub_video_vbe_get_info_and_fini): Use grub_video_fb_get_info_and_fini. - (grub_video_vbe_adapter): Use grub_video_fb_swap_buffers, - grub_video_fb_set_active_render_target and - grub_video_fb_get_active_render_target. - * video/i386/pc/vga.c (SEQUENCER_ADDR_PORT): Move to include/grub/vga.h. - (SEQUENCER_DATA_PORT): Likewise. - (MAP_MASK_REGISTER): Likewise. - (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. - (get_map_mask): Use grub_vga_sr_read. - (set_map_mask): Use grub_vga_sr_write. - (set_read_map): Use grub_vga_gr_write. - (set_start_address): Use grub_vga_cr_write. - * video/sm712.c (framebuffer): Remove leftover fields. - -2010-06-20 Colin Watson - - * util/grub-mkconfig.in: Capitalise and export GRUB_PREFIX. Stop - setting GRUB_VIDEO_BACKEND. Make it available as a user override - instead. Replace the gfxterm backend check with a check that - ${GRUB_PREFIX}/video.lst is non-empty. - * util/grub.d/00_header.in: Use GRUB_PREFIX rather than computing it - again. - (load_video): New generated function. Call it before loading - gfxterm rather than loading ${GRUB_VIDEO_BACKEND}. - * util/grub.d/10_linux.in (linux_entry): Call load_video. - * util/grub.d/30_os-prober.in (osx_entry): Likewise. - * docs/grub.texi (Simple configuration): Document - GRUB_VIDEO_BACKEND. - -2010-06-20 Vladimir Serbinenko - - Use video functions in linux and xnu loaders. - - * conf/i386-pc.rmk (xnu_mod_SOURCES): Remove loader/i386/pc/xnu.c. - * conf/x86-efi.rmk (xnu_mod_SOURCES): Remove loader/i386/efi/xnu.c. - * include/grub/i386/xnu.h (grub_xnu_set_video): Removed. - * loader/i386/efi/linux.c (grub_linux_setup_video): Copied from - loader/i386/pc/linux.c. - (grub_linux_boot): Resynced with loader/i386/pc/linux.c. - (find_line_len): Removed. - (find_framebuf): Likewise. - (grub_cmd_linux): Declare grub_linux_boot as possibly returning. - * loader/i386/efi/xnu.c: Removed. - * loader/i386/pc/xnu.c: Moved from here... - * loader/i386/xnu.c: ...here. - - Enable priorities in video drivers. - - * include/grub/video.h (grub_video_adapter_prio_t): New type. - (grub_video_adapter): New field prio. - (grub_video_register): Respect prio when inserting. - * video/efi_gop.c (grub_video_gop_adapter): Add prio. - * video/efi_uga.c (grub_video_uga_adapter): Likewise. - * video/emu/sdl.c (grub_video_sdl_adapter): Likewise. - * video/i386/pc/vbe.c (grub_video_vbe_adapter): Likewise. - * video/i386/pc/vga.c (grub_video_vga_adapter): Likewise. - * video/ieee1275.c (grub_video_ieee1275_adapter): Likewise. - * video/sm712.c (grub_video_sm712_adapter): Likewise. - - Fix SDL driver ID. - - * include/grub/video.h (grub_video_driver_id_t): New value - GRUB_VIDEO_DRIVER_SDL. - * video/emu/sdl.c (grub_video_sdl_adapter): Add id. - -2010-06-17 Colin Watson - - * util/i386/pc/grub-setup.c (usage): Pass an extra `program_name' - argument to printf. - * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. - -2010-06-17 Colin Watson - - * util/i386/pc/grub-setup.c (usage): Fix syntax error. - * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. - -2010-06-17 Colin Watson - - * util/i386/pc/grub-setup.c (usage): Warn against running grub-setup - directly, and recommend grub-install instead. - * util/sparc64/ieee1275/grub-setup.c (usage): Likewise. - -2010-06-17 Colin Watson - - Fix i386-pc prefix handling with nested partitions (Debian bug - #585068). Note that the case where the core image is booted using - multiboot and relocated from its original location still requires - more work. - - * kern/i386/pc/init.c (make_install_device): If the prefix starts - with "(,", fill the boot drive in between those two characters, but - expect that a full partition specification including partition map - names will follow. - * util/i386/pc/grub-setup.c (setup): Unless an explicit prefix was - specified, write a prefix without the drive name but including a - full partition specification. - -2010-06-16 Colin Watson - - * util/grub-mkconfig.in: Ignore non-option arguments, for - compatibility with older versions (before 2010-06-12) which did the - same. In particular, this makes it easier to ship an update-grub - wrapper which is compatible with that used with GRUB Legacy (Debian - bug #586056). - -2010-06-14 Grégoire Sutre - - * Makefile.in (install-local): Use $$file.h2m instead of $$dest.h2m - for manual page generation. - -2010-06-14 Grégoire Sutre - - * po/POTFILES: Remove leftover commands/handler.c. - -2010-06-14 Colin Watson - - * util/grub-mkconfig.in: Remove vestige of old argument parsing that - left this script non-functional. - -2010-06-14 Colin Watson - - * docs/man/grub-emu.h2m: New file. - -2010-06-13 Colin Watson - - * docs/grub.texi (Commands): Document reduced command set in rescue - mode. - (cpuid): New section. - -2010-06-13 Grégoire Sutre - - * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev): Use the - new partition naming style. - * util/grub-install.in: Adapt sed subtitutions in grub-probe calls. - -2010-06-12 BVK Chaitanya - - Add "-o grub.iso" like cmdline options support. - - * util/grub-install.in: Improve cmdline option parsing. - * util/grub-mkconfig.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/i386/efi/grub-install.in: Likewise. - * util/ieee1275/grub-install.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2010-06-12 Colin Watson - - * .bzrignore: Ignore 41_custom. - -2010-06-12 Thomas Schmitt - - * util/grub-mkrescue.in: Pass unrecognized options to xorriso. - -2010-06-12 Colin Watson - - Avoid false positives in fs.lst, partmap.lst, and video.lst due to - prototype declarations. - - * genmk.rb (PModule::rule): Define GRUB_LST_GENERATOR when - generating fs, partmap, and video lists. - * include/grub/fs.h (grub_fs_register): Omit prototype if - GRUB_LST_GENERATOR is defined. - * include/grub/partition.h (grub_partition_map_register): Likewise. - * include/grub/video.h (grub_video_register): Likewise. - -2010-06-12 Javier Martín - - * include/grub/types.h: Check for GRUB_CPU_SIZEOF_LONG when appropriate. - -2010-06-12 Thomas Schmitt - - * util/grub-mkrescue.in: Support --xorriso argument. - -2010-06-12 Vladimir Serbinenko - - * util/grub-mkrescue.in: Use -graft-points instead of -pathspecs. - Suggested by: Thomas Schmitt. - -2010-06-12 Vladimir Serbinenko - - * util/grub-mkrescue.in: Add --sort-weight arguments to xorriso. - Suggested by: Thomas Schmitt. - -2010-06-12 Vladimir Serbinenko - - custom.cfg support. - - * conf/common.rmk (grub-mkconfig_SCRIPTS): Add 41_custom. - * util/grub.d/41_custom.in: New file. - -2010-06-12 Colin Watson - - * util/grub-mkrescue.in (make_image): Remove sh module, which has - been merged back into normal. - -2010-06-11 Colin Watson - - * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... - (GRUB_EFI_UGA_BLT_MAX): ... this (typo fix). - -2010-06-11 Colin Watson - - * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m - when generating manual pages. - * docs/man/grub-bin2h.h2m: New file. - * docs/man/grub-editenv.h2m: New file. - * docs/man/grub-fstest.h2m: New file. - * docs/man/grub-install.h2m: New file. - * docs/man/grub-macho2img.h2m: New file. - * docs/man/grub-mkconfig.h2m: New file. - * docs/man/grub-mkdevicemap.h2m: New file. - * docs/man/grub-mkfont.h2m: New file. - * docs/man/grub-mkimage.h2m: New file. - * docs/man/grub-mkpasswd-pbkdf2.h2m: New file. - * docs/man/grub-mkrelpath.h2m: New file. - * docs/man/grub-mkrescue.h2m: New file. - * docs/man/grub-ofpathname.h2m: New file. - * docs/man/grub-pe2elf.h2m: New file. - * docs/man/grub-probe.h2m: New file. - * docs/man/grub-reboot.h2m: New file. - * docs/man/grub-script-check.h2m: New file. - * docs/man/grub-set-default.h2m: New file. - * docs/man/grub-setup.h2m: New file. - -2010-06-10 Vladimir Serbinenko - - Use FOR_* macros instead of *_iterate whenever possible. - - * commands/handler.c: Removed. - * commands/help.c (grub_cmd_help): Use FOR_COMMANDS. - * commands/minicmd.c (grub_mini_cmd_lsmod): Use FOR_DL_MODULES. - * conf/any-emu.rmk (kernel_img_SOURCES): Remove kern/handler.c. - * conf/common.rmk (script/lexer.c_DEPENDENCIES): Add grub_script.yy.h. - (grub_probe_SOURCES): Remove kern/parser.c. - (util/grub-script-check.c_DEPENDENCIES): Removed. - (grub_script_check_SOURCES): Remove kern/handler.c, kern/parser.c - and grub_script_check_init.c. - (grub_script_check_init.lst): Removed. - (grub_script_check_init.h): Likewise. - (grub_script_check_init.c): Likewise. - (pkglib_MODULES): Remove handler.mod and sh.mod. - (handler_mod_SOURCES): Removed. - (handler_mod_CFLAGS): Likewise. - (handler_mod_LDFLAGS): Likewise. - (normal_mod_SOURCES): Remove normal/handler.c. - Add script/main.c, script/script.c, script/execute.c, - script/function.c, script/lexer.c, grub_script.tab.c - and grub_script.yy.c. - * conf/i386-coreboot.rmk (kernel_img_SOURCES): Remove kern/handler.c. - * conf/i386-ieee1275.rmk (kernel_img_SOURCES): Likewise. - * conf/i386-pc.rmk (kernel_img_SOURCES): Likewise. - (grub_setup_SOURCES): Remove kern/parser.c. - * conf/i386-qemu.rmk (kernel_img_SOURCES): Remove kern/handler.c. - * conf/mips-qemu-mips.rmk (kernel_img_SOURCES): Likewise. - * conf/mips-yeeloong.rmk (kernel_img_SOURCES): Likewise. - * conf/powerpc-ieee1275.rmk (kernel_img_SOURCES): Likewise. - * conf/sparc64-ieee1275.rmk (kernel_img_SOURCES): Likewise. - (grub_setup_SOURCES): Remove kern/parser.c. - * conf/x86-efi.rmk (kernel_img_SOURCES): Remove kern/handler.c. - * gettext/gettext.c (grub_gettext_delete_list): Don't use grub_list_pop. - * include/grub/command.h (grub_command_iterate): Removed. - (FOR_COMMANDS): New macro. - * include/grub/dl.h (grub_dl): New member next. - (grub_dl_iterate): Removed. - (grub_dl_head): New variable declaration. - (FOR_DL_MODULES): New macro. - * include/grub/fs.h: Include list.h. - (grub_fs): Make next first element. - (grub_fs_list): New variable declaration. - (grub_fs_register): Make inline. - (grub_fs_unregister): Likewise. - (grub_fs_iterate): Removed. - (FOR_FILESYSTEMS): New macro. - * include/grub/handler.h: Removed. - * include/grub/list.h (grub_list_hook_t): Removed. - (grub_list_test_t): Likewise. - (grub_list_pop): Likewise. - (grub_list_iterate): Likewise. - (grub_list_insert): Likewise. - (FOR_LIST_ELEMENTS): New macro. - * include/grub/parser.h (grub_parser_class): Removed. - (grub_parser_register): Likewise. - (grub_parser_unregister): Likewise. - (grub_parser_get_current): Likewise. - (grub_parser_set_current): Likewise. - (grub_register_rescue_parser): Likewise. - (grub_rescue_parse_line): New function. - * include/grub/partition.h (FOR_PARTITION_MAPS): Use FOR_LIST_ELEMENTS. - * include/grub/script_sh.h (grub_script_function_list): New variable - declaration. - (FOR_SCRIPT_FUNCTIONS): New macro. - (grub_script_function_iterate): Removed. - (grub_normal_parse_line): New prototype. - * include/grub/term.h (FOR_ACTIVE_TERM_INPUTS): Use FOR_LIST_ELEMENTS. - (FOR_DISABLED_TERM_INPUTS): Likewise. - (FOR_ACTIVE_TERM_OUTPUTS): Likewise. - (FOR_DISABLED_TERM_OUTPUTS): Likewise. - * include/grub/video.h (grub_video_adapter): Move 'next' to first - element. - (grub_video_register): Inline. - (grub_video_unregister): Likewise. - (grub_video_adapter_list): New variable declaration. - (grub_video_iterate): Removed. - (FOR_VIDEO_ADAPTERS): New macro. - * kern/dl.c (grub_dl_list): Removed. All users updated. - (grub_dl_iterate): Removed. - * kern/fs.c (grub_fs_list): Make global. - (grub_fs_register): Removed. - (grub_fs_unregister): Likewise. - (grub_fs_iterate): Likewise. - * kern/handler.c: Removed. - * kern/list.c (grub_list_pop): Removed. - (grub_list_iterate): Likewise. - (grub_list_insert): Likewise. - (grub_named_list_find): Use FOR_LIST_ELEMENTS. - (grub_prio_list_insert): Don't use grub_list_insert. - * kern/main.c (grub_register_rescue_parser): Don't call - grub_register_rescue_parser. - * kern/parser.c (grub_parser_class): Removed. - (grub_parser_execute): Use grub_rescue_parse_line. - * kern/rescue_parser.c (grub_rescue_parse_line): Make global. - (grub_rescue_parser): Removed. - (grub_register_rescue_parser): Likewise. - * kern/rescue_reader.c (grub_rescue_run): Use grub_rescue_parse_line. - * normal/auth.c (is_authenticated): Use FOR_LIST_ELEMENTS. - (grub_auth_check_authentication): Likewise. - * normal/completion.c (iterate_command): Removed. - (grub_normal_do_completion): Use FOR_COMMANDS. - * normal/handler.c: Removed. - * normal/main.c (read_config_file): Remove parser changing. - (grub_normal_execute): Don't call read_handler_list. - (grub_normal_read_line_real): Statically allocate prompt. - (grub_cmdline_run): Use grub_normal_parse_line. - (GRUB_MOD_FINI): Don't call free_handler_list. - * normal/menu_entry.c (run): Likewise. - * script/function.c (grub_script_function_list): Make global. - (grub_script_function_iterate): Removed. - * script/main.c (grub_normal_parse_line): Make global. - (grub_sh_parser): Removed. - (GRUB_MOD_INIT): Likewise. - (GRUB_MOD_FINI): Likewise. - * tests/lib/functional_test.c (grub_functional_test): Use - FOR_LIST_ELEMENTS. - * tests/lib/test.c (free_failures): Don't use grub_list_pop. - (grub_test_run): Use FOR_LIST_ELEMENTS. - * tests/lib/unit_test.c (main): Likewise. - * util/deviceiter.c (grub_util_iterate_devices): Don't use - grub_list_pop. - * util/grub-fstest.c (grub_term_input_class): Removed. - (grub_term_output_class): Likewise. - * util/grub-probe.c: Likewise. - * util/i386/pc/grub-setup.c: Likewise. - * util/sparc64/ieee1275/grub-setup.c: Likewise. - * util/grub-script-check.c (main): Don't call grub_init_all and - grub_fini_all. - * video/video.c (grub_video_adapter_list): Make global. - (grub_video_register): Removed. - (grub_video_unregister): Likewise. - (grub_video_iterate): Likewise. - -2010-06-09 Vladimir Serbinenko - - * docs/grub.texi (Vendor power-on button): Add Asus EeePC 1005PE as - reported by Henrique Ferreiro. - -2010-06-09 Robert Millan - - * util/grub.d/10_linux.in: Prefer compressed images over non-compressed - ones, when both are available. - -2010-06-08 Grégoire Sutre - - Make --version uniform and avoid hard-coded program name. - - * util/grub-mkimage.c (main): Use `program_name' instead of - hard-coded string. - * util/i386/pc/grub-setup.c (main): Likewise. - * util/sparc64/ieee1275/grub-setup.c (parse_options): Likewise. - * util/grub-install.in: Save the basename of $0 in $self, and use the - latter in informational messages. Use the same format for --version - as the binary programs. - * util/grub-mkconfig.in: Likewise. - * util/grub-mkrescue.in: Likewise. - * util/grub-reboot.in: Likewise. - * util/grub-set-default.in: Likewise. - * util/i386/efi/grub-install.in: Likewise. - * util/ieee1275/grub-install.in: Likewise. - * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. - -2010-06-08 Grégoire Sutre - - * util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of - embedding area. Use <= instead of == when checking for non-emptiness. - -2010-06-08 Grégoire Sutre - - * configure.ac: Add `.' to the directories searched for unifont. - -2010-06-08 Colin Watson - - * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and - grub_script.yy.h. - -2010-06-08 Colin Watson - - * docs/grub.texi (History): Expand to cover GRUB 2. - (Serial terminal): Refer to `terminal_input' and `terminal_output' - commands, not `terminal'. - (serial): Likewise. - (terminal_input): New section. - (terminal_output): New section. - (uppermem): New section (stub). - (Obtaining and Building GRUB): Refer to Bazaar, not Subversion. - -2010-06-08 Colin Watson - - * docs/grub.texi (Security): Menu entries are unrestricted by - default, not restricted to superusers as I had previously thought. - Reword to account for this. - -2010-06-07 Colin Watson - - * kern/emu/misc.c (device_mapper_null_log): New function. - (grub_device_mapper_supported): New function. - * include/grub/emu/misc.h (grub_device_mapper_supported): Add - prototype. - * kern/emu/hostdisk.c (find_partition_start): Check whether - device-mapper is supported before trying to use it. - * util/deviceiter.c (grub_util_iterate_devices): Likewise. - -2010-06-07 Colin Watson - - * docs/grub.texi (Naming convention): Use GRUB 2 syntax. - (File name syntax): Likewise. - (help): --all is no longer supported in GRUB 2. Be more precise - about pattern matching. - -2010-06-07 Colin Watson - - * normal/completion.c (grub_normal_do_completion): When completing - arguments to "set" and the current word contains an equals sign, - skip to after the equals sign before starting completion. - -2010-06-07 Colin Watson - - * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. - -2010-06-07 Colin Watson - - * docs/grub.texi (Network): New section. - (Device syntax): The network device is called `(pxe)' in GRUB 2, not - `(nd)' as in GRUB Legacy. - (pxe_unload): New section. - -2010-06-07 Colin Watson - - * docs/grub.texi (Troubleshooting): `echo' is not usually available - in the rescue shell, so recommend using `set' instead. Thanks, - Jordan Uggla. - -2010-06-07 Colin Watson - - * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. - (password): New section. - (password_pbkdf2): New section. - (search): New section. - (Security): New section. - (Troubleshooting): New section, currently very incomplete. - (Invoking grub-mkpasswd-pbkdf2): New section. - (Internals): New section, currently very incomplete. - -2010-06-07 Colin Watson - - * util/grub.d/00_header.in: Add some more quoting (of - "${prev_saved_entry}" and "${boot_once}") needed to make savedefault - work again. - Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812). - -2010-06-07 Colin Watson - - * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable - to `count', fixing variable shadowing that broke the -c option. - -2010-06-05 Colin Watson - - * util/grub.d/00_header.in: Quote values assigned to `saved_entry', - in case they contain spaces. - -2010-06-04 Colin Watson - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend - "part_" to partmap module names, in line with grub-install. - Reported by: Jindřich Makovička (Debian bug #584426). - -2010-06-04 Colin Watson - - * util/grub-mkimage.c: Make target-related error messages slightly - more helpful; -O talks about "format". Explicitly point to the use - of -O if no target is specified. - Reported by: Didier Raboud (Debian bug #584415). - -2010-06-03 Colin Watson - - * INSTALL: Document several build requirements for optional features - (libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont). - -2010-06-02 Grégoire Sutre - - * kern/emu/hostdisk.c (convert_system_partition_to_system_disk) - [__NetBSD__]: Handle all device names matching /dev/r[a-z]+[0-9][a-z]. - (find_partition_start) [__NetBSD__]: Correct error messages for NetBSD. - -2010-06-02 Colin Watson - - * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. - Thanks to Jordan Uggla for spotting this. - -2010-06-02 Aleš Nesrsta - - Finally make USB usable. - - * bus/usb/ohci.c (grub_ohci_reg_t): Add missing values. - (GRUB_OHCI_RHUB_PORT_POWER_MASK): New macro. - (GRUB_OHCI_RHUB_PORT_ALL_POWERED): Likewise. - (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK): Likewise. - (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT): Likewise. - (GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT): Likewise. - (GRUB_OHCI_FSMPS): Likewise. - (GRUB_OHCI_PERIODIC_START): Likewise. - (GRUB_OHCI_FRAME_INTERVAL): Likewise. - (GRUB_OHCI_SET_PORT_ENABLE): Likewise. - (GRUB_OHCI_CLEAR_PORT_ENABLE): Likewise. - (GRUB_OHCI_SET_PORT_RESET): Likewise. - (GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE): Likewise. - * bus/usb/ohci.c (grub_ohci_pci_iter): Various important fixups. - (grub_ohci_transaction): Likewise. - (grub_ohci_transfer): Improve condition detection algorithms. - Handle toggle property. Program the transactions correctly. - Improve error handling. Various important fixups. - (grub_ohci_portstatus): Put register writes in right order. - * bus/usb/uhci.c (grub_free_queue): Compute last_trans. - (grub_uhci_transfer): Don't show "failed" message on success. - * bus/usb/usb.c (grub_usb_set_configuration): Zero-fill whole "toggle" - array. - (grub_usb_device_initialize): Read first 8 bytes of descriptor to - determine its size. - * bus/usb/usbtrans.c (grub_usb_control_msg): Use descdev.maxsize0 even - before initialization is completed. Use IN direction for empty - transfers. Use last_trans and compute toggle. - * include/grub/usbtrans.h (grub_usb_transfer): New field last_trans. - (GRUB_USB_FEATURE_ENDP_HALT): Correct the value. - (GRUB_USB_FEATURE_DEV_REMOTE_WU): Likewise. - (GRUB_USB_FEATURE_TEST_MODE): Likewise. - * include/grub/usb.h (grub_usb_err_t): New value GRUB_USB_ERR_UNRECOVERABLE. - (grub_usb_device): Increase toggle to 256. - (grub_usbms_subclass_t): New values GRUB_USBMS_SUBCLASS_RBC, - GRUB_USBMS_SUBCLASS_MMC2, GRUB_USBMS_SUBCLASS_UFI and - GRUB_USBMS_SUBCLASS_SFF8070. - * include/grub/scsicmd.h (grub_scsi_test_unit_ready): New structure. - (grub_scsi_inquiry): New member page and alloc_length. - (grub_scsi_request_sense): New structure. - (grub_scsi_request_sense_data): Likewise. - (grub_scsi_read_capacity): New fields logical_block_addr, PMI and - control. - * disk/scsi.c (grub_scsi_request_sense): New function. - (grub_scsi_test_unit_ready): Likewise. - (grub_scsi_inquiry): Fill new fields. - (grub_scsi_read_capacity): Likewise. - (grub_scsi_read10): Add request sense at the end. - (grub_scsi_read12): Likewise. - (grub_scsi_write10): Likewise. - (grub_scsi_write12): Likewise. - (grub_scsi_open): Add Test Unit Ready. - * disk/usbms.c (grub_usbms_finddevs): Check configcnt. - Support additional subclasses. Con't clear halt yet. Activate the - proper config. Calculate LUNs correctly. - (grub_usbms_transfer): Various important fixups. - -2010-06-02 Vladimir Serbinenko - - * bus/pci.c (grub_pci_iterate) [GRUB_MACHINE_MIPS_YEELOONG]: Skip ghosts. - * bus/usb/ohci.c (grub_ohci_portstatus): Handle R/WC correctly. - (grub_ohci_fini_hw): New function. - (grub_ohci_restore_hw): Likewise. - (GRUB_MOD_INIT(ohci)): Register preboot hook. - (GRUB_MOD_FINI(ohci)): Shutdown OHCI. - * term/usb_keyboard.c: Remove include of grub/machine/console.h. - -2010-06-02 Vladimir Serbinenko - - Dedicated DMA allocations. - - * bus/pci.c (grub_memalign_dma32): New function - (grub_dma_free): Likewise. - (grub_dma_get_virt): Likewise. - (grub_dma_get_phys): Likewise. - * bus/usb/ohci.c (grub_ohci): New members hcca_addr and hcca_chunk. - (grub_ohci_pci_iter): Use dma32_alloc. - (grub_ohci_transfer): Likewise. - * bus/usb/usbtrans.c (grub_usb_control_msg): Likewise. - (grub_usb_bulk_readwrite): Likewise. - * include/grub/pci.h: Add declarations. - -2010-06-02 Vladimir Serbinenko - - CS5536 support. - - * bus/cs5536.c: New file. - * bus/usb/ohci.c (grub_ohci_pci_iter): Check for CS5536. - * conf/i386.rmk (pkglib_MODULES): Add cs5536.mod. - (cs5536_mod_SOURCES): New variable. - (cs5536_mod_CFLAGS): Likewise. - (cs5536_mod_LDFLAGS): Likewise. - * conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add cs5536.h and - machine/pci.h. - (kernel_img_SOURCES): Add bus/cs5536.c. - (pkglib_MODULES): Add usb.mod, usbtest.mod, ohci.mod, usbms.mod and - usb_keyboard.mod. - (usb_mod_SOURCES): New variable. - (usb_mod_CFLAGS): New variable. - (usb_mod_LDFLAGS): New variable. - (usbtest_mod_SOURCES): New variable. - (usbtest_mod_CFLAGS): New variable. - (usbtest_mod_LDFLAGS): New variable. - (ohci_mod_SOURCES): New variable. - (ohci_mod_CFLAGS): New variable. - (ohci_mod_LDFLAGS): New variable. - (usbms_mod_SOURCES): New variable. - (usbms_mod_CFLAGS): New variable. - (usbms_mod_LDFLAGS): New variable. - (usb_keyboard_mod_SOURCES): New variable. - (usb_keyboard_mod_CFLAGS): New variable. - (usb_keyboard_mod_LDFLAGS): New variable. - * include/grub/smbus.h: New file. - * include/grub/cs5536.h: New file. - -2010-06-02 Colin Watson - - * util/grub.d/00_header.in: Add safety check to make sure that - ${locale_dir} exists before trying to probe it. - -2010-06-02 Colin Watson - - * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and - per the GNU Coding Standards; this is now too obscure to be worth - documenting. - (QNX): Likewise. - (chainloader): Remove cross-reference to `SCO UnixWare'. - -2010-06-02 Colin Watson - - * docs/grub.texi (Chain-loading): New section. - (DOS/Windows): New section, borrowed from GRUB Legacy with details - adjusted for GRUB 2. - (SCO UnixWare): Likewise. - (QNX): Likewise. - (chainloader): Add reference to `Block list syntax'. - (drivemap): New section. - (parttool): New section. - -2010-06-02 Colin Watson - - * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking - the grub shell'. - (Installation): Add reference to `Making a GRUB bootable CD-ROM'. - (Installing GRUB using grub-install): Remove reference to the grub - shell; mention `grub-mkimage' and `grub-setup' instead. - (Invoking grub-install): Likewise. - (Interface): Add reference to `Menu entry editor'. - (serial): Remove `--device' option. - -2010-06-02 Colin Watson - - * docs/grub.texi (Configuration): New section, documenting - configuration file generation using grub-mkconfig. I've left a slot - for documenting the full shell scripting format but have not yet - started on writing that up. - (Invoking grub-mkconfig): New section. - -2010-06-02 Colin Watson - - * docs/grub.texi (direntry): Remove grub-terminfo reference. - (GNU GRUB manual): Likewise. - (General commands): Update description of `terminfo' for GRUB 2. - -2010-06-02 Colin Watson - - * commands/gptsync.c (grub_cmd_gptsync): Fix typos. - (GRUB_MOD_INIT): Fix capitalisation. - * docs/grub.texi (Command-line and menu entry commands): Document - gettext and gptsync commands. - -2010-06-02 Colin Watson - - * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include - kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes. - -2010-06-01 Colin Watson - - Add btrfs probing support, currently only in the single-device case. - - * kern/emu/getroot.c (find_root_device_from_mountinfo): New - function. - (grub_guess_root_device): Call find_root_device_from_mountinfo - before looking in /dev. - -2010-05-31 Vladimir Serbinenko - - * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use - GRUB_DISK_SIZE_UNKNOWN. - * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. - -2010-05-31 Jiro SEKIBA - - * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. - * fs/nilfs.c: Support 2nd super block in case 1st one is accidently - corrupted or not synced properly. - -2010-05-31 Vladimir Serbinenko - - * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. - Reported by: Seth Goldberg. - -2010-05-31 Vladimir Serbinenko - - * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect - addition of dest. - Reported by: Seth Goldberg. - -2010-05-31 Vladimir Serbinenko - - * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. - Reported by: Seth Goldberg. - -2010-05-31 Vladimir Serbinenko - - * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check - 64-bit address as signed on MIPS. - -2010-05-28 Colin Watson - - * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not - to the empty string. - -2010-05-28 BVK Chaitanya - - Fix grub-emu issues on NetBSD, with gcc 4.1.3. - - * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. - * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. - * kern/misc.c (__enable_execute_stack): Disable on - GRUB_MACHINE_EMU. - -2010-05-28 Colin Watson - - Make grub-probe work with symbolic links under /dev/mapper as well - as with real block devices. The Linux world seems to be (at best) - in transition here, and GRUB shouldn't get caught in the middle. - - * kern/emu/getroot.c (find_root_device): Follow symbolic links under - /dev/mapper. - -2010-05-27 Colin Watson - - * util/grub-script-check.c (main): Ensure defined behaviour on empty - input files (in which case exit zero). - -2010-05-27 Colin Watson - - * kern/emu/misc.c (canonicalize_file_name): realpath can still - return NULL for various reasons even if it has a maximum-length - buffer: for example, there might be a symlink loop, or the path - might exceed PATH_MAX. If this happens, return NULL. - -2010-05-27 Robert Millan - - * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert - partmap module to handle cross-partmap setups. - Reported by Orestes Mas. Gràcies! - -2010-05-27 Colin Watson - - * util/grub-mkrescue.in: Initialise override_dir rather than - assuming that it's unset or empty in the environment. - -2010-05-26 Grégoire Sutre - - * kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed - variable index into p_index to suppress a warning with -Wshadow. - -2010-05-25 BVK Chaitanya - - * INSTALL: Added flex >= 2.5.35 requirement. - -2010-05-23 Vladimir Serbinenko - - * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. - -2010-05-23 Vladimir Serbinenko - - cmostest support. - - * commands/i386/cmostest.c: New file. - * conf/i386-coreboot.rmk (pkglib_MODULES): Add cmostest.mod. - (cmostest_mod_SOURCES): New variable. - (cmostest_mod_CFLAGS): Likewise. - (cmostest_mod_LDFLAGS): Likewise. - * conf/i386-pc.rmk: Likewise. - * docs/grub.texi (Vendor power-on keys): New section. - * util/grub-mkconfig.in: export GRUB_DEFAULT_BUTTON, - GRUB_HIDDEN_TIMEOUT_BUTTON, GRUB_TIMEOUT_BUTTON - and GRUB_BUTTON_CMOS_ADDRESS. - * util/grub.d/00_header.in: Handle powering-on by separate button. - -2010-05-23 Vladimir Serbinenko - - * gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding. - Removed drawing_scrollbar argument. All users updated - Fixes #29792. - Reported by Jo Shields - -2010-05-23 Vladimir Serbinenko - - * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current - buffer since gfxterm handles double repaint. - -2010-05-23 Vladimir Serbinenko - - * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. - * term/gfxterm.c (real_scroll): Likewise. - -2010-05-21 Vladimir Serbinenko - - * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry - before calling BIOS. - -2010-05-21 Vladimir Serbinenko - - * include/grub/i18n.h: Always enable grub_gettext. - -2010-05-21 Vladimir Serbinenko - - * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old - partition naming style. - -2010-05-21 Colin Watson - - * util/grub-mkconfig.in: Fix handling of -o so that it works when - not the first option. - -2010-05-20 Colin Watson - - * util/grub-mkrelpath.c (usage): Remove excess apostrophe. - -2010-05-20 Colin Watson - - * util/misc.c: Move inclusion of to ... - * kern/emu/misc.c: ... here. Needed for canonicalize_file_name. - -2010-05-20 Grégoire Sutre - - * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]: - Fix merge error in NetBSD code. - (find_partition_start) [__NetBSD__]: Likewise. - -2010-05-19 BVK Chaitanya - - Fix grub-mkrescue usage unit testing. - - * tests/util/grub-shell.in: Use --grub-mkimage with grub-mkrescue. - -2010-05-18 Christian Franke - - * util/grub.d/10_windows.in: Use path names instead of - drive letters to prevent warning from Cygwin 1.7. - Add drivemap command to menuentry if needed. - -2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> - - * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only - gnumach and gnumach.gz. - -2010-05-18 Vladimir Serbinenko - - * include/grub/i18n.h (gettext): Inline instead of using #define. - (grub_gettext): Likewise. - (_): Likewise. - -2010-05-18 Vladimir Serbinenko - - * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with - -DGRUB_PKGLIBROOTDIR= and prepend @PACKAGE_TARNAME@. All users updated. - * util/grub-mkimage.c (image_targets): Add i386-multiboot. - (main): Add a slash after pkglibdirroot. - -2010-05-18 Vladimir Serbinenko - - * util/grub-install.in: Add missing "in" keyword. - -2010-05-18 Vladimir Serbinenko - - * util/grub-mkrescue.in: Remove -O i386-pc duplication. - Reported by: Seth Goldberg. - -2010-05-18 Vladimir Serbinenko - - * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. - -2010-05-18 Colin Watson - - * configure.ac: Check for Linux device-mapper support. - - * util/hostdisk.c (device_is_mapped): New function. - (find_partition_start): New function, partly broken out from - linux_find_partition and grub_util_biosdisk_get_grub_dev but with - device-mapper support added. - (linux_find_partition): Use find_partition_start. - (convert_system_partition_to_system_disk): Add `st' argument. - Support Linux /dev/mapper/* devices if device-mapper support is - available; only DM-RAID devices are understood at present. - (find_system_device): Add `st' argument. Pass it to - convert_system_partition_to_system_disk. - (grub_util_biosdisk_get_grub_dev): Pass stat result to - find_system_device and convert_system_partition_to_system_disk. Use - find_partition_start. - - * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, - kern/err.c, kern/list.c, kern/misc.c, and kern/emu/mm.c. - * util/deviceiter.c [__linux__]: Define MINOR. - (grub_util_iterate_devices): Add support for DM-RAID disk devices. - * util/mkdevicemap.c (grub_putchar): New function. - (grub_getkey): New function. - (grub_refresh): New function. - (main): Set debug=all if -v -v is used. - -2010-05-18 Colin Watson - - Fix build with non-GNU libcs. - - * util/misc.c (canonicalize_file_name): Move to ... - * kern/emu/misc.c (canonicalize_file_name): ... here. Needed by - grub_make_system_path_relative_to_its_root. - -2010-05-18 Colin Watson - - * util/grub-mkrescue.in: Sync up with grub-install in terms of how - we handle finding grub-mkimage. Default to finding grub-mkimage in - ${bindir} with program_transform_name applied, and provide a - --grub-mkimage option to override this. - -2010-05-17 Vladimir Serbinenko - - Remove grub-mkisofs. - - * conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs. - (grub_mkisofs_SOURCES): Removed. - (grub_mkisofs_CFLAGS): Removed. - * util/mkisofs/defaults.h: Removed. - * util/mkisofs/eltorito.c: Likewise. - * util/mkisofs/exclude.h: Likewise. - * util/mkisofs/hash.c: Likewise. - * util/mkisofs/include/: 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/msdos_partition.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. - -2010-05-17 Vladimir Serbinenko - - Unify grub-mkimage accross platforms. - - * Makefile.in (CPPFLAGS): Set GRUB_LIBDIR to $(libdir). - * conf/common.rmk (bin_UTILITIES): Removed grub-mkelfimage. - (grub_mkelfimage_SOURCES): Removed. - (util/elf/grub-mkimage.c_DEPENDENCIES): Renamed to .. - (util/grub-mkimage.c_DEPENDENCIES): .. this. - (bin_UTILITIES): Add grub-mkimage. - (grub_mkimage_SOURCES): New variable. - (kernel_img_HEADERS): Remove machine/kernel.h. - * conf/i386-pc.rmk (pkglib_IMAGES): Remove kernel.img. - (pkglib_PROGRAMS): Add kernel.img. - (kernel_img_HEADERS): Add machine/kernel.h. - (kernel_img_FORMAT): Removed. - (bin_UTILITIES): Remove grub-mkimage. - (grub_mkimage_SOURCES): Removed. - (grub_mkimage_CFLAGS): Likewise. - (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. - * conf/i386-qemu.rmk (pkglib_IMAGES): Remove kernel.img. - (pkglib_PROGRAMS): Add kernel.img. - (bin_UTILITIES): Remove grub-mkimage. - (grub_mkimage_SOURCES): Removed. - (grub_mkimage_CFLAGS): Likewise. - (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. - * conf/mips-qemu-mips.rmk (pkglib_IMAGES): Remove kernel.img. - (pkglib_PROGRAMS): Add kernel.img. - * conf/mips-yeeloong.rmk (pkglib_IMAGES): Remove kernel.img. - (pkglib_PROGRAMS): Add kernel.img. - * conf/mips.rmk (bin_UTILITIES): Remove grub-mkimage. - (grub_mkimage_SOURCES): Removed. - (grub_mkimage_CFLAGS): Likewise. - (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. - * conf/sparc64-ieee1275.rmk (pkglib_IMAGES): Remove kernel.img. - (pkglib_PROGRAMS): Add kernel.img. - (bin_UTILITIES): Remove grub-mkimage. - (grub_mkimage_SOURCES): Removed. - (grub_mkimage_CFLAGS): Likewise. - (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. - * conf/x86-efi.rmk (bin_UTILITIES): Remove grub-mkimage. - (grub_mkimage_SOURCES): Removed. - (grub_mkimage_CFLAGS): Likewise. - (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. - * configure.ac (machine_CFLAGS): Add "-DMACHINE". - * include/grub/efi/pe32.h (grub_pe32_optional_header): Split into ... - (grub_pe32_optional_header): ... this. - (grub_pe64_optional_header): ... and this. All users updated. - (GRUB_PE32_PE32_MAGIC): Split into .. - (GRUB_PE32_PE32_MAGIC): .. this. - (GRUB_PE32_PE64_MAGIC): .. and this. - (GRUB_PE32_SIGNATURE_SIZE): New definition. - * include/grub/elf.h (PT_GNU_STACK): New definition. - * include/grub/i386/coreboot/kernel.h: Merged into include/grub/offsets.h. All users updated. - * include/grub/i386/efi/kernel.h: Likewise. - * include/grub/i386/kernel.h: Likewise. - * include/grub/i386/pc/kernel.h: Likewise. - * include/grub/i386/qemu/boot.h: Likewise. - * include/grub/mips/kernel.h: Likewise. - * include/grub/mips/qemu-mips/kernel.h: Likewise. - * include/grub/powerpc/ieee1275/kernel.h: Likewise. - * include/grub/powerpc/kernel.h: Likewise. - * include/grub/sparc64/ieee1275/boot.h: Likewise. - * include/grub/sparc64/ieee1275/kernel.h: Likewise. - * include/grub/sparc64/kernel.h: Likewise. - * include/grub/x86_64/efi/kernel.h: Likewise. - * include/grub/x86_64/kernel.h: Likewise. - * include/grub/offsets.h: New file. - * include/grub/kernel.h (grub_module_info): Split into ... - (grub_module_info32): ... this. - (grub_module_info64): ... and this. - * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_KERNEL_SEG): Moved from here ... - * include/grub/offsets.h (GRUB_BOOT_I386_PC_KERNEL_SEG): ... here. - (grub_boot_blocklist): Moved from here ... - * include/grub/offsets.h (grub_pc_bios_boot_blocklist): ... here. - * include/grub/i386/pc/memory.h (GRUB_MEMORY_MACHINE_UPPER): Moved from here. - * include/grub/offsets.h (GRUB_MEMORY_I386_PC_UPPER): .. here. - * include/grub/types.h (grub_target_to_host16): Removed. - (grub_target_to_host32): Likewise. - (grub_target_to_host64): Likewise. - (grub_host_to_target16): Likewise. - (grub_host_to_target32): Likewise. - (grub_host_to_target64): Likewise. - (grub_host_to_target_addr): Likewise. - - Support grub-mkrescue for efi, coreboot and qemu. - - * conf/x86-efi.rmk (bin_SCRIPTS): Add grub-mkrescue. - * kern/efi/init.c (grub_efi_set_prefix): Handle baked in prefix. - * util/elf/grub-mkimage.c: Merged into util/grub-mkimage.c. - * util/grub-mkrawimage.c: Moved from here ... - * util/grub-mkimage.c: ... here. All users updated. - (ALIGN_ADDR): Use image_target. - (TARGET_NO_FIELD): New const. - (image_target_desc): New type. - (image_targets): New array. - (grub_target_to_host64): Use image_target. - (grub_target_to_host32): Likewise. - (grub_target_to_host16): Likewise. - (grub_host_to_target64): Likewise. - (grub_host_to_target32): Likewise. - (grub_host_to_target16): Likewise. - (grub_host_to_target_addr): Likewise. - (generate_image): Handle multiimage. - (main): Require -O parameter. All users updated. - * util/grub-mkimagexx.c: New file. Based on util/grub-mkrawimage.c and - util/efi/grub-mkimage.c - * util/grub-mkrescue.in: Handle coreboot, efi and qemu. - New option --rom-directory. - Use xorriso. - * util/i386/efi/grub-mkimage.c: Removed. - * util/i386/pc/grub-setup.c (grub_target_to_host16): New definition. - (grub_target_to_host32): Likewise. - (grub_target_to_host64): Likewise. - (grub_host_to_target16): Likewise. - (grub_host_to_target32): Likewise. - (grub_host_to_target64): Likewise. - * util/sparc64/ieee1275/grub-setup.c (grub_target_to_host16): New definition. - (grub_target_to_host32): Likewise. - (grub_target_to_host64): Likewise. - (grub_host_to_target16): Likewise. - (grub_host_to_target32): Likewise. - (grub_host_to_target64): Likewise. - -2010-05-17 BVK Chaitanya - - Source tree is reorganized for emu build. - - * include/grub/util/console.h: Move from here... - * include/grub/emu/console.h: ...to here. - * include/grub/util/getroot.h: Move from here... - * include/grub/emu/getroot.h: ...to here. - * include/grub/util/hostdisk.h: Move from here... - * include/grub/emu/hostdisk.h: ...to here. - * util/console.c: Move from here... - * kern/emu/console.c: ...to here. - * util/getroot.c: Move from here... - * kern/emu/getroot.c: ...to here. - * util/grub-emu.c: Move from here... - * kern/emu/main.c: ...to here. - * util/hostdisk.c: Move from here... - * kern/emu/hostdisk.c: ...to here. - * util/hostfs.c: Move from here... - * kern/emu/hostfs.c: ...to here. - * util/mm.c: Move from here... - * kern/emu/mm.c: ...to here. - * util/pci.c: Move from here... - * bus/emu/pci.c: ...to here. - * util/sdl.c: Move from here... - * video/emu/sdl.c: ...to here. - * util/time.c: Move from here... - * kern/emu/time.c: ...to here. - * util/usb.c: Move from here... - * bus/usb/emu/usb.c: ...to here. - - * include/grub/emu/misc.h: New header for grub-emu functions. - * kern/emu/misc.c: grub-emu functions separated from util/misc.c - - * conf/any-emu.rmk: Rule updates for above renames. - * conf/common.rmk: Likewise. - * conf/i386-pc.rmk: Likewise. - * conf/i386-qemu.rmk: Likewise. - * conf/mips.rmk: Likewise. - * conf/sparc64-ieee1275.rmk: Likewise. - * conf/x86-efi.rmk: Likewise. - - * disk/lvm.h: #include updates for above renames. - * util/grub-mkrelpath.c: Likewise. - * util/grub-probe.c: Likewise. - * util/i386/pc/grub-setup.c: Likewise. - * util/sparc64/ieee1275/grub-setup.c: Likewise. - * kern/emu/console.c: Likewise. - * kern/emu/getroot.c: Likewise. - * kern/emu/hostdisk.c: Likewise. - * kern/emu/main.c: Likewise. (was grub-emu.c earlier) - - * include/grub/dl.h: Remove grub_dl_{ref,unref}. - * include/grub/util/misc.h: Move grub-emu functions to emu/misc.h. - * kern/dl.c: Handle null mod in grub_dl_{ref,unref}. - * util/misc.c: Remove grub-emu functions. - -2010-05-13 Vladimir Serbinenko - - Fix gfxmenu crash. - Reported by: Thorsten Grützmacher. - - * gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister - timeout hook. - (circprog_set_property): Register and unregister timeout hook. - * gfxmenu/gui_label.c (grub_gui_label): New fields template and value. - (label_destroy): Free template. and unregister hook. - (label_set_state): New function. - (label_set_property): Handle templates and hooks. - * gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister - timeout hook. - (progress_bar_set_property): Register and unregister timeout hook. - * gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ... - * include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here - * gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable. - (update_timeout_visit): Removed. - (update_timeouts): New function. - (redraw_timeouts): Likewise. - (grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts. - (grub_gfxmenu_clear_timeout): Likewise. - * include/grub/gui.h (grub_gfxmenu_set_state_t): New type. - (grub_gfxmenu_timeout_notify): Likewise. - (grub_gfxmenu_timeout_notifications): New external variable. - (grub_gfxmenu_timeout_register): New function. - (grub_gfxmenu_timeout_unregister): Likewise. - -2010-05-09 Vladimir Serbinenko - - Transform (broken) vga terminal into (working) vga video driver. - - * conf/i386-pc.rmk (vga_mod_SOURCES): Change term/i386/pc/vga.c to - video/i386/pc/vga.c. - * include/grub/video.h (grub_video_driver_id): - Add GRUB_VIDEO_DRIVER_VGA. - * term/i386/pc/vga.c: Renamed to ... - * video/i386/pc/vga.c: ...this - (DEBUG_VGA): Removed. - (CHAR_WIDTH): Likewise. - (CHAR_HEIGHT): Likewise. - (TEXT_WIDTH): Likewise. - (TEXT_HEIGHT): Likewise. - (DEFAULT_FG_COLOR): Likewise. - (DEFAULT_BG_COLOR): Likewise. - (colored_char): Likewise. - (xpos): Likewise. - (ypos): Likewise. - (cursor_state): Likewise. - (fg_color): Likewise. - (bg_color): Likewise. - (text_buf): Likewise. - (page): Likewise. - (font): Likewise. - (framebuffer): New variable. - (set_read_map): Disabled. - (setup): New variable. - (is_target): Likewise. - (grub_vga_mod_init): Likewise. - (grub_vga_mod_fini): Likewise. - (check_vga_mem): Likewise. - (write_char): Likewise. - (write_cursor): Likewise. - (scroll_up): Likewise. - (grub_vga_putchar): Likewise. - (grub_vga_getcharwidth): Likewise. - (grub_vga_getwh): Likewise. - (grub_vga_getxy): Likewise. - (grub_vga_gotoxy): Likewise. - (grub_vga_cls): Likewise. - (grub_vga_setcolorstate): Likewise. - (grub_vga_setcursor): Likewise. - (grub_video_vga_init): New function. - (grub_video_vga_setup): Likewise. - (grub_video_vga_fini): Likewise. - (update_target): Likewise. - (grub_video_vga_blit_bitmap): Likewise. - (grub_video_vga_blit_render_target): Likewise. - (grub_video_vga_set_active_render_target): Likewise. - (grub_video_vga_get_active_render_target): Likewise. - (grub_video_vga_swap_buffers): Likewise. - (grub_video_vga_set_palette): Likewise. - (grub_video_vga_get_info_and_fini): Likewise. - (grub_vga_term): Removed. - (grub_video_vga_adapter): New variable. - (GRUB_MOD_INIT): Register a video driver instead of terminal. - (GRUB_MOD_FINI): Unrefister a video driver instead of terminal. - -2010-05-05 Vladimir Serbinenko - - * video/readers/jpeg.c: Indented. - -2010-05-05 Vladimir Serbinenko - - Various jpeg cleanups. - - * video/readers/jpeg.c (grub_jpeg_get_huff_code): Use ARRAY_SIZE. - (grub_jpeg_decode_quan_table): Use sizeof. - (grub_jpeg_decode_du): Use ARRAY_SIZE. - -2010-05-05 Peter Hurley (tiny change) - - * video/readers/jpeg.c (grub_jpeg_decode_huff_table): Loop over all - tables. Ignore non-last ac bit. - (grub_jpeg_decode_quan_table): Likewise. - -2010-05-05 Vladimir Serbinenko - - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New value - GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM. - * kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set - GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM on qemu. - * kern/ieee1275/init.c (grub_claim_heap): Don0t allocate below - 1.5MiB if GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM is set. - -2010-05-05 Vladimir Serbinenko - - * term/ieee1275/ofconsole.c (grub_ofconsole_getkey): Fix off-by-one - error. - -2010-05-05 Vladimir Serbinenko - - * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Support C0 code. - -2010-05-03 Vladimir Serbinenko - - * commands/parttool.c (grub_cmd_parttool): Fix #if !GRUB_NO_MODULES - condition. - -2010-05-03 Vladimir Serbinenko - - * kern/mm.c (grub_real_malloc): Put magic and size assignment in common - part. - -2010-05-03 Vladimir Serbinenko - - * kern/mm.c (grub_mm_init_region): Check for region size after aligning - pointers. - -2010-05-03 Vladimir Serbinenko - - * kern/mm.c (grub_real_malloc): Fix size calculation when extra == 0. - -2010-05-01 Christian Franke - - * util/grub-mkconfig_lib.in (make_system_path_relative_to_its_root): - Remove broken Cygwin path conversion. - * util/misc.c: [__CYGWIN__] Add include and define. - [__CYGWIN__] (get_win32_path): Copy function from getroot.c, modify - for Cygwin 1.7. - (make_system_path_relative_to_its_root): Simplify loop, replace early - return by break. - [__CYGWIN__] Add conversion to win32 path. - Include "/" case in trailing slash removal. - -2010-05-01 Vladimir Serbinenko - - * kern/main.c (grub_load_config): Fix copy-pasted comment. - Reported by: Seth Goldberg - -2010-05-01 Vladimir Serbinenko - - * commands/help.c (grub_cmd_help): Fix a typo. - Reported by: Seth Goldberg - -2010-05-01 Vladimir Serbinenko - - * commands/hashsum.c (GRUB_MOD_INIT): Remove duplication of command - name and add N_. - * commands/i386/pc/drivemap.c (GRUB_MOD_INIT): Likewise. - * commands/iorw.c (GRUB_MOD_INIT): Likewise. - * commands/password_pbkdf2.c (GRUB_MOD_INIT): Likewise. - * commands/regexp.c (GRUB_MOD_INIT): Likewise. - * commands/setpci.c (GRUB_MOD_INIT): Likewise. - * commands/terminal.c (GRUB_MOD_INIT): Likewise. - * efiemu/main.c (GRUB_MOD_INIT): Likewise. - * font/font_cmd.c (GRUB_MOD_INIT): Likewise. - * kern/corecmd.c (GRUB_MOD_INIT): Likewise. - * mmap/mmap.c (GRUB_MOD_INIT): Likewise. - * normal/context.c (GRUB_MOD_INIT): Likewise. - * normal/main.c (GRUB_MOD_INIT): Likewise. - * term/gfxterm.c (GRUB_MOD_INIT): Likewise. - * term/serial.c (GRUB_MOD_INIT): Likewise. - * term/terminfo.c (GRUB_MOD_INIT): Likewise. - -2010-05-01 Vladimir Serbinenko - - * kern/mm.c (grub_real_malloc): Satisfy alignment requirement when - extra == 0. - -2010-05-01 Vladimir Serbinenko - - * commands/iorw.c: New file. - * conf/i386.rmk (pkglib_MODULES): Add iorw.mod. - (iorw_mod_SOURCES): New variable. - (iorw_mod_CFLAGS): Likewise. - (iorw_mod_LDFLAGS): Likewise. - -2010-05-01 Vladimir Serbinenko - - Hotkey support - - * include/grub/menu.h (grub_menu_entry): New field 'hotkey'. - * normal/main.c (hotkey_aliases): New variable. - (grub_normal_add_menu_entry): Parse "--hotkey". - * normal/menu_text.c (run_menu): Handle hotkeys. - -2010-05-01 Vladimir Serbinenko - - * kern/i386/coreboot/init.c (grub_machine_init): Call - grub_machine_mmap_init on qemu. - -2010-05-01 Vladimir Serbinenko - - * boot/i386/qemu/boot.S: Add a missing .code16. - -2010-05-01 Vladimir Serbinenko - - Use LBIO on coreboot. - - * conf/i386-coreboot.rmk (kernel_img_SOURCES): Change - kern/i386/multiboot_mmap.c to kern/i386/coreboot/mmap.c. - * include/grub/i386/coreboot/memory.h (GRUB_LINUXBIOS_MEMBER_LINK): - New declaration. - * kern/i386/coreboot/init.c (grub_machine_init): Don't call - grub_machine_mmap_init on coreboot. - * kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate): Handle - GRUB_LINUXBIOS_MEMBER_LINK. - (grub_machine_mmap_iterate): Fix declaration. - * kern/i386/coreboot/startup.S: Don't save mbi location on coreboot. - -2010-05-01 Vladimir Serbinenko - - Split coreboot and multiboot ports. - - * conf/i386-multiboot.rmk: New file. - * configure.ac: Add multiboot port. - * include/grub/i386/multiboot/boot.h: New file. - * include/grub/i386/multiboot/console.h: Likewise. - * include/grub/i386/multiboot/init.h: Likewise. - * include/grub/i386/multiboot/kernel.h: Likewise. - * include/grub/i386/multiboot/loader.h: Likewise. - * include/grub/i386/multiboot/memory.h: Likewise. - * include/grub/i386/multiboot/serial.h: Likewise. - * include/grub/i386/multiboot/time.h: Likewise. - * include/grub/multiboot.h: Add GRUB_MACHINE_MULTIBOOT to ifdef. - * loader/multiboot.c: Likewise. - * loader/multiboot_mbi2.c: Likewise. - * util/grub-mkrescue.in: Generate multiboot rescue. - -2010-05-01 Vladimir Serbinenko - - * kern/parser.c (grub_parser_execute): Cope with read-only config. - -2010-05-01 Vladimir Serbinenko - - Merge handling of input and output terminals. Fix a hang. - - * commands/terminal.c (abstract_terminal): New struct. - (handle_command): New function. Based on grub_cmd_terminal_input. - (grub_cmd_terminal_input): Use handle_command. - (grub_cmd_terminal_output): Use handle_command. - -2010-05-01 BVK Chaitanya - - Fix comment handling. - - * tests/grub_script_comments.in: New testcase. - * conf/tests.rmk: Rules for new testcase. - * script/yylex.l: Updated flex rules. - -2010-04-28 Samuel Thibault - - * docs/grub.texi (play): Document that zero pitches produce rests. - * commands/i386/pc/play.c (grub_cmd_play): Call 'grub_file_open' only - if argc is 1. - -2010-04-27 Vladimir Serbinenko - - * conf/x86-efi.rmk (linux_mod_SOURCES): Write explicitly to avoid - autogen issues. - -2010-04-26 Christian Franke - - * include/grub/util/getroot.h (grub_get_prefix): Remove prototype. - * util/getroot.c [__CYGWIN__] (get_win32_path): Remove function. - (grub_get_prefix): Remove function. - * util/grub-emu.c (main): Replace grub_get_prefix () call by - make_system_path_relative_to_its_root (). - * util/sparc64/ieee1275/grub-setup.c (main): Likewise. - -2010-04-24 Christian Franke - - * Makefile.in (TARGET_LDFLAGS): Add -static-libgcc. - (kernel_img_LDFLAGS): Remove -static-libgcc. - -2010-04-24 Christian Franke - - * configure.ac: Do not CHECK_BSS_START_SYMBOL - and CHECK_END_SYMBOL if grub-emu is built. - Unset TARGET_OBJ2ELF if grub-emu is built - without module support. - -2010-04-24 Jiro SEKIBA - - Nilfs2 support. - - * conf/common.rmk (grub_probe_SOURCES): Add fs/nilfs2.c. - (grub_fstest_SOURCES): Likewise. - (pkglib_MODULES): Add nilfs2.mod. - (nilfs2_mod_SOURCES): New variable. - (nilfs2_mod_CFLAGS): Likewise. - (nilfs2_mod_LDFLAGS): Likewise. - * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. - * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. - * fs/nilfs2.c: New file. - -2010-04-21 Vladimir Serbinenko - - * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large - is not supported. - -2010-04-19 Grégoire Sutre - - Add grub-mkconfig support for NetBSD. - - * util/grub.d/10_netbsd.in: grub-mkconfig helper script for NetBSD. - * util/grub-mkconfig.in: export new NetBSD specific variables. - * po/POTFILES-shell: added 10_netbsd.in. - * util/grub-mkconfig_lib.in: check for gettext binary, default to echo. - -2010-04-19 BVK Chaitanya - - Fix emu build with grub-emu-pci and grub-emu-modules. - - * include/grub/util/misc.h: Export grub_util_{info,error,warn} - functions. - * include/grub/libpciaccess.h: New file. - * conf/any-emu.rmk: Update kernel headers for emu build. - -2010-04-19 Vladimir Serbinenko - - * fs/udf.c (grub_udf_iterate_dir): Silence a spurious warning. - -2010-04-19 Vladimir Serbinenko - - * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. - -2010-04-18 Vladimir Serbinenko - - * boot/sparc64/ieee1275/boot.S: Various size-reducing changes. - Retrieve chosen/bootpath if bootpath isn't hardcoded. - * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add - util/ieee1275/ofpath.c. - * util/sparc64/ieee1275/grub-ofpathname.c: Renamed to ... - * util/ieee1275/grub-ofpathname.c: ... this. All users updated - * include/grub/sparc64/ieee1275/boot.h - (GRUB_BOOT_MACHINE_KERNEL_SECTOR): Renamed to ... - (GRUB_BOOT_MACHINE_KERNEL_BYTE): ...this. Moved 8 bytes lower. - * util/hostdisk.c (grub_util_biosdisk_get_osdev): New function. - * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath): Make argument - const char *. - * util/sparc64/ieee1275/grub-setup.c (compute_dest_ofpath): Removed. - (setup): Use KERNEL_BYTE instead of KERNEL_SECTOR. - Use grub_util_devname_to_ofpath. Zero-fill boot_devpath on same disk - install. - -2010-04-18 Grégoire Sutre - - * util/grub-mkconfig.in: Corrected two == equality tests. - Set grub_prefix as in grub-install for NetBSD and OpenBSD. - * configure.ac: All definitions and uses of TARGET_IMG_LDFLAGS_AC now - expect a number appended to it. - * acinclude.m4 (grub_PROG_OBJCOPY_ABSOLUTE): ${TARGET_IMG_LDFLAGS_AC} - expects a number appended to it. - -2010-04-18 Vladimir Serbinenko - - * po/POTFILES: Renamed multiboot_loader.c to multiboot.c - -2010-04-18 Vladimir Serbinenko - - * util/hostdisk.c (make_device_name): Change to new partition naming. - -2010-04-17 Vladimir Serbinenko - - * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. - -2010-04-17 Christian Franke - - * Makefile.in: Add missing localedir setting. - -2010-04-14 Colin Watson - - Restore TEXTDOMAINDIR correction from r1889, lost apparently by - mistake in r2156. Noticed by Anthony Fok. - - * util/grub.d/10_kfreebsd.in (TEXTDOMAINDIR): Set to lowercased - @localedir@. - * util/grub.d/10_linux.in (TEXTDOMAINDIR): Likewise. - -2010-04-14 BVK Chaitanya - - Fix a spurious, uninitialized variable warning. - - * loader/i386/bsdXX.c (grub_freebsd_load_elfmodule_obj): - Initialize variable, shdr. - (grub_freebsd_load_elfmodule): Likewise. - (grub_freebsd_load_elf_meta): Likewise. - -2010-04-13 BVK Chaitanya - - Fix for escaped dollar in double quoted strings. - - * script/yylex.l: Updated flex rules. - * conf/tests.rmk: Rule for new testcase. - * tests/grub_script_dollar.in: New testcase. - -2010-04-13 Carles Pina i Estany -2010-04-13 Colin Watson - - Enclose all translated strings in grub.cfg in single quotes, and - escape them appropriately (Ubuntu bug #552921). - - * util/grub-mkconfig_lib.in (gettext_quoted): New function. - * util/grub.d/10_hurd.in: Use it. - * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Likewise. - * util/grub.d/10_linux.in (linux_entry): Likewise. - -2010-04-11 Vladimir Serbinenko - - Fix cygwin compilation. - - * configure.ac: Define NEED_REGISTER_FRAME_INFO. - * include/grub/misc.h (__register_frame_info) - [NEED_REGISTER_FRAME_INFO && !UTIL]: New export. - (__deregister_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: Likewise. - * kern/misc.c (__register_frame_info) - [NEED_REGISTER_FRAME_INFO && !UTIL]: New empty function. - (__deregister_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: Likewise. - -2010-04-11 Vladimir Serbinenko - - * configure.ac: Respect grub_cv_asm_uscore when defining dummy symbols. - -2010-04-11 Vladimir Serbinenko - - Unify libgcc processing. - - * Makefile.in (kernel_img_LDFLAGS): New variable. - * conf/common.rmk (kernel_img_HEADERS): Add libgcc.h. - * conf/i386-coreboot.rmk (kernel_img_LDFLAGS): Append instead of - overwriting. - * conf/i386-ieee1275.rmk (kernel_img_LDFLAGS): Likewise. - * conf/i386-pc.rmk (kernel_img_LDFLAGS): Likewise. - * conf/i386-qemu.rmk (kernel_img_LDFLAGS): Likewise. - * conf/x86-efi.rmk (kernel_img_LDFLAGS): Likewise. - * conf/mips-qemu-mips.rmk (kernel_img_LDFLAGS): Append instead of - overwriting. Remove -lgcc and -static-libgcc - * conf/mips-yeeloong.rmk (kernel_img_LDFLAGS): Likewise. - * conf/mips.rmk (kernel_img_HEADERS): Remove cpu/libgcc.h - * conf/powerpc-ieee1275.rmk (kernel_img_HEADERS): Remove cpu/libgcc.h - (kernel_img_LDFLAGS): Append instead of overwriting. - Remove -lgcc and -static-libgcc - * conf/sparc64-ieee1275.rmk: Likewise. - * include/grub/powerpc/libgcc.h: Move to ... - * include/grub/libgcc.h: .. this. - * include/grub/libgcc.h: Don't export most of the function on x86. - (__bswapsi2): New export. - (__bswapdi2): Likewise. - * include/grub/mips/libgcc.h: Removed. - * include/grub/sparc64/libgcc.h: Likewise. - -2010-04-10 Vladimir Serbinenko - - * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Remove - disk_info_msg (conflicts with gettexting into languages with cases). - -2010-04-10 Grégoire Sutre - - Add grub-probe support for NetBSD. - - * util/getroot.c (find_root_device): Convert block device to - character device on NetBSD. - * util/probe.c (probe): Require character device on NetBSD. - * util/hostdisk.c: NetBSD specific headers. - (configure_device_driver): new function to tune device driver - parameters (currently only for NetBSD floppy driver). - (grub_util_biosdisk_open): NetBSD specific code (get disk size - via disklabel ioctl). - (open_device): call configure_device_driver on NetBSD. - (convert_system_partition_to_system_disk): NetBSD specific code. - (device_is_wholedisk): Likewise. - (grub_util_biosdisk_get_grub_dev): Likewise. - (make_device_name): Fixed a typo in bsd_part_str. - * configure.ac: check for opendisk() and getrawpartition() on - NetBSD and set LIBUTIL. - * Makefile.in: add LIBUTIL to LIBS. - -2010-04-10 BVK Chaitanya - - Documentation fix. - - * util/grub-script-check.c: Better help message. - -2010-04-10 BVK Chaitanya - - Fix FreeBSD build. - - * configure.ac: Flex version check. - * conf/common.rmk: Add -Wno-error to sh.mod. - * script/yylex.l: Remove all #pragma. - -2010-04-10 Vladimir Serbinenko - - * include/grub/util/misc.h (canonicalise_file_name): Add missing - prototype. - Reported by: Seth Goldberg. - -2010-04-10 Vladimir Serbinenko - - * loader/multiboot.c (GRUB_MOD_INIT) [GRUB_USE_MULTIBOOT2]: - Rename "module" to "module2". - Reported by: Seth Goldberg. - -2010-04-10 Vladimir Serbinenko - - * include/grub/efi/memory.h (grub_machine_mmap_iterate): Remove - EXPORT_FUNC. - Reported by: Seth Goldberg. - -2010-04-10 Vladimir Serbinenko - - * lib/posix_wrap/locale.h: Add missing file. - Reported by: Seth Goldberg. - -2010-04-10 Vladimir Serbinenko - - grub-emu module load support. - - * Makefile.in (TARGET_NO_MODULES): New variable. All users of - NO_DYNAMIC_MODULES switched to this. - (TARGET_CFLAGS): Add -DGRUB_TARGET_NO_MODULES=1 if applicable. - (CFLAGS): Likewise. - * conf/any-emu.rmk: Generate symlist. - (kernel_img_HEADERS): Add util/datetime.h. - (kernel_img_HEADERS) [sdl]: Add sdl.h. - (kernel_img_HEADERS) [libusb]: Add libusb.h. - (kernel_img_SOURCES) [TARGET_NO_MODULES = no && !x86]: Add - kern/$(target_cpu)/cache.S. - * configure.ac (grub-emu-modules): New option. - * genmk.rb: Handle multiple source lists. - * include/grub/sdl.h: New file. - * include/grub/libusb.h: Likewise. - * util/grub-emu.c (main): Hanle (host) root. - * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Error with - GRUB_ERR_UNKNOWN_DEVICE. - * util/misc.c: Move mm functions to ... - * util/mm.c: ... here. All users updated. - -2010-04-09 Vladimir Serbinenko - - * Makefile.in (RMKFILES): Search in srcdir and not current directory. - (MAINTAINER_CLEANFILES): Don't add $(srcdir) to MKFILES. Add few - missing files. - (maintainer-clean): Remove libgcrypt-grub. - -2010-04-09 Vladimir Serbinenko - - * term/efi/console.c (grub_console_checkkey): Macroify key contants. - -2010-04-09 EFI Coder - - * normal/menu_text.c (print_message): Clean up the message and show - the Fn information when on EFI - * term/efi/console.c (grub_console_checkkey): Add F4 support. - -2010-04-09 Vladimir Serbinenko - - * normal/autofs.c (read_fs_list): New parameter 'prefix'. - All users updated. - * normal/crypto.c (read_crypto_list): Likewise. - * normal/dyncmd.c (read_command_list): Likewise. - * normal/term.c (read_terminal_list): Likewise. - * normal/main.c (read_lists): Use explicit prefix. - (read_lists_hook): Use read_lists. - (grub_normal_execute): Likewise. - -2010-04-09 Vladimir Serbinenko - - * util/grub-mkrescue.in: Fix incorrect path in coreboot part. - Reported by: Thomas Schmitt. - Add -no-emul-boot to grub-mkisofs parameters. - -2010-04-09 Vladimir Serbinenko - - * font/font.c: Indented. - -2010-04-09 BVK Chaitanya - - Elif support to GRUB script (by Deepak Vankadaru). - - * tests/grub_script_if.in: New testcase. - * conf/tests.rmk: Rule for new testcase. - * script/parser.y: Grammar rules for elif. - -2010-04-09 BVK Chaitanya - - While and until loops support to GRUB script. - - * include/grub/script_sh.h (grub_script_cmdwhile): New struct. - (grub_script_create_cmdwhile): New function prototype. - (grub_script_execute_cmdwhile): New function prototype. - * script/execute.c (grub_script_execute_cmdwhile): New function. - * script/parser.y (command): New commands. - (whilecmd): New grammar rule. - (untilcmd): New grammar rule. - * script/script.c (grub_script_create_cmdwhile): New function. - * util/grub-script-check.c (grub_script_execute_cmdwhile): New - function. - - * tests/grub_script_while1.in: New testcase. - * conf/tests.rmk: Rule for new testcase. - -2010-04-09 Vladimir Serbinenko - - * util/grub.d/00_header.in: Add few missing quotes. Recognise *.jpeg - as *.jpg. - -2010-04-09 Mario Vazquez - - GRUB_BACKGROUND support. - - * util/grub-mkconfig.in: Export GRUB_BACKGROUND. - * util/grub.d/00_header.in: Parse GRUB_BACKGROUND. - -2010-04-09 Vladimir Serbinenko - - Load fonts and modules for gfxmenu in grub-mkconfig. - Idea by: Mario Vazquez - - * util/grub.d/00_header.in: Load pf2 and image modules. - -2010-04-09 Vladimir Serbinenko - - grub-mkconfig multiple terminal support. - - * util/grub-mkconfig.in: Handle multiple terminals correctly. - * util/grub.d/00_header.in: Likewise. - -2010-04-09 Vladimir Serbinenko - - * Makefile.in: Specify files explicitly instead of using $< and $@ since - we use cd $(srcdir). - -2010-04-08 Colin Watson - - * util/grub.d/10_linux.in: Only use the first word of - GRUB_DISTRIBUTOR for --class, to avoid problems if somebody puts - spaces in GRUB_DISTRIBUTOR. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_hurd.in: Likewise. - -2010-04-06 BVK Chaitanya - - Fix unit testing framework for Qemu 0.12. - - * tests/util/grub-shell.in: Remove -serial stdio option. - -2010-04-06 Vladimir Serbinenko - - POSIX header file wrappers. - - * lib/posix_wrap/assert.h: New file. Wrapper for its POSIX - equivalents. - * lib/posix_wrap/ctype.h: Likewise. - * lib/posix_wrap/errno.h: Likewise. - * lib/posix_wrap/langinfo.h: Likewise. - * lib/posix_wrap/limits.h: Likewise. - * lib/posix_wrap/localcharset.h: Likewise. - * lib/posix_wrap/stdint.h: Likewise. - * lib/posix_wrap/stdio.h: Likewise. - * lib/posix_wrap/stdlib.h: Likewise. - * lib/posix_wrap/string.h: Likewise. - * lib/posix_wrap/sys/types.h: Likewise. - * lib/posix_wrap/unistd.h: Likewise. - * lib/posix_wrap/wchar.h: Likewise. - * lib/posix_wrap/wctype.h: Likewise. - * conf/common.rmk (grub_script.yy.c): Remove #include elimination. - (grub_script.yy.h): Likewise. - * script/yylex.l: Remove POSIX emulation #defines. - * Makefile.in (POSIX_CFLAGS): New variable. - (GNULIB_UTIL_CFLAGS): Likewise. - - Regexp support. - - * conf/common.rmk (pkglib_MODULES): Add regexp.mod. - (regexp_mod_SOURCES): New variable. - (regexp_mod_CFLAGS): Likewise. - (regexp_mod_LDFLAGS): Likewise. - * commands/regexp.c: New file. - * gnulib/regcomp.c: New file. Imported from gnulib. - * gnulib/regex.c: Likewise. - * gnulib/regex_internal.c: Likewise. - * gnulib/regex_internal.h: Likewise. - * gnulib/regexec.c: Likewise. - * gnulib/regex.h: Likewise. - -2010-04-05 Vladimir Serbinenko - - * loader/i386/multiboot_mbi.c (grub_multiboot_load): Correctly report - unsupported video mode types. - -2010-04-05 Vladimir Serbinenko - - * kern/i386/pc/startup.S (grub_getrtsecs): Removed (dead code). - -2010-04-05 Vladimir Serbinenko - - * include/grub/i386/pc/init.h (grub_get_mmap_entry): Don't export. - * conf/i386-pc.rmk (kernel_img_HEADERS): Remove machine/init.h. - -2010-04-04 Vladimir Serbinenko - - Remove unused grub_vga_get_font. - - * kern/i386/pc/startup.S (grub_vga_get_font): Removed. - * include/grub/i386/pc/vga.h (grub_vga_get_font): Likewise. - -2010-04-03 Grégoire Sutre - - * kern/misc.c: Disable the __enable_execute_stack hack for utilities. - * include/grub/misc.h: Likewise. - -2010-04-03 Grégoire Sutre - - * util/grub-install.in: Add `|| exit 1' to all grub-probe calls - for which failure is fatal. - -2010-04-03 Grégoire Sutre - - * util/grub-install.in: Use mkdir -p to create grub directory. - * util/i386/efi/grub-install.in: Likewise. - * util/ieee1275/grub-install.in: Likewise. - -2010-04-03 Grégoire Sutre - - * Makefile.in (LEX): new variable. - -2010-04-03 Grégoire Sutre - - * util/i386/efi/grub-dumpdevtree: replaced the non-portable `==' by - `=' and added double quotes on operands of this equality test. - -2010-04-03 Vladimir Serbinenko - - * Makefile.in (uninstall): Remove a leftover debug echo. - Reported by: Grégoire Sutre - -2010-04-03 Vladimir Serbinenko - - MIPS multiboot2 support. - - * conf/mips.rmk (pkglib_MODULES): Add multiboot2.mod. - (multiboot2_mod_SOURCES): New variable. - (multiboot2_mod_CFLAGS): Likewise. - (multiboot2_mod_LDFLAGS): Likewise. - (multiboot2_mod_ASFLAGS): Likewise. - * include/grub/i386/multiboot.h (MULTIBOOT_INITIAL_STATE): New - definition. - (MULTIBOOT_ENTRY_REGISTER): Likewise. - (MULTIBOOT_MBI_REGISTER): Likewise. - (MULTIBOOT_ARCHITECTURE_CURRENT): Likewise. - (MULTIBOOT_ELF32_MACHINE): Likewise. - (MULTIBOOT_ELF64_MACHINE): Likewise. - * include/grub/mips/multiboot.h: New file. - * include/grub/video.h (grub_video_driver_id): New type - GRUB_VIDEO_DRIVER_SM712. - (grub_video_get_info_and_fini): Export. - (grub_video_get_palette): Likewise. - (grub_video_get_driver_id): Likewise. - * include/multiboot2.h: Resynced with spec. - * loader/i386/multiboot.c: Moved from here ... - * loader/multiboot.c: ... here. All users updated. - (grub_multiboot_boot): Use platform-specific macros. - * loader/i386/multiboot_elfxx.c: Moved from here ... - * loader/multiboot_elfxx.c: ... here. All users updated. - (E_MACHINE): Use MULTIBOOT_ELF32_MACHINE and MULTIBOOT_ELF64_MACHINE. - * loader/i386/multiboot_mbi2.c (grub_multiboot_load): Check arcitecture. - * video/sm712.c (grub_video_sm712_adapter): Add missing id field. - -2010-04-02 Vladimir Serbinenko - - Import gnulib argp module. - - * gnulib/argp-ba.c: New file. - * gnulib/argp-eexst.c: Likewise. - * gnulib/argp-fmtstream.c: Likewise. - * gnulib/argp-fmtstream.h: Likewise. - * gnulib/argp-fs-xinl.c: Likewise. - * gnulib/argp-help.c: Likewise. - * gnulib/argp-namefrob.h: Likewise. - * gnulib/argp-parse.c: Likewise. - * gnulib/argp-pin.c: Likewise. - * gnulib/argp-pv.c: Likewise. - * gnulib/argp-pvh.c: Likewise. - * gnulib/argp-version-etc.c: Likewise. - * gnulib/argp-version-etc.h: Likewise. - * gnulib/argp-xinl.c: Likewise. - * gnulib/argp.h: Likewise. - -2010-03-31 Vladimir Serbinenko - - * kern/device.c (grub_device_iterate): Clear errors after failed - opening device. - -2010-03-31 Vladimir Serbinenko - - * kern/ieee1275/openfw.c (grub_children_iterate): Skip device itself if - returned by firmware. - -2010-03-30 Vladimir Serbinenko - - * loader/i386/multiboot_mbi2.c (retrieve_video_parameters): Fix - compilation on coreboot and qemu - -2010-03-28 Vladimir Serbinenko - - * include/multiboot2.h: Resync with spec. - -2010-03-28 Vladimir Serbinenko - - Multiboot2 tag support - - * conf/i386.rmk (multiboot2_mod_SOURCES): Replace - loader/i386/multiboot_mbi.c with loader/i386/multiboot_mbi2.c. - Remove loader/multiboot_loader.c. - * include/grub/i386/multiboot.h (grub_multiboot_real_boot): Removed. - (grub_multiboot2_real_boot): Likewise. - * include/grub/multiboot.h (grub_multiboot_set_accepts_video): Removed. - (grub_get_multiboot_mmap_count): New proto. - (grub_fill_multiboot_mmap): Likewise. - (grub_multiboot_set_video_mode): Likewise. - (grub_multiboot_set_console): Likewise. - (grub_multiboot_load): Likewise. - (grub_multiboot_load_elf): Likewise. - (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT): New definition. - (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER): Likewise. - * include/multiboot.h: Resynced with specification. - * include/multiboot2.h: Resynced with specification. - * loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): Moved from here... - * loader/i386/multiboot.c (DEFAULT_VIDEO_MODE): ... here. - * loader/i386/multiboot_mbi.c (HAS_VGA_TEXT): Moved from here .. - * include/grub/multiboot.h (GRUB_MACHINE_HAS_VGA_TEXT): ... here. All - users updated. - * loader/i386/multiboot_mbi.c (accepts_video): Moved from here... - * loader/i386/multiboot.c (accepts_video): ... here. All users updated. - * loader/i386/multiboot_mbi.c (grub_multiboot_set_accepts_video): - Removed. - * loader/i386/multiboot_mbi.c (grub_get_multiboot_mmap_len): - Moved from here... - * loader/i386/multiboot.c (grub_get_multiboot_mmap_len): ... here. - * loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): - Moved from here... - * loader/i386/multiboot.c (grub_fill_multiboot_mmap): ... here. - * loader/i386/multiboot_mbi.c (set_video_mode): Moved from here... - * loader/i386/multiboot.c (grub_multiboot_set_video_mode): ... here. - All users updated. - * loader/i386/multiboot_mbi2.c: New file. - -2010-03-27 Vladimir Serbinenko - - Resync with gnulib. - - * Makefile.in (GNULIB_CFLAGS): New variable. - * conf/common.rmk (grub_mkisofs_CFLAGS): Add GNULIB_CFLAGS. - (grub_script_check_CFLAGS): New variable. - * gnulib/alloca.h: Resync with gnulib. - * gnulib/error.c: Likewise. - * gnulib/error.h: Likewise. - * gnulib/fnmatch.c: Likewise. - * gnulib/fnmatch_loop.c: Likewise. - * gnulib/getdelim.c: Likewise. - * gnulib/getline.c: Likewise. - * gnulib/getopt.c: Likewise. - * gnulib/getopt1.c: Likewise. - * gnulib/getopt_int.h: Likewise. - * gnulib/gettext.h: Likewise. - * gnulib/progname.c: Likewise. - * gnulib/progname.h: Likewise. - -2010-03-27 Grégoire Sutre - - Fix a build failure (-Wundef -Werror) when ENABLE_NLS is not defined, - which is the case with --disabled-nls. - - * include/grub/i18n.h: Use (defined(ENABLE_NLS) - && ENABLE_NLS) instead of ENABLE_NLS in all #if preprocessor macros. - * util/misc.c: Likewise. - * util/mkisofs/mkisofs.c: Likewise. - * util/mkisofs/mkisofs.h: Likewise. - -2010-03-27 Vladimir Serbinenko - - Simplify Apple CC support. - - * commands/i386/pc/drivemap_int13h.S: Use LOCAL when possible. - Add 0 byte at the end not to have a symbol with empty target. - * mmap/i386/pc/mmap_helper.S: Likewise. - * genmk.rb: Ignore errors 2030 and 2050. - * kern/i386/pc/startup.S: Use LOCAL when possible. - -2010-03-26 BVK Chaitanya - - Testcase and the fix for final semicolon on cmdline. - - * tests/grub_script_final_semicolon.in: New testcase. - * conf/tests.rmk: Rules for the new testcase. - * script/parser.y: Grammar fix. - -2010-03-26 BVK Chaitanya - - Blank lines testcase for GRUB script. - - * tests/grub_script_blanklines.in: New testcase. - * conf/tests.rmk: Rules for the new testcase. - -2010-03-26 Vladimir Serbinenko - - Don't use __FILE__. - - * genmk.rb: Add -DGRUB_FILE to all C targets. - * fs/reiserfs.c: Replace __FILE__ with GRUB_FILE. - * include/grub/list.h: Likewise. - * include/grub/misc.h: Likewise. - * include/grub/mm.h: Likewise. - * include/grub/test.h: Likewise. - * kern/mm.c: Likewise. - * lib/libgcrypt_wrap/cipher_wrap.h: Likewise. - -2010-03-26 Vladimir Serbinenko - - Sunpc partitions support. - - * conf/common.rmk (grub_probe_SOURCES): Add partmap/sunpc.c. - (grub_fstest_SOURCES): Likewise. - (pkglib_MODULES): Add part_sunpc.mod. - (part_sunpc_mod_SOURCES): New variable. - (part_sunpc_mod_CFLAGS): Likewise. - (part_sunpc_mod_LDFLAGS): Likewise. - * conf/i386-pc.rmk (grub_setup_SOURCES): Add partmap/sunpc.c. - * partmap/sunpc.c: New file. - -2010-03-26 BVK Chaitanya - - For loop support to GRUB script. - - * include/grub/script_sh.h (grub_script_cmdfor): New struct. - (grub_script_create_cmdfor): New function prototype. - (grub_script_execute_cmdfor): New function prototype. - * script/execute.c (grub_script_execute_cmdfor): New function. - * script/parser.y (command): New for command. - (forcmd): New grammar rule. - * script/script.c (grub_script_create_cmdfor): New function. - * util/grub-script-check.c (grub_script_execute_cmdfor): New - function. - * tests/grub_script_for1.in: New testcase. - * conf/tests.rmk: Rules for new testcase. - -2010-03-26 Vladimir Serbinenko - - Nested partitions - - * commands/blocklist.c (grub_cmd_blocklist): Don't check whether - 'partition' is NULL, grub_partition_get_start already does that. - * commands/loadenv.c (check_blocklists): Likewise. - (write_blocklists): Likewise. - * conf/common.rmk (grub_probe_SOURCES): Add partmap/bsdlabel.c. - (grub_fstest_SOURCES): Likewise. - (pkglib_MODULES): Add part_bsd.mod. - (part_bsd_mod_SOURCES): New variable. - (part_bsd_mod_CFLAGS): Likewise. - (part_bsd_mod_LDFLAGS): Likewise. - * conf/i386-pc.rmk (grub_setup_SOURCES): Add partmap/bsdlabel.c. - (grub_emu_SOURCES): Likewise. - * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. - * include/grub/bsdlabel.h: New file. - * include/grub/partition.h (grub_partition_map): Remove 'probe' and - 'get_name'. - (grub_partition): Add 'parent' and 'number'. Remove 'data'. - (grub_partition_map_list): New variable. - (grub_partition_map_register): Inline. - (grub_partition_map_unregister): Likewise. - (FOR_PARTITION_MAPS): New macro. - (grub_partition_map_iterate): Removed. - (grub_partition_get_start): Handle nested partitions. - * include/grub/msdos_partition.h: Remove bsd-related entries. - (grub_pc_partition): Remove. - * kern/disk.c (grub_disk_close): Free partition data. - (grub_disk_adjust_range): Handle nested partitions. - * kern/partition.c (grub_partition_map_probe): New function. - (grub_partition_probe): Parse name to number, handle subpartitions. - (get_partmap): New function. - (grub_partition_iterate): Handle subpartitions. - (grub_partition_get_name): Likewise. - * loader/i386/pc/bsd.c (grub_bsd_get_device): Likewise. - * loader/i386/multiboot.c (grub_multiboot_get_bootdev): Likewise. - * loader/i386/pc/chainloader.c (grub_chainloader_cmd): Likewise. - * partmap/acorn.c (acorn_partition_map_iterate): Don't force raw access. - Set 'number'. - (acorn_partition_map_probe): Remove. - (acorn_partition_map_get_name): Likewise. - * partmap/amiga.c (amiga_partition_map_iterate): Don't force raw access. - Set 'number'. - Set 'index' to 0 since there can be only one partition entry per sector. - (amiga_partition_map_probe): Remove. - (amiga_partition_map_get_name): Likewise. - * partmap/apple.c (apple_partition_map_iterate): Don't force raw access. - Set 'number'. - Set 'offset' and 'index' to real positions of partitions. - (apple_partition_map_probe): Remove. - (apple_partition_map_get_name): Likewise. - * partmap/bsdlabel.c: New file. - * partmap/gpt.c (gpt_partition_map_iterate): Don't force raw access. - Set 'number'. - Allocate 'data' so it can be correctly freed. - Set 'index' to offset inside sector. - (gpt_partition_map_probe): Remove. - (gpt_partition_map_get_name): Likewise. - * partmap/msdos.c (grub_partition_parse): Remove. - (pc_partition_map_iterate): Don't force raw access. - Set 'number'. - Make 'ext_offset' a local variable. - (pc_partition_map_probe): Remove. - (pc_partition_map_get_name): Remove. - * partmap/sun.c (sun_partition_map_iterate): Don't force raw access. - Set 'number'. - (sun_partition_map_probe): Remove. - (sun_partition_map_get_name): Likewise. - * parttool/msdospart.c (grub_pcpart_boot): Handle nested partitions. - (grub_pcpart_type): Likewise. - * util/hostdisk.c (open_device): Handle new numbering scheme. - (grub_util_biosdisk_get_grub_dev): Handle nested partitions. - * util/i386/pc/grub-setup.c (setup): Handle new numbering scheme. - * util/grub-probe.c (probe_partmap): Handle nested paritions. - * util/grub-install.in: Insert all subpartition modules. - * util/ieee1275/grub-install.in: Likewise. - -2010-03-24 Adrian Glaubitz - - * kern/dl.c (grub_dl_resolve_symbols): Improve error message - grammar. - -2010-03-24 Colin Watson - - * .bzrignore: Add grub-bin2h, grub-reboot, and grub-set-default. - -2010-03-21 Colin Watson - - * util/grub-install.in: Copy .mo files from @datadir@/locale, to - match where 'make install' puts them. - * util/i386/efi/grub-install.in: Likewise. - -2010-03-19 Colin Watson - - * .bzrignore: Add gentrigtables, grub-script-check, - grub_script_check_init.c, grub_script_check_init.h, and - trigtables.c. - -2010-03-18 Vladimir Serbinenko - - * kern/parser.c: Indented. - -2010-03-17 Vladimir Serbinenko - - * term/i386/pc/vesafb.c: Removed (orphaned, deprecated and broken). - -2010-03-17 Vladimir Serbinenko - - * video/fb/fbblit.c (grub_video_fbblit_blend_XXXA8888_1bit): Handle - alpha_mask_size == 0 case. - -2010-03-14 BVK Chaitanya - - GRUB shell lexer and parser improvements. - - * conf/any-emu.rmk: Build rule updates. - * conf/common.rmk: 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/x86_64-efi.rmk: Likewise. - - * configure.ac: Configure check for flex. - - * include/grub/script_sh.h (grub_script_arg_type_t): More argument - types. - (grub_lexer_param): Struct member updates. - (grub_parser_param): Likewise. - (GRUB_LEXER_TOKEN_MAX): Maximum token size. - (GRUB_LEXER_RECORD_INCREMENT): Memory increments' size. - (grub_script_lexer_init): Prototype update. - (grub_script_lexer_record_start): Likewise. - (grub_script_lexer_record_stop): Likewise. - (grub_script_lexer_yywrap): New function prototype. - (grub_script_lexer_fini): Likewise. - (grub_script_execute_argument_to_string): Removed by... - (grub_script_execute_argument_to_argv): ...better version. - - * script/execute.c (ROUND_UPTO): New macro. - (grub_script_execute_cmdline): Out of memory fixes. - (grub_script_execute_menuentry): Likewise. - (grub_script_execute_argument_to_string): Removed. Update all - users by... - (grub_script_execute_argument_to_argv): ...better version. - * script/function.c (grub_script_function_create): Use - grub_script_execute_argument_to_argv instead of - grub_script_execute_argument_to_string. - - * script/lexer.c (check_varstate): Removed. - (check_textstate): Removed. - (grub_script_lexer_record_start): Likewise. - (grub_script_lexer_record_stop): Likewise. - (recordchar): Replaced with... - (grub_script_lexer_record): ...new function. - (nextchar): Removed. - (grub_script_lexer_init): Rewritten. - (grub_script_yylex): Rewritten. - (append_newline): New function. - (grub_script_lexer_yywrap): New function. - (grub_script_lexer_fini): New function. - (grub_script_yyerror): Sets error flag. - - * script/yylex.l: New file. - (grub_lexer_yyfree): Wrapper for flex yyffre. - (grub_lexer_yyalloc): Likewise. - (grub_lexer_yyrealloc): Likewise. - * script/parser.y: Refactored. - - * script/script.c (grub_script_arg_add): Out of memory fixes. - (grub_script_add_arglist): Likewise. - (grub_script_create_cmdline): Likewise. - (grub_script_create_cmdmenu): Likewise. - (grub_script_add_cmd): Likewise. - (grub_script_parse): Use grub_script_lexer_fini to deallocated. - * util/grub-script-check.c (grub_script_execute_menuentry): Remove - unnecessary code. - - * tests/grub_script_echo1.in: New testcase. - * tests/grub_script_vars1.in: New testcase. - * tests/grub_script_echo_keywords.in: New testcase. - -2010-03-14 Vladimir Serbinenko - - Remove some redundancy in build system. - - * Makefile.in (TARGET_CFLAGS): Add -ffreestanding. - (TARGET_ASFLAGS): Add -nostdinc -fno-builtin. - (TARGET_LDFLAGS): Add -nostdlib. - (TARGET_IMG_LDFLAGS): Likewise. - * commands/lsmmap.c (grub_cmd_lsmmap) [GRUB_MACHINE_EMU]: Don't do - anything since mmap isn't available. - * conf/any-emu.rmk (kernel_img_SOURCES): Remove commands/boot.c. - Add util/time.c. - (pkglib_MODULES): Remove reboot.mod. - (reboot_mod_SOURCES): Removed. - (reboot_mod_CFLAGS): Likewise. - (reboot_mod_LDFLAGS): Likewise. - * conf/common.rmk (script/lexer.c_DEPENDENCIES): New variable. - (MOSTLYCLEANFILES): Add symlist.c kernel_syms.lst. - (DEFSYMFILES): Add kernel_syms.lst. - (kernel_img_HEADERS): Add common headers. - (symlist.c): New target. - (kernel_syms.lst): Likewise. - (pkglib_MODULES): Add memdisk.mod. - (memdisk_mod_SOURCES): New variable. - (memdisk_mod_CFLAGS): Likewise. - (memdisk_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add reboot.mod. - (reboot_mod_SOURCES): New variable. - (reboot_mod_CFLAGS): Likewise. - (reboot_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add date.mod. - (date_mod_SOURCES): New variable. - (date_mod_CFLAGS): Likewise. - (date_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add datehook.mod. - (datehook_mod_SOURCES): New variable. - (datehook_mod_CFLAGS): Likewise. - (datehook_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add lsmmap.mod. - (lsmmap_mod_SOURCES): New variable. - (lsmmap_mod_CFLAGS): Likewise. - (lsmmap_mod_LDFLAGS): Likewise. - (pkglib_MODULES): Add boot.mod. - (boot_mod_SOURCES): New variable. - (boot_mod_CFLAGS): Likewise. - (boot_mod_LDFLAGS): Likewise. - * conf/i386-coreboot.rmk: Removed redundant parts. - * conf/i386-ieee1275.rmk: Likewise. - * conf/i386-pc.rmk: Likewise. - * conf/mips-yeeloong.rmk: Likewise. - * conf/mips.rmk: Likewise. - * conf/powerpc-ieee1275.rmk: Likewise. - * conf/sparc64-ieee1275.rmk: Likewise. - * conf/x86_64-efi.rmk: Likewise. - * conf/i386-coreboot.rmk: Moved qemu parts .. - * conf/i386-qemu.rmk: ... here - * conf/i386-efi.rmk: Moved common parts to... - * conf/x86-efi.rmk: ... here. - * conf/i386.rmk: Added modules common to all x86 variants. - * configure.ac: Add -m32/-m64 to TARGET_ASFLAGS. - * disk/memdisk.c: Remove grub/machine/kernel.h. - * gensymlist.sh.in: Include symbol.h. - * hook/datehook.c: Correct module name. - * include/grub/datetime.h (grub_get_datetime) [GRUB_MACHINE_EMU]: Export. - (grub_set_datetime) [GRUB_MACHINE_EMU]: Likewise. - * include/grub/i386/efi/serial.h: New file. - * include/grub/x86_64/efi/serial.h: Likewise. - * util/time.c: Likewise. - * video/ieee1275.c (grub_video_ieee1275_setup): Handle 64-bit void *. - -2010-03-14 Colin King -2010-03-14 Colin Watson - - Shrink the pre-partition-table part of boot.img by eight bytes. - - * boot/i386/pc/boot.S (ERR): New macro. - (chs_mode): Use ERR. - (geometry_error): Likewise. - (hd_probe_error): Remove. This is only used once, so we wrwite - it inline instead. - (read_error): Instead of printing read_error_string, just set up - %si and fall through to ... - (error_message): ... this new function, also used by ERR. - -2010-03-14 Colin Watson - - Speed up consecutive hostdisk operations on the same device. - - * util/hostdisk.c (struct grub_util_biosdisk_data): New structure. - (grub_util_biosdisk_open): Initialise disk->data. - (struct linux_partition_cache): New structure. - (linux_find_partition): Cache partition start positions; these are - expensive to compute on every read and write. - (open_device): Cache open file descriptor in disk->data, so that we - don't have to reopen it and flush the buffer cache for consecutive - operations on the same device. - (grub_util_biosdisk_close): New function. - (grub_util_biosdisk_dev): Set `close' member. - - * conf/common.rmk (grub_probe_SOURCES): Add kern/list.c. - * conf/i386-efi.rmk (grub_setup_SOURCES): Likewise. - * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. - * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise. - * conf/x86_64-efi.rmk (grub_setup_SOURCES): Likewise. - -2010-03-14 Vladimir Serbinenko - - Compile parts of grub-emu as modules. - - * Makefile.in (TARGET_CPPFLAGS) [emu]: Remove -nostdinc -isystem. - (pkglib_DATA) [emu]: Remove moddep.lst command.lst fs.lst - partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst. - (all-local): Add $(GRUB_EMU). - (install-local): Install $(GRUB_EMU). - (uninstall): Uninstall $(GRUB_EMU). - * commands/parttool.c: Replace GRUB_UTIL with GRUB_NO_MODULES. - * kern/dl.c: Likewise. - * commands/sleep.c: Not include machine/time.h. - * conf/any-emu.rmk (COMMON_LDFLAGS): New variable. - (COMMON_CFLAGS): Likewise. - (sbin_UTILITIES): Remove grub-emu. - (grub_emu_SOURCES): Removed. - (kernel_img_RELOCATABLE): New variable. - (pkglib_PROGRAMS): Add kernel.img. - (kernel_img_SOURCES): New variable - (kernel_img_CFLAGS): Likewise. - (kernel_img_LDFLAGS): Likewise. - (TARGET_NO_STRIP): Likewise. - (TARGET_NO_DYNAMIC_MODULES): Likewise. - (pkglib_MODULES): Add progname.mod, hostfs.mod, host.mod, reboot.mod, - halt.mod, cpuid.mod, usb.mod, sdl.mod and pci.mod. - (grub-emu): New target. - (GRUB_EMU): New variable. - * configure.ac: Whitelist -emu as possible x86_64 architecture. - * efiemu/main.c: Replace GRUB_UTIL with GRUB_MACHINE_EMU. - * loader/xnu.c: Likewise. - * include/grub/pci.h: Likewise. - * genemuinit.sh: New file. - * genemuinitheader.sh: Likewise. - * genmk.rb: Don't strip if TARGET_NO_STRIP is yes. - Support TARGET_NO_DYNAMIC_MODULES. - * include/grub/dl.h (GRUB_NO_MODULES): New variable. - * commands/search.c: Fix GRUB_MOD_INIT and GRUB_MOD_FINI arguments. - * disk/loopback.c: Likewise. - * font/font_cmd.c: Likewise. - * partmap/acorn.c: Likewise. - * partmap/amiga.c: Likewise. - * partmap/apple.c: Likewise. - * partmap/gpt.c: Likewise. - * partmap/msdos.c: Likewise. - * partmap/sun.c: Likewise. - * parttool/msdospart.c: Likewise. - * term/gfxterm.c: Likewise. - * video/bitmap.c: Likewise. - * video/readers/jpeg.c: Likewise. - * video/readers/png.c: Likewise. - * video/readers/tga.c: Likewise. - * video/video.c: Likewise. - * util/grub-emu.c (read_command_list): Removed. - (main): Don't call util_init_nls. - * util/misc.c (grub_err_printf) [!GRUB_UTIL]: Removed. - (grub_util_init_nls) [!GRUB_UTIL]: Likewise. - -2010-03-14 Vladimir Serbinenko - - * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add datetime.mod, - date.mod, datehook.mod. - (datetime_mod_SOURCES): New variable. - (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/sparc64-ieee1275.rmk: Likewise. - * lib/ieee1275/datetime.c: New file. - -2010-03-14 Vladimir Serbinenko - - * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add ieee1275_fb.mod. - (ieee1275_fb_mod_SOURCES): New variable. - (ieee1275_fb_mod_CFLAGS): Likewise. - (ieee1275_fb_mod_LDFLAGS): Likewise. - * include/grub/ieee1275/ieee1275.h (grub_ieee1275_devices_iterate): - New proto. - * kern/ieee1275/init.c (HEAP_MAX_SIZE): Increased. - (HEAP_MAX_ADDR): Likewise. - * kern/ieee1275/openfw.c (grub_children_iterate): Don't skip empty - type. - Correct stop condition. - (grub_ieee1275_devices_iterate): New function. - * video/ieee1275.c: New file. - -2010-03-14 Vladimir Serbinenko - - Merge sparc grub-mkimage into generic grub-mkimage and a.out support. - - * boot/sparc64/ieee1275/boot.S (boot_continue): Use SCRATCH_PAD_BOOT - as scratch. - * boot/sparc64/ieee1275/diskboot.S (after_info_block): Use - SCRATCH_PAD_DISKBOOT as scratch. - (bootit): Pass Openfirmware pointer in %o4. - * conf/sparc64-ieee1275.rmk (kernel_img_LDFLAGS): Link at 0x4400 instead - of 0x200000. - (grub_mkimage_SOURCES): Replace util/sparc64/ieee1275/grub-mkimage.c - with util/grub-mkrawimage.c. - * configure.ac: Handle GRUB_MACHINE_SPARC64 and GRUB_MACHINE_MIPS. - * include/grub/aout.h (AOUT_MID_SUN): New definition. - (grub_aout_get_type) [GRUB_UTIL]: Removed. - (grub_aout_load) [GRUB_UTIL]: Likewise. - * include/grub/kernel.h (grub_modules_get_end): New proto. - * include/grub/sparc64/ieee1275/boot.h (SCRATCH_PAD): Removed. - (SCRATCH_PAD_BOOT): New definition. - (SCRATCH_PAD_DISKBOOT): Likewise. - (GRUB_BOOT_MACHINE_IMAGE_ADDRESS): Set to 0x4400. - * include/grub/sparc64/ieee1275/ieee1275.h - (grub_ieee1275_original_stack): New variable - * include/grub/sparc64/ieee1275/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): - New definition - (GRUB_KERNEL_MACHINE_STACK_SIZE): Likewise. - (GRUB_PLATFORM_IMAGE_FORMATS): Likewise. - (GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT): Likewise. - (GRUB_PLATFORM_IMAGE_DEFAULT): Likewise. - (GRUB_PLATFORM_IMAGE_RAW): Likewise. - (GRUB_PLATFORM_IMAGE_AOUT): Likewise. - (grub_platform_image_format_t): New type. - * kern/mips/yeeloong/init.c (grub_modules_get_end): Move from here ... - * kern/main.c (grub_modules_get_end) - [GRUB_MACHINE_MIPS_YEELOONG || GRUB_MACHINE_SPARC64]: ... here. - * kern/sparc64/ieee1275/crt0.S: Store firmware entry point in %o0. - (codestart): Switch stacks. - * kern/sparc64/ieee1275/init.c (grub_ieee1275_original_stack): New - variable. - (grub_heap_init): Use grub_modules_get_end. - * loader/sparc64/ieee1275/linux.c (grub_linux_boot): Restore original - stack. - * util/grub-mkrawimage.c (generate_image): Support sparc64. - (main): Likewise. - * util/sparc64/ieee1275/grub-mkimage.c: Removed. - -2010-03-14 Thorsten Glaser - - * util/grub-mkrescue.in: Base ISO UUID on UTC. - -2010-03-08 Matt Kraai - - * util/i386/pc/grub-setup.c (setup): Fix a grammatical error (Debian - bug #559005). - -2010-03-07 Vladimir Serbinenko - - * genmoddep.awk: Output all missing symbols and not only first. - -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 8acb40902..724584c57 100644 --- a/INSTALL +++ b/INSTALL @@ -4,6 +4,10 @@ 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 ================ @@ -11,33 +15,16 @@ 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 4.1.3 or later - Note: older versions may work but support is limited - - Experimental support for clang 3.3 or later (results in much bigger binaries) +* 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 - Note: clang 3.2 or later works for i386 and x86_64 targets but results in - much bigger binaries. - earlier versions not tested - Note: clang 3.2 or later works for arm - earlier versions not tested - Note: clang on arm64 is not supported due to - https://llvm.org/bugs/show_bug.cgi?id=26030 - Note: clang 3.3 or later works for mips(el) - earlier versions fail to generate .reginfo and hence gprel relocations - fail. - Note: clang 3.2 or later works for powerpc - earlier versions not tested - Note: clang 3.5 or later works for sparc64 - earlier versions return "error: unable to interface with target machine" - Note: clang has no support for ia64 and hence you can't compile GRUB - for ia64 with clang * GNU Make * GNU Bison 2.3 or later -* GNU gettext 0.17 or later +* GNU gettext * 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) @@ -49,24 +36,74 @@ For optional grub-emu features, you need: * SDL (recommended) * libpciaccess (optional) -* libusb (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 2.6 or later -* Autoconf 2.63 or later -* Automake 1.11 or later +* 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/ Prerequisites for make-check: -* qemu, specifically the binary 'qemu-system-i386' +* 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) Configuring the GRUB ==================== @@ -104,9 +141,8 @@ The simplest way to compile this package is: 3. Type `./bootstrap'. - * autogen.sh (called by bootstrap) uses python. By default the - invocation is "python", but it can be overridden by setting the - variable $PYTHON. + 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. If you're using `csh' on an old version of System V, you might @@ -119,12 +155,16 @@ The simplest way to compile this package is: 6. Type `make' to compile the package. 7. Optionally, type `make check' to run any self-tests that come with - the package. + the package. Note that many of the tests require root privileges in + order to run. 8. Type `make install' to install the programs and any data files and documentation. - 9. You can remove the program binaries and object files from the + 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 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 @@ -160,42 +200,59 @@ 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_CC=gcc BUILD_PKG_CONFIG=pkg-config --host=amd64-linux-gnu -CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" PKG_CONFIG=amd64-linux-gnu-pkg-config ---target=arm --with-platform=uboot TARGET_CC=arm-elf-gcc -TARGET_CFLAGS="-Os -march=armv6" TARGET_CCASFLAGS="-march=armv6" -TARGET_OBJCOPY="arm-elf-objcopy" TARGET_STRIP="arm-elf-strip" -TARGET_NM=arm-elf-nm TARGET_RANLIB=arm-elf-ranlib LEX=gflex + ./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_CC= to gcc able to compile for build. This is used, for + 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. - 2. BUILD_CFLAGS= for C options for build. - 3. BUILD_CPPFLAGS= for C preprocessor options for build. - 4. BUILD_LDFLAGS= for linker options for build. - 5. BUILD_PKG_CONFIG= for pkg-config for build (optional). + 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. HOST_CFLAGS= for C options for host. - 4. HOST_CPPFLAGS= for C preprocessor options for host. - 5. HOST_LDFLAGS= for linker options for host. - 6. PKG_CONFIG= for pkg-config for host (optional). - 7. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional). - 8. Libfuse if any must be in standard linker folders (-lfuse) (optional). - 9. Libzfs if any must be in standard linker folders (-lzfs) (optional). - 10. Liblzma if any must be in standard linker folders (-llzma) (optional). + 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 + 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. @@ -204,11 +261,14 @@ corresponding platform are not needed for the platform in question. 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) - 3. libusb is looked for in standard linker directories (-lusb) (optional) - Platform-agnostic tools and data. 1. make is the tool you execute after ./configure. diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 000000000..45e870c78 --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,35 @@ +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 index 1f4bb9b8c..43635d5ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,6 +24,15 @@ 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 @@ -37,13 +46,13 @@ grub_script.yy.c: grub_script.yy.h CLEANFILES += grub_script.yy.c grub_script.yy.h # For libgrub.a -libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES) +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) + 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 @@ -51,13 +60,13 @@ libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh CLEANFILES += libgrub_a_init.c # For grub-fstest -grub_fstest.pp: $(grub_fstest_SOURCES) +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) + 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 @@ -473,8 +482,6 @@ ChangeLog: FORCE touch $@; \ fi -EXTRA_DIST += ChangeLog ChangeLog-2015 - 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 diff --git a/Makefile.util.def b/Makefile.util.def index 969d32f00..038253b37 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -3,7 +3,7 @@ AutoGen definitions Makefile.tpl; library = { name = libgrubkern.a; cflags = '$(CFLAGS_GNULIB)'; - cppflags = '$(CPPFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_GNULIB) -I$(srcdir)/grub-core/lib/json'; common = util/misc.c; common = grub-core/kern/command.c; @@ -36,8 +36,11 @@ library = { 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; @@ -53,7 +56,7 @@ library = { library = { name = libgrubmods.a; - cflags = '-fno-builtin -Wno-undef'; + 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; @@ -96,6 +99,7 @@ library = { 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; @@ -139,7 +143,7 @@ library = { common = grub-core/lib/crc.c; common = grub-core/lib/adler32.c; common = grub-core/lib/crc64.c; - common = grub-core/normal/datetime.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; @@ -161,6 +165,7 @@ library = { 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; @@ -201,7 +206,32 @@ program = { ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBLZMA)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - cppflags = '-DGRUB_PKGLIBDIR=\"$(pkglibdir)\"'; +}; + +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 = { @@ -240,8 +270,19 @@ program = { 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; @@ -297,11 +338,13 @@ program = { 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) -lfuse'; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) $(FUSE_LIBS)'; condition = COND_GRUB_MOUNT; }; @@ -496,12 +539,24 @@ script = { 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; @@ -723,6 +778,12 @@ script = { 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; @@ -731,470 +792,512 @@ script = { }; script = { - testcase; + testcase = native; + name = erofs_test; + common = tests/erofs_test.in; +}; + +script = { + testcase = native; name = ext234_test; common = tests/ext234_test.in; }; script = { - testcase; + testcase = native; name = squashfs_test; common = tests/squashfs_test.in; }; script = { - testcase; + testcase = native; name = iso9660_test; common = tests/iso9660_test.in; }; script = { - testcase; + testcase = native; name = hfsplus_test; common = tests/hfsplus_test.in; }; script = { - testcase; + testcase = native; name = ntfs_test; common = tests/ntfs_test.in; }; script = { - testcase; + testcase = native; name = reiserfs_test; common = tests/reiserfs_test.in; }; script = { - testcase; + testcase = native; name = fat_test; common = tests/fat_test.in; }; script = { - testcase; + testcase = native; name = minixfs_test; common = tests/minixfs_test.in; }; script = { - testcase; + testcase = native; name = xfs_test; common = tests/xfs_test.in; }; script = { - testcase; + testcase = native; name = f2fs_test; common = tests/f2fs_test.in; }; script = { - testcase; + testcase = native; name = nilfs2_test; common = tests/nilfs2_test.in; }; script = { - testcase; + testcase = native; name = romfs_test; common = tests/romfs_test.in; }; script = { - testcase; + testcase = native; name = exfat_test; common = tests/exfat_test.in; }; script = { - testcase; + testcase = native; name = tar_test; common = tests/tar_test.in; }; script = { - testcase; + testcase = native; name = udf_test; common = tests/udf_test.in; }; script = { - testcase; + testcase = native; name = hfs_test; common = tests/hfs_test.in; }; script = { - testcase; + testcase = native; name = jfs_test; common = tests/jfs_test.in; }; script = { - testcase; + testcase = native; name = btrfs_test; common = tests/btrfs_test.in; }; script = { - testcase; + testcase = native; name = zfs_test; common = tests/zfs_test.in; }; script = { - testcase; + testcase = native; name = cpio_test; common = tests/cpio_test.in; }; script = { - testcase; + testcase = native; name = example_scripted_test; common = tests/example_scripted_test.in; }; script = { - testcase; + testcase = native; name = gettext_strings_test; common = tests/gettext_strings_test.in; extra_dist = po/exclude.pot; }; script = { - testcase; + testcase = nonnative; name = pata_test; common = tests/pata_test.in; }; script = { - testcase; + testcase = nonnative; name = ahci_test; common = tests/ahci_test.in; }; script = { - testcase; + testcase = nonnative; name = uhci_test; common = tests/uhci_test.in; }; script = { - testcase; + testcase = nonnative; name = ohci_test; common = tests/ohci_test.in; }; script = { - testcase; + testcase = nonnative; name = ehci_test; common = tests/ehci_test.in; }; script = { - testcase; + testcase = nonnative; name = example_grub_script_test; common = tests/example_grub_script_test.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_eval; common = tests/grub_script_eval.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_test; common = tests/grub_script_test.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_echo1; common = tests/grub_script_echo1.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_leading_whitespace; common = tests/grub_script_leading_whitespace.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_echo_keywords; common = tests/grub_script_echo_keywords.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_vars1; common = tests/grub_script_vars1.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_for1; common = tests/grub_script_for1.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_while1; common = tests/grub_script_while1.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_if; common = tests/grub_script_if.in; }; script = { - testcase; + testcase = native; name = grub_script_blanklines; common = tests/grub_script_blanklines.in; }; script = { - testcase; + testcase = native; name = grub_script_final_semicolon; common = tests/grub_script_final_semicolon.in; }; script = { - testcase; + testcase = native; name = grub_script_dollar; common = tests/grub_script_dollar.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_comments; common = tests/grub_script_comments.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_functions; common = tests/grub_script_functions.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_break; common = tests/grub_script_break.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_continue; common = tests/grub_script_continue.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_shift; common = tests/grub_script_shift.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_blockarg; common = tests/grub_script_blockarg.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_setparams; common = tests/grub_script_setparams.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_return; common = tests/grub_script_return.in; }; script = { - testcase; + 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; + testcase = nonnative; name = grub_cmd_date; common = tests/grub_cmd_date.in; }; script = { - testcase; + testcase = nonnative; name = grub_cmd_set_date; common = tests/grub_cmd_set_date.in; }; script = { - testcase; + testcase = nonnative; name = grub_cmd_sleep; common = tests/grub_cmd_sleep.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_expansion; common = tests/grub_script_expansion.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_not; common = tests/grub_script_not.in; }; script = { - testcase; + testcase = native; name = grub_script_no_commands; common = tests/grub_script_no_commands.in; }; script = { - testcase; + testcase = nonnative; name = partmap_test; common = tests/partmap_test.in; }; script = { - testcase; + testcase = nonnative; name = hddboot_test; common = tests/hddboot_test.in; }; script = { - testcase; + testcase = nonnative; name = fddboot_test; common = tests/fddboot_test.in; }; script = { - testcase; + testcase = nonnative; name = cdboot_test; common = tests/cdboot_test.in; }; script = { - testcase; + testcase = nonnative; name = netboot_test; common = tests/netboot_test.in; }; script = { - testcase; + testcase = nonnative; + name = serial_test; + common = tests/serial_test.in; +}; + +script = { + testcase = nonnative; name = pseries_test; common = tests/pseries_test.in; }; script = { - testcase; + testcase = nonnative; name = core_compress_test; common = tests/core_compress_test.in; }; script = { - testcase; + testcase = nonnative; name = xzcompress_test; common = tests/xzcompress_test.in; }; script = { - testcase; + testcase = nonnative; name = gzcompress_test; common = tests/gzcompress_test.in; }; script = { - testcase; + testcase = nonnative; name = lzocompress_test; common = tests/lzocompress_test.in; }; script = { - testcase; + testcase = nonnative; name = grub_cmd_echo; common = tests/grub_cmd_echo.in; }; script = { - testcase; + testcase = nonnative; name = help_test; common = tests/help_test.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_gettext; common = tests/grub_script_gettext.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_escape_comma; common = tests/grub_script_escape_comma.in; }; script = { - testcase; + testcase = nonnative; name = grub_script_strcmp; common = tests/grub_script_strcmp.in; }; script = { - testcase; + testcase = nonnative; name = test_sha512sum; common = tests/test_sha512sum.in; }; script = { - testcase; + testcase = nonnative; name = test_unset; common = tests/test_unset.in; }; script = { - testcase; + testcase = nonnative; name = grub_func_test; common = tests/grub_func_test.in; }; script = { - testcase; + testcase = nonnative; name = grub_cmd_tr; common = tests/grub_cmd_tr.in; }; script = { - testcase; + testcase = nonnative; name = file_filter_test; common = tests/file_filter_test.in; }; script = { - testcase; + testcase = nonnative; name = grub_cmd_test; common = tests/grub_cmd_test.in; }; script = { - testcase; + 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; + testcase = native; name = example_unit_test; common = tests/example_unit_test.c; common = tests/lib/unit_test.c; @@ -1209,7 +1312,7 @@ program = { }; program = { - testcase; + testcase = native; name = printf_test; common = tests/printf_unit_test.c; common = tests/lib/unit_test.c; @@ -1224,7 +1327,7 @@ program = { }; program = { - testcase; + testcase = native; name = date_test; common = tests/date_unit_test.c; common = tests/lib/unit_test.c; @@ -1239,7 +1342,7 @@ program = { }; program = { - testcase; + testcase = native; name = priority_queue_unit_test; common = tests/priority_queue_unit_test.cc; common = tests/lib/unit_test.c; @@ -1256,7 +1359,7 @@ program = { }; program = { - testcase; + testcase = native; name = cmp_test; common = tests/cmp_unit_test.c; common = tests/lib/unit_test.c; diff --git a/NEWS b/NEWS index e7ca7fb3f..310130962 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,37 @@ +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. diff --git a/README b/README index 685b01657..49ce15ea3 100644 --- a/README +++ b/README @@ -7,6 +7,12 @@ 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 . diff --git a/SECURITY b/SECURITY new file mode 100644 index 000000000..1c3e8ef36 --- /dev/null +++ b/SECURITY @@ -0,0 +1,60 @@ +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/acinclude.m4 b/acinclude.m4 index 78cdf6e1d..fa7840f09 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -305,9 +305,9 @@ fi ]) -dnl Check if the C compiler supports `-fstack-protector'. +dnl Check if the C compiler supports the stack protector AC_DEFUN([grub_CHECK_STACK_PROTECTOR],[ -[# Smashing stack protector. +[# Stack smashing protector. ssp_possible=yes] AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector']) # Is this a reliable test case? @@ -324,6 +324,40 @@ 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). @@ -396,7 +430,7 @@ 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,-d -nostdlib -Werror -o conftest.o" 2> /dev/null; then] +[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 diff --git a/autogen.sh b/autogen.sh index ef43270fc..ebd614792 100755 --- a/autogen.sh +++ b/autogen.sh @@ -7,13 +7,26 @@ if [ ! -e grub-core/lib/gnulib/stdlib.in.h ]; then exit 1 fi -# Set ${PYTHON} to plain 'python' if not set already -: ${PYTHON:=python} +# 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 + + 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/*' ! -iname './grub-core/lib/gnulib/*' |sort > po/POTFILES.in +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..." @@ -38,6 +51,39 @@ for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul 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. diff --git a/bootstrap b/bootstrap index 5b08e7e2d..dc2238f4a 100755 --- a/bootstrap +++ b/bootstrap @@ -1,10 +1,10 @@ #! /bin/sh # Print a version string. -scriptversion=2019-01-04.17; # UTC +scriptversion=2022-01-26.05; # UTC # Bootstrap this package from checked-out sources. -# Copyright (C) 2003-2019 Free Software Foundation, Inc. +# 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 @@ -47,7 +47,7 @@ PERL="${PERL-perl}" me=$0 -default_gnulib_url=git://git.sv.gnu.org/gnulib +default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git usage() { cat </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 @@ -290,62 +313,6 @@ find_tool () eval "export $find_tool_envvar" } -# 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;; - --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;; - *) - 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 - # Strip blank and comment lines to leave significant entries. gitignore_entries() { sed '/^#/d; /^$/d' "$@" @@ -387,6 +354,137 @@ insert_vc_ignore() { 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 \ @@ -665,9 +763,25 @@ if $use_gnulib; then 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 - git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \ - || cleanup_gnulib trap - 1 2 13 15 fi @@ -784,75 +898,6 @@ case $SKIP_PO in fi;; esac -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 - } -} - version_controlled_file() { parent=$1 file=$2 @@ -970,7 +1015,7 @@ bootstrap_post_import_hook \ # 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 init' and bootstrap again." + "Run 'git submodule update --init' and bootstrap again." fi # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some @@ -1064,7 +1109,7 @@ bootstrap_epilogue echo "$0: done. Now you can run './configure'." -# Local variables: +# Local Variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" diff --git a/bootstrap.conf b/bootstrap.conf index 988dda099..7a7813d28 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -1,6 +1,6 @@ # Bootstrap configuration. -# Copyright (C) 2006-2019 Free Software Foundation, Inc. +# 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 @@ -16,13 +16,13 @@ # along with this program. If not, see . -GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263 +GNULIB_REVISION=9f48fb992a3d7e96610c4ce8be969cff2d61a01b # gnulib modules used by this package. -# mbswidth is used by gnulib-fix-width.diff's changes to argp rather than -# directly. +# mbswidth is used by fix-width.diff's changes to argp rather than directly. gnulib_modules=" argp + base64 error fnmatch getdelim @@ -34,6 +34,7 @@ gnulib_modules=" realloc-gnu regex save-cwd + stdbool " gnulib_tool_option_extras="\ @@ -65,10 +66,11 @@ SKIP_PO=t # Build prerequisites buildreq="\ -autoconf 2.63 -automake 1.11 -gettext 0.18.3 +autoconf 2.64 +automake 1.14 +gettext - git 1.5.5 +patch - tar - " @@ -78,9 +80,19 @@ cp -a INSTALL INSTALL.grub bootstrap_post_import_hook () { set -e - for patchname in fix-null-deref fix-width no-abort; do - patch -d grub-core/lib/gnulib -p2 \ - < "grub-core/lib/gnulib-patches/$patchname.patch" + + # 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. + patch -d grub-core/lib/gnulib -p2 < grub-core/lib/gnulib-patches/fix-width.patch + + 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 diff --git a/conf/Makefile.common b/conf/Makefile.common index 6cd71cbb2..c60f55386 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -20,6 +20,9 @@ endif if COND_powerpc_ieee1275 CFLAGS_PLATFORM += -mcpu=powerpc endif +if COND_HAVE_PCI + CFLAGS_PLATFORM += -DGRUB_HAS_PCI +endif # Other options @@ -39,9 +42,16 @@ 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,-d +LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r CPPFLAGS_MODULE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) CCASFLAGS_MODULE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) @@ -65,7 +75,7 @@ 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 +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 @@ -84,7 +94,9 @@ 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) \ @@ -99,27 +111,29 @@ 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 = -pkgdata_DATA = -bin_SCRIPTS = -sbin_SCRIPTS = -bin_PROGRAMS = -platform_DATA = -sbin_PROGRAMS = -check_SCRIPTS = -dist_grubconf_DATA = -check_PROGRAMS = noinst_SCRIPTS = noinst_PROGRAMS = -grubconf_SCRIPTS = noinst_LIBRARIES = -dist_noinst_DATA = +pkgdata_DATA = +platform_DATA = platform_SCRIPTS = platform_PROGRAMS = +sbin_SCRIPTS = +sbin_PROGRAMS = -TESTS = EXTRA_DIST = CLEANFILES = BUILT_SOURCES = diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 46c4e95e2..d9e2b8cc7 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -21,6 +21,7 @@ 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/extra_deps.lst EXTRA_DIST += grub-core/genmoddep.awk EXTRA_DIST += grub-core/genmod.sh.in EXTRA_DIST += grub-core/gensyminfo.sh.in @@ -28,9 +29,7 @@ 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-null-deref.patch EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch -EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch EXTRA_DIST += grub-core/lib/libgcrypt EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic @@ -110,6 +109,21 @@ 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 diff --git a/conf/i386-cygwin-img-ld.sc b/conf/i386-cygwin-img-ld.sc index 3ac26fcce..578da91b0 100644 --- a/conf/i386-cygwin-img-ld.sc +++ b/conf/i386-cygwin-img-ld.sc @@ -14,6 +14,8 @@ SECTIONS { __data_start__ = . ; *(.data) + /* Do not discard this section. */ + . = . ; __data_end__ = . ; __rdata_start__ = . ; *(.rdata) @@ -34,6 +36,8 @@ SECTIONS .edata : { *(.edata) + /* Do not discard this section. */ + . = . ; end = . ; _end = . ; __end = . ; diff --git a/config.h.in b/config.h.in index 9e8f9911b..9b1d39971 100644 --- a/config.h.in +++ b/config.h.in @@ -9,6 +9,10 @@ #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@ @@ -22,46 +26,124 @@ #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 -#define BUILD_WORDS_BIGENDIAN @BUILD_WORDS_BIGENDIAN@ -#endif +# 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 -#define HAVE_FONT_SOURCE @HAVE_FONT_SOURCE@ +# 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 HAVE_ASM_USCORE @HAVE_ASM_USCORE@ /* Define it to one of __bss_start, edata and _edata. */ -#define BSS_START_SYMBOL @BSS_START_SYMBOL@ +# define BSS_START_SYMBOL @BSS_START_SYMBOL@ /* Define it to either end or _end. */ -#define END_SYMBOL @END_SYMBOL@ +# define END_SYMBOL @END_SYMBOL@ /* Name of package. */ -#define PACKAGE "@PACKAGE@" +# define PACKAGE "@PACKAGE@" /* Version number of package. */ -#define VERSION "@VERSION@" +# define VERSION "@VERSION@" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "@PACKAGE_STRING@" +# define PACKAGE_STRING "@PACKAGE_STRING@" /* Define to the version of this package. */ -#define PACKAGE_VERSION "@PACKAGE_VERSION@" +# define PACKAGE_VERSION "@PACKAGE_VERSION@" /* Define to the full name of this package. */ -#define PACKAGE_NAME "@PACKAGE_NAME@" +# define PACKAGE_NAME "@PACKAGE_NAME@" /* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" +# define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" -#define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" -#define GRUB_PLATFORM "@GRUB_PLATFORM@" +# define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" +# define GRUB_PLATFORM "@GRUB_PLATFORM@" -#define RE_ENABLE_I18N 1 +# define GRUB_STACK_PROTECTOR_INIT @GRUB_STACK_PROTECTOR_INIT@ -#define _GNU_SOURCE 1 +# 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/configure.ac b/configure.ac index 7656f2434..83e3ddf90 100644 --- a/configure.ac +++ b/configure.ac @@ -26,18 +26,26 @@ dnl This is necessary because the target type in autoconf does not dnl describe such a system very well. dnl dnl The current strategy is to use variables with no prefix (such as -dnl CC, CFLAGS, etc.) for the host type, variables with prefix "BUILD_" -dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables -dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are -dnl used for the target type. See INSTALL for full list of variables. +dnl CC, CFLAGS, etc.) for the host and target type, variables with +dnl prefix "BUILD_" (such as BUILD_CC, BUILD_CFLAGS, etc.) for the +dnl build type, variables with prefix "HOST_" (such as HOST_CC, +dnl HOST_CFLAGS, etc.) for the host type and variables with the prefix +dnl "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for +dnl the target type. See INSTALL for full list of variables and +dnl description of the relationships between them. -AC_INIT([GRUB],[2.04],[bug-grub@gnu.org]) +AC_INIT([GRUB],[2.13],[bug-grub@gnu.org]) -AC_CONFIG_AUX_DIR([build-aux]) +AS_CASE(["$ERROR_PLATFORM_NOT_SUPPORT_SSP"], + [n | no | nO | N | No | NO], [ERROR_PLATFORM_NOT_SUPPORT_SSP=no], + [ERROR_PLATFORM_NOT_SUPPORT_SSP=yes]) # We don't want -g -O2 by default in CFLAGS : ${CFLAGS=""} +AC_USE_SYSTEM_EXTENSIONS +AC_CONFIG_AUX_DIR([build-aux]) + # Checks for build, host and target systems. AC_CANONICAL_BUILD AC_CANONICAL_HOST @@ -46,9 +54,9 @@ AC_CANONICAL_TARGET program_prefix="${save_program_prefix}" AM_INIT_AUTOMAKE([1.11]) -AC_PREREQ(2.63) +AC_PREREQ(2.64) AC_CONFIG_SRCDIR([include/grub/dl.h]) -AC_CONFIG_HEADER([config-util.h]) +AC_CONFIG_HEADERS([config-util.h]) # Explicitly check for pkg-config early on, since otherwise conditional # calls are problematic. @@ -68,6 +76,7 @@ grub_TRANSFORM([grub-mkpasswd-pbkdf2]) grub_TRANSFORM([grub-mkrelpath]) grub_TRANSFORM([grub-mkrescue]) grub_TRANSFORM([grub-probe]) +grub_TRANSFORM([grub-protect]) grub_TRANSFORM([grub-reboot]) grub_TRANSFORM([grub-script-check]) grub_TRANSFORM([grub-set-default]) @@ -75,11 +84,22 @@ grub_TRANSFORM([grub-sparc64-setup]) grub_TRANSFORM([grub-render-label]) grub_TRANSFORM([grub-file]) +# Allow HOST_CC to override CC. +if test "x$HOST_CC" != x; then + CC=$HOST_CC +fi + # Optimization flag. Allow user to override. if test "x$TARGET_CFLAGS" = x; then - TARGET_CFLAGS="$TARGET_CFLAGS -Os" + TARGET_CFLAGS=-Os fi +# Enable support for "restrict" keyword and other +# features from gnu99 C language standard. +BUILD_CFLAGS="-std=gnu99 -fno-common $BUILD_CFLAGS" +HOST_CFLAGS="-std=gnu99 -fno-common $HOST_CFLAGS" +TARGET_CFLAGS="-std=gnu99 -fno-common $TARGET_CFLAGS" + # Default HOST_CPPFLAGS HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W" HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1" @@ -98,18 +118,11 @@ case "$target_cpu" in target_cpu=mips machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS=1" ;; - arm*) - target_cpu=arm - ;; - aarch64*) - target_cpu=arm64 - ;; - riscv32*) - target_cpu=riscv32 - ;; - riscv64*) - target_cpu=riscv64 - ;; + arm*) target_cpu=arm ;; + aarch64*) target_cpu=arm64 ;; + loongarch64) target_cpu=loongarch64 ;; + riscv32*) target_cpu=riscv32 ;; + riscv64*) target_cpu=riscv64 ;; esac # Specify the platform (such as firmware). @@ -133,6 +146,7 @@ if test "x$with_platform" = x; then ia64-*) platform=efi ;; arm-*) platform=uboot ;; arm64-*) platform=efi ;; + loongarch64-*) platform=efi;; riscv32-*) platform=efi ;; riscv64-*) platform=efi ;; *) @@ -183,6 +197,7 @@ case "$target_cpu"-"$platform" in arm-coreboot) ;; arm-efi) ;; arm64-efi) ;; + loongarch64-efi) ;; riscv32-efi) ;; riscv64-efi) ;; *-emu) ;; @@ -238,7 +253,7 @@ case "$platform" in emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;; qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; - arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; + arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; esac if test x${target_cpu} = xmipsel ; then machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo mips_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" @@ -324,7 +339,7 @@ fi AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_AWK -AC_PROG_LEX +AC_PROG_LEX([noyywrap]) AC_PROG_YACC AC_PROG_MAKE_SET AC_PROG_MKDIR_P @@ -360,11 +375,15 @@ test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required]) AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no) -AC_GNU_SOURCE AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.18.3]) AC_SYS_LARGEFILE +PLATFORMS_PCI=" $(PYTHONPATH="${srcdir}" $PYTHON -c 'import gentpl; print(" ".join(gentpl.GROUPS[["pci"]]))') " +if test x"${PLATFORMS_PCI##* ${target_cpu}_${platform} *}" = x ; then + have_pci=y +fi + # Identify characteristics of the host architecture. unset ac_cv_c_bigendian @@ -410,12 +429,12 @@ else fi # Check for functions and headers. -AC_CHECK_FUNCS(posix_memalign memalign getextmntent) +AC_CHECK_FUNCS(posix_memalign memalign getextmntent atexit) AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h) # 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. +# as well to force proper sys/sysmacros.h detection. Used in include/grub/osdep/major.h. SAVED_CFLAGS="$CFLAGS" CFLAGS="$HOST_CFLAGS -Werror" AC_HEADER_MAJOR @@ -562,6 +581,24 @@ 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" @@ -750,24 +787,6 @@ if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then TARGET_CFLAGS="$TARGET_CFLAGS -march=i386" fi -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 - 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 @@ -784,11 +803,24 @@ if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then 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 # 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" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], @@ -796,17 +828,19 @@ if test "x$target_cpu" = xi386; then [grub_cv_cc_falign_loop=no]) ]) - AC_CACHE_CHECK([whether -malign-loops works], [grub_cv_cc_malign_loop], [ - CFLAGS="$TARGET_CFLAGS -malign-loops=1 -Werror" + if test "x$grub_cv_cc_falign_loop" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -falign-loops=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_malign_loop=yes], - [grub_cv_cc_malign_loop=no]) + [grub_cv_cc_falign_jumps=yes], + [grub_cv_cc_falign_jumps=no]) ]) - if test "x$grub_cv_cc_falign_loop" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" - elif test "x$grub_cv_cc_malign_loop" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" + if test "x$grub_cv_cc_falign_jumps" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1" fi fi @@ -827,6 +861,83 @@ if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$p 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) @@ -843,17 +954,30 @@ if test x"$platform" != xemu ; 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 @@ -933,6 +1057,19 @@ if test x"$target_cpu" = xsparc64 ; then 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" +fi + # By default, GCC 4.4 generates .eh_frame sections containing unwind # information in some cases where it previously did not. GRUB doesn't need # these and they just use up vital space. Restore the old compiler @@ -999,6 +1136,17 @@ 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" @@ -1077,9 +1225,9 @@ if test x$grub_cv_target_cc_link_format = x-arch,i386 || test x$grub_cv_target_c 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)'"/${grub_coredir}/conf/i386-cygwin-img-ld.sc" + 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}/${grub_coredir}/conf/i386-cygwin-img-ld.sc" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc" TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" TARGET_IMG_CFLAGS= else @@ -1198,7 +1346,8 @@ 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"; do + "-mllvm -arm-use-movt=0" \ + "-mword-relocations"; do if test x"$grub_cv_target_cc_mno_movt" != xno ; then break fi @@ -1251,6 +1400,7 @@ grub_CHECK_LINK_PIE # `-fPIE' or '-fpie' and '-pie' 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 @@ -1285,12 +1435,68 @@ fi] CFLAGS="$TARGET_CFLAGS" -# Smashing stack protector. +# Stack smashing protector. grub_CHECK_STACK_PROTECTOR -# Need that, because some distributions ship compilers that include -# `-fstack-protector' in the default specs. -if test "x$ssp_possible" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" +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]) fi CFLAGS="$TARGET_CFLAGS" @@ -1337,28 +1543,12 @@ fi # Set them to their new values for the tests below. CC="$TARGET_CC" -if test x"$platform" = xemu ; then -CFLAGS="$TARGET_CFLAGS -Wno-error" -elif test "x$TARGET_APPLE_LINKER" = x1 ; then -CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" -else -CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" -fi CPPFLAGS="$TARGET_CPPFLAGS" -grub_ASM_USCORE -if test "x$TARGET_APPLE_LINKER" = x0 && test x"$platform" != xemu; then -if test x$grub_cv_asm_uscore = xyes; then -DEFSYM="-Wl,--defsym,_abort=_main -Wl,--defsym,__main=_main" -else -DEFSYM="-Wl,--defsym,abort=main -Wl,--defsym,_main=main -Wl,--defsym,__main=main" -fi -CFLAGS="$TARGET_CFLAGS -nostdlib $DEFSYM" -fi - # Check for libgcc symbols if test x"$platform" = xemu; then -AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __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) +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 if test "x$TARGET_APPLE_LINKER" = x1 ; then @@ -1368,7 +1558,8 @@ CFLAGS="$TARGET_CFLAGS -nostdlib" fi LIBS="" -# Defined in aclocal.m4. +# Defined in acinclude.m4. +grub_ASM_USCORE grub_PROG_TARGET_CC if test "x$TARGET_APPLE_LINKER" != x1 ; then grub_PROG_OBJCOPY_ABSOLUTE @@ -1404,9 +1595,9 @@ int va_arg_func (int fixed, va_list args);]], [[]])], 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 + 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], [ @@ -1435,9 +1626,14 @@ LIBS="$tmp_LIBS" # Memory manager debugging. AC_ARG_ENABLE([mm-debug], AS_HELP_STRING([--enable-mm-debug], - [include memory manager debugging]), - [AC_DEFINE([MM_DEBUG], [1], - [Define to 1 if you enable memory manager debugging.])]) + [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]) AC_ARG_ENABLE([cache-stats], AS_HELP_STRING([--enable-cache-stats], @@ -1461,6 +1657,10 @@ else 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-sdl], [AS_HELP_STRING([--enable-grub-emu-sdl], [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) @@ -1470,63 +1670,86 @@ 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 -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_sdl" = xno ; then + grub_emu_sdl_excuse="explicitly 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 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_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 [ 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], [], [grub_emu_pci_excuse=["need libpciaccess headers"]]) -[fi] + [fi] -if test x"$grub_emu_pci_excuse" = x ; then -enable_grub_emu_pci=yes -else + if test x"$grub_emu_pci_excuse" = x ; then + enable_grub_emu_pci=yes + else + enable_grub_emu_pci=no + fi -enable_grub_emu_pci=no -fi - -AC_SUBST([enable_grub_emu_sdl]) -AC_SUBST([enable_grub_emu_pci]) + AC_SUBST([enable_grub_emu_sdl2]) + AC_SUBST([enable_grub_emu_sdl]) + AC_SUBST([enable_grub_emu_pci]) else -# Ignore --enable-emu-* if platform is not emu -enable_grub_emu_sdl=no -enable_grub_emu_pci=no + # Ignore --enable-emu-* if platform is not emu + enable_grub_emu_sdl2=no + enable_grub_emu_sdl=no + enable_grub_emu_pci=no fi AC_ARG_ENABLE([grub-mkfont], @@ -1552,15 +1775,18 @@ if test x"$grub_mkfont_excuse" = x ; then 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 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)]) 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]) @@ -1573,7 +1799,7 @@ CC="$BUILD_CC" CPP="$BUILD_CPP" CFLAGS="$BUILD_CFLAGS" CPPFLAGS="$BUILD_CPPFLAGS" -LDFLAGS="$BUILD_LDFAGS" +LDFLAGS="$BUILD_LDFLAGS" unset ac_cv_c_bigendian unset ac_cv_header_ft2build_h @@ -1606,6 +1832,11 @@ if test x"$grub_build_mkfont_excuse" = x ; then 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 @@ -1632,8 +1863,6 @@ CPPFLAGS="$SAVED_CPPFLAGS" LDFLAGS="$SAVED_LDFLAGS" -DJVU_FONT_SOURCE= - starfield_excuse= AC_ARG_ENABLE([grub-themes], @@ -1647,19 +1876,28 @@ if test x"$starfield_excuse" = x && test x"$enable_build_grub_mkfont" = xno ; th starfield_excuse="No build-time grub-mkfont" fi -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; do - if test -f "$dir/DejaVuSans.$ext"; then - DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext" - break 2 - fi - done - done +AC_ARG_WITH([dejavufont], + AS_HELP_STRING([--with-dejavufont=FILE], + [set the DejeVu source [[guessed]]])) - if test "x$DJVU_FONT_SOURCE" = x; then - starfield_excuse="No DejaVu found" - fi +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 @@ -1668,21 +1906,28 @@ fi AC_SUBST([DJVU_FONT_SOURCE]) -FONT_SOURCE= +AC_ARG_WITH([unifont], + AS_HELP_STRING([--with-unifont=FILE], + [set the unifont source [[guessed]]])) -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/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc; 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 +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 - FONT_SOURCE="$dir/unifont.$ext" - break 2 - fi + done done -done +else + FONT_SOURCE="$with_unifont" +fi if test x"$enable_build_grub_mkfont" = xno ; then FONT_SOURCE= @@ -1711,17 +1956,11 @@ if test x"$enable_grub_mount" = xno ; then fi if test x"$grub_mount_excuse" = x ; then - AC_CHECK_LIB([fuse], [fuse_main_real], [], - [grub_mount_excuse="need FUSE library"]) -fi - -if test x"$grub_mount_excuse" = x ; then - # Check for fuse headers. - SAVED_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -DFUSE_USE_VERSION=26" - AC_CHECK_HEADERS([fuse/fuse.h], [], - [grub_mount_excuse=["need FUSE headers"]]) - CPPFLAGS="$SAVED_CPPFLAGS" + 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 @@ -1825,8 +2064,19 @@ fi if test x"$libzfs_excuse" = x ; then AC_CHECK_LIB([nvpair], [nvlist_lookup_string], - [], - [libzfs_excuse="need nvpair library"]) + [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 @@ -1836,16 +2086,37 @@ fi if test x"$libzfs_excuse" = x ; then # We need both libzfs and libnvpair for a successful build. LIBZFS="-lzfs" - AC_DEFINE([HAVE_LIBZFS], [1], - [Define to 1 if you have the ZFS library.]) LIBNVPAIR="-lnvpair" - AC_DEFINE([HAVE_LIBNVPAIR], [1], - [Define to 1 if you have the NVPAIR library.]) + 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]) @@ -1864,6 +2135,10 @@ AC_ARG_ENABLE([werror], 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" @@ -1911,36 +2186,38 @@ AC_SUBST(BUILD_LIBM) AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone]) AM_CONDITIONAL([COND_emu], [test x$platform = xemu]) -AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc]) -AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi]) -AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -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_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) -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_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen]) -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_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc]) -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_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) -AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) -AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) -AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) 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]) @@ -1951,10 +2228,12 @@ 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 @@ -1972,6 +2251,7 @@ 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}" @@ -2028,6 +2308,11 @@ 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 +else +echo SDL2 support for grub-emu: No "($grub_emu_sdl2_excuse)" +fi if [ x"$grub_emu_sdl_excuse" = x ]; then echo SDL support for grub-emu: Yes else @@ -2076,6 +2361,11 @@ 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 @@ -2103,5 +2393,10 @@ echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excus 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/docs/grub-dev.texi b/docs/grub-dev.texi index ee389fd83..f4367f895 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -77,7 +77,9 @@ This edition documents version @value{VERSION}. * 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:: @@ -86,6 +88,7 @@ This edition documents version @value{VERSION}. * PFF2 Font File Format:: * Graphical Menu Software Design:: * Verifiers framework:: +* Lockdown framework:: * Copying This Manual:: Copying This Manual * Index:: @end menu @@ -94,8 +97,8 @@ This edition documents version @value{VERSION}. @node Getting the source code @chapter Getting the source code -GRUB is maintained using the @uref{GIT revision -control system}. To fetch: +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 @@ -344,8 +347,8 @@ manual and try GRUB 2 out to see what you think is missing from there. Here are additional pointers: @itemize -@item @url{https://savannah.gnu.org/task/?group=grub GRUB's Task Tracker} -@item @url{https://savannah.gnu.org/bugs/?group=grub GRUB's Bug Tracker} +@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 @@ -459,7 +462,7 @@ and the FSF clerks have dealt with your copyright assignment. @section When you are approved for write access to project's files As you might know, GRUB is hosted on -@url{https://savannah.gnu.org/projects/grub Savannah}, thus the membership +@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: @@ -482,6 +485,17 @@ 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 @@ -490,6 +504,9 @@ to update it. @menu * Gnulib:: +* jsmn:: +* minilzo:: +* libtasn1:: @end menu @node Gnulib @@ -545,6 +562,303 @@ AC_SYS_LARGEFILE @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 @@ -722,7 +1036,7 @@ 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 later folowing this template: +include/$cpu/types.h. The latter following this template: @example #ifndef GRUB_TYPES_CPU_HEADER @@ -768,13 +1082,13 @@ 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 (vois *start, grub_size_t s) for every of this region. +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 +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). @@ -782,7 +1096,7 @@ 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 termino ieee1275 (same files) and for +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 @@ -996,20 +1310,23 @@ On emu stack and heap are just normal host OS stack and heap. Stack is typically 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 adressable -space is unlimited. When compiled for x86-64 with older GCC version adressable -space is limited to 2GiB. When compiling for i386 adressable space is limited -to 4GiB. All adressable pages except the ones for stack, GRUB binary, special +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 adressable space is unlimited. When compiled for x86-64 with older GCC -version adressable space is limited to 2GiB. For all other platforms adressable +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. -It allocates at most 32MiB for its heap. + +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. @@ -1037,7 +1354,7 @@ In short: @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 < 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 @@ -1731,7 +2048,7 @@ use in GRUB at this time: @item BDF Inefficient storage; uses ASCII to describe properties and hexadecimal numbers in ASCII for the bitmap rows. -@item PCF +@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. @@ -1852,8 +2169,8 @@ 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. - +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. @@ -1998,7 +2315,7 @@ functions (defined in @file{gfxmenu/gui_util.c}) that are particularly useful: @item @code{grub_gui_find_by_id (root, id, callback, userdata)}: -This function ecursively traverses the component tree rooted at @var{root}, and +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 @@ -2086,6 +2403,32 @@ 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 diff --git a/docs/grub.texi b/docs/grub.texi index 87795075a..34b3484dc 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -96,22 +96,15 @@ This edition documents version @value{VERSION}. * Filesystem:: Filesystem syntax and semantics * Interface:: The menu and the command-line * Environment:: GRUB environment variables -* Commands:: The list of available builtin commands +* Modules:: Available modules +* Commands:: Available builtin commands * Internationalisation:: Topics relating to language support * Security:: Authentication, authorisation, and signatures -* Platform limitations:: The list of platform-specific limitations +* Platform limitations:: Platform-specific limitations * Platform-specific operations:: Platform-specific operations -* Supported kernels:: The list of supported kernels +* Supported kernels:: Supported kernels * Troubleshooting:: Error messages produced by GRUB -* 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-script-check:: Check GRUB script file for syntax errors +* User-space utilities:: Usage of user-space utilities * 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 @@ -360,6 +353,7 @@ 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), @@ -369,6 +363,8 @@ Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS}, @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). @item Support automatic decompression Can decompress files which were compressed by @command{gzip} or @@ -695,13 +691,6 @@ floppy instead of exposing the USB drive as a hard disk (they call it This install doesn't conflict with standard install as long as they are in separate directories. -Note that @command{grub-install} is actually just a shell script and the -real task is done by other tools such as @command{grub-mkimage}. Therefore, -you may run those commands 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. - 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: @@ -829,25 +818,55 @@ 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 31 KiB), or the core image can be installed in a +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. -Each of these has different problems. There is no way to reserve space in +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; and systems are sometimes partitioned without leaving enough -space before the first partition. On the other hand, 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. +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 31 KiB (63 sectors) from the start of +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. @@ -894,6 +913,7 @@ 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 @@ -901,17 +921,17 @@ magic. @node General boot methods @section How to boot operating systems -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. +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. @menu * Loading an operating system directly:: +* Kexec:: * Chain-loading:: @end menu @@ -937,13 +957,27 @@ 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. +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 @@ -975,21 +1009,42 @@ 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{initrd}), @command{multiboot_module}, +@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. Aditionally behaviour of +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 appleloader, chainloader (BIOS, EFI, coreboot), -freedos, ntldr and plan9 provide no possibility of loading initial ramdisk and +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 +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 @@ -1093,12 +1148,6 @@ grub> @kbd{initrd16 /initrd} Finally, run the command @command{boot} (@pxref{boot}). @end enumerate -@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 NetBSD @subsection NetBSD @@ -1215,7 +1264,7 @@ need to write the whole thing by hand. @menu * Simple configuration:: Recommended for most users -* Root Identifcation Heuristics:: Summary on how the root file system is identified. +* 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 @@ -1309,12 +1358,12 @@ 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} is pressed 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 +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 @@ -1382,6 +1431,13 @@ 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 @@ -1400,6 +1456,16 @@ for all respectively normal entries. 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}. @@ -1441,6 +1507,15 @@ enable the use of partition UUIDs, set this option to @samp{false}. 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, @@ -1462,7 +1537,8 @@ resolution. @xref{gfxmode}. 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. +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. @@ -1481,21 +1557,27 @@ 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 -Normally, @command{grub-mkconfig} will try to use the external -@command{os-prober} program, if installed, to discover other operating -systems installed on the same system and generate appropriate menu entries -for them. Set this option to @samp{true} to disable this. +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 FS UUIDs of filesystems to be ignored from os-prober -output. For efi chainloaders it's @@ +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{y}, flat menu with all entries +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 @@ -1529,16 +1611,16 @@ configurations, but have better replacements: @table @samp @item GRUB_HIDDEN_TIMEOUT -Wait this many seconds before displaying the menu. If @key{ESC} is pressed -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. +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} is pressed. +@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 @@ -1568,8 +1650,8 @@ edit the scripts in @file{/etc/grub.d} directly. 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 Identifcation Heuristics -@section Root Identifcation Heuristics +@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 @@ -1614,7 +1696,8 @@ command. @end multitable Remember, @samp{GRUB_DISABLE_LINUX_PARTUUID} and @samp{GRUB_DISABLE_LINUX_UUID} -are also considered to be set to @samp{false} when they are unset. +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 @@ -1733,18 +1816,20 @@ of the last command that executes. If the expansion of the items following 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. If its exit status is zero, the -@code{then} @var{list} is executed. Otherwise, each @code{elif} @var{list} -is executed in turn, and if its 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. +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. The +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 @@ -1812,10 +1897,9 @@ than zero; otherwise 0. @section Multi-boot manual config Currently autogenerating config files for multi-boot environments depends on -os-prober and has several shortcomings. While fixing it is scheduled for the -next release, meanwhile you can make use of the power of GRUB syntax and do it -yourself. A possible configuration is detailed here, feel free to adjust to your -needs. +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, @@ -2486,6 +2570,57 @@ grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i38 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. @@ -2506,6 +2641,12 @@ 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. @@ -2546,6 +2687,9 @@ The default interface's MAC address. Read-only. This is alias for the 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 @@ -2576,8 +2720,11 @@ grub> @kbd{terminal_input serial; terminal_output serial} 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, so please refer to @ref{serial}, -for more details. +command accepts many other options, @pxref{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 @@ -2591,11 +2738,11 @@ command. However, note that GRUB assumes that your terminal emulator is compatible with VT100 by default. This is true for most 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. +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. @node Vendor power-on keys @@ -2850,12 +2997,12 @@ The device syntax is like this: 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 refered just by driver +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 necessarry. +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 @@ -2913,6 +3060,18 @@ 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 boot GRUB from a CD-ROM, @samp{(cd)} is available. @xref{Making a GRUB bootable CD-ROM}, for details. @@ -2945,16 +3104,18 @@ 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} +@code{0+100,200+1,300+300,800+} @end example This represents that GRUB should read blocks 0 through 99, block 200, -and blocks 300 through 599. If you omit an offset, then GRUB assumes -the offset is zero. +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. 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 @@ -2989,9 +3150,8 @@ 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{Command-line and menu entry commands}) are a -subset of those available in the configuration file, used with exactly -the same syntax. +way.}. The commands (@pxref{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: @@ -3073,6 +3233,9 @@ 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 @@ -3125,6 +3288,7 @@ These variables have special meaning to GRUB. * color_normal:: * config_directory:: * config_file:: +* cryptodisk_passphrase_tries:: * debug:: * default:: * fallback:: @@ -3136,9 +3300,12 @@ These variables have special meaning to GRUB. * 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:: @@ -3153,14 +3320,14 @@ These variables have special meaning to GRUB. * net_default_server:: * pager:: * prefix:: -* pxe_blksize:: -* pxe_default_gateway:: * pxe_default_server:: * root:: +* shim_lock:: * superusers:: * theme:: * timeout:: * timeout_style:: +* tpm_fail_fatal:: @end menu @@ -3284,13 +3451,28 @@ processed by commands @command{configfile} (@pxref{configfile}) or @command{norm (@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 a list of debug facility names separated by -whitespace or @samp{,}, or @samp{all} to enable all available debugging -output. The facility names are the first argument to grub_dprintf. Consult +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. @@ -3444,6 +3626,13 @@ 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 @@ -3473,6 +3662,18 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}). @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 @@ -3562,18 +3763,6 @@ dynamically loaded from this directory, so it must be set correctly in order for many parts of GRUB to work. -@node pxe_blksize -@subsection pxe_blksize - -@xref{Network}. - - -@node pxe_default_gateway -@subsection pxe_default_gateway - -@xref{Network}. - - @node pxe_default_server @subsection pxe_default_server @@ -3593,6 +3782,13 @@ 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 @@ -3635,6 +3831,20 @@ 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 @@ -3661,9 +3871,2111 @@ 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 The list of available commands +@chapter Available commands In this chapter, we list all commands that are available in GRUB. @@ -3680,14 +5992,16 @@ shell}. @menu * Menu-specific commands:: +* Loader commands:: * General commands:: -* Command-line and menu entry commands:: +* Command-line commands:: * Networking commands:: +* Undocumented commands:: @end menu @node Menu-specific commands -@section The list of commands for the menu only +@section Commands for the menu only The semantics used in parsing the configuration file are the following: @@ -3767,8 +6081,196 @@ All options are the same as in the @command{menuentry} command @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. +@end deffn + + @node General commands -@section The list of general commands +@section General commands Commands usable anywhere in the menu and in the command-line. @@ -3786,18 +6288,53 @@ Commands usable anywhere in the menu and in the command-line. @deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] 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; if specified it takes precedence over @var{unit}. +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. + @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. + 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}). +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 @@ -3843,7 +6380,7 @@ names active. @node terminfo @subsection terminfo -@deffn Command terminfo [-a|-u|-v] [term] +@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. @@ -3860,13 +6397,15 @@ specifies logically-ordered UTF-8; and @option{-v} specifies 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. @end deffn -@node Command-line and menu entry commands -@section The list of command-line and menu entry commands +@node Command-line commands +@section Command-line 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} @@ -3882,7 +6421,6 @@ you forget a command, you can run the command @command{help} * blocklist:: Print a block list * boot:: Start up your operating system * cat:: Show the contents of a file -* chainloader:: Chain-load another boot loader * clear:: Clear the screen * cmosclean:: Clear bit in CMOS * cmosdump:: Dump CMOS contents @@ -3891,26 +6429,30 @@ you forget a command, you can run the command @command{help} * 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 * 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 -* initrd:: Load a Linux initrd -* initrd16:: Load a Linux initrd (16-bit mode) +* hexdump:: Show raw contents of a file or memory * insmod:: Insert a module * keystatus:: Check key modifier status -* linux:: Load a Linux kernel -* linux16:: Load a Linux kernel (16-bit mode) * list_env:: List variables in environment block * list_trusted:: List trusted public keys * load_env:: Load variables from environment block @@ -3928,9 +6470,9 @@ you forget a command, you can run the command @command{help} * 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 -* pxe_unload:: Unload the PXE environment * rdmsr:: Read values from model-specific registers * read:: Read user input * reboot:: Reboot your computer @@ -3944,19 +6486,19 @@ you forget a command, you can run the command @command{help} * 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 -* uppermem:: Set the upper memory size @comment * vbeinfo:: List available video modes * verify_detached:: Verify detached digital signature * videoinfo:: List available video modes -@comment * xen_*:: Xen boot commands for AArch64 * wrmsr:: Write values to model-specific registers -* xen_hypervisor:: Load xen hypervisor binary (only on AArch64) -* xen_module:: Load xen modules for xen hypervisor (only on AArch64) @end menu @@ -3986,6 +6528,11 @@ 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 @@ -4029,7 +6576,6 @@ can be changed only when using @samp{gfxterm} for terminal output. @deffn Command badram addr,mask[,addr,mask...] Filter out bad RAM. -@end deffn This command notifies the memory manager that specified regions of RAM ought to be filtered out (usually, because they're damaged). This @@ -4046,6 +6592,13 @@ 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 @@ -4080,19 +6633,12 @@ 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. -@end deffn - -@node chainloader -@subsection chainloader - -@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 (@pxref{Block list -syntax}) 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. +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 @@ -4135,9 +6681,14 @@ on platforms that support CMOS. @node cmp @subsection cmp -@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: +@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: @example Differ in size: 0x1234 [foo], 0x4321 [bar] @@ -4150,7 +6701,6 @@ 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 @@ -4190,21 +6740,81 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum} (@pxref{hashsum}) for full description. @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 device|@option{-u} uuid|@option{-a}|@option{-b} -Setup access to encrypted device. If necessary, passphrase -is requested interactively. Option @var{device} configures specific grub device +@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. -GRUB suports devices encrypted using LUKS and geli. Note that necessary modules (@var{luks} and @var{geli}) have to be loaded manually before this command can -be used. +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 @@ -4220,13 +6830,15 @@ hour, minute, and second unchanged. @node devicetree -@subsection linux +@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. -@ref{GNU/Linux}. + +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 @@ -4268,6 +6880,8 @@ For example: @example drivemap -s (hd0) (hd1) @end example + +NOTE: Only available on i386-pc. @end deffn @@ -4314,6 +6928,47 @@ 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 @@ -4341,6 +6996,141 @@ 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 @@ -4376,10 +7166,10 @@ type are omitted, then the partition will be inactive. @node halt @subsection halt -@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. +@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 @@ -4420,27 +7210,22 @@ about each of the commands whose names begin with those @var{patterns}. @end deffn -@node initrd -@subsection initrd +@node hexdump +@subsection hexdump -@deffn Command initrd file -Load an initial ramdisk 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 also -@ref{GNU/Linux}. -@end deffn +@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. -@node initrd16 -@subsection initrd16 +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. -@deffn Command initrd16 file -Load an initial ramdisk 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}. - -This command is only available on x86 systems. @end deffn @@ -4466,42 +7251,6 @@ only if checking key modifier status is supported. @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 list_env @subsection list_env @@ -4574,7 +7323,7 @@ suffix @samp{.pf2} appended. @xref{Theme file format,,Fonts}. @node loopback @subsection loopback -@deffn Command loopback [@option{-d}] device file +@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: @@ -4583,6 +7332,9 @@ 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 @@ -4646,7 +7398,7 @@ 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 prefered ELF information while 0.97 and GRUB 2 +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. @@ -4749,6 +7501,77 @@ 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 @@ -4771,19 +7594,11 @@ a rest. @node probe @subsection probe -@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label} device +@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. -@end deffn - -@node pxe_unload -@subsection pxe_unload - -@deffn Command pxe_unload -Unload the PXE environment (@pxref{Network}). - -This command is only available on PC BIOS systems. +The option @option{--part-uuid} is currently only implemented for MSDOS and GPT formatted disks. @end deffn @@ -4808,10 +7623,11 @@ and the system will reboot. @node read @subsection read -@deffn Command read [var] +@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. +with no terminating newline. If the parameter @option{-s} is used, enable +silent mode where input is not printed to the terminal. @end deffn @@ -4870,21 +7686,42 @@ unbootable. @xref{Using digital signatures}, for more information. @deffn Command search @ [@option{--file}|@option{--label}|@option{--fs-uuid}] @ - [@option{--set} [var]] [@option{--no-floppy}] name + [@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{--set} option is used, the first device found is set as the -value of environment variable @var{var}. The default variable is +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{--no-floppy} option prevents searching floppy devices, which can -be slow. +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 @@ -4904,7 +7741,9 @@ 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. +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, @@ -5041,7 +7880,9 @@ This command is only available on PC BIOS systems. @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. +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 @@ -5077,9 +7918,84 @@ Alias for @code{hashsum --hash sha512 arg @dots{}}. See command @command{hashsum @deffn Command sleep [@option{--verbose}] [@option{--interruptible}] count Sleep for @var{count} seconds. If option @option{--interruptible} is given, -allow @key{ESC} 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 by @key{ESC}. +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 @@ -5165,6 +8081,71 @@ 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 @@ -5199,12 +8180,6 @@ Unset the environment variable @var{envvar}. @end deffn -@node uppermem -@subsection uppermem - -This command is not yet implemented for GRUB 2, although it is planned. - - @ignore @node vbeinfo @subsection vbeinfo @@ -5256,42 +8231,23 @@ 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 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. +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 The list of 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 autoconfiguration +* 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 @@ -5299,6 +8255,7 @@ This command is only available on AArch64 systems. * 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 @@ -5338,8 +8295,44 @@ by @var{shortname} which can be used to remove it (@pxref{net_del_route}). @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. If configuration was +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 @@ -5366,35 +8359,17 @@ Sets environment variable @samp{net_}@var{}@samp{_dhcp_rootpath} @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_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_get_dhcp_option @subsection net_get_dhcp_option @@ -5457,6 +8432,122 @@ 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 @@ -5469,7 +8560,7 @@ assumed to be encoded in UTF-8. 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, ext2, ext3, ext4, FAT (short names), +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 @@ -5547,7 +8638,7 @@ Moreover all current input consumers are limited to ASCII. 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 cannonical +Regexps work on unicode characters, however no attempt at checking canonical equivalence has been made. Moreover the classes like [:alpha:] match only ASCII subset. @@ -5561,7 +8652,7 @@ 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-insenstive identifiers are matched +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. @@ -5580,7 +8671,10 @@ environment variables and commands are listed in the same order. * 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 @@ -5612,7 +8706,10 @@ 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. +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 @@ -5672,15 +8769,9 @@ verified with a public key currently trusted by GRUB validation fails, then file @file{foo} cannot be opened. This failure may halt or otherwise impact the boot process. -@comment Unfortunately --pubkey is not yet supported by grub-install, -@comment but we should not bring up internal detail grub-mkimage here -@comment in the user guide (as opposed to developer's manual). - -@comment An initial trusted public key can be embedded within the GRUB -@comment @file{core.img} using the @code{--pubkey} option to -@comment @command{grub-mkimage} (@pxref{Invoking grub-install}). Presently it -@comment is necessary to write a custom wrapper around @command{grub-mkimage} -@comment using the @code{--grub-mkimage} flag to @command{grub-install}. +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 @@ -5746,16 +8837,38 @@ secure boot chain. @node UEFI secure boot and shim @section UEFI secure boot and shim support -The GRUB, except the @command{chainloader} command, works with the UEFI secure -boot and the shim. This functionality is provided by the shim_lock module. It -is recommend to build in this and other required modules into the @file{core.img}. -All modules not stored in the @file{core.img} and the ACPI tables for the -@command{acpi} command have to be signed, e.g. using PGP. Additionally, the -@command{iorw}, the @command{memrw} and the @command{wrmsr} commands are -prohibited if the UEFI secure boot is enabled. This is done due to -security reasons. All above mentioned requirements are enforced by the -shim_lock module. And itself it is a persistent module which means that -it cannot be unloaded if it was loaded into the memory. +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 @@ -5792,7 +8905,463 @@ 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 platforms. +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 @@ -5801,6 +9370,15 @@ 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. @@ -5810,7 +9388,7 @@ 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 refered console is vga_text. Loongson always uses +and coreboot ports the referred console is vga_text. Loongson always uses gfxterm. Most limited one is ASCII. CP437 provides additionally pseudographics. @@ -5819,8 +9397,8 @@ 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. +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. @@ -5835,6 +9413,7 @@ 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. @@ -5849,7 +9428,7 @@ 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 +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. @@ -5972,7 +9551,7 @@ Advanced operations for power users: @item x86: iorw (direct access to I/O ports) @end itemize -Miscelaneous: +Miscellaneous: @itemize @item cmos (x86-*, ieee1275, mips-qemu_mips, mips-loongson): cmostest (used on some laptops to check for special power-on key), cmosclean @@ -6213,8 +9792,25 @@ 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 -@chapter Invoking grub-install +@section 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 @@ -6280,7 +9876,7 @@ outside of the MBR. Disable the Reed-Solomon codes with this option. @end table @node Invoking grub-mkconfig -@chapter Invoking grub-mkconfig +@section Invoking grub-mkconfig The program @command{grub-mkconfig} generates a configuration file for GRUB (@pxref{Simple configuration}). @@ -6306,7 +9902,7 @@ it to standard output. @node Invoking grub-mkpasswd-pbkdf2 -@chapter Invoking grub-mkpasswd-pbkdf2 +@section Invoking grub-mkpasswd-pbkdf2 The program @command{grub-mkpasswd-pbkdf2} generates password hashes for GRUB (@pxref{Security}). @@ -6334,7 +9930,7 @@ Length of the salt. Defaults to 64. @node Invoking grub-mkrelpath -@chapter 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 @@ -6361,7 +9957,7 @@ Print the version number of GRUB and exit. @node Invoking grub-mkrescue -@chapter 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}). @@ -6419,7 +10015,7 @@ built-in default. @node Invoking grub-mount -@chapter 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 @@ -6506,7 +10102,7 @@ Print verbose messages. @node Invoking grub-probe -@chapter Invoking grub-probe +@section Invoking grub-probe The program @command{grub-probe} probes device information for a given path or device. @@ -6591,8 +10187,243 @@ 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 -@chapter 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 diff --git a/docs/man/grub-protect.h2m b/docs/man/grub-protect.h2m new file mode 100644 index 000000000..ecf1c9eab --- /dev/null +++ b/docs/man/grub-protect.h2m @@ -0,0 +1,4 @@ +[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/gentpl.py b/gentpl.py index 387588c05..d8c6965d8 100644 --- a/gentpl.py +++ b/gentpl.py @@ -32,27 +32,28 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "mips_loongson", "sparc64_ieee1275", "powerpc_ieee1275", "mips_arc", "ia64_efi", "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", - "arm_coreboot", "riscv32_efi", "riscv64_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["riscv32"] = [ "riscv32_efi" ] -GROUPS["riscv64"] = [ "riscv64_efi" ] +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", - "riscv32_efi", "riscv64_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" ] @@ -79,7 +80,7 @@ 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", "riscv32_efi", "riscv64_efi" ] +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 @@ -568,6 +569,7 @@ def foreach_platform_value(defn, platform, suffix, closure): 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): @@ -629,7 +631,10 @@ def platform_values(defn, platform, suffix): def extra_dist(defn): return foreach_value(defn, "extra_dist", lambda value: value + " ") -def platform_sources(defn, p): return platform_values(defn, p, "") +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") @@ -655,7 +660,7 @@ def first_time(defn, snippet): def is_platform_independent(defn): if 'enable' in defn: return False - for suffix in [ "", "_nodist" ]: + 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): @@ -697,10 +702,14 @@ def module(defn, platform): 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 > $@; rm -f $@.new + grep 'MARKER' $@.new | grep -v '^#' > $@; rm -f $@.new """) def kernel(defn, platform): @@ -766,7 +775,7 @@ def image(defn, platform): 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 .ARM.exidx $< $@; \ + $(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 """) @@ -817,8 +826,7 @@ def program(defn, platform, test=False): set_canonical_name_suffix("") if 'testcase' in defn: - gvar_add("check_PROGRAMS", name) - gvar_add("TESTS", name) + gvar_add("check_PROGRAMS_" + defn['testcase'], name) else: var_add(installdir(defn) + "_PROGRAMS", name) if 'mansection' in defn: @@ -859,8 +867,7 @@ def script(defn, platform): name = defn['name'] if 'testcase' in defn: - gvar_add("check_SCRIPTS", name) - gvar_add ("TESTS", name) + gvar_add("check_SCRIPTS_" + defn['testcase'], name) else: var_add(installdir(defn) + "_SCRIPTS", name) if 'mansection' in defn: diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 3ea8e7ff4..e50db8106 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -71,6 +71,7 @@ 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 @@ -79,6 +80,7 @@ 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 @@ -88,8 +90,11 @@ 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 @@ -149,6 +154,7 @@ 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 @@ -236,6 +242,7 @@ 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 @@ -284,6 +291,12 @@ 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 @@ -303,9 +316,13 @@ 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 @@ -375,8 +392,10 @@ command.lst: $(MARKER_FILES) 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;}" $$pp; \ + -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 @@ -436,8 +455,11 @@ crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst platform_DATA += crypto.lst CLEANFILES += crypto.lst -syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES) - cat kernel_syms.lst > $@.new +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 @@ -447,7 +469,7 @@ syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES) 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 +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 $^ $@ diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 474a63e68..f70e02e69 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -20,8 +20,8 @@ transform_data = { transform_data = { installdir = platform; - name = gmodule.pl; - common = gmodule.pl.in; + name = gdb_helper.py; + common = gdb_helper.py.in; }; transform_data = { @@ -49,26 +49,36 @@ kernel = { nostrip = emu; - emu_ldflags = '-Wl,-r,-d'; - i386_efi_ldflags = '-Wl,-r,-d'; + 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_ldflags = '-Wl,-r,-d'; + 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 = '-fno-builtin -fpic -minline-int-divide-max-throughput'; - ia64_efi_ldflags = '-Wl,-r,-d'; + 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_ldflags = '-Wl,-r,-d'; + 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_ldflags = '-Wl,-r,-d'; + 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'; - riscv32_efi_ldflags = '-Wl,-r,-d'; + 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_ldflags = '-Wl,-r,-d'; + 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)'; @@ -98,9 +108,9 @@ kernel = { 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,-d'; + 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,-d'; + 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; @@ -120,9 +130,11 @@ kernel = { 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; @@ -140,6 +152,7 @@ kernel = { 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; @@ -198,11 +211,14 @@ kernel = { 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; @@ -221,7 +237,6 @@ kernel = { x86_64 = kern/x86_64/dl.c; x86_64_xen = kern/x86_64/dl.c; - x86_64_efi = kern/x86_64/efi/callwrap.S; x86_64_efi = kern/i386/efi/init.c; x86_64_efi = bus/pci.c; @@ -254,6 +269,9 @@ kernel = { 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; @@ -332,6 +350,11 @@ kernel = { 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; @@ -395,7 +418,7 @@ program = { ldadd = 'kernel.exec$(EXEEXT)'; ldadd = '$(MODULE_FILES)'; - ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(SDL2_LIBS) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; enable = emu; }; @@ -407,7 +430,7 @@ program = { emu_nodist = symlist.c; ldadd = 'kernel.exec$(EXEEXT)'; - ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + ldadd = 'lib/gnulib/libgnu.a $(LIBINTL) $(LIBUTIL) $(LIBSDL) $(SDL2_LIBS) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; enable = emu; }; @@ -513,7 +536,7 @@ image = { image = { name = xz_decompress; - mips = boot/mips/startup_raw.S; + mips_head = boot/mips/startup_raw.S; common = boot/decompressor/minilib.c; common = boot/decompressor/xz.c; common = lib/xzembed/xz_dec_bcj.c; @@ -531,7 +554,7 @@ image = { image = { name = none_decompress; - mips = boot/mips/startup_raw.S; + mips_head = boot/mips/startup_raw.S; common = boot/decompressor/none.c; cppflags = '-DGRUB_EMBED_DECOMPRESSOR=1'; @@ -691,12 +714,16 @@ 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 = { @@ -739,6 +766,9 @@ 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)'; @@ -804,6 +834,12 @@ module = { enable = efi; }; +module = { + name = efitextmode; + efi = commands/efi/efitextmode.c; + enable = efi; +}; + module = { name = blocklist; common = commands/blocklist.c; @@ -823,6 +859,7 @@ module = { enable = arm64_efi; enable = arm_uboot; enable = arm_coreboot; + enable = loongarch64_efi; enable = riscv32_efi; enable = riscv64_efi; }; @@ -942,17 +979,6 @@ module = { cppflags = '-I$(srcdir)/lib/posix_wrap'; }; -module = { - name = verifiers; - common = commands/verifiers.c; -}; - -module = { - name = shim_lock; - common = commands/efi/shim_lock.c; - enable = x86_64_efi; -}; - module = { name = hdparm; common = commands/hdparm.c; @@ -1097,6 +1123,21 @@ module = { 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; @@ -1110,6 +1151,13 @@ module = { 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; @@ -1161,10 +1209,32 @@ module = { 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; - common = disk/AFSplitter.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 = { @@ -1212,6 +1282,11 @@ module = { common = disk/raid6_recover.c; }; +module = { + name = key_protector; + common = disk/key_protector.c; +}; + module = { name = scsi; common = disk/scsi.c; @@ -1372,6 +1447,11 @@ module = { common = fs/odc.c; }; +module = { + name = erofs; + common = fs/erofs.c; +}; + module = { name = ext2; common = fs/ext2.c; @@ -1526,6 +1606,7 @@ module = { 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 = { @@ -1655,6 +1736,7 @@ module = { module = { name = datetime; + common = lib/datetime.c; cmos = lib/cmos_datetime.c; efi = lib/efi/datetime.c; uboot = lib/dummy/datetime.c; @@ -1667,7 +1749,6 @@ module = { i386_xen_pvh = lib/xen/datetime.c; mips_arc = lib/arc/datetime.c; - enable = noemu; }; module = { @@ -1683,6 +1764,7 @@ module = { 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 = { @@ -1781,14 +1863,17 @@ module = { sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; ia64_efi = loader/ia64/efi/linux.c; arm_coreboot = loader/arm/linux.c; - arm_efi = loader/arm64/linux.c; + arm_efi = loader/efi/linux.c; arm_uboot = loader/arm/linux.c; - arm64 = loader/arm64/linux.c; - riscv32 = loader/riscv/linux.c; - riscv64 = loader/riscv/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; - enable = noemu; }; module = { @@ -1880,6 +1965,7 @@ module = { enable = ia64_efi; enable = arm_efi; enable = arm64_efi; + enable = loongarch64_efi; enable = riscv32_efi; enable = riscv64_efi; enable = mips; @@ -1894,7 +1980,6 @@ module = { common = normal/autofs.c; common = normal/color.c; common = normal/completion.c; - common = normal/datetime.c; common = normal/menu.c; common = normal/menu_entry.c; common = normal/menu_text.c; @@ -1923,7 +2008,7 @@ module = { extra_dist = script/yylex.l; extra_dist = script/parser.y; - cflags = '$(CFLAGS_POSIX) -Wno-redundant-decls'; + cflags = '$(CFLAGS_POSIX) -Wno-redundant-decls -Wno-unused-but-set-variable'; cppflags = '$(CPPFLAGS_POSIX)'; }; @@ -2009,9 +2094,11 @@ 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; @@ -2253,6 +2340,14 @@ module = { 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; @@ -2469,7 +2564,35 @@ module = { name = tpm; common = commands/tpm.c; efi = commands/efi/tpm.c; - enable = x86_64_efi; + 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 = { @@ -2503,3 +2626,46 @@ module = { 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/bus/bonito.c b/grub-core/bus/bonito.c index 9a63f073c..23b9a9915 100644 --- a/grub-core/bus/bonito.c +++ b/grub-core/bus/bonito.c @@ -21,12 +21,12 @@ #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, +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] = +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}; @@ -93,9 +93,9 @@ 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) + 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; } @@ -111,23 +111,23 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), /* First try already used registers. */ for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) - if (usage_win[i] && base_win[i] <= base + if (usage_win[i] && base_win[i] <= base && base_win[i] + sizes_win[i] > base + size) { usage_win[i]++; - return (void *) + 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 + if (!usage_win[i] && newbase <= base && newbase + sizes_win[i] > base + size) { usage_win[i]++; base_win[i] = newbase; write_bases_2f (); - return (void *) + return (void *) (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); } grub_fatal ("Out of PCI windows."); @@ -164,7 +164,7 @@ grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), { int i; for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) - if (usage_win[i] && addr_win[i] + if (usage_win[i] && addr_win[i] == (((grub_addr_t) mem | 0x20000000) & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK)) { diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c index bb9aa27e5..cd0a45e58 100644 --- a/grub-core/bus/cs5536.c +++ b/grub-core/bus/cs5536.c @@ -72,7 +72,7 @@ grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr) addr); ret = (grub_uint64_t) grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0)); - ret |= (((grub_uint64_t) + ret |= (((grub_uint64_t) grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1))) << 32); @@ -100,7 +100,7 @@ grub_cs5536_smbus_wait (grub_port_t smbbase) 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; + 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) @@ -122,8 +122,8 @@ grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, smbbase + GRUB_CS5536_SMB_REG_CTRL1); /* Send device address. */ - err = grub_cs5536_smbus_wait (smbbase); - if (err) + err = grub_cs5536_smbus_wait (smbbase); + if (err) return err; grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA); @@ -139,8 +139,8 @@ grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA); /* Send START. */ - err = grub_cs5536_smbus_wait (smbbase); - if (err) + 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, @@ -161,7 +161,7 @@ grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, smbbase + GRUB_CS5536_SMB_REG_CTRL1); err = grub_cs5536_smbus_wait (smbbase); - if (err) + if (err) return err; *res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA); @@ -198,8 +198,8 @@ grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, 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; + + return GRUB_ERR_NONE; } grub_err_t @@ -217,7 +217,7 @@ grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, 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++) { @@ -310,7 +310,7 @@ grub_cs5536_init_geode (grub_pci_device_t dev) /* Initialise USB controller. */ /* FIXME: assign adresses dynamically. */ - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, + 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); @@ -331,8 +331,9 @@ grub_cs5536_init_geode (grub_pci_device_t dev) { volatile grub_uint32_t *oc; - oc = grub_pci_device_map_range (dev, 0x05022000, - GRUB_CS5536_USB_OPTION_REGS_SIZE); + + 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] diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c index b388ce5c8..c1ee9dc58 100644 --- a/grub-core/bus/pci.c +++ b/grub-core/bus/pci.c @@ -159,12 +159,12 @@ grub_pci_find_capability (grub_pci_device_t dev, grub_uint8_t cap) pos &= ~3; - addr = grub_pci_make_address (dev, pos); + addr = grub_pci_make_address (dev, pos); id = grub_pci_read_byte (addr); if (id == 0xff) break; - + if (id == cap) return pos; pos++; diff --git a/grub-core/bus/usb/ehci-pci.c b/grub-core/bus/usb/ehci-pci.c index 65e6cb574..aa04988fd 100644 --- a/grub-core/bus/usb/ehci-pci.c +++ b/grub-core/bus/usb/ehci-pci.c @@ -96,7 +96,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, 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); @@ -125,7 +125,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, 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"); } @@ -142,7 +142,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, /* Determine and change ownership. */ /* EECP offset valid in HCCPARAMS */ /* Ownership can be changed via EECP only */ - if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40) + if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40) { grub_pci_address_t pciaddr_eecp; pciaddr_eecp = grub_pci_make_address (dev, eecp_offset); diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c index d966fc210..2db07c7c0 100644 --- a/grub-core/bus/usb/ehci.c +++ b/grub-core/bus/usb/ehci.c @@ -218,7 +218,7 @@ enum #define GRUB_EHCI_TERMINATE (1<<0) -#define GRUB_EHCI_TOGGLE (1<<31) +#define GRUB_EHCI_TOGGLE ((grub_uint32_t) 1<<31) enum { @@ -498,8 +498,8 @@ grub_ehci_init_device (volatile void *regs) } e->iobase = ((volatile grub_uint32_t *) e->iobase_ehcc + (caplen / sizeof (grub_uint32_t))); -#else - e->iobase = (volatile grub_uint32_t *) +#else + e->iobase = (volatile grub_uint32_t *) ((grub_uint8_t *) e->iobase_ehcc + caplen); #endif @@ -869,7 +869,7 @@ grub_ehci_find_qh (struct grub_ehci *e, grub_usb_transfer_t transfer) 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); @@ -1813,7 +1813,7 @@ static struct grub_usb_controller_dev usb_controller = { .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 + .max_bulk_tds = GRUB_EHCI_N_TD * 3 / 4 }; GRUB_MOD_INIT (ehci) diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c index f0be533d4..5363a61f6 100644 --- a/grub-core/bus/usb/ohci.c +++ b/grub-core/bus/usb/ohci.c @@ -196,7 +196,7 @@ grub_ohci_td_virt2phys (struct grub_ohci *o, grub_ohci_td_t x) 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) { @@ -224,7 +224,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, struct grub_ohci *o; grub_uint32_t revision; int j; - + /* Determine IO base address. */ grub_dprintf ("ohci", "pciid = %x\n", pciid); @@ -253,7 +253,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, 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; @@ -315,7 +315,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, * 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); @@ -385,7 +385,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, grub_dprintf("ohci", "Ownership changing timeout, change forced !\n"); } } - else if (((control & 0x100) == 0) && + else if (((control & 0x100) == 0) && ((control & 0xc0) != 0)) /* Not owned by SMM nor reset */ { grub_dprintf("ohci", "OHCI is owned by BIOS\n"); @@ -396,7 +396,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, { grub_dprintf("ohci", "OHCI is not owned by SMM nor BIOS\n"); /* We can setup OHCI. */ - } + } } /* Suspend the OHCI by issuing a reset. */ @@ -513,7 +513,7 @@ grub_ohci_find_ed (struct grub_ohci *o, int bulk, grub_uint32_t target) /* Use proper values and structures. */ if (bulk) - { + { count = GRUB_OHCI_BULK_EDS; ed = o->ed_bulk; ed_next = grub_ohci_ed_phys2virt(o, bulk, @@ -576,7 +576,7 @@ grub_ohci_alloc_td (struct grub_ohci *o) 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) ); + 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 */ } @@ -586,7 +586,7 @@ 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) { @@ -596,12 +596,12 @@ grub_ohci_free_tds (struct grub_ohci *o, grub_ohci_td_t td) 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; @@ -658,7 +658,7 @@ grub_ohci_transaction (grub_ohci_td_t td, td->buffer = grub_cpu_to_le32 (buffer); td->buffer_end = grub_cpu_to_le32 (buffer_end); } - else + else { td->buffer = 0; td->buffer_end = 0; @@ -728,7 +728,7 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev, 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; @@ -743,7 +743,7 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev, 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) @@ -762,7 +762,7 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev, } 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; @@ -775,10 +775,10 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev, /* 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 */ @@ -807,7 +807,7 @@ grub_ohci_setup_transfer (grub_usb_controller_t dev, 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 @@ -923,7 +923,7 @@ finish_transfer (grub_usb_controller_t dev, 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); + 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, @@ -935,7 +935,7 @@ finish_transfer (grub_usb_controller_t dev, { 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; @@ -978,7 +978,7 @@ parse_halt (grub_usb_controller_t dev, } 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); @@ -1089,7 +1089,7 @@ parse_success (grub_usb_controller_t dev, /* 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; @@ -1207,7 +1207,7 @@ grub_ohci_cancel_transfer (grub_usb_controller_t dev, 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", @@ -1249,7 +1249,7 @@ grub_ohci_portstatus (grub_usb_controller_t dev, 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... */ @@ -1276,7 +1276,7 @@ grub_ohci_portstatus (grub_usb_controller_t dev, 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) @@ -1290,10 +1290,10 @@ grub_ohci_portstatus (grub_usb_controller_t dev, /* "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; } diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c index 8e94c7dc0..e9c995a0a 100644 --- a/grub-core/bus/usb/serial/common.c +++ b/grub-core/bus/usb/serial/common.c @@ -93,7 +93,7 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, /* 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); diff --git a/grub-core/bus/usb/serial/ftdi.c b/grub-core/bus/usb/serial/ftdi.c index 1a99cba17..3c1388ed2 100644 --- a/grub-core/bus/usb/serial/ftdi.c +++ b/grub-core/bus/usb/serial/ftdi.c @@ -174,7 +174,7 @@ static struct grub_serial_driver grub_ftdi_driver = .fini = grub_usbserial_fini }; -static const struct +static const struct { grub_uint16_t vendor, product; } products[] = diff --git a/grub-core/bus/usb/serial/pl2303.c b/grub-core/bus/usb/serial/pl2303.c index d1945a2cb..8576c4611 100644 --- a/grub-core/bus/usb/serial/pl2303.c +++ b/grub-core/bus/usb/serial/pl2303.c @@ -187,7 +187,7 @@ static struct grub_serial_driver grub_pl2303_driver = .fini = grub_usbserial_fini }; -static const struct +static const struct { grub_uint16_t vendor, product; } products[] = diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c index 7c5811fd6..0fdea4c1e 100644 --- a/grub-core/bus/usb/uhci.c +++ b/grub-core/bus/usb/uhci.c @@ -244,10 +244,10 @@ grub_uhci_pci_iter (grub_pci_device_t dev, 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); + 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_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); @@ -399,7 +399,7 @@ grub_free_queue (struct grub_uhci *u, grub_uhci_qh_t qh, grub_uhci_td_t td, 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++) { @@ -411,7 +411,7 @@ grub_free_queue (struct grub_uhci *u, grub_uhci_qh_t qh, grub_uhci_td_t td, transfer->last_trans = i; *actual += (td->ctrl_status + 1) & 0x7ff; - + /* Unlink the queue. */ tdprev = td; if (!td->linkptr2) @@ -537,7 +537,7 @@ grub_uhci_setup_transfer (grub_usb_controller_t dev, } grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase); - + for (i = 0; i < transfer->transcnt; i++) { grub_usb_transaction_t tr = &transfer->transactions[i]; @@ -604,7 +604,7 @@ grub_uhci_check_transfer (grub_usb_controller_t dev, 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", @@ -632,27 +632,27 @@ grub_uhci_check_transfer (grub_usb_controller_t dev, /* 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"); @@ -719,7 +719,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, 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) @@ -746,7 +746,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, 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)); @@ -796,7 +796,7 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed) 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) @@ -818,7 +818,7 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed) } else *changed = 0; - + if (! (status & GRUB_UHCI_DETECT_HAVE_DEVICE)) return GRUB_USB_SPEED_NONE; else if (status & GRUB_UHCI_DETECT_LOW_SPEED) diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c index 8da5e4c74..7bd49d201 100644 --- a/grub-core/bus/usb/usb.c +++ b/grub-core/bus/usb/usb.c @@ -75,6 +75,9 @@ grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook, 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 @@ -134,14 +137,14 @@ grub_usb_device_initialize (grub_usb_device_t dev) return err; descdev = &dev->descdev; - for (i = 0; i < 8; i++) + for (i = 0; i < GRUB_USB_MAX_CONF; i++) dev->config[i].descconf = NULL; - if (descdev->configcnt == 0) + if (descdev->configcnt == 0 || descdev->configcnt > GRUB_USB_MAX_CONF) { err = GRUB_USB_ERR_BADDEVICE; goto fail; - } + } for (i = 0; i < descdev->configcnt; i++) { @@ -172,6 +175,12 @@ grub_usb_device_initialize (grub_usb_device_t dev) /* 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++) { @@ -217,7 +226,7 @@ grub_usb_device_initialize (grub_usb_device_t dev) fail: - for (i = 0; i < 8; i++) + for (i = 0; i < GRUB_USB_MAX_CONF; i++) grub_free (dev->config[i].descconf); return err; @@ -226,7 +235,7 @@ grub_usb_device_initialize (grub_usb_device_t dev) 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++) { @@ -322,7 +331,7 @@ 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) { - grub_list_remove (GRUB_AS_LIST (desc)); + grub_list_remove (GRUB_AS_LIST (desc)); } diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index 34a7ff1b5..f5608e330 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -82,7 +82,7 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, if (i == GRUB_USBHUB_MAX_DEVICES) { grub_error (GRUB_ERR_IO, "can't assign address to USB device"); - for (i = 0; i < 8; i++) + for (i = 0; i < GRUB_USB_MAX_CONF; i++) grub_free (dev->config[i].descconf); grub_free (dev); return NULL; @@ -96,7 +96,7 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, i, 0, 0, NULL); if (err) { - for (i = 0; i < 8; i++) + for (i = 0; i < GRUB_USB_MAX_CONF; i++) grub_free (dev->config[i].descconf); grub_free (dev); return NULL; @@ -115,11 +115,11 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, grub_millisleep (2); grub_boot_time ("Probing USB device driver"); - + grub_usb_device_attach (dev); grub_boot_time ("Attached USB device"); - + return dev; } @@ -130,7 +130,7 @@ 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), @@ -149,8 +149,8 @@ grub_usb_add_hub (grub_usb_device_t dev) grub_usb_set_configuration (dev, 1); dev->nports = hubdesc.portcnt; - dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0])); - dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0])); + 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); @@ -268,8 +268,8 @@ grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *d /* Query the number of ports the root Hub has. */ hub->nports = controller->dev->hubports (controller); - hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports); - hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports); + 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); @@ -328,7 +328,7 @@ grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) speed = hub->controller->dev->detect_dev (hub->controller, portno, &changed); - + if (hub->ports[portno].state == PORT_STATE_NORMAL && speed != GRUB_USB_SPEED_NONE) { @@ -422,7 +422,7 @@ 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) { @@ -564,7 +564,7 @@ poll_nonroot_hub (grub_usb_device_t dev) 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) { @@ -642,7 +642,7 @@ poll_nonroot_hub (grub_usb_device_t dev) 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); @@ -707,12 +707,12 @@ grub_usb_poll_devices (int wait_for_completion) 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); } @@ -723,7 +723,7 @@ grub_usb_poll_devices (int wait_for_completion) 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); } diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c index 85f081fff..c5680b33a 100644 --- a/grub-core/bus/usb/usbtrans.c +++ b/grub-core/bus/usb/usbtrans.c @@ -40,7 +40,7 @@ grub_usb_bulk_maxpacket (grub_usb_device_t dev, static grub_usb_err_t -grub_usb_execute_and_wait_transfer (grub_usb_device_t dev, +grub_usb_execute_and_wait_transfer (grub_usb_device_t dev, grub_usb_transfer_t transfer, int timeout, grub_size_t *actual) { @@ -205,7 +205,7 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_dprintf ("usb", "control: err=%d\n", err); grub_free (transfer->transactions); - + grub_free (transfer); grub_dma_free (setupdata_chunk); diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index 5a1499aa0..f72a19c03 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef GRUB_MACHINE_EFI #include @@ -37,6 +38,20 @@ 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."), @@ -167,7 +182,7 @@ grub_acpi_create_ebda (void) struct grub_acpi_rsdp_v10 *v1; struct grub_acpi_rsdp_v20 *v2; - ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4); + 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; @@ -297,7 +312,7 @@ grub_acpi_create_ebda (void) *target = 0; grub_dprintf ("acpi", "Switching EBDA\n"); - (*((grub_uint16_t *) 0x40e)) = ((grub_addr_t) targetebda) >> 4; + (*((grub_uint16_t *) grub_absolute_pointer (0x40e))) = ((grub_addr_t) targetebda) >> 4; grub_dprintf ("acpi", "EBDA switched\n"); return GRUB_ERR_NONE; @@ -489,21 +504,21 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) if (rsdp) { - grub_uint32_t *entry_ptr; + grub_uint8_t *entry_ptr; char *exclude = 0; char *load_only = 0; char *ptr; - /* RSDT consists of header and an array of 32-bit pointers. */ - struct grub_acpi_table_header *rsdt; + grub_size_t tbl_addr_size; + struct grub_acpi_table_header *table_head; - exclude = state[0].set ? grub_strdup (state[0].arg) : 0; + exclude = state[OPTION_EXCLUDE].set ? grub_strdup (state[OPTION_EXCLUDE].arg) : 0; if (exclude) { for (ptr = exclude; *ptr; ptr++) *ptr = grub_tolower (*ptr); } - load_only = state[1].set ? grub_strdup (state[1].arg) : 0; + load_only = state[OPTION_LOAD_ONLY].set ? grub_strdup (state[OPTION_LOAD_ONLY].arg) : 0; if (load_only) { for (ptr = load_only; *ptr; ptr++) @@ -513,17 +528,32 @@ 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; - rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp->rsdt_addr; + 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); + } + /* Load host tables. */ - for (entry_ptr = (grub_uint32_t *) (rsdt + 1); - entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) - + rsdt->length); - entry_ptr++) + 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) { char signature[5]; struct efiemu_acpi_table *table; - struct grub_acpi_table_header *curtable - = (struct grub_acpi_table_header *) (grub_addr_t) *entry_ptr; + 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); + signature[4] = 0; for (i = 0; i < 4;i++) signature[i] = grub_tolower (curtable->signature[i]); @@ -607,26 +637,26 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) } /* Does user specify versions to generate? */ - if (state[2].set || state[3].set) + if (state[OPTION_V1].set || state[OPTION_V2].set) { - rev1 = state[2].set; - if (state[3].set) + rev1 = state[OPTION_V1].set; + if (state[OPTION_V2].set) rev2 = rev2 ? : 2; else rev2 = 0; } /* Does user override root header information? */ - if (state[4].set) - grub_strncpy (root_oemid, state[4].arg, sizeof (root_oemid)); - if (state[5].set) - grub_strncpy (root_oemtable, state[5].arg, sizeof (root_oemtable)); - if (state[6].set) - root_oemrev = grub_strtoul (state[6].arg, 0, 0); - if (state[7].set) - grub_strncpy (root_creator_id, state[7].arg, sizeof (root_creator_id)); - if (state[8].set) - root_creator_rev = grub_strtoul (state[8].arg, 0, 0); + 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); /* Load user tables */ for (i = 0; i < argc; i++) @@ -742,7 +772,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) acpi_tables = 0; #if defined (__i386__) || defined (__x86_64__) - if (! state[9].set) + if (! state[OPTION_NO_EBDA].set) { grub_err_t err; err = grub_acpi_create_ebda (); @@ -758,13 +788,13 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) #ifdef GRUB_MACHINE_EFI { - struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID; - struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID; + static grub_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID; + static grub_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID; - efi_call_2 (grub_efi_system_table->boot_services->install_configuration_table, - &acpi20, grub_acpi_get_rsdpv2 ()); - efi_call_2 (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 @@ -775,13 +805,13 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(acpi) { - cmd = grub_register_extcmd ("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_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); } GRUB_MOD_FINI(acpi) diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index 9cc7f18e3..9a5e22155 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -78,7 +78,7 @@ 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) @@ -231,7 +231,7 @@ 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) @@ -337,7 +337,7 @@ get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end, } default: grub_printf ("Unknown opcode 0x%x\n", *ptr); - return -1; + return -1; } } diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c new file mode 100644 index 000000000..298c5f70a --- /dev/null +++ b/grub-core/commands/bli.c @@ -0,0 +1,138 @@ +/* + * 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 index 944449b77..48fd85a33 100644 --- a/grub-core/commands/blocklist.c +++ b/grub-core/commands/blocklist.c @@ -53,9 +53,9 @@ print_blocklist (grub_disk_addr_t sector, unsigned num, } /* Helper for grub_cmd_blocklist. */ -static void +static grub_err_t read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, - void *data) + char *buf __attribute__ ((unused)), void *data) { struct blocklist_ctx *ctx = data; @@ -70,7 +70,7 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, } if (!length) - return; + return GRUB_ERR_NONE; print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx); ctx->num_sectors = 0; } @@ -87,7 +87,7 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, } if (!length) - return; + return GRUB_ERR_NONE; if (length & (GRUB_DISK_SECTOR_SIZE - 1)) { @@ -103,6 +103,8 @@ read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, ctx->start_sector = sector; ctx->num_sectors = length >> GRUB_DISK_SECTOR_BITS; } + + return GRUB_ERR_NONE; } static grub_err_t diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c index bbca81e94..61514788e 100644 --- a/grub-core/commands/boot.c +++ b/grub-core/commands/boot.c @@ -27,10 +27,20 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_err_t (*grub_loader_boot_func) (void); -static grub_err_t (*grub_loader_unload_func) (void); +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 { grub_err_t (*preboot_func) (int); @@ -44,6 +54,29 @@ static int grub_loader_loaded; static struct grub_preboot *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) { @@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd) } void -grub_loader_set (grub_err_t (*boot) (void), - grub_err_t (*unload) (void), - int flags) +grub_loader_set_ex (grub_err_t (*boot) (void *context), + grub_err_t (*unload) (void *context), + void *context, + int flags) { if (grub_loader_loaded && grub_loader_unload_func) - grub_loader_unload_func (); + grub_loader_unload_func (grub_loader_context); grub_loader_boot_func = boot; grub_loader_unload_func = unload; + grub_loader_context = context; grub_loader_flags = flags; 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_unload_func (grub_loader_context); grub_loader_boot_func = 0; grub_loader_unload_func = 0; + grub_loader_context = 0; grub_loader_loaded = 0; } @@ -158,7 +208,7 @@ grub_loader_boot (void) return err; } } - err = (grub_loader_boot_func) (); + err = (grub_loader_boot_func) (grub_loader_context); for (cur = preboots_tail; cur; cur = cur->prev) if (! err) diff --git a/grub-core/commands/boottime.c b/grub-core/commands/boottime.c index dcc078c2a..424412851 100644 --- a/grub-core/commands/boottime.c +++ b/grub-core/commands/boottime.c @@ -43,7 +43,7 @@ grub_cmd_boottime (struct grub_command *cmd __attribute__ ((unused)), grub_uint32_t tmrel = cur->tp - last_time; last_time = cur->tp; - grub_printf ("%3d.%03ds %2d.%03ds %s:%d %s\n", + grub_printf ("%3d.%03ds %2d.%03ds %s:%d %s\n", tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000, cur->file, cur->line, cur->msg); } diff --git a/grub-core/commands/cacheinfo.c b/grub-core/commands/cacheinfo.c index d34a34696..e8ee05b85 100644 --- a/grub-core/commands/cacheinfo.c +++ b/grub-core/commands/cacheinfo.c @@ -42,7 +42,7 @@ grub_rescue_cmd_info (struct grub_command *cmd __attribute__ ((unused)), hits, misses); } else - grub_printf ("%s\n", _("No disk cache statistics available\n")); + grub_printf ("%s\n", _("No disk cache statistics available\n")); return 0; } diff --git a/grub-core/commands/cat.c b/grub-core/commands/cat.c index ba5f0061a..2b67c1c7f 100644 --- a/grub-core/commands/cat.c +++ b/grub-core/commands/cat.c @@ -104,7 +104,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) || grub_isspace (code)) && code != '\r') { grub_printf ("%C", code); - count = 0; + count = 0; code = 0; utcount = 0; continue; @@ -113,7 +113,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) if (dos && code == '\r') { is_0d = 1; - count = 0; + count = 0; code = 0; utcount = 0; continue; @@ -123,7 +123,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) for (j = 0; j < utcount; j++) grub_printf ("<%x>", (unsigned int) utbuf[j]); grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - count = 0; + count = 0; code = 0; utcount = 0; } diff --git a/grub-core/commands/cmp.c b/grub-core/commands/cmp.c index e9c3b25d3..46185fbbc 100644 --- a/grub-core/commands/cmp.c +++ b/grub-core/commands/cmp.c @@ -22,14 +22,21 @@ #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_command_t cmd __attribute__ ((unused)), +grub_cmd_cmp (grub_extcmd_context_t ctxt, int argc, char **args) { grub_ssize_t rd1, rd2; @@ -38,19 +45,20 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), 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")); - grub_printf_ (N_("Compare file `%s' with `%s':\n"), args[0], - args[1]); + if (ctxt->state[0].set) + grub_printf_ (N_("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); if (! file1 || ! file2) goto cleanup; - if (grub_file_size (file1) != grub_file_size (file2)) + 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]); @@ -78,9 +86,10 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), { if (buf1[i] != buf2[i]) { - 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]); + 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]); goto cleanup; } } @@ -90,7 +99,9 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)), while (rd2); /* TRANSLATORS: it's always exactly 2 files. */ - grub_printf_ (N_("The files are identical.\n")); + if (ctxt->state[0].set) + grub_printf_ (N_("The files are identical.\n")); + err = GRUB_ERR_NONE; } cleanup: @@ -102,18 +113,19 @@ cleanup: if (file2) grub_file_close (file2); - return grub_errno; + return err; } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(cmp) { - cmd = grub_register_command ("cmp", grub_cmd_cmp, - N_("FILE1 FILE2"), N_("Compare two files.")); + cmd = grub_register_extcmd ("cmp", grub_cmd_cmp, 0, + N_("FILE1 FILE2"), N_("Compare two files."), + options); } GRUB_MOD_FINI(cmp) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } diff --git a/grub-core/commands/date.c b/grub-core/commands/date.c index 8e1f41f14..5cb4fafd4 100644 --- a/grub-core/commands/date.c +++ b/grub-core/commands/date.c @@ -59,7 +59,8 @@ grub_cmd_date (grub_command_t cmd __attribute__ ((unused)), for (; argc; argc--, args++) { - char *p, c; + const char *p; + char c; int m1, ofs, n, cur_mask; p = args[0]; diff --git a/grub-core/commands/echo.c b/grub-core/commands/echo.c index 81ba50d68..f95877285 100644 --- a/grub-core/commands/echo.c +++ b/grub-core/commands/echo.c @@ -119,7 +119,7 @@ grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) if (newline) grub_printf ("\n"); - grub_refresh (); + grub_refresh (); return 0; } diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c index 7a137a72a..704f9d352 100644 --- a/grub-core/commands/efi/efifwsetup.c +++ b/grub-core/commands/efi/efifwsetup.c @@ -27,6 +27,8 @@ 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)), @@ -36,14 +38,23 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), grub_efi_uint64_t os_indications = GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI; grub_err_t status; grub_size_t oi_size; - grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + static grub_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; - old_os_indications = grub_efi_get_variable ("OsIndications", &global, - &oi_size); + 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) @@ -61,26 +72,27 @@ efifwsetup_is_supported (void) { grub_efi_uint64_t *os_indications_supported = NULL; grub_size_t oi_size = 0; - grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + static grub_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + grub_efi_boolean_t ret = 0; - os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported", - &global, &oi_size); + grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size, + (void **) &os_indications_supported); if (!os_indications_supported) - return 0; + goto done; if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) - return 1; + ret = 1; - return 0; + done: + grub_free (os_indications_supported); + return ret; } GRUB_MOD_INIT (efifwsetup) { - if (efifwsetup_is_supported ()) - cmd = grub_register_command ("fwsetup", grub_cmd_fwsetup, NULL, - N_("Reboot into firmware setup menu.")); - + cmd = grub_register_command ("fwsetup", grub_cmd_fwsetup, NULL, + N_("Reboot into firmware setup menu.")); } GRUB_MOD_FINI (efifwsetup) diff --git a/grub-core/commands/efi/efitextmode.c b/grub-core/commands/efi/efitextmode.c new file mode 100644 index 000000000..198bc694d --- /dev/null +++ b/grub-core/commands/efi/efitextmode.c @@ -0,0 +1,153 @@ +/* + * 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/loadbios.c b/grub-core/commands/efi/loadbios.c index d41d521a4..8e042095a 100644 --- a/grub-core/commands/efi/loadbios.c +++ b/grub-core/commands/efi/loadbios.c @@ -27,9 +27,9 @@ GRUB_MOD_LICENSE ("GPLv3+"); -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; +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; #define EBDA_SEG_ADDR 0x40e #define LOW_MEM_ADDR 0x413 @@ -46,7 +46,7 @@ enable_rom_area (void) grub_uint32_t *rom_ptr; grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; - rom_ptr = (grub_uint32_t *) VBIOS_ADDR; + rom_ptr = grub_absolute_pointer (VBIOS_ADDR); if (*rom_ptr != BLANK_MEM) { grub_puts_ (N_("ROM image is present.")); @@ -92,47 +92,29 @@ 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_uint16_t *) EBDA_SEG_ADDR; - low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR; + ebda_seg_ptr = grub_absolute_pointer (EBDA_SEG_ADDR); + low_mem_ptr = grub_absolute_pointer (LOW_MEM_ADDR); if ((*ebda_seg_ptr) || (*low_mem_ptr)) return; - acpi = 0; - smbios = 0; - for (i = 0; i < grub_efi_system_table->num_table_entries; i++) - { - grub_efi_packed_guid_t *guid = - &grub_efi_system_table->configuration_table[i].vendor_guid; + 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); + } - 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); - } - } + smbios = grub_efi_find_configuration_table (&smbios_guid); + 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 *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr; */ + *((grub_uint16_t *) (grub_absolute_pointer (FAKE_EBDA_SEG << 4))) = 640 - *low_mem_ptr; if (acpi) grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16); @@ -205,14 +187,14 @@ static grub_command_t cmd_fakebios, cmd_loadbios; GRUB_MOD_INIT(loadbios) { - cmd_fakebios = grub_register_command ("fakebios", grub_cmd_fakebios, - 0, N_("Create BIOS-like structures for" - " backward compatibility with" - " existing OS.")); + cmd_fakebios = grub_register_command_lockdown ("fakebios", grub_cmd_fakebios, + 0, N_("Create BIOS-like structures for" + " backward compatibility with" + " existing OS.")); - cmd_loadbios = grub_register_command ("loadbios", grub_cmd_loadbios, - N_("BIOS_DUMP [INT10_DUMP]"), - N_("Load BIOS dump.")); + cmd_loadbios = grub_register_command_lockdown ("loadbios", grub_cmd_loadbios, + N_("BIOS_DUMP [INT10_DUMP]"), + N_("Load BIOS dump.")); } GRUB_MOD_FINI(loadbios) diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c index d1ce99af4..7b8316d41 100644 --- a/grub-core/commands/efi/lsefi.c +++ b/grub-core/commands/efi/lsefi.c @@ -29,11 +29,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); -struct known_protocol +static struct known_protocol { - grub_efi_guid_t guid; + grub_guid_t guid; const char *name; -} known_protocols[] = +} known_protocols[] = { { GRUB_EFI_DISK_IO_GUID, "disk" }, { GRUB_EFI_BLOCK_IO_GUID, "block" }, @@ -55,6 +55,7 @@ struct known_protocol { 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" }, @@ -95,7 +96,7 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)), grub_efi_handle_t handle = handles[i]; grub_efi_status_t status; grub_efi_uintn_t num_protocols; - grub_efi_packed_guid_t **protocols; + grub_packed_guid_t **protocols; grub_efi_device_path_t *dp; grub_printf ("Handle %p\n", handle); @@ -107,8 +108,9 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)), grub_efi_print_device_path (dp); } - status = efi_call_3 (grub_efi_system_table->boot_services->protocols_per_handle, - handle, &protocols, &num_protocols); + 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; @@ -122,18 +124,7 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)), if (k < ARRAY_SIZE (known_protocols)) grub_printf (" %s\n", known_protocols[k].name); else - grub_printf (" %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", - protocols[j]->data1, - protocols[j]->data2, - protocols[j]->data3, - (unsigned) protocols[j]->data4[0], - (unsigned) protocols[j]->data4[1], - (unsigned) protocols[j]->data4[2], - (unsigned) protocols[j]->data4[3], - (unsigned) protocols[j]->data4[4], - (unsigned) protocols[j]->data4[5], - (unsigned) protocols[j]->data4[6], - (unsigned) protocols[j]->data4[7]); + grub_printf (" %pG\n", protocols[j]); } } diff --git a/grub-core/commands/efi/lsefimmap.c b/grub-core/commands/efi/lsefimmap.c index c85ff7f36..d0885d72f 100644 --- a/grub-core/commands/efi/lsefimmap.c +++ b/grub-core/commands/efi/lsefimmap.c @@ -59,9 +59,9 @@ grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)), { grub_efi_uint64_t size; grub_efi_uint64_t attr; - static const char types_str[][9] = + static const char types_str[][9] = { - "reserved", + "reserved", "ldr-code", "ldr-data", "BS-code ", @@ -81,7 +81,7 @@ grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)), 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, diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c index df1030221..ffb24fc3b 100644 --- a/grub-core/commands/efi/lsefisystab.c +++ b/grub-core/commands/efi/lsefisystab.c @@ -29,7 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct guid_mapping { - grub_efi_guid_t guid; + grub_guid_t guid; const char *name; }; @@ -37,17 +37,22 @@ 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"}, @@ -59,19 +64,26 @@ grub_cmd_lsefisystab (struct grub_command *cmd __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: %08x\n", - st->hdr.signature, st->hdr.revision); + 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++); - vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1); + /* 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, @@ -90,15 +102,11 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)), grub_printf ("%p ", t->vendor_table); - grub_printf ("%08x-%04x-%04x-", - t->vendor_guid.data1, t->vendor_guid.data2, - t->vendor_guid.data3); - for (j = 0; j < 8; j++) - grub_printf ("%02x", t->vendor_guid.data4[j]); - + 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_efi_guid_t)) == 0) + sizeof (grub_guid_t)) == 0) grub_printf (" %s", guid_mappings[j].name); grub_printf ("\n"); @@ -111,7 +119,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(lsefisystab) { - cmd = grub_register_command ("lsefisystab", grub_cmd_lsefisystab, + cmd = grub_register_command ("lsefisystab", grub_cmd_lsefisystab, "", "Display EFI system tables."); } diff --git a/grub-core/commands/efi/lssal.c b/grub-core/commands/efi/lssal.c index 5084ddd8b..7248bdc29 100644 --- a/grub-core/commands/efi/lssal.c +++ b/grub-core/commands/efi/lssal.c @@ -136,22 +136,16 @@ grub_cmd_lssal (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; - grub_efi_configuration_table_t *t = st->configuration_table; - unsigned int i; - grub_efi_packed_guid_t guid = GRUB_EFI_SAL_TABLE_GUID; + static grub_guid_t guid = GRUB_EFI_SAL_TABLE_GUID; + void *table = grub_efi_find_configuration_table (&guid); - for (i = 0; i < st->num_table_entries; i++) + if (table == NULL) { - if (grub_memcmp (&guid, &t->vendor_guid, - sizeof (grub_efi_packed_guid_t)) == 0) - { - disp_sal (t->vendor_table); - return GRUB_ERR_NONE; - } - t++; + grub_printf ("SAL not found\n"); + return GRUB_ERR_NONE; } - grub_printf ("SAL not found\n"); + + disp_sal (table); return GRUB_ERR_NONE; } diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c deleted file mode 100644 index 764098cfc..000000000 --- a/grub-core/commands/efi/shim_lock.c +++ /dev/null @@ -1,142 +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 . - * - * EFI shim lock verifier. - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define GRUB_EFI_SHIM_LOCK_GUID \ - { 0x605dab50, 0xe046, 0x4300, \ - { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \ - } - -struct grub_efi_shim_lock_protocol -{ - grub_efi_status_t - (*verify) (void *buffer, grub_uint32_t size); -}; -typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t; - -static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID; -static grub_efi_shim_lock_protocol_t *sl; - -/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */ -static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL}; - -static grub_err_t -shim_lock_init (grub_file_t io, enum grub_file_type type, - void **context __attribute__ ((unused)), - enum grub_verify_flags *flags) -{ - const char *b, *e; - int i; - - *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; - - if (!sl) - return GRUB_ERR_NONE; - - switch (type & GRUB_FILE_TYPE_MASK) - { - case GRUB_FILE_TYPE_GRUB_MODULE: - /* Establish GRUB module name. */ - b = grub_strrchr (io->name, '/'); - e = grub_strrchr (io->name, '.'); - - b = b ? (b + 1) : io->name; - e = e ? e : io->name + grub_strlen (io->name); - e = (e > b) ? e : io->name + grub_strlen (io->name); - - for (i = 0; disabled_mods[i]; i++) - if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e))) - { - grub_error (GRUB_ERR_ACCESS_DENIED, - N_("module cannot be loaded in UEFI secure boot mode: %s"), - io->name); - return GRUB_ERR_ACCESS_DENIED; - } - - /* Fall through. */ - - case GRUB_FILE_TYPE_ACPI_TABLE: - case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: - *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH; - - return GRUB_ERR_NONE; - - 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: - for (i = 0; disabled_mods[i]; i++) - if (grub_dl_get (disabled_mods[i])) - { - grub_error (GRUB_ERR_ACCESS_DENIED, - N_("cannot boot due to dangerous module in memory: %s"), - disabled_mods[i]); - return GRUB_ERR_ACCESS_DENIED; - } - - *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK; - - /* Fall through. */ - - default: - return GRUB_ERR_NONE; - } -} - -static grub_err_t -shim_lock_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size) -{ - 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 = - { - .name = "shim_lock", - .init = shim_lock_init, - .write = shim_lock_write - }; - -GRUB_MOD_INIT(shim_lock) -{ - sl = grub_efi_locate_protocol (&shim_lock_guid, 0); - grub_verifier_register (&shim_lock); - - if (!sl) - return; - - grub_dl_set_persistent (mod); -} - -GRUB_MOD_FINI(shim_lock) -{ - grub_verifier_unregister (&shim_lock); -} diff --git a/grub-core/commands/efi/smbios.c b/grub-core/commands/efi/smbios.c new file mode 100644 index 000000000..717e5fc1d --- /dev/null +++ b/grub-core/commands/efi/smbios.c @@ -0,0 +1,37 @@ +/* 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 index 32909c192..cbac69866 100644 --- a/grub-core/commands/efi/tpm.c +++ b/grub-core/commands/efi/tpm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,8 +30,9 @@ typedef TCG_PCR_EVENT grub_tpm_event_t; -static grub_efi_guid_t tpm_guid = EFI_TPM_GUID; -static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID; +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; @@ -51,14 +53,17 @@ grub_tpm1_present (grub_efi_tpm_protocol_t *tpm) caps.Size = (grub_uint8_t) sizeof (caps); - status = efi_call_5 (tpm->status_check, tpm, &caps, &flags, &eventlog, - &lastevent); + status = tpm->status_check (tpm, &caps, &flags, &eventlog, &lastevent); if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag || !caps.TPMPresentFlag) - return tpm1_present = 0; + tpm1_present = 0; + else + tpm1_present = 1; - return 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 @@ -72,12 +77,16 @@ grub_tpm2_present (grub_efi_tpm2_protocol_t *tpm) if (tpm2_present != -1) return (grub_efi_boolean_t) tpm2_present; - status = efi_call_2 (tpm->get_capability, tpm, &caps); + status = tpm->get_capability (tpm, &caps); if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) - return tpm2_present = 0; + tpm2_present = 0; + else + tpm2_present = 1; - return 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 @@ -102,6 +111,7 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle, *tpm_handle = handles[0]; grub_tpm_version = 1; *protocol_version = 1; + grub_dprintf ("tpm", "TPM handle Found, version: 1\n"); return 1; } @@ -113,6 +123,7 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle, *tpm_handle = handles[0]; grub_tpm_version = 2; *protocol_version = 2; + grub_dprintf ("tpm", "TPM handle Found, version: 2\n"); return 1; } @@ -120,102 +131,25 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle, } static grub_err_t -grub_tpm1_execute (grub_efi_handle_t tpm_handle, - PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) +grub_efi_log_event_status (grub_efi_status_t status) { - grub_efi_status_t status; - grub_efi_tpm_protocol_t *tpm; - grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn); - grub_uint32_t outhdrsize = - sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut); - - tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm1_present (tpm)) - return 0; - - /* UEFI TPM protocol takes the raw operand block, no param block header. */ - status = efi_call_5 (tpm->pass_through_to_tpm, tpm, - inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, - outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); - switch (status) { case GRUB_EFI_SUCCESS: - return 0; + return GRUB_ERR_NONE; case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("Command failed")); + return grub_error (GRUB_ERR_IO, N_("command failed")); case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("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")); + 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_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); + return grub_error (grub_is_tpm_fail_fatal () ? GRUB_ERR_UNKNOWN_DEVICE : GRUB_ERR_NONE, N_("unknown TPM error")); } } -static grub_err_t -grub_tpm2_execute (grub_efi_handle_t tpm_handle, - PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_status_t status; - grub_efi_tpm2_protocol_t *tpm; - grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn); - grub_uint32_t outhdrsize = - sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut); - - tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm2_present (tpm)) - return 0; - - /* UEFI TPM protocol takes the raw operand block, no param block header. */ - status = efi_call_5 (tpm->submit_command, tpm, - inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, - outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); - - switch (status) - { - case GRUB_EFI_SUCCESS: - return 0; - 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_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } -} - -grub_err_t -grub_tpm_execute (PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_handle_t tpm_handle; - grub_uint8_t protocol_version; - - /* Absence of a TPM isn't a failure. */ - if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) - return 0; - - if (protocol_version == 1) - return grub_tpm1_execute (tpm_handle, inbuf, outbuf); - else - return grub_tpm2_execute (tpm_handle, inbuf, outbuf); -} - 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, @@ -242,28 +176,14 @@ grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, event->PCRIndex = pcr; event->EventType = EV_IPL; event->EventSize = grub_strlen (description) + 1; - grub_memcpy (event->Event, description, event->EventSize); + grub_strcpy ((char *) event->Event, description); algorithm = TCG_ALG_SHA; - status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size, - algorithm, event, &eventnum, &lastevent); + status = tpm->log_extend_event (tpm, (grub_addr_t) buf, (grub_uint64_t) size, + algorithm, event, &eventnum, &lastevent); + grub_free (event); - switch (status) - { - case GRUB_EFI_SUCCESS: - return 0; - 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_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } + return grub_efi_log_event_status (status); } static grub_err_t @@ -293,41 +213,122 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, event->Header.EventType = EV_IPL; event->Size = sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1; - grub_memcpy (event->Event, description, grub_strlen (description) + 1); + grub_strcpy ((char *) event->Event, description); - status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf, - (grub_uint64_t) size, event); + status = tpm->hash_log_extend_event (tpm, 0, (grub_addr_t) buf, + (grub_uint64_t) size, event); + grub_free (event); - switch (status) + 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) { - case GRUB_EFI_SUCCESS: - return 0; - 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_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); + 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_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, +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/extcmd.c b/grub-core/commands/extcmd.c index 69574e2b0..c236be13a 100644 --- a/grub-core/commands/extcmd.c +++ b/grub-core/commands/extcmd.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,9 @@ grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, } 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; @@ -110,6 +114,28 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func, 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) { diff --git a/grub-core/commands/file.c b/grub-core/commands/file.c index 2574e6685..19602d757 100644 --- a/grub-core/commands/file.c +++ b/grub-core/commands/file.c @@ -25,10 +25,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -134,7 +134,8 @@ enum IS_IA_EFI, IS_ARM64_EFI, IS_ARM_EFI, - IS_RISCV_EFI, + IS_RISCV32_EFI, + IS_RISCV64_EFI, IS_HIBERNATED, IS_XNU64, IS_XNU32, @@ -305,6 +306,8 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) 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; @@ -390,7 +393,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) } case IS_ARM_LINUX: { - struct linux_arm_kernel_header lh; + struct linux_arch_kernel_header lh; if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) break; @@ -411,13 +414,24 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) } case IS_ARM64_LINUX: { - struct linux_arm64_kernel_header lh; + struct linux_arch_kernel_header lh; if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) break; - if (lh.magic == - grub_cpu_to_le32_compile_time (GRUB_LINUX_ARM64_MAGIC_SIGNATURE)) + /* + * 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; @@ -576,7 +590,8 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) case IS_IA_EFI: case IS_ARM64_EFI: case IS_ARM_EFI: - case IS_RISCV_EFI: + case IS_RISCV32_EFI: + case IS_RISCV64_EFI: { char signature[4]; grub_uint32_t pe_offset; @@ -622,13 +637,13 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) && coff_head.machine != grub_cpu_to_le16_compile_time (GRUB_PE32_MACHINE_ARMTHUMB_MIXED)) break; - if (type == IS_RISCV_EFI + 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_RISCV_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)) diff --git a/grub-core/commands/halt.c b/grub-core/commands/halt.c index f8596ecdc..8f2e88040 100644 --- a/grub-core/commands/halt.c +++ b/grub-core/commands/halt.c @@ -37,7 +37,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/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index 456ba908b..d56b5b0bb 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -39,7 +39,7 @@ static const struct grub_arg_option options[] = { {0, 0, 0, 0, 0, 0} }; -static struct { const char *name; const char *hashname; } aliases[] = +static struct { const char *name; const char *hashname; } aliases[] = { {"sha256sum", "sha256"}, {"sha512sum", "sha512"}, @@ -116,7 +116,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST); if (!hashlist) return grub_errno; - + while (grub_free (buf), (buf = grub_file_getline (hashlist))) { const char *p = buf; @@ -128,19 +128,28 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, high = hextoval (*p++); low = hextoval (*p++); if (high < 0 || low < 0) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + { + grub_free (buf); + 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')) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + { + grub_free (buf); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + } p += 2; if (prefix) { char *filename; - + filename = grub_xasprintf ("%s/%s", prefix, p); if (!filename) - return grub_errno; + { + 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)); @@ -183,7 +192,7 @@ 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); } diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c index d3fa9661e..96f2336f3 100644 --- a/grub-core/commands/hdparm.c +++ b/grub-core/commands/hdparm.c @@ -333,7 +333,7 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) grub_disk_close (disk); return grub_error (GRUB_ERR_IO, "not an ATA device"); } - + /* Change settings. */ if (aam >= 0) @@ -436,9 +436,9 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(hdparm) { - cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm, 0, - N_("[OPTIONS] DISK"), - N_("Get/set ATA disk parameters."), options); + cmd = grub_register_extcmd_lockdown ("hdparm", grub_cmd_hdparm, 0, + N_("[OPTIONS] DISK"), + N_("Get/set ATA disk parameters."), options); } GRUB_MOD_FINI(hdparm) diff --git a/grub-core/commands/help.c b/grub-core/commands/help.c index f0be89baa..113d0d0ca 100644 --- a/grub-core/commands/help.c +++ b/grub-core/commands/help.c @@ -64,11 +64,11 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, stringwidth = 0; - while (unicode_last_screen_position < unicode_last_position && + while (unicode_last_screen_position < unicode_last_position && stringwidth < ((grub_term_width (term) / 2) - 2)) { struct grub_unicode_glyph glyph; - unicode_last_screen_position + unicode_last_screen_position += grub_unicode_aglomerate_comb (unicode_last_screen_position, unicode_last_position - unicode_last_screen_position, @@ -88,7 +88,7 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, if (cnt % 2) grub_printf ("\n"); cnt++; - + grub_free (command_help); grub_free (unicode_command_help); } @@ -135,6 +135,8 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, } } + grub_printf ("\n\nTo enable less(1)-like paging, \"set pager=1\".\n"); + return 0; } diff --git a/grub-core/commands/hexdump.c b/grub-core/commands/hexdump.c index eaa12465b..d6f61d98a 100644 --- a/grub-core/commands/hexdump.c +++ b/grub-core/commands/hexdump.c @@ -24,6 +24,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -51,7 +52,11 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args) length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256; if (!grub_strcmp (args[0], "(mem)")) - hexdump (skip, (char *) (grub_addr_t) skip, length); + { + 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); + } else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')')) { grub_disk_t disk; diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index c839b704d..1f0c5341d 100644 --- a/grub-core/commands/i386/cmostest.c +++ b/grub-core/commands/i386/cmostest.c @@ -27,7 +27,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_err_t parse_args (int argc, char *argv[], int *byte, int *bit) { - char *rest; + const char *rest; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "address required"); @@ -104,13 +104,13 @@ static grub_command_t cmd, cmd_clean, cmd_set; GRUB_MOD_INIT(cmostest) { - cmd = grub_register_command ("cmostest", grub_cmd_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 ("cmosclean", grub_cmd_cmosclean, + 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 ("cmosset", grub_cmd_cmosset, + 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.")); diff --git a/grub-core/commands/i386/coreboot/cb_timestamps.c b/grub-core/commands/i386/coreboot/cb_timestamps.c index e97ea6bed..c44abb3fa 100644 --- a/grub-core/commands/i386/coreboot/cb_timestamps.c +++ b/grub-core/commands/i386/coreboot/cb_timestamps.c @@ -84,7 +84,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, 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", + 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) diff --git a/grub-core/commands/i386/coreboot/cbls.c b/grub-core/commands/i386/coreboot/cbls.c index 102291f42..50b7b8750 100644 --- a/grub-core/commands/i386/coreboot/cbls.c +++ b/grub-core/commands/i386/coreboot/cbls.c @@ -84,7 +84,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, 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, + 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, diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index 7f7f2d41c..a7ee4c9bd 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -31,9 +31,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); -/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13. */ -static grub_uint32_t *const int13slot = (grub_uint32_t *) (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 @@ -185,7 +182,7 @@ list_mappings (void) return GRUB_ERR_NONE; } - /* TRANSLATORS: This is the header of mapping list. + /* 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")); @@ -280,6 +277,8 @@ 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; @@ -354,6 +353,9 @@ 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; diff --git a/grub-core/commands/i386/pc/halt.c b/grub-core/commands/i386/pc/halt.c index 1e7c2c9b3..e87e8dccd 100644 --- a/grub-core/commands/i386/pc/halt.c +++ b/grub-core/commands/i386/pc/halt.c @@ -59,7 +59,7 @@ grub_halt (int no_apm) regs.ebx = 0; regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x15, ®s); - + if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY) stop (); diff --git a/grub-core/commands/i386/pc/lsapm.c b/grub-core/commands/i386/pc/lsapm.c index c82476df1..8f49880da 100644 --- a/grub-core/commands/i386/pc/lsapm.c +++ b/grub-core/commands/i386/pc/lsapm.c @@ -34,7 +34,7 @@ grub_apm_get_info (struct grub_apm_info *info) 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; diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c index c81813105..7ff8cd633 100644 --- a/grub-core/commands/i386/pc/play.c +++ b/grub-core/commands/i386/pc/play.c @@ -80,7 +80,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), { if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, + 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. @@ -132,7 +132,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), } else { - char *end; + const char *end; unsigned tempo; struct note note; int i; diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c index 26d9acd3d..282bb5d42 100644 --- a/grub-core/commands/i386/pc/sendkey.c +++ b/grub-core/commands/i386/pc/sendkey.c @@ -55,12 +55,12 @@ static const struct grub_arg_option options[] = {"no-led", 0, 0, N_("don't update LED state"), 0, 0}, {0, 0, 0, 0, 0, 0} }; -static int simple_flag_offsets[] +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 +struct keysym { const char *unshifted_name; /* the name in unshifted state */ @@ -171,13 +171,13 @@ static struct keysym keysym_table[] = {"right", 0, 0xe0, 0, 0x4d} }; -/* Set a simple flag in flags variable +/* 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); @@ -199,7 +199,7 @@ 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 + if (grub_strcmp (state.arg, "off") == 0 || grub_strcmp (state.arg, "0") == 0 || grub_strcmp (state.arg, "unpress") == 0) return 0; @@ -216,12 +216,12 @@ static grub_err_t grub_sendkey_postboot (void) { /* For convention: pointer to flags. */ - grub_uint32_t *flags = (grub_uint32_t *) 0x417; + grub_uint32_t *flags = grub_absolute_pointer (0x417); *flags = oldflags; - *((char *) 0x41a) = 0x1e; - *((char *) 0x41c) = 0x1e; + *((volatile char *) grub_absolute_pointer (0x41a)) = 0x1e; + *((volatile char *) grub_absolute_pointer (0x41c)) = 0x1e; return GRUB_ERR_NONE; } @@ -231,13 +231,13 @@ static grub_err_t grub_sendkey_preboot (int noret __attribute__ ((unused))) { /* For convention: pointer to flags. */ - grub_uint32_t *flags = (grub_uint32_t *) 0x417; + grub_uint32_t *flags = grub_absolute_pointer (0x417); oldflags = *flags; - + /* Set the sendkey. */ - *((char *) 0x41a) = 0x1e; - *((char *) 0x41c) = keylen + 0x1e; + *((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. */ @@ -247,7 +247,7 @@ grub_sendkey_preboot (int noret __attribute__ ((unused))) /* 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. */ @@ -294,10 +294,10 @@ find_key_code (char *key) for (i = 0; i < ARRAY_SIZE(keysym_table); i++) { - if (keysym_table[i].unshifted_name + 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 + else if (keysym_table[i].shifted_name && grub_strcmp (key, keysym_table[i].shifted_name) == 0) return keysym_table[i].keycode; } @@ -313,10 +313,10 @@ find_ascii_code (char *key) for (i = 0; i < ARRAY_SIZE(keysym_table); i++) { - if (keysym_table[i].unshifted_name + 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 + else if (keysym_table[i].shifted_name && grub_strcmp (key, keysym_table[i].shifted_name) == 0) return keysym_table[i].shifted_ascii; } @@ -340,7 +340,7 @@ grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args) for (i = 0; i < argc && keylen < 0x20; i++) { int key_code; - + key_code = find_key_code (args[i]); if (key_code) { @@ -353,7 +353,7 @@ grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args) { unsigned i; for (i = 0; i < ARRAY_SIZE(simple_flag_offsets); i++) - grub_sendkey_set_simple_flag (simple_flag_offsets[i], + grub_sendkey_set_simple_flag (simple_flag_offsets[i], grub_sendkey_parse_op(state[i])); } @@ -374,8 +374,8 @@ GRUB_MOD_INIT (sendkey) keypresses. */ N_("Emulate a keystroke sequence"), options); - preboot_hook - = grub_loader_register_preboot_hook (grub_sendkey_preboot, + preboot_hook + = grub_loader_register_preboot_hook (grub_sendkey_preboot, grub_sendkey_postboot, GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE); } diff --git a/grub-core/commands/i386/pc/smbios.c b/grub-core/commands/i386/pc/smbios.c new file mode 100644 index 000000000..069d66367 --- /dev/null +++ b/grub-core/commands/i386/pc/smbios.c @@ -0,0 +1,52 @@ +/* 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 index 15b9adfca..2e42f6197 100644 --- a/grub-core/commands/i386/rdmsr.c +++ b/grub-core/commands/i386/rdmsr.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include GRUB_MOD_LICENSE("GPLv3+"); @@ -42,27 +42,16 @@ static const struct grub_arg_option options[] = static grub_err_t grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) { - grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr; + grub_err_t err; + grub_uint32_t addr; grub_uint64_t value; - char *ptr; + const char *ptr; char buf[sizeof("1122334455667788")]; - /* - * 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_error (GRUB_ERR_BUG, N_("unsupported instruction")); + err = grub_cpu_is_msr_supported (); - grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]); - - if (max_cpuid < 1) - return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); - - grub_cpuid (1, a, b, c, features); - - if (!(features & (1 << 5))) - return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); + 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")); @@ -76,7 +65,7 @@ grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) if (*ptr != '\0') return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); - value = grub_msr_read (addr); + value = grub_rdmsr (addr); if (ctxt->state[0].set) { diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c index 9c5e510eb..7fbedaed9 100644 --- a/grub-core/commands/i386/wrmsr.c +++ b/grub-core/commands/i386/wrmsr.c @@ -24,9 +24,10 @@ #include #include #include +#include #include #include -#include +#include GRUB_MOD_LICENSE("GPLv3+"); @@ -35,26 +36,15 @@ 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_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr; + grub_err_t err; + grub_uint32_t addr; grub_uint64_t value; - char *ptr; + const char *ptr; - /* - * 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_error (GRUB_ERR_BUG, N_("unsupported instruction")); + err = grub_cpu_is_msr_supported (); - grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]); - - if (max_cpuid < 1) - return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); - - grub_cpuid (1, a, b, c, features); - - if (!(features & (1 << 5))) - return grub_error (GRUB_ERR_BUG, N_("unsupported instruction")); + 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")); @@ -76,15 +66,15 @@ grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char if (*ptr != '\0') return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); - grub_msr_write (addr, value); + grub_wrmsr (addr, value); return GRUB_ERR_NONE; } GRUB_MOD_INIT(wrmsr) { - cmd_write = grub_register_command ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), - N_("Write a value to a CPU model specific register.")); + 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) diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c new file mode 100644 index 000000000..4958b04a9 --- /dev/null +++ b/grub-core/commands/ieee1275/ibmvtpm.c @@ -0,0 +1,117 @@ +/* + * 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 index a0c164e54..584baec8f 100644 --- a/grub-core/commands/iorw.c +++ b/grub-core/commands/iorw.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -131,17 +132,17 @@ GRUB_MOD_INIT(memrw) N_("PORT"), N_("Read 32-bit value from PORT."), options); cmd_write_byte = - grub_register_command ("outb", grub_cmd_write, - N_("PORT VALUE [MASK]"), - N_("Write 8-bit VALUE to PORT.")); + 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 ("outw", grub_cmd_write, - N_("PORT VALUE [MASK]"), - N_("Write 16-bit VALUE to PORT.")); + 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 ("outl", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 32-bit VALUE to PORT.")); + grub_register_command_lockdown ("outl", grub_cmd_write, + N_("ADDR VALUE [MASK]"), + N_("Write 32-bit VALUE to PORT.")); } GRUB_MOD_FINI(memrw) diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c index c05d6128a..aa3ba34f2 100644 --- a/grub-core/commands/keylayouts.c +++ b/grub-core/commands/keylayouts.c @@ -35,7 +35,7 @@ static struct grub_keyboard_layout layout_us = { /* Keyboard errors. Handled by driver. */ /* 0x00 */ 0, 0, 0, 0, - /* 0x04 */ 'a', 'b', 'c', 'd', + /* 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', @@ -43,11 +43,11 @@ static struct grub_keyboard_layout layout_us = { /* 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. + Map 0x31 to 0. */ /* 0x30 */ ']', 0, '\\', ';', '\'', '`', ',', '.', /* 0x39 is CapsLock. Handled by driver. */ - /* 0x38 */ '/', 0, GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, + /* 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, @@ -56,16 +56,16 @@ static struct grub_keyboard_layout layout_us = { /* PrtScr and ScrollLock. Not handled yet. */ /* 0x46 */ 0, 0, /* 0x48 is Pause. Not handled yet. */ - /* 0x48 */ 0, GRUB_TERM_KEY_INSERT, + /* 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 */ '/', '*', + /* 0x54 */ '/', '*', /* 0x56 */ '-', '+', - /* 0x58 */ '\n', GRUB_TERM_KEY_END, + /* 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, @@ -77,7 +77,7 @@ static struct grub_keyboard_layout layout_us = { /* Keyboard errors. Handled by driver. */ /* 0x00 */ 0, 0, 0, 0, - /* 0x04 */ 'A', 'B', 'C', 'D', + /* 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', '!', '@', @@ -87,27 +87,27 @@ static struct grub_keyboard_layout layout_us = { /* 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. + 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, + /* 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, + /* 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, @@ -118,7 +118,7 @@ static struct grub_keyboard_layout layout_us = { /* 0x51 */ GRUB_TERM_KEY_DOWN | GRUB_TERM_SHIFT, /* 0x53 is NumLock. Handled by driver. */ /* 0x52 */ GRUB_TERM_KEY_UP | GRUB_TERM_SHIFT, 0, - /* 0x54 */ '/', '*', + /* 0x54 */ '/', '*', /* 0x56 */ '-', '+', /* 0x58 */ '\n' | GRUB_TERM_SHIFT, '1', '2', '3', '4', '5','6', '7', /* 0x60 */ '8', '9', '0', '.', '|' @@ -148,7 +148,7 @@ map_key_core (int code, int status, int *alt_gr_consumed) else if (grub_current_layout->keyboard_map_l3[code]) { *alt_gr_consumed = 1; - return grub_current_layout->keyboard_map_l3[code]; + return grub_current_layout->keyboard_map_l3[code]; } } if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) @@ -172,12 +172,12 @@ grub_term_map_key (grub_keyboard_key_t code, int status) } 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')) @@ -185,8 +185,8 @@ grub_term_map_key (grub_keyboard_key_t code, int status) else if ((key >= 'A') && (key <= 'Z')) key += 'a' - 'A'; } - - if ((status & GRUB_TERM_STATUS_LALT) || + + 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)) @@ -212,7 +212,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), { const char *prefix = grub_env_get ("prefix"); if (!prefix) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable `%s' isn't set"), "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; diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c index 460cf4e7e..ff3f58781 100644 --- a/grub-core/commands/keystatus.c +++ b/grub-core/commands/keystatus.c @@ -35,24 +35,6 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -static 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; -} - static grub_err_t grub_cmd_keystatus (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index db7a8f002..3bf9fe2e4 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -32,6 +32,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -104,13 +105,22 @@ legacy_file (const char *filename) 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, grub_strlen (suffix) - + grub_strlen (newsuffix) + 1); + suffix = grub_realloc (suffix, sz); if (!suffix) { grub_free (t); + + fail_0: grub_free (entrysrc); grub_free (parsed); grub_free (newsuffix); @@ -154,13 +164,22 @@ legacy_file (const char *filename) 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, grub_strlen (entrysrc) - + grub_strlen (parsed) + 1); + entrysrc = grub_realloc (entrysrc, sz); if (!entrysrc) { grub_free (t); + + fail_1: grub_free (parsed); grub_free (suffix); return grub_errno; @@ -179,7 +198,6 @@ legacy_file (const char *filename) const char **args = grub_malloc (sizeof (args[0])); if (!args) { - grub_file_close (file); grub_free (suffix); grub_free (entrysrc); return grub_errno; @@ -238,8 +256,8 @@ grub_cmd_legacy_source (struct grub_command *cmd, } static enum - { - GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD + { + GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD } kernel_type; static grub_err_t @@ -254,7 +272,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), char **cutargs; int cutargc; grub_err_t err = GRUB_ERR_NONE; - + for (i = 0; i < 2; i++) { /* FIXME: really support this. */ @@ -314,7 +332,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), if (argc < 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1)); + cutargs = grub_calloc (argc - 1, sizeof (cutargs[0])); if (!cutargs) return grub_errno; cutargc = argc - 1; @@ -391,7 +409,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), if (dev) grub_device_close (dev); } - + /* k*BSD didn't really work well with grub-legacy. */ if (kernel_type == GUESS_IT || kernel_type == KFREEBSD) { @@ -436,7 +454,7 @@ grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), { char rbuf[3] = "-r"; bsdargc = cutargc + 2; - bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc); + bsdargs = grub_calloc (bsdargc, sizeof (bsdargs[0])); if (!bsdargs) { err = grub_errno; @@ -559,7 +577,7 @@ grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), "module"); - newargs = grub_malloc ((argc + 1) * sizeof (newargs[0])); + newargs = grub_calloc (argc + 1, sizeof (newargs[0])); if (!newargs) return grub_errno; grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); @@ -613,7 +631,7 @@ check_password_md5_real (const char *entered, 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 */ @@ -635,7 +653,7 @@ check_password_md5_real (const char *entered, 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); diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c index 3fd664aac..166445849 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -352,16 +352,16 @@ struct grub_cmd_save_env_ctx }; /* Store blocklists in a linked list. */ -static void +static grub_err_t save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length, - void *data) + char *buf __attribute__ ((unused)), void *data) { struct grub_cmd_save_env_ctx *ctx = data; struct blocklist *block; block = grub_malloc (sizeof (*block)); if (! block) - return; + return GRUB_ERR_NONE; block->sector = sector; block->offset = offset; @@ -374,6 +374,8 @@ save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length, ctx->tail = block; if (! ctx->head) ctx->head = block; + + return GRUB_ERR_NONE; } static grub_err_t diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 5b7491aa4..c3bcb089a 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -70,7 +70,7 @@ grub_ls_list_devices (int longlist) FOR_NET_APP_LEVEL (proto) { if (first) - grub_puts_ (N_ ("Network protocols:")); + grub_puts_ (N_("Network protocols:")); first = 0; grub_printf ("%s ", proto->name); } @@ -87,37 +87,44 @@ grub_ls_list_devices (int longlist) 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_files (const char *filename, const struct grub_dirhook_info *info, - void *data) -{ - struct grub_ls_list_files_ctx *ctx = data; - - if (ctx->all || filename[0] != '.') - grub_printf ("%s%s ", filename, info->dir ? "/" : ""); - - return 0; -} - -/* Helper for grub_ls_list_files. */ -static int -print_files_long (const char *filename, const struct grub_dirhook_info *info, +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; - char *pathname; if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/') pathname = grub_xasprintf ("%s%s", ctx->dirname, filename); @@ -131,20 +138,19 @@ print_files_long (const char *filename, const struct grub_dirhook_info *info, should be reported as directories. */ file = grub_file_open (pathname, GRUB_FILE_TYPE_GET_SIZE | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (! file) + if (file) { - grub_errno = 0; - grub_free (pathname); - return 0; - } - - if (! ctx->human) - grub_printf ("%-12llu", (unsigned long long) file->size); - else - grub_printf ("%-12s", grub_get_human_size (file->size, + 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); - grub_free (pathname); + grub_file_close (file); + } + else + grub_xputs ("????????????"); + + grub_errno = GRUB_ERR_NONE; } else grub_printf ("%-12s", _("DIR")); @@ -165,13 +171,22 @@ print_files_long (const char *filename, const struct grub_dirhook_info *info, datetime.day, datetime.hour, datetime.minute, datetime.second); } - grub_printf ("%s%s\n", filename, info->dir ? "/" : ""); + /* + * 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) +grub_ls_list_files (char *dirname, int longlist, int all, int human, int dirhdr) { char *device_name; grub_fs_t fs; @@ -196,7 +211,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) goto fail; } - if (! *path) + if (! *path && device_name) { if (grub_errno == GRUB_ERR_UNKNOWN_FS) grub_errno = GRUB_ERR_NONE; @@ -216,44 +231,38 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) { struct grub_ls_list_files_ctx ctx = { .dirname = dirname, + .filename = NULL, .all = all, - .human = human + .human = human, + .longlist = longlist, + .print_dirhdr = dirhdr }; - if (longlist) - (fs->fs_dir) (dev, path, print_files_long, &ctx); - else - (fs->fs_dir) (dev, path, print_files, &ctx); + (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. */ - char *p; - grub_file_t file; - struct grub_dirhook_info info; - grub_errno = 0; + ctx.print_dirhdr = 0; + ctx.filename = grub_strrchr (dirname, '/'); + if (ctx.filename == NULL) + goto fail; + ++(ctx.filename); - file = grub_file_open (dirname, GRUB_FILE_TYPE_GET_SIZE - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (! file) + ctx.dirname = grub_strndup (dirname, ctx.filename - dirname); + if (ctx.dirname == NULL) goto fail; - grub_file_close (file); + (fs->fs_dir) (dev, ctx.dirname + (path - dirname), print_file, &ctx); - 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, &ctx); - else - print_files (p, &info, &ctx); - - grub_free (dirname); + grub_free (ctx.dirname); } if (grub_errno == GRUB_ERR_NONE) @@ -268,7 +277,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) grub_free (device_name); - return 0; + return GRUB_ERR_NONE; } static grub_err_t @@ -281,10 +290,10 @@ grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char **args) 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); + grub_ls_list_files (args[i], state[0].set, state[2].set, state[1].set, + argc > 1); - return 0; + return GRUB_ERR_NONE; } static grub_extcmd_t cmd; diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c index 082491405..f7a1a1b05 100644 --- a/grub-core/commands/lsacpi.c +++ b/grub-core/commands/lsacpi.c @@ -35,7 +35,7 @@ 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 (" "); + grub_printf (" "); } #define print_field(x) print_strn(x, sizeof (x)) diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c index 65213a372..b3cdab1b3 100644 --- a/grub-core/commands/lspci.c +++ b/grub-core/commands/lspci.c @@ -171,7 +171,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 +195,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"); diff --git a/grub-core/commands/macbless.c b/grub-core/commands/macbless.c index 85cefd0f7..3d761452a 100644 --- a/grub-core/commands/macbless.c +++ b/grub-core/commands/macbless.c @@ -220,12 +220,10 @@ 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.")); + 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.")); + N_("Bless DIR of HFS or HFS+ partition for PPC macs.")); } GRUB_MOD_FINI(macbless) diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c index 98769eadb..3542683d1 100644 --- a/grub-core/commands/memrw.c +++ b/grub-core/commands/memrw.c @@ -22,6 +22,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -121,29 +122,32 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) GRUB_MOD_INIT(memrw) { cmd_read_byte = - grub_register_extcmd ("read_byte", grub_cmd_read, 0, - N_("ADDR"), N_("Read 8-bit value from ADDR."), - options); + grub_register_extcmd_lockdown ("read_byte", grub_cmd_read, 0, + N_("ADDR"), + N_("Read 8-bit value from ADDR."), + options); cmd_read_word = - grub_register_extcmd ("read_word", grub_cmd_read, 0, - N_("ADDR"), N_("Read 16-bit value from ADDR."), - options); + grub_register_extcmd_lockdown ("read_word", grub_cmd_read, 0, + N_("ADDR"), + N_("Read 16-bit value from ADDR."), + options); cmd_read_dword = - grub_register_extcmd ("read_dword", grub_cmd_read, 0, - N_("ADDR"), N_("Read 32-bit value from ADDR."), - options); + grub_register_extcmd_lockdown ("read_dword", grub_cmd_read, 0, + N_("ADDR"), + N_("Read 32-bit value from ADDR."), + options); cmd_write_byte = - grub_register_command ("write_byte", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 8-bit VALUE to ADDR.")); + grub_register_command_lockdown ("write_byte", grub_cmd_write, + N_("ADDR VALUE [MASK]"), + N_("Write 8-bit VALUE to ADDR.")); cmd_write_word = - grub_register_command ("write_word", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 16-bit VALUE to ADDR.")); + grub_register_command_lockdown ("write_word", grub_cmd_write, + N_("ADDR VALUE [MASK]"), + N_("Write 16-bit VALUE to ADDR.")); cmd_write_dword = - grub_register_command ("write_dword", grub_cmd_write, - N_("ADDR VALUE [MASK]"), - N_("Write 32-bit VALUE to ADDR.")); + grub_register_command_lockdown ("write_dword", grub_cmd_write, + N_("ADDR VALUE [MASK]"), + N_("Write 32-bit VALUE to ADDR.")); } GRUB_MOD_FINI(memrw) diff --git a/grub-core/commands/memtools.c b/grub-core/commands/memtools.c new file mode 100644 index 000000000..ae0a9bec3 --- /dev/null +++ b/grub-core/commands/memtools.c @@ -0,0 +1,152 @@ +/* + * 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 index 2c5363da7..720e6d8ea 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -154,7 +154,7 @@ grub_normal_add_menu_entry (int argc, const char **args, goto fail; /* Save argc, args to pass as parameters to block arg later. */ - menu_args = grub_malloc (sizeof (char*) * (argc + 1)); + menu_args = grub_calloc (argc + 1, sizeof (char *)); if (! menu_args) goto fail; @@ -230,7 +230,7 @@ setparams_prefix (int argc, char **args) len += 3; /* 3 = 1 space + 2 quotes */ p = args[i]; while (*p) - len += (*p++ == '\'' ? 3 : 1); + len += (*p++ == '\'' ? 4 : 1); } result = grub_malloc (len + 2); diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c index 6bbce3128..ff4ff021c 100644 --- a/grub-core/commands/minicmd.c +++ b/grub-core/commands/minicmd.c @@ -29,6 +29,10 @@ #include #include +#ifdef GRUB_MACHINE_EFI +#include +#endif + GRUB_MOD_LICENSE ("GPLv3+"); /* cat FILE */ @@ -140,8 +144,11 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)), if (grub_dl_is_persistent (mod)) return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent module"); - if (grub_dl_unref (mod) <= 0) - grub_dl_unload (mod); + 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; } @@ -164,7 +171,7 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), { grub_dl_dep_t dep; - grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count); + 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) @@ -184,6 +191,13 @@ 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. */ } @@ -200,8 +214,8 @@ GRUB_MOD_INIT(minicmd) grub_register_command ("help", grub_mini_cmd_help, 0, N_("Show this message.")); cmd_dump = - grub_register_command ("dump", grub_mini_cmd_dump, - N_("ADDR [SIZE]"), N_("Show memory contents.")); + 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.")); diff --git a/grub-core/commands/mips/loongson/lsspd.c b/grub-core/commands/mips/loongson/lsspd.c index a88ab87ac..97569816d 100644 --- a/grub-core/commands/mips/loongson/lsspd.c +++ b/grub-core/commands/mips/loongson/lsspd.c @@ -44,7 +44,7 @@ grub_cmd_lsspd (grub_command_t cmd __attribute__ ((unused)), } 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; diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c index 699447d11..580c8d3b0 100644 --- a/grub-core/commands/nativedisk.c +++ b/grub-core/commands/nativedisk.c @@ -31,7 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static const char *modnames_def[] = { +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" @@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)), else path_prefix = prefix; - mods = grub_malloc (argc * sizeof (mods[0])); + mods = grub_calloc (argc, sizeof (mods[0])); if (!mods) return grub_errno; diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c index 22b46b187..ff45c65e6 100644 --- a/grub-core/commands/parttool.c +++ b/grub-core/commands/parttool.c @@ -59,7 +59,13 @@ 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_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc)); + grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc)); + if (!cur->args) + { + grub_free (cur); + curhandle--; + return -1; + } grub_memcpy (cur->args, args, (nargs + 1) * sizeof (struct grub_parttool_argdesc)); @@ -257,7 +263,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), return err; } - parsed = (int *) grub_zalloc (argc * sizeof (int)); + parsed = (int *) grub_calloc (argc, sizeof (int)); for (i = 1; i < argc; i++) if (! parsed[i]) @@ -290,7 +296,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } ptool = cur; pargs = (struct grub_parttool_args *) - grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args)); + grub_calloc (ptool->nargs, sizeof (struct grub_parttool_args)); for (j = i; j < argc; j++) if (! parsed[j]) { @@ -309,7 +315,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), switch (curarg->type) { case GRUB_PARTTOOL_ARG_BOOL: - pargs[curarg - ptool->args].bool + pargs[curarg - ptool->args].b = (args[j][grub_strlen (curarg->name)] != '-'); break; diff --git a/grub-core/commands/password_pbkdf2.c b/grub-core/commands/password_pbkdf2.c index da636e621..bcb902f97 100644 --- a/grub-core/commands/password_pbkdf2.c +++ b/grub-core/commands/password_pbkdf2.c @@ -86,7 +86,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_err_t err; - char *ptr, *ptr2; + const char *ptr, *ptr2; grub_uint8_t *ptro; struct pbkdf2_password *pass; @@ -162,7 +162,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; diff --git a/grub-core/commands/pcidump.c b/grub-core/commands/pcidump.c index f99ad4a21..f72628fce 100644 --- a/grub-core/commands/pcidump.c +++ b/grub-core/commands/pcidump.c @@ -95,7 +95,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (ctxt->state[0].set) { ptr = ctxt->state[0].arg; - ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff); + ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -108,8 +108,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (*ptr != ':') return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); ptr++; - ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff) - << 16; + ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16; if (grub_errno == GRUB_ERR_BAD_NUMBER) grub_errno = GRUB_ERR_NONE; else @@ -121,10 +120,10 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (ctxt->state[1].set) { const char *optr; - + ptr = ctxt->state[1].arg; optr = ptr; - ctx.bus = grub_strtoul (ptr, (char **) &ptr, 16); + ctx.bus = grub_strtoul (ptr, &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -138,7 +137,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); ptr++; optr = ptr; - ctx.device = grub_strtoul (ptr, (char **) &ptr, 16); + ctx.device = grub_strtoul (ptr, &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -149,7 +148,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (*ptr == '.') { ptr++; - ctx.function = grub_strtoul (ptr, (char **) &ptr, 16); + ctx.function = grub_strtoul (ptr, &ptr, 16); if (grub_errno) return grub_errno; ctx.check_function = 1; diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c index bbf6871fe..5fadc33c4 100644 --- a/grub-core/commands/pgp.c +++ b/grub-core/commands/pgp.c @@ -74,7 +74,7 @@ read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len) if (type == 0) { *out_type = 0xfe; - return 0; + return 0; } if (!(type & 0x80)) @@ -166,7 +166,7 @@ struct 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[] = +} 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" }, @@ -320,7 +320,7 @@ grub_load_public_key (grub_file_t f) 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)) { @@ -335,7 +335,7 @@ grub_load_public_key (grub_file_t f) 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)) { @@ -479,7 +479,7 @@ grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig) 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")); @@ -633,8 +633,8 @@ grub_verify_signature_real (struct grub_pubkey_context *ctxt, if (!sk) { /* TRANSLATORS: %08x is 32-bit key id. */ - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), - keyid); + grub_error (GRUB_ERR_BAD_SIGNATURE, + N_("public key %08" PRIxGRUB_UINT64_T " not found"), keyid); goto fail; } @@ -922,7 +922,7 @@ grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)), return grub_strdup (sec ? "enforce" : "no"); } -static grub_ssize_t +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); @@ -931,7 +931,7 @@ pseudo_read (struct grub_file *file, char *buf, grub_size_t len) /* Filesystem descriptor. */ -struct grub_fs pseudo_fs = +struct grub_fs pseudo_fs = { .name = "pseudo", .fs_read = pseudo_read @@ -1010,6 +1010,8 @@ GRUB_MOD_INIT(pgp) 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); diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index 95d272287..be9637f33 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -45,6 +47,7 @@ static const struct grub_arg_option options[] = {"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} }; @@ -98,9 +101,66 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) 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) - return grub_errno; + { + grub_error_push (); + grub_device_close (dev); + grub_error_pop (); + return grub_errno; + } if (state[3].set) { if (state[0].set) @@ -114,14 +174,23 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) { char *uuid; if (! fs->fs_uuid) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("%s does not support UUIDs"), fs->name); + { + 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 (err) - return err; + { + grub_device_close (dev); + return err; + } if (! uuid) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("%s does not support UUIDs"), fs->name); + { + grub_device_close (dev); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("%s does not support UUIDs"), fs->name); + } if (state[0].set) grub_env_set (state[0].arg, uuid); @@ -135,16 +204,25 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) { char *label; if (! fs->fs_label) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("filesystem `%s' does not support labels"), - fs->name); + { + 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 (err) - return err; + { + grub_device_close (dev); + return err; + } if (! label) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("filesystem `%s' does not support labels"), - fs->name); + { + grub_device_close (dev); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("filesystem `%s' does not support labels"), + fs->name); + } if (state[0].set) grub_env_set (state[0].arg, label); diff --git a/grub-core/commands/read.c b/grub-core/commands/read.c index fe3e88b15..8d72e45c9 100644 --- a/grub-core/commands/read.c +++ b/grub-core/commands/read.c @@ -23,21 +23,29 @@ #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 (void) +grub_getline (int silent) { - int i; + grub_size_t i; char *line; char *tmp; - char c; + int c; + grub_size_t alloc_size; i = 0; - line = grub_malloc (1 + i + sizeof('\0')); + line = grub_malloc (1 + sizeof('\0')); if (! line) return NULL; @@ -47,11 +55,23 @@ grub_getline (void) if ((c == '\n') || (c == '\r')) break; - line[i] = c; - if (grub_isprint (c)) + if (!grub_isprint (c)) + continue; + + line[i] = (char) c; + if (!silent) grub_printf ("%c", c); - i++; - tmp = grub_realloc (line, 1 + i + sizeof('\0')); + 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); if (! tmp) { grub_free (line); @@ -65,9 +85,11 @@ grub_getline (void) } static grub_err_t -grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) +grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **args) { - char *line = grub_getline (); + struct grub_arg_list *state = ctxt->state; + char *line = grub_getline (state[0].set); + if (! line) return grub_errno; if (argc > 0) @@ -77,16 +99,16 @@ grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **arg return 0; } -static grub_command_t cmd; +static grub_extcmd_t cmd; GRUB_MOD_INIT(read) { - cmd = grub_register_command ("read", grub_cmd_read, - N_("[ENVVAR]"), - N_("Set variable with user input.")); + cmd = grub_register_extcmd ("read", grub_cmd_read, 0, + N_("[-s] [ENVVAR]"), + N_("Set variable with user input."), options); } GRUB_MOD_FINI(read) { - grub_unregister_command (cmd); + grub_unregister_extcmd (cmd); } diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c index f00b184c8..246af39f0 100644 --- a/grub-core/commands/regexp.c +++ b/grub-core/commands/regexp.c @@ -36,7 +36,7 @@ static const struct grub_arg_option options[] = groups with parentheses. These groups are then numbered and you can save some of them in variables. In other programs - those components aree often referenced with + 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. @@ -64,7 +64,7 @@ set_matches (char **varnames, char *str, grub_size_t nmatches, { int i; char *p; - char *q; + const char * q; grub_err_t err; unsigned long j; @@ -116,7 +116,7 @@ grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args) if (ret) goto fail; - matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1)); + matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches)); if (! matches) goto fail; diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c index ed090b3af..49b679e80 100644 --- a/grub-core/commands/search.c +++ b/grub-core/commands/search.c @@ -47,13 +47,48 @@ struct search_ctx { const char *key; const char *var; - int no_floppy; + 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) @@ -62,9 +97,49 @@ iterate_device (const char *name, void *data) int found = 0; /* Skip floppy drives when requested. */ - if (ctx->no_floppy && + if (ctx->flags & SEARCH_FLAGS_NO_FLOPPY && name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') - return 1; + 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 @@ -181,14 +256,14 @@ part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) if (!devname) return 1; ret = iterate_device (devname, ctx); - grub_free (devname); + grub_free (devname); return ret; } /* Helper for FUNC_NAME. */ static void -try (struct search_ctx *ctx) +try (struct search_ctx *ctx) { unsigned i; struct cache_entry **prev; @@ -261,13 +336,13 @@ try (struct search_ctx *ctx) } void -FUNC_NAME (const char *key, const char *var, int no_floppy, +FUNC_NAME (const char *key, const char *var, enum search_flags flags, char **hints, unsigned nhints) { struct search_ctx ctx = { .key = key, .var = var, - .no_floppy = no_floppy, + .flags = flags, .hints = hints, .nhints = nhints, .count = 0, diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index d7fd26b94..5f536006c 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -40,6 +40,8 @@ static const struct grub_arg_option options[] = 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}, @@ -73,6 +75,8 @@ enum options SEARCH_FS_UUID, SEARCH_SET, SEARCH_NO_FLOPPY, + SEARCH_EFIDISK_ONLY, + SEARCH_CRYPTODISK_ONLY, SEARCH_HINT, SEARCH_HINT_IEEE1275, SEARCH_HINT_BIOS, @@ -89,6 +93,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) 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++) @@ -122,7 +127,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) for (i = 0; state[SEARCH_HINT_BAREMETAL].args[i]; i++) nhints++; - hints = grub_malloc (sizeof (hints[0]) * nhints); + hints = grub_calloc (nhints, sizeof (hints[0])); if (!hints) return grub_errno; j = 0; @@ -180,15 +185,21 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) 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, state[SEARCH_NO_FLOPPY].set, - hints, nhints); + grub_search_label (id, var, flags, hints, nhints); else if (state[SEARCH_FS_UUID].set) - grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); + grub_search_fs_uuid (id, var, flags, hints, nhints); else if (state[SEARCH_FILE].set) - grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); + grub_search_fs_file (id, var, flags, hints, nhints); else grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); @@ -204,7 +215,7 @@ 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] [--hint HINT [--hint HINT] ...]" + N_("[-f|-l|-u|-s|-n] [--cryptodisk-only] [--hint HINT [--hint HINT] ...]" " NAME"), N_("Search devices by file, filesystem label" " or filesystem UUID." diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index d5bc97d60..5917625f8 100644 --- a/grub-core/commands/setpci.c +++ b/grub-core/commands/setpci.c @@ -169,7 +169,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (ctxt->state[0].set) { ptr = ctxt->state[0].arg; - pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff); + pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -182,8 +182,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (*ptr != ':') return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); ptr++; - pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff) - << 16; + pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16; if (grub_errno == GRUB_ERR_BAD_NUMBER) grub_errno = GRUB_ERR_NONE; else @@ -197,10 +196,10 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (ctxt->state[1].set) { const char *optr; - + ptr = ctxt->state[1].arg; optr = ptr; - bus = grub_strtoul (ptr, (char **) &ptr, 16); + bus = grub_strtoul (ptr, &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -214,7 +213,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); ptr++; optr = ptr; - device = grub_strtoul (ptr, (char **) &ptr, 16); + device = grub_strtoul (ptr, &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -225,7 +224,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (*ptr == '.') { ptr++; - function = grub_strtoul (ptr, (char **) &ptr, 16); + function = grub_strtoul (ptr, &ptr, 16); if (grub_errno) return grub_errno; check_function = 1; @@ -253,7 +252,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (i == ARRAY_SIZE (pci_registers)) { regsize = 0; - regaddr = grub_strtoul (ptr, (char **) &ptr, 16); + regaddr = grub_strtoul (ptr, &ptr, 16); if (grub_errno) return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown register"); } @@ -270,7 +269,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (*ptr == '+') { ptr++; - regaddr += grub_strtoul (ptr, (char **) &ptr, 16); + regaddr += grub_strtoul (ptr, &ptr, 16); if (grub_errno) return grub_errno; } @@ -302,17 +301,16 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) if (*ptr == '=') { ptr++; - regwrite = grub_strtoul (ptr, (char **) &ptr, 16); + regwrite = grub_strtoul (ptr, &ptr, 16); if (grub_errno) return grub_errno; write_mask = 0xffffffff; if (*ptr == ':') { ptr++; - write_mask = grub_strtoul (ptr, (char **) &ptr, 16); + write_mask = grub_strtoul (ptr, &ptr, 16); if (grub_errno) return grub_errno; - write_mask = 0xffffffff; } regwrite &= write_mask; } @@ -329,10 +327,10 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(setpci) { - cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0, - N_("[-s POSITION] [-d DEVICE] [-v VAR] " - "REGISTER[=VALUE[:MASK]]"), - N_("Manipulate PCI devices."), options); + 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); } GRUB_MOD_FINI(setpci) diff --git a/grub-core/commands/sleep.c b/grub-core/commands/sleep.c index e77e7900f..a1370b710 100644 --- a/grub-core/commands/sleep.c +++ b/grub-core/commands/sleep.c @@ -55,7 +55,7 @@ grub_interruptible_millisleep (grub_uint32_t ms) start = grub_get_time_ms (); while (grub_get_time_ms () - start < ms) - if (grub_getkey_noblock () == GRUB_TERM_ESC) + if (grub_key_is_interrupt (grub_getkey_noblock ())) return 1; return 0; diff --git a/grub-core/commands/smbios.c b/grub-core/commands/smbios.c new file mode 100644 index 000000000..1a9086ddd --- /dev/null +++ b/grub-core/commands/smbios.c @@ -0,0 +1,398 @@ +/* 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/terminal.c b/grub-core/commands/terminal.c index 3002186d2..78a140099 100644 --- a/grub-core/commands/terminal.c +++ b/grub-core/commands/terminal.c @@ -87,7 +87,7 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, i++; if (i == argc) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("no terminal specified")); for (; i < argc; i++) { @@ -199,9 +199,9 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, 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) @@ -241,8 +241,8 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), (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:")); + N_("Active input terminals:"), + N_("Available input terminals:")); } static grub_err_t @@ -258,8 +258,8 @@ grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), (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:")); + N_("Active output terminals:"), + N_("Available output terminals:")); } static grub_command_t cmd_terminal_input, cmd_terminal_output; diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c index 4e929e045..b585c3d70 100644 --- a/grub-core/commands/test.c +++ b/grub-core/commands/test.c @@ -29,9 +29,12 @@ 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, char **end, int base) +grub_strtosl (char *arg, const char ** const end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); @@ -150,7 +153,7 @@ get_fileinfo (char *path, struct test_parse_ctx *ctx) /* Parse a test expression starting from *argn. */ static int -test_parse (char **args, int *argn, int argc) +test_parse (char **args, int *argn, int argc, int *depth) { struct test_parse_ctx ctx = { .and = 1, @@ -387,13 +390,24 @@ test_parse (char **args, int *argn, int argc) if (grub_strcmp (args[*argn], ")") == 0) { (*argn)++; + if (*depth > 0) + (*depth)--; + return ctx.or || ctx.and; } /* Recursively invoke if parenthesis. */ if (grub_strcmp (args[*argn], "(") == 0) { (*argn)++; - update_val (test_parse (args, argn, argc), &ctx); + + 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); continue; } @@ -428,11 +442,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) ? GRUB_ERR_NONE + return test_parse (args, &argn, argc, &depth) ? GRUB_ERR_NONE : grub_error (GRUB_ERR_TEST_FAILURE, N_("false")); } diff --git a/grub-core/commands/testload.c b/grub-core/commands/testload.c index ff01a0516..76a8af94c 100644 --- a/grub-core/commands/testload.c +++ b/grub-core/commands/testload.c @@ -32,10 +32,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* Helper for grub_cmd_testload. */ -static void +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) @@ -43,6 +44,7 @@ read_progress (grub_disk_addr_t sector __attribute__ ((unused)), if (len) grub_xputs ("."); grub_refresh (); + return GRUB_ERR_NONE; } static grub_err_t diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c index 1441c494d..dde74ab83 100644 --- a/grub-core/commands/tpm.c +++ b/grub-core/commands/tpm.c @@ -29,13 +29,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); -grub_err_t -grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - return grub_tpm_log_event (buf, size, pcr, description); -} - static grub_err_t grub_tpm_verify_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)), @@ -43,13 +36,29 @@ grub_tpm_verify_init (grub_file_t io, { *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) { - return grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context); + 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 @@ -81,7 +90,11 @@ grub_tpm_verify_string (char *str, enum grub_verify_string_type type) grub_tpm_measure ((unsigned char *) str, grub_strlen (str), GRUB_STRING_PCR, description); grub_free (description); - return status; + 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 = { @@ -93,10 +106,20 @@ struct grub_file_verifier grub_tpm_verifier = { 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 new file mode 100644 index 000000000..48c39de01 --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/args.c @@ -0,0 +1,127 @@ +/* + * 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 new file mode 100644 index 000000000..857f3753f --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/module.c @@ -0,0 +1,1489 @@ +/* + * 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 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"); + + 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 (ctx->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 (ctx->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; + + 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 new file mode 100644 index 000000000..1c1d871b4 --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/tpm2.h @@ -0,0 +1,36 @@ +/* + * 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 new file mode 100644 index 000000000..bdbf9f373 --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/tpm2_args.h @@ -0,0 +1,49 @@ +/* + * 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 new file mode 100644 index 000000000..e1fb51545 --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/tpm2key.asn @@ -0,0 +1,49 @@ +-- +-- 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 new file mode 100644 index 000000000..3b6001d84 --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/tpm2key.c @@ -0,0 +1,499 @@ +/* + * 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 new file mode 100644 index 000000000..f749d62c2 --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/tpm2key.h @@ -0,0 +1,87 @@ +/* + * 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 new file mode 100644 index 000000000..bebe108a3 --- /dev/null +++ b/grub-core/commands/tpm2_key_protector/tpm2key_asn1_tab.c @@ -0,0 +1,63 @@ +/* + * 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/videoinfo.c b/grub-core/commands/videoinfo.c index 4be8107d5..205ba78c9 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -29,7 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct hook_ctx { - unsigned height, width, depth; + unsigned height, width, depth; struct grub_video_mode_info *current_mode; }; @@ -136,7 +136,7 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), ctx.height = ctx.width = ctx.depth = 0; if (argc) { - char *ptr; + const char *ptr; ptr = args[0]; ctx.width = grub_strtoul (ptr, &ptr, 0); if (grub_errno) @@ -191,6 +191,11 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), /* 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 ()) diff --git a/grub-core/commands/videotest.c b/grub-core/commands/videotest.c index b6c181b52..ac145afc2 100644 --- a/grub-core/commands/videotest.c +++ b/grub-core/commands/videotest.c @@ -158,7 +158,7 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), { if (i == 0 || i == 1) - { + { color = grub_video_map_rgb (0, 0, 0); grub_video_fill_rect (color, 0, 0, width, height); diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index 4a106ca04..ed6586505 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -48,6 +49,7 @@ merge (char **dest, char **ps) int i; int j; char **p; + grub_size_t sz; if (! dest) return ps; @@ -60,7 +62,12 @@ merge (char **dest, char **ps) for (j = 0; ps[j]; j++) ; - p = grub_realloc (dest, sizeof (char*) * (i + j + 1)); + 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); @@ -115,8 +122,15 @@ make_regex (const char *start, const char *end, regex_t *regexp) char ch; int i = 0; unsigned len = end - start; - char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */ + 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; @@ -226,6 +240,7 @@ 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, ',')) @@ -239,11 +254,16 @@ match_devices_iter (const char *name, void *data) if (regexec (ctx->regexp, buffer, 0, 0, 0)) { grub_dprintf ("expand", "not matched\n"); + fail: grub_free (buffer); return 0; } - t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2)); + 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); @@ -300,6 +320,7 @@ match_files_iter (const char *name, 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) @@ -315,9 +336,14 @@ match_files_iter (const char *name, if (! buffer) return 1; - t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2)); - if (! t) + 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; } @@ -418,7 +444,7 @@ check_file_iter (const char *name, const struct grub_dirhook_info *info, ctx->found = 1; return 1; } - + return 0; } diff --git a/grub-core/disk/AFSplitter.c b/grub-core/disk/AFSplitter.c index f5a8ddc61..249163ff0 100644 --- a/grub-core/disk/AFSplitter.c +++ b/grub-core/disk/AFSplitter.c @@ -21,9 +21,12 @@ */ #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); diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c index 0e6d56c24..f3c968195 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -150,10 +150,9 @@ struct grub_ahci_device int atapi; }; -static grub_err_t +static grub_err_t grub_ahci_readwrite_real (struct grub_ahci_device *dev, - struct grub_disk_ata_pass_through_parms *parms, - int spinup, int reset); + struct grub_disk_ata_pass_through_parms *parms, int reset); enum @@ -457,7 +456,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, 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, + 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)); @@ -543,7 +542,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, 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 - + (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); @@ -557,7 +556,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, 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 - + (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); @@ -573,7 +572,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, /* 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, 1);*/ + grub_ahci_readwrite_real (dev, &parms2, 1);*/ } endtime = grub_get_time_ms () + 32000; @@ -702,7 +701,7 @@ grub_ahci_fini_hw (int noreturn __attribute__ ((unused))) return GRUB_ERR_NONE; } -static int +static int reinit_port (struct grub_ahci_device *dev) { struct grub_pci_dma_chunk *command_list; @@ -743,7 +742,7 @@ reinit_port (struct grub_ahci_device *dev) dev->hba->ports[dev->port].fbs = 2; - dev->rfis = grub_memalign_dma32 (4096, + 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)); @@ -861,13 +860,13 @@ static const int register_map[11] = { 3 /* Features */, 13 /* Sectors 48 */, 8 /* LBA48 low */, 9 /* LBA48 mid */, - 10 /* LBA48 high */ }; + 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) @@ -908,15 +907,14 @@ grub_ahci_reset_port (struct grub_ahci_device *dev, int force) 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, 1); + return grub_ahci_readwrite_real (dev, &parms2, 1); } return GRUB_ERR_NONE; } -static grub_err_t +static grub_err_t grub_ahci_readwrite_real (struct grub_ahci_device *dev, - struct grub_disk_ata_pass_through_parms *parms, - int spinup, int reset) + struct grub_disk_ata_pass_through_parms *parms, int reset) { struct grub_pci_dma_chunk *bufc; grub_uint64_t endtime; @@ -928,7 +926,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, 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; @@ -990,7 +988,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, 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]; + 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], @@ -1038,7 +1036,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, grub_dprintf ("ahci", "AHCI tfd = %x\n", dev->hba->ports[dev->port].task_file_data); - endtime = grub_get_time_ms () + (spinup ? 20000 : 20000); + 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)) @@ -1094,12 +1092,12 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, return err; } -static grub_err_t +static grub_err_t grub_ahci_readwrite (grub_ata_t disk, struct grub_disk_ata_pass_through_parms *parms, - int spinup) + int spinup __attribute__((__unused__))) { - return grub_ahci_readwrite_real (disk->data, parms, spinup, 0); + return grub_ahci_readwrite_real (disk->data, parms, 0); } static grub_err_t diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 685f33a19..a2433e29e 100644 --- a/grub-core/disk/ata.c +++ b/grub-core/disk/ata.c @@ -112,10 +112,10 @@ grub_ata_identify (struct grub_ata *dev) 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; - if (! info16) - return grub_errno; grub_memset (&parms, 0, sizeof (parms)); parms.buffer = info16; @@ -181,10 +181,7 @@ grub_ata_identify (struct grub_ata *dev) if (secsize & (secsize - 1) || !secsize || secsize > 1048576) secsize = 256; - for (dev->log_sector_size = 0; - (1U << dev->log_sector_size) < secsize; - dev->log_sector_size++); - dev->log_sector_size++; + dev->log_sector_size = grub_log2ull (secsize) + 1; } else dev->log_sector_size = 9; @@ -219,8 +216,9 @@ grub_ata_setaddress (struct grub_ata *dev, if (dev->sectors_per_track == 0 || dev->heads == 0) return grub_error (GRUB_ERR_OUT_OF_RANGE, - "sector %d cannot be addressed " - "using CHS addressing", sector); + "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; @@ -232,9 +230,10 @@ grub_ata_setaddress (struct grub_ata *dev, || cylinder > dev->cylinders || head > dev->heads) return grub_error (GRUB_ERR_OUT_OF_RANGE, - "sector %d cannot be addressed " - "using CHS addressing", sector); - + "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; @@ -343,7 +342,7 @@ grub_ata_readwrite (grub_disk_t disk, grub_disk_addr_t sector, parms.write = rw; if (ata->dma) parms.dma = 1; - + err = ata->dev->readwrite (ata, &parms, 0); if (err) return err; @@ -428,7 +427,7 @@ grub_ata_iterate_iter (int id, int bus, void *data) grub_ata_real_close (ata); return 0; } - grub_snprintf (devname, sizeof (devname), + grub_snprintf (devname, sizeof (devname), "%s%d", grub_scsi_names[id], bus); ret = ctx->hook (devname, ctx->hook_data); grub_ata_real_close (ata); @@ -441,7 +440,7 @@ grub_ata_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, { 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; @@ -544,7 +543,7 @@ grub_atapi_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, parms.size = size; parms.buffer = buf; - + err = dev->dev->readwrite (dev, &parms, 0); if (err) return err; @@ -573,7 +572,7 @@ grub_atapi_open (int id, int bus, struct grub_scsi *scsi) 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"); @@ -621,7 +620,7 @@ grub_atapi_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data, { 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; diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 5037768fc..7065bcdcb 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc. + * 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 @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -26,6 +27,8 @@ #include #include #include +#include +#include #ifdef GRUB_UTIL #include @@ -35,15 +38,42 @@ 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) @@ -224,7 +254,8 @@ lrw_xor (const struct lrw_sector *sec, 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, int do_encrypt) + grub_disk_addr_t sector, grub_size_t log_sector_size, + int do_encrypt) { grub_size_t i; gcry_err_code_t err; @@ -237,7 +268,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, 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 += (1U << dev->log_sector_size)) + 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) @@ -270,7 +301,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, if (!ctx) return GPG_ERR_OUT_OF_MEMORY; - tmp = grub_cpu_to_le64 (sector << dev->log_sector_size); + 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)); @@ -281,25 +312,38 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, } break; case GRUB_CRYPTODISK_MODE_IV_PLAIN64: - iv[1] = grub_cpu_to_le32 (sector >> 32); - /* FALLTHROUGH */ case GRUB_CRYPTODISK_MODE_IV_PLAIN: - iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF); + /* + * 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: - iv[1] = grub_cpu_to_le32 (sector >> (32 - dev->log_sector_size)); - iv[0] = grub_cpu_to_le32 ((sector << dev->log_sector_size) - & 0xFFFFFFFF); + /* 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 >> 32); - iv[sz - 1] = grub_cpu_to_be32 (num & 0xFFFFFFFF); + 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 & 0xFFFFFFFF); + 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) @@ -311,10 +355,10 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, case GRUB_CRYPTODISK_MODE_CBC: if (do_encrypt) err = grub_crypto_cbc_encrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size), iv); + ((grub_size_t) 1 << log_sector_size), iv); else err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size), iv); + ((grub_size_t) 1 << log_sector_size), iv); if (err) return err; break; @@ -322,10 +366,10 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, case GRUB_CRYPTODISK_MODE_PCBC: if (do_encrypt) err = grub_crypto_pcbc_encrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size), iv); + ((grub_size_t) 1 << log_sector_size), iv); else err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size), iv); + ((grub_size_t) 1 << log_sector_size), iv); if (err) return err; break; @@ -336,18 +380,18 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, dev->cipher->cipher->blocksize); if (err) return err; - - for (j = 0; j < (1U << dev->log_sector_size); + + 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, + 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, + err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j, data + i + j, dev->cipher->cipher->blocksize); if (err) @@ -366,13 +410,13 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, lrw_xor (&sec, dev, data + i); if (do_encrypt) - err = grub_crypto_ecb_encrypt (dev->cipher, data + i, + err = grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size)); + (1U << log_sector_size)); else - err = grub_crypto_ecb_decrypt (dev->cipher, data + i, + err = grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size)); + (1U << log_sector_size)); if (err) return err; lrw_xor (&sec, dev, data + i); @@ -381,10 +425,10 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, case GRUB_CRYPTODISK_MODE_ECB: if (do_encrypt) err = grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size)); + (1U << log_sector_size)); else err = grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i, - (1U << dev->log_sector_size)); + (1U << log_sector_size)); if (err) return err; break; @@ -399,9 +443,174 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, 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_disk_addr_t sector, grub_size_t log_sector_size) { - return grub_cryptodisk_endecrypt (dev, data, len, sector, 0); + 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 @@ -415,7 +624,7 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke 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) @@ -499,7 +708,7 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk) if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0) { for (dev = cryptodisk_list; dev != NULL; dev = dev->next) - if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0) + if (grub_uuidcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid, sizeof (dev->uuid)) == 0) break; } else @@ -515,16 +724,31 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk) if (!dev) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); - disk->log_sector_size = dev->log_sector_size; - #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 @@ -538,7 +762,8 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk) } disk->data = dev; - disk->total_sectors = dev->total_length; + 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++; @@ -593,12 +818,11 @@ grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_dprintf ("cryptodisk", "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%" PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n", - size, sector, dev->offset); + size, sector, dev->offset_sectors); err = grub_disk_read (dev->source_disk, - (sector << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS)) + dev->offset, 0, - size << disk->log_sector_size, buf); + 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); @@ -606,7 +830,7 @@ grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector, } gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) buf, size << disk->log_sector_size, - sector, 0); + sector, dev->log_sector_size, 0); return grub_crypto_gcry_error (gcry_err); } @@ -643,11 +867,11 @@ grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector, grub_dprintf ("cryptodisk", "Writing %" PRIuGRUB_SIZE " sectors to sector 0x%" PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n", - size, sector, dev->offset); + size, sector, dev->offset_sectors); gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) tmp, size << disk->log_sector_size, - sector, 1); + sector, disk->log_sector_size, 1); if (gcry_err) { grub_free (tmp); @@ -655,12 +879,10 @@ grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector, } /* 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, - (sector << (disk->log_sector_size - - GRUB_DISK_SECTOR_BITS)) - + dev->offset, + 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"); @@ -712,10 +934,7 @@ grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name, { newdev->source = grub_strdup (name); if (!newdev->source) - { - grub_free (newdev); - return grub_errno; - } + return grub_errno; newdev->id = last_cryptodisk_id++; newdev->source_id = source->id; @@ -732,7 +951,7 @@ grub_cryptodisk_get_by_uuid (const char *uuid) { grub_cryptodisk_t dev; for (dev = cryptodisk_list; dev != NULL; dev = dev->next) - if (grub_strcasecmp (dev->uuid, uuid) == 0) + if (grub_uuidcasecmp (dev->uuid, uuid, sizeof (dev->uuid)) == 0) return dev; return NULL; } @@ -807,9 +1026,6 @@ grub_util_cryptodisk_get_uuid (grub_disk_t disk) #endif -static int check_boot, have_it; -static char *search_uuid; - static void cryptodisk_close (grub_cryptodisk_t dev) { @@ -820,39 +1036,277 @@ cryptodisk_close (grub_cryptodisk_t dev) } static grub_err_t -grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source) +cryptodisk_read_hook (grub_disk_addr_t sector, unsigned offset, + unsigned length, char *buf, void *data) { - grub_err_t err; + 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 GRUB_ERR_NONE; + 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) { - dev = cr->scan (source, search_uuid, check_boot); + /* + * 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) - return grub_errno; + goto error_no_close; if (!dev) continue; - - err = cr->recover_key (source, dev); - if (err) + break; + } + + if (dev == NULL) { - cryptodisk_close (dev); - return err; + grub_error (GRUB_ERR_BAD_MODULE, + "no cryptodisk module can handle this device"); + goto error_no_close; } - grub_cryptodisk_insert (dev, name, source); + if (cargs->protectors) + { + for (i = 0; cargs->protectors[i]; i++) + { + if (cargs->key_cache[i].invalid) + continue; - have_it = 1; + 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; + } - return GRUB_ERR_NONE; - } - return 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 @@ -864,6 +1318,7 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) 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); @@ -874,13 +1329,13 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) if (dev) { - grub_disk_close (source); + grub_disk_close (source); return GRUB_ERR_NONE; } FOR_CRYPTODISK_DEVS (cr) { - dev = cr->scan (source, search_uuid, check_boot); + dev = cr->scan (source, &cargs); if (grub_errno) return grub_errno; if (!dev) @@ -904,10 +1359,13 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) static int grub_cryptodisk_scan_device (const char *name, - void *data __attribute__ ((unused))) + void *data) { - grub_err_t err; + 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); @@ -917,64 +1375,220 @@ grub_cryptodisk_scan_device (const char *name, return 0; } - err = grub_cryptodisk_scan_device_real (name, source); + 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; + } - grub_disk_close (source); - - if (err) + /* + * 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 (); - return have_it && search_uuid ? 1 : 0; + + 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[1].set && !state[2].set) + if (argc < 1 && !state[OPTION_ALL].set && !state[OPTION_BOOT].set) return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); - have_it = 0; - if (state[0].set) + 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; } - check_boot = state[2].set; - search_uuid = args[0]; - grub_device_iterate (&grub_cryptodisk_scan_device, NULL); - search_uuid = NULL; + 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 (!have_it) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found"); - return GRUB_ERR_NONE; + 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[1].set || (argc == 0 && state[2].set)) + else if (state[OPTION_ALL].set || (argc == 0 && state[OPTION_BOOT].set)) /* -a|-b */ { - search_uuid = NULL; - check_boot = state[2].set; - grub_device_iterate (&grub_cryptodisk_scan_device, NULL); - search_uuid = NULL; + 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_err_t err; grub_disk_t disk; grub_cryptodisk_t dev; char *diskname; char *disklast = NULL; grub_size_t len; - search_uuid = NULL; - check_boot = state[2].set; + cargs.check_boot = state[OPTION_BOOT].set; diskname = args[0]; len = grub_strlen (diskname); if (len && diskname[0] == '(' && diskname[len - 1] == ')') @@ -987,6 +1601,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) disk = grub_disk_open (diskname); if (!disk) { + grub_cryptodisk_clear_key_cache (&cargs); if (disklast) *disklast = ')'; return grub_errno; @@ -997,18 +1612,20 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) { 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; } - err = grub_cryptodisk_scan_device_real (diskname, disk); + dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); + grub_cryptodisk_clear_key_cache (&cargs); grub_disk_close (disk); if (disklast) *disklast = ')'; - return err; + return (dev == NULL) ? grub_errno : GRUB_ERR_NONE; } } @@ -1039,46 +1656,76 @@ static char * luks_script_get (grub_size_t *sz) { grub_cryptodisk_t i; - grub_size_t size = 0; + 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) + if (grub_strcmp (i->modname, "luks") == 0 || + grub_strcmp (i->modname, "luks2") == 0) { - size += sizeof ("luks_mount "); - size += grub_strlen (i->uuid); - size += grub_strlen (i->cipher->cipher->name); - size += 54; + /* + * 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) - size += grub_strlen (i->essiv_hash->name); - size += i->keysize * 2; + { + 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 + 1); + 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) + if (grub_strcmp (i->modname, "luks") == 0 || + grub_strcmp (i->modname, "luks2") == 0) { unsigned j; const char *iptr; - ptr = grub_stpcpy (ptr, "luks_mount "); + ptr = grub_stpcpy (ptr, i->modname); + ptr = grub_stpcpy (ptr, "_mount "); ptr = grub_stpcpy (ptr, i->uuid); *ptr++ = ' '; - grub_snprintf (ptr, 21, "%" PRIuGRUB_UINT64_T " ", i->offset); - while (*ptr) - 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"); + ptr = grub_stpcpy (ptr, "-ecb"); break; case GRUB_CRYPTODISK_MODE_CBC: ptr = grub_stpcpy (ptr, "-cbc"); @@ -1097,19 +1744,19 @@ luks_script_get (grub_size_t *sz) switch (i->mode_iv) { case GRUB_CRYPTODISK_MODE_IV_NULL: - ptr = grub_stpcpy (ptr, "-null"); + ptr = grub_stpcpy (ptr, "-null"); break; case GRUB_CRYPTODISK_MODE_IV_PLAIN: - ptr = grub_stpcpy (ptr, "-plain"); + ptr = grub_stpcpy (ptr, "-plain"); break; case GRUB_CRYPTODISK_MODE_IV_PLAIN64: - ptr = grub_stpcpy (ptr, "-plain64"); + ptr = grub_stpcpy (ptr, "-plain64"); break; case GRUB_CRYPTODISK_MODE_IV_BENBI: - ptr = grub_stpcpy (ptr, "-benbi"); + ptr = grub_stpcpy (ptr, "-benbi"); break; case GRUB_CRYPTODISK_MODE_IV_ESSIV: - ptr = grub_stpcpy (ptr, "-essiv:"); + ptr = grub_stpcpy (ptr, "-essiv:"); ptr = grub_stpcpy (ptr, i->essiv_hash->name); break; case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64: @@ -1129,6 +1776,114 @@ luks_script_get (grub_size_t *sz) 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", @@ -1141,14 +1896,21 @@ GRUB_MOD_INIT (cryptodisk) { grub_disk_dev_register (&grub_cryptodisk_dev); cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, - N_("SOURCE|-u UUID|-a|-b"), + 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 index c3b578acf..3a26de60c 100644 --- a/grub-core/disk/diskfilter.c +++ b/grub-core/disk/diskfilter.c @@ -20,10 +20,12 @@ #include #include #include +#include #include #include #include #include +#include #ifdef GRUB_UTIL #include #include @@ -140,7 +142,7 @@ scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data) #endif disk->partition = p; - + for (arr = array_list; arr != NULL; arr = arr->next) { struct grub_diskfilter_pv *m; @@ -148,14 +150,14 @@ scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data) 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_get_size (disk)) + && 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", + grub_util_info ("Scanning for %s devices on disk %s", diskfilter->name, name); #endif id.uuid = 0; @@ -226,15 +228,28 @@ scan_devices (const char *arname) int need_rescan; for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) - 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; - } + { + /* 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; @@ -300,6 +315,8 @@ grub_diskfilter_memberlist (grub_disk_t disk) 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; @@ -331,27 +348,52 @@ grub_diskfilter_memberlist (grub_disk_t disk) } } - for (pv = lv->vg->pvs; pv; pv = pv->next) - { - if (!pv->disk) + 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) { - /* 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; + 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; } - tmp = grub_malloc (sizeof (*tmp)); - 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 @@ -593,7 +635,7 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, 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; @@ -612,17 +654,17 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, 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, + 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; @@ -677,7 +719,7 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, size -= read_size; if (! size) return GRUB_ERR_NONE; - + b = 0; disknr += (near - i); while (disknr >= seg->node_count) @@ -693,7 +735,7 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, case GRUB_DISKFILTER_RAID6: { grub_disk_addr_t read_sector; - grub_uint64_t b, p, n, disknr, e; + grub_uint64_t b, p, n, disknr; /* n = 1 for level 4 and 5, 2 for level 6. */ n = seg->type / 3; @@ -738,12 +780,11 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, { grub_size_t read_size; int next_level; - + read_size = seg->stripe_size - b; if (read_size > size) read_size = size; - e = 0; /* Reset read error. */ if (grub_errno == GRUB_ERR_READ_ERROR || grub_errno == GRUB_ERR_UNKNOWN_DEVICE) @@ -757,7 +798,6 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, if ((err) && (err != GRUB_ERR_READ_ERROR && err != GRUB_ERR_UNKNOWN_DEVICE)) return err; - e++; if (err) { @@ -843,7 +883,7 @@ read_segment (struct grub_diskfilter_segment *seg, grub_disk_addr_t sector, disknr = 0; } } - } + } return GRUB_ERR_NONE; default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, @@ -867,7 +907,7 @@ read_lv (struct grub_diskfilter_lv *lv, grub_disk_addr_t sector, grub_uint64_t to_read; extent = grub_divmod64 (sector, vg->extent_size, NULL); - + /* Find the right segment. */ { unsigned int i; @@ -941,8 +981,6 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg) for (lv = vg->lvs; lv; lv = lv->next) { - grub_err_t err; - /* 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++) @@ -954,6 +992,10 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg) && 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) @@ -969,7 +1011,8 @@ grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg) for (p = vgp->lvs; p; p = p->next) { int cur_num; - char *num, *end; + char *num; + const char *end; if (!p->fullname) continue; if (grub_strncmp (p->fullname, lv->fullname, len) != 0) @@ -1013,11 +1056,18 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, { struct grub_diskfilter_vg *array; int i; - grub_size_t j; + 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: @@ -1107,7 +1157,11 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, } array->lvs->vg = array; - array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen); + 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; @@ -1134,7 +1188,10 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, array->lvs->segments->node_count = nmemb; array->lvs->segments->raid_member_size = disk_size; array->lvs->segments->nodes - = grub_zalloc (nmemb * sizeof (array->lvs->segments->nodes[0])); + = 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++) { @@ -1189,27 +1246,27 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, 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_get_size (disk), + (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_get_size (disk), + (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) + && 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_get_size (disk) >= pv->part_size) + 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) @@ -1218,7 +1275,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, 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_get_size (disk); + pv->part_size = grub_disk_native_sectors (disk); #ifdef GRUB_UTIL { @@ -1226,7 +1283,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, grub_partition_t p; for (p = disk->partition; p; p = p->parent) s++; - pv->partmaps = xmalloc (s * sizeof (pv->partmaps[0])); + 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); @@ -1310,7 +1367,7 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk, 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_get_size (disk)) + && pv->part_size == grub_disk_native_sectors (disk)) { if (vg_out) *vg_out = vg; @@ -1321,6 +1378,86 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk, } #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", @@ -1337,14 +1474,21 @@ static struct grub_disk_dev grub_diskfilter_dev = .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/dmraid_nvidia.c b/grub-core/disk/dmraid_nvidia.c index 060279124..6372663e6 100644 --- a/grub-core/disk/dmraid_nvidia.c +++ b/grub-core/disk/dmraid_nvidia.c @@ -107,7 +107,7 @@ grub_dmraid_nv_detect (grub_disk_t disk, /* Skip partition. */ return NULL; - sector = grub_disk_get_size (disk); + sector = grub_disk_native_sectors (disk); if (sector == GRUB_DISK_SIZE_UNKNOWN) /* Not raid. */ return NULL; @@ -122,7 +122,7 @@ grub_dmraid_nv_detect (grub_disk_t disk, if (sb.version != NV_VERSION) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unknown version: %d.%d", sb.version); + "unknown version: %d.%d", sb.version >> 8, sb.version & 0xFF); return NULL; } diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c index 9e20af70e..3b5ed5691 100644 --- a/grub-core/disk/efi/efidisk.c +++ b/grub-core/disk/efi/efidisk.c @@ -37,7 +37,7 @@ struct grub_efidisk_data }; /* GUID. */ -static grub_efi_guid_t block_io_guid = GRUB_EFI_BLOCK_IO_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; @@ -319,7 +319,7 @@ name_devices (struct grub_efidisk_data *devices) == GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE) { grub_efi_vendor_device_path_t *vendor = (grub_efi_vendor_device_path_t *) dp; - const struct grub_efi_guid apple = GRUB_EFI_VENDOR_APPLE_GUID; + static const grub_guid_t apple = GRUB_EFI_VENDOR_APPLE_GUID; if (vendor->header.length == sizeof (*vendor) && grub_memcmp (&vendor->vendor_guid, &apple, @@ -335,7 +335,7 @@ name_devices (struct grub_efidisk_data *devices) { grub_efi_acpi_device_path_t *acpi = (grub_efi_acpi_device_path_t *) dp; - /* Floppy EISA ID. */ + /* Floppy EISA ID. */ if (acpi->hid == 0x60441d0 || acpi->hid == 0x70041d0 || acpi->hid == 0x70141d1) is_floppy = 1; @@ -523,9 +523,7 @@ grub_efidisk_open (const char *name, struct grub_disk *disk) if (m->block_size & (m->block_size - 1) || !m->block_size) return grub_error (GRUB_ERR_IO, "invalid sector size %d", m->block_size); - for (disk->log_sector_size = 0; - (1U << disk->log_sector_size) < m->block_size; - disk->log_sector_size++); + disk->log_sector_size = grub_log2ull (m->block_size); disk->data = d; grub_dprintf ("efidisk", "opening %s succeeded\n", name); @@ -553,8 +551,19 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector, d = disk->data; bio = d->block_io; - /* Set alignment to 1 if 0 specified */ - io_align = bio->media->io_align ? bio->media->io_align : 1; + /* + * 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)) @@ -570,9 +579,10 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector, aligned_buf = buf; } - status = efi_call_5 ((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); + 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)) { @@ -707,7 +717,7 @@ grub_efidisk_get_device_handle (grub_disk_t disk) == 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) + && (grub_partition_get_start (disk->partition) == (hd->partition_start << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) && (grub_partition_get_len (disk->partition) @@ -867,7 +877,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) if (ctx.hd->partition_start == 0 && (ctx.hd->partition_size << (parent->log_sector_size - GRUB_DISK_SECTOR_BITS)) - == grub_disk_get_size (parent)) + == grub_disk_native_sectors (parent)) { dev_name = grub_strdup (parent->name); } diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index e9d23299a..722910d64 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -135,8 +135,6 @@ const char *algorithms[] = { [0x16] = "aes" }; -#define MAX_PASSPHRASE 256 - static gcry_err_code_t geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) { @@ -159,7 +157,7 @@ geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) return gcry_err; return grub_cryptodisk_setkey (dev, (grub_uint8_t *) key, - dev->rekey_derived_size); + dev->rekey_derived_size); } static inline gcry_err_code_t @@ -202,7 +200,7 @@ grub_util_get_geli_uuid (const char *dev) unsigned log_secsize; grub_uint8_t hdr[512]; struct grub_geli_phdr *header; - char *uuid; + char *uuid; gcry_err_code_t err; fd = grub_util_fd_open (dev, GRUB_UTIL_FD_O_RDONLY); @@ -220,7 +218,7 @@ grub_util_get_geli_uuid (const char *dev) grub_util_error ("%s", _("couldn't read ELI metadata")); grub_util_fd_close (fd); - + COMPILE_TIME_ASSERT (sizeof (header) <= 512); header = (void *) &hdr; @@ -242,8 +240,7 @@ grub_util_get_geli_uuid (const char *dev) #endif static grub_cryptodisk_t -configure_ciphers (grub_disk_t disk, const char *check_uuid, - int boot_only) +geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) { grub_cryptodisk_t newdev; struct grub_geli_phdr header; @@ -255,10 +252,14 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, 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_get_size (disk); + sector = grub_disk_native_sectors (disk); if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0) return NULL; @@ -291,11 +292,11 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, return NULL; } - if (boot_only && !(grub_le_to_cpu32 (header.flags) & GRUB_GELI_FLAGS_BOOT)) + 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) @@ -304,9 +305,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, return NULL; } - if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) + if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, uuid, sizeof (uuid)) != 0) { - grub_dprintf ("geli", "%s != %s\n", uuid, check_uuid); + grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid); return NULL; } @@ -361,7 +362,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, } newdev->cipher = cipher; newdev->secondary_cipher = secondary_cipher; - newdev->offset = 0; + newdev->offset_sectors = 0; newdev->source_disk = NULL; newdev->benbi_log = 0; if (grub_le_to_cpu16 (header.alg) == 0x16) @@ -379,9 +380,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, newdev->hash = GRUB_MD_SHA512; newdev->iv_hash = GRUB_MD_SHA256; - for (newdev->log_sector_size = 0; - (1U << newdev->log_sector_size) < grub_le_to_cpu32 (header.sector_size); - newdev->log_sector_size++); + newdev->log_sector_size = grub_log2ull (grub_le_to_cpu32 (header.sector_size)); if (grub_le_to_cpu32 (header.version) >= 5) { @@ -391,14 +390,14 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, newdev->modname = "geli"; - newdev->total_length = grub_disk_get_size (disk) - 1; + 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 -recover_key (grub_disk_t source, grub_cryptodisk_t dev) +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]; @@ -406,21 +405,22 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) 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]; - char passphrase[MAX_PASSPHRASE] = ""; unsigned i; gcry_err_code_t gcry_err; struct grub_geli_phdr header; - char *tmp; 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_get_size (source); + sector = grub_disk_native_sectors (source); if (sector == GRUB_DISK_SIZE_UNKNOWN || sector == 0) return grub_error (GRUB_ERR_BUG, "not a geli"); @@ -434,23 +434,12 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) grub_puts_ (N_("Attempting to decrypt master key...")); - /* Get the passphrase from the user. */ - tmp = NULL; - if (source->partition) - tmp = grub_partition_get_name (source->partition); - grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, - source->partition ? "," : "", tmp ? : "", - dev->uuid); - grub_free (tmp); - if (!grub_password_get (passphrase, MAX_PASSPHRASE)) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); - /* 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, (grub_uint8_t *) passphrase, - grub_strlen (passphrase), + gcry_err = grub_crypto_pbkdf2 (dev->hash, cargs->key_data, + cargs->key_len, header.salt, sizeof (header.salt), grub_le_to_cpu32 (header.niter), @@ -473,7 +462,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) 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, passphrase, grub_strlen (passphrase)); + grub_crypto_hmac_write (hnd, cargs->key_data, cargs->key_len); gcry_err = grub_crypto_hmac_fini (hnd, geomkey); if (gcry_err) @@ -549,7 +538,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) if (grub_le_to_cpu16 (header.alg) == 0x16) real_keysize *= 2; gcry_err = grub_cryptodisk_setkey (dev, candidate_key.cipher_key, - real_keysize); + real_keysize); if (gcry_err) return grub_crypto_gcry_error (gcry_err); } @@ -580,8 +569,8 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) } struct grub_cryptodisk_dev geli_crypto = { - .scan = configure_ciphers, - .recover_key = recover_key + .scan = geli_scan, + .recover_key = geli_recover_key }; GRUB_MOD_INIT (geli) diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c index c151d225d..f34529f86 100644 --- a/grub-core/disk/host.c +++ b/grub-core/disk/host.c @@ -20,8 +20,8 @@ /* 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 diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 8ca250c77..1d6788950 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -71,7 +71,7 @@ static int grub_biosdisk_get_num_floppies (void) * non-zero, otherwise zero. */ -static int +static int grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) { struct grub_bios_int_registers regs; @@ -91,7 +91,7 @@ grub_biosdisk_rw_int13_extensions (int ah, int drive, void *dap) * NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs, * return non-zero, otherwise zero. */ -static int +static int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, int soff, int nsec, int segment) { @@ -110,7 +110,7 @@ grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff, /* set bits 0-5 of %cl to sector */ regs.ecx |= soff & 0x3f; - /* set %dh to head and %dl to drive */ + /* set %dh to head and %dl to drive */ regs.edx = (drive & 0xff) | ((hoff << 8) & 0xff00); /* set %ah to AH */ regs.eax = (ah << 8) & 0xff00; @@ -153,7 +153,7 @@ grub_biosdisk_check_int13_extensions (int drive) 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; @@ -171,7 +171,7 @@ grub_biosdisk_check_int13_extensions (int drive) * Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an * error occurs, then return non-zero, otherwise zero. */ -static int +static int grub_biosdisk_get_diskinfo_standard (int drive, unsigned long *cylinders, unsigned long *heads, @@ -185,12 +185,12 @@ grub_biosdisk_get_diskinfo_standard (int drive, regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x13, ®s); - /* Check if unsuccessful. Ignore return value if carry isn't set to + /* 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 */ + /* 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 */ @@ -218,7 +218,7 @@ grub_biosdisk_get_diskinfo_real (int drive, void *drp, grub_uint16_t ax) regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x13, ®s); - /* Check if unsuccessful. Ignore return value if carry isn't set to + /* 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; @@ -367,7 +367,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) if (version) { struct grub_biosdisk_drp *drp - = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + = (struct grub_biosdisk_drp *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); /* Clear out the DRP. */ grub_memset (drp, 0, sizeof (*drp)); @@ -388,11 +388,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) && !(drp->bytes_per_sector & (drp->bytes_per_sector - 1)) && drp->bytes_per_sector >= 512 && drp->bytes_per_sector <= 16384) - { - for (disk->log_sector_size = 0; - (1 << disk->log_sector_size) < drp->bytes_per_sector; - disk->log_sector_size++); - } + disk->log_sector_size = grub_log2ull (drp->bytes_per_sector); } } } @@ -475,7 +471,7 @@ grub_biosdisk_rw (int cmd, grub_disk_t disk, struct grub_biosdisk_dap *dap; dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR - + (data->sectors + + (GRUB_DISK_MAX_LBA_SECTORS << disk->log_sector_size)); dap->length = sizeof (*dap); dap->reserved = 0; @@ -565,6 +561,9 @@ get_safe_sectors (grub_disk_t disk, grub_disk_addr_t sector) 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); @@ -654,7 +653,7 @@ grub_disk_biosdisk_fini (void) GRUB_MOD_INIT(biosdisk) { struct grub_biosdisk_cdrp *cdrp - = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + = (struct grub_biosdisk_cdrp *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); grub_uint8_t boot_drive; if (grub_disk_firmware_is_tainted) diff --git a/grub-core/disk/ieee1275/obdisk.c b/grub-core/disk/ieee1275/obdisk.c index ec413c3fd..fcc39e0a2 100644 --- a/grub-core/disk/ieee1275/obdisk.c +++ b/grub-core/disk/ieee1275/obdisk.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -128,9 +129,17 @@ count_commas (const char *src) static char * decode_grub_devname (const char *name) { - char *devpath = grub_malloc (grub_strlen (name) + 1); + 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; @@ -156,12 +165,20 @@ static char * encode_grub_devname (const char *path) { char *encoding, *optr; + grub_size_t sz; if (path == NULL) return NULL; - encoding = grub_malloc (sizeof (IEEE1275_DEV) + count_commas (path) + - grub_strlen (path) + 1); + 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) { @@ -396,8 +413,22 @@ canonicalise_disk (const char *devname) 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); @@ -413,6 +444,7 @@ canonicalise_disk (const char *devname) 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)); @@ -428,13 +460,18 @@ add_canon_disk (const char *cname) * arguments and allows a client program to open * the entire (raw) disk. Any disk label is ignored. */ - dev->raw_name = grub_malloc (grub_strlen (cname) + sizeof (":nolabel")); + 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, grub_strlen (cname) + sizeof (":nolabel"), - "%s:nolabel", cname); + grub_snprintf (dev->raw_name, sz, "%s:nolabel", cname); } /* @@ -1023,11 +1060,7 @@ grub_obdisk_open (const char *name, grub_disk_t disk) dev->num_blocks = GRUB_DISK_SIZE_UNKNOWN; if (dev->block_size != 0) - { - for (dev->log_sector_size = 0; - (1U << dev->log_sector_size) < dev->block_size; - dev->log_sector_size++); - } + dev->log_sector_size = grub_log2ull (dev->block_size); else dev->log_sector_size = 9; diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index f73257e66..dbc0f1aba 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -24,6 +24,7 @@ #include #include #include +#include static char *last_devpath; static grub_ieee1275_ihandle_t last_ihandle; @@ -80,6 +81,7 @@ ofdisk_hash_add_real (char *devpath) 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) @@ -87,8 +89,14 @@ ofdisk_hash_add_real (char *devpath) p->devpath = devpath; - p->grub_devpath = grub_malloc (sizeof ("ieee1275/") - + 2 * grub_strlen (p->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) { @@ -98,7 +106,13 @@ ofdisk_hash_add_real (char *devpath) if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) { - p->open_path = grub_malloc (grub_strlen (p->devpath) + 3); + 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); @@ -224,6 +238,7 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) args; char *buf, *bufptr; unsigned i; + grub_size_t sz; if (grub_ieee1275_open (alias->path, &ihandle)) return; @@ -243,9 +258,19 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) return; } - buf = grub_malloc (grub_strlen (alias->path) + 32); + 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) - return; + { + grub_ieee1275_close (ihandle); + return; + } bufptr = grub_stpcpy (buf, alias->path); for (i = 0; i < args.nentries; i++) @@ -287,9 +312,15 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) grub_uint64_t *table; grub_uint16_t table_size; grub_ieee1275_ihandle_t ihandle; + grub_size_t sz; - buf = grub_malloc (grub_strlen (alias->path) + - sizeof ("/disk@7766554433221100")); + 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); @@ -297,7 +328,7 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) /* 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_malloc (table_size * sizeof (grub_uint64_t)); + table = grub_calloc (table_size, sizeof (grub_uint64_t)); if (!table) { @@ -380,7 +411,7 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, return 0; scan (); - + for (i = 0; i < ARRAY_SIZE (ofdisk_hash); i++) { static struct ofdisk_hash_ent *ent; @@ -420,16 +451,24 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, if (hook (ent->grub_shortest, hook_data)) return 1; } - } + } return 0; } static char * compute_dev_path (const char *name) { - char *devpath = grub_malloc (grub_strlen (name) + 3); + 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; @@ -516,11 +555,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) return err; } if (block_size != 0) - { - for (disk->log_sector_size = 0; - (1U << disk->log_sector_size) < block_size; - disk->log_sector_size++); - } + disk->log_sector_size = grub_log2ull (block_size); else disk->log_sector_size = 9; } @@ -558,7 +593,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) 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; + last_devpath = disk->data; } pos = sector << disk->log_sector_size; @@ -629,6 +664,7 @@ 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) @@ -639,7 +675,13 @@ insert_bootpath (void) return; } - bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); + 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 (); diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c new file mode 100644 index 000000000..0d146c1c0 --- /dev/null +++ b/grub-core/disk/key_protector.c @@ -0,0 +1,73 @@ +/* + * 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 index 2a22d2d6c..0f4f22aaa 100644 --- a/grub-core/disk/ldm.c +++ b/grub-core/disk/ldm.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -135,7 +136,7 @@ msdos_has_ldm_partition (grub_disk_t dsk) return has_ldm; } -static const grub_gpt_part_guid_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM; +static const grub_guid_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM; /* Helper for gpt_ldm_sector. */ static int @@ -178,6 +179,36 @@ gpt_ldm_sector (grub_disk_t dsk) 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) @@ -195,11 +226,8 @@ make_vg (grub_disk_t disk, vg->name = grub_malloc (LDM_NAME_STRLEN + 1); vg->uuid = grub_malloc (LDM_GUID_STRLEN + 1); if (! vg->uuid || !vg->name) - { - grub_free (vg->uuid); - grub_free (vg->name); - return NULL; - } + 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; @@ -218,6 +246,7 @@ make_vg (grub_disk_t disk, 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) @@ -249,20 +278,26 @@ make_vg (grub_disk_t disk, grub_free (pv); goto fail2; } - pv->internal_id = grub_malloc (ptr[0] + 2); - if (!pv->internal_id) + 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)) { - grub_free (pv); + free_pv (pv); goto fail2; } /* ptr = name. */ @@ -270,11 +305,23 @@ make_vg (grub_disk_t disk, if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (pv); + free_pv (pv); goto fail2; } pv->id.uuidlen = *ptr; - pv->id.uuid = grub_malloc (pv->id.uuidlen + 1); + + 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; @@ -289,6 +336,7 @@ make_vg (grub_disk_t disk, 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) @@ -318,26 +366,37 @@ make_vg (grub_disk_t disk, lv->visible = 1; lv->segments = grub_zalloc (sizeof (*lv->segments)); if (!lv->segments) - goto fail2; + { + 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_zalloc (sizeof (*lv->segments->nodes) - * lv->segments->node_alloc); + lv->segments->nodes = grub_calloc (lv->segments->node_alloc, + sizeof (*lv->segments->nodes)); if (!lv->segments->nodes) - goto fail2; + { + free_lv (lv); + goto fail2; + } ptr = vblk[i].dynamic; if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv); + free_lv (lv); goto fail2; } - lv->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2); + if (grub_add (ptr[0], 2, &sz)) + { + free_lv (lv); + goto fail2; + } + lv->internal_id = grub_malloc (sz); if (!lv->internal_id) { - grub_free (lv); + free_lv (lv); goto fail2; } grub_memcpy (lv->internal_id, ptr, ptr[0] + 1); @@ -347,14 +406,18 @@ make_vg (grub_disk_t disk, if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv); + free_lv (lv); goto fail2; } - lv->name = grub_malloc (*ptr + 1); + if (grub_add (*ptr, 1, &sz)) + { + free_lv (lv); + goto fail2; + } + lv->name = grub_malloc (sz); if (!lv->name) { - grub_free (lv->internal_id); - grub_free (lv); + free_lv (lv); goto fail2; } grub_memcpy (lv->name, ptr + 1, *ptr); @@ -363,36 +426,28 @@ make_vg (grub_disk_t disk, vg->uuid, lv->name); if (!lv->fullname) { - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv); + free_lv (lv); goto fail2; } ptr += *ptr + 1; if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv); + free_lv (lv); goto fail2; } /* ptr = volume type. */ ptr += *ptr + 1; if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv); + free_lv (lv); goto fail2; } /* ptr = flags. */ ptr += *ptr + 1; if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv); + free_lv (lv); goto fail2; } @@ -401,17 +456,13 @@ make_vg (grub_disk_t disk, /* ptr = number of children. */ if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv); + free_lv (lv); goto fail2; } ptr += *ptr + 1; if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv); + free_lv (lv); goto fail2; } @@ -421,9 +472,7 @@ make_vg (grub_disk_t disk, || ptr + *ptr + 1>= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv); + free_lv (lv); goto fail2; } lv->size = read_int (ptr + 1, *ptr); @@ -440,6 +489,7 @@ make_vg (grub_disk_t disk, 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) @@ -472,12 +522,18 @@ make_vg (grub_disk_t disk, ptr = vblk[i].dynamic; if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { + free_lv (comp); goto fail2; } - comp->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2); + if (grub_add (ptr[0], 2, &sz)) + { + free_lv (comp); + goto fail2; + } + comp->internal_id = grub_malloc (sz); if (!comp->internal_id) { - grub_free (comp); + free_lv (comp); goto fail2; } grub_memcpy (comp->internal_id, ptr, ptr[0] + 1); @@ -486,16 +542,14 @@ make_vg (grub_disk_t disk, ptr += *ptr + 1; if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (comp->internal_id); - grub_free (comp); + free_lv (comp); goto fail2; } /* ptr = name. */ ptr += *ptr + 1; if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (comp->internal_id); - grub_free (comp); + free_lv (comp); goto fail2; } /* ptr = state. */ @@ -505,8 +559,7 @@ make_vg (grub_disk_t disk, ptr += 4; if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (comp->internal_id); - grub_free (comp); + free_lv (comp); goto fail2; } @@ -514,16 +567,14 @@ make_vg (grub_disk_t disk, ptr += *ptr + 1; if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (comp->internal_id); - grub_free (comp); + free_lv (comp); goto fail2; } ptr += 8 + 8; if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (comp->internal_id); - grub_free (comp); + free_lv (comp); goto fail2; } for (lv = vg->lvs; lv; lv = lv->next) @@ -534,8 +585,7 @@ make_vg (grub_disk_t disk, } if (!lv) { - grub_free (comp->internal_id); - grub_free (comp); + free_lv (comp); continue; } comp->size = lv->size; @@ -543,10 +593,13 @@ make_vg (grub_disk_t disk, { comp->segment_alloc = 8; comp->segment_count = 0; - comp->segments = grub_malloc (sizeof (*comp->segments) - * comp->segment_alloc); + comp->segments = grub_calloc (comp->segment_alloc, + sizeof (*comp->segments)); if (!comp->segments) - goto fail2; + { + free_lv (comp); + goto fail2; + } } else { @@ -554,7 +607,10 @@ make_vg (grub_disk_t disk, comp->segment_count = 1; comp->segments = grub_malloc (sizeof (*comp->segments)); if (!comp->segments) - goto fail2; + { + free_lv (comp); + goto fail2; + } comp->segments->start_extent = 0; comp->segments->extent_count = lv->size; comp->segments->layout = 0; @@ -566,17 +622,22 @@ make_vg (grub_disk_t disk, comp->segments->layout = GRUB_RAID_LAYOUT_SYMMETRIC_MASK; } else - goto fail2; + { + free_lv (comp); + goto fail2; + } ptr += *ptr + 1; ptr++; if (!(vblk[i].flags & 0x10)) - goto fail2; + { + free_lv (comp); + goto fail2; + } if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) || ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (comp->internal_id); - grub_free (comp); + free_lv (comp); goto fail2; } comp->segments->stripe_size = read_int (ptr + 1, *ptr); @@ -584,27 +645,37 @@ make_vg (grub_disk_t disk, if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) { - grub_free (comp->internal_id); - grub_free (comp); + 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_zalloc (sizeof (*comp->segments->nodes) - * comp->segments->node_alloc); - if (!lv->segments->nodes) - goto fail2; + 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; - lv->segments->node_alloc *= 2; - t = grub_realloc (lv->segments->nodes, - sizeof (*lv->segments->nodes) - * lv->segments->node_alloc); + + 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) - goto fail2; + { + free_lv (comp); + goto fail2; + } lv->segments->nodes = t; } lv->segments->nodes[lv->segments->node_count].pv = 0; @@ -723,10 +794,13 @@ make_vg (grub_disk_t disk, if (comp->segment_alloc == comp->segment_count) { void *t; - comp->segment_alloc *= 2; - t = grub_realloc (comp->segments, - comp->segment_alloc - * sizeof (*comp->segments)); + 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; @@ -739,7 +813,10 @@ make_vg (grub_disk_t disk, comp->segments[comp->segment_count].nodes = grub_malloc (sizeof (*comp->segments[comp->segment_count].nodes)); if (!comp->segments[comp->segment_count].nodes) - goto fail2; + { + grub_free (comp->segments); + goto fail2; + } comp->segments[comp->segment_count].nodes[0] = part; comp->segment_count++; } @@ -754,30 +831,24 @@ make_vg (grub_disk_t disk, struct grub_diskfilter_pv *pv, *next_pv; for (lv = vg->lvs; lv; lv = next_lv) { - unsigned i; - for (i = 0; i < lv->segment_count; i++) - grub_free (lv->segments[i].nodes); - next_lv = lv->next; - grub_free (lv->segments); - grub_free (lv->internal_id); - grub_free (lv->name); - grub_free (lv->fullname); - grub_free (lv); + free_lv (lv); + } for (pv = vg->pvs; pv; pv = next_pv) { next_pv = pv->next; - grub_free (pv->id.uuid); - grub_free (pv); + free_pv (pv); } } + fail1: grub_free (vg->uuid); + grub_free (vg->name); grub_free (vg); return NULL; } -static struct grub_diskfilter_vg * +static struct grub_diskfilter_vg * grub_ldm_detect (grub_disk_t disk, struct grub_diskfilter_pv_id *id, grub_disk_addr_t *start_sector) @@ -807,7 +878,7 @@ grub_ldm_detect (grub_disk_t disk, /* LDM is never inside a partition. */ if (!has_ldm || disk->partition) continue; - sector = grub_disk_get_size (disk); + sector = grub_disk_native_sectors (disk); if (sector == GRUB_DISK_SIZE_UNKNOWN) continue; sector--; @@ -924,7 +995,7 @@ grub_util_is_ldm (grub_disk_t disk) /* LDM is never inside a partition. */ if (!has_ldm || disk->partition) continue; - sector = grub_disk_get_size (disk); + sector = grub_disk_native_sectors (disk); if (sector == GRUB_DISK_SIZE_UNKNOWN) continue; sector--; @@ -1017,7 +1088,7 @@ grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors, *nsectors = lv->size; if (*nsectors > max_nsectors) *nsectors = max_nsectors; - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); if (!*sectors) return grub_errno; for (i = 0; i < *nsectors; i++) diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index cdf9123fa..2bea4e922 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -24,6 +24,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -33,6 +34,7 @@ struct grub_loopback grub_file_t file; struct grub_loopback *next; unsigned long id; + grub_uint64_t refcnt; }; static struct grub_loopback *loopback_list; @@ -43,6 +45,7 @@ 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}, {0, 0, 0, 0, 0, 0} }; @@ -63,6 +66,8 @@ 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; @@ -79,6 +84,7 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) { struct grub_arg_list *state = ctxt->state; grub_file_t file; + enum grub_file_type type = GRUB_FILE_TYPE_LOOPBACK; struct grub_loopback *newdev; grub_err_t ret; @@ -87,28 +93,22 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) /* Check if `-d' was used. */ if (state[0].set) - return delete_loopback (args[0]); + return delete_loopback (args[0]); + + if (!state[1].set) + type |= GRUB_FILE_TYPE_NO_DECOMPRESS; if (argc < 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (args[1], GRUB_FILE_TYPE_LOOPBACK - | GRUB_FILE_TYPE_NO_DECOMPRESS); - if (! file) - return grub_errno; - - /* First try to replace the old device. */ + /* 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) - break; + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name already exists"); - if (newdev) - { - grub_file_close (newdev->file); - newdev->file = file; - - return 0; - } + file = grub_file_open (args[1], type); + if (! file) + return grub_errno; /* Unable to replace it, make a new entry. */ newdev = grub_malloc (sizeof (struct grub_loopback)); @@ -124,6 +124,7 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) newdev->file = file; newdev->id = last_id++; + newdev->refcnt = 0; /* Add the new entry to the list. */ newdev->next = loopback_list; @@ -165,6 +166,9 @@ 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"); + /* 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) @@ -182,6 +186,15 @@ grub_loopback_open (const char *name, grub_disk_t disk) return 0; } +static void +grub_loopback_close (grub_disk_t disk) +{ + struct grub_loopback *dev = disk->data; + + if (grub_sub (dev->refcnt, 1, &dev->refcnt)) + grub_fatal ("Reference count underflow"); +} + static grub_err_t grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) @@ -224,6 +237,7 @@ static struct grub_disk_dev grub_loopback_dev = .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, .next = 0 @@ -234,7 +248,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(loopback) { cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0, - N_("[-d] DEVICENAME FILE."), + 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); diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 86c50c612..9e1e6a5d9 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2007,2010,2011 Free Software Foundation, Inc. + * 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 @@ -29,8 +29,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); -#define MAX_PASSPHRASE 256 - #define LUKS_KEY_ENABLED 0x00AC71F3 /* On disk LUKS header */ @@ -65,28 +63,16 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_size_t blocknumbers); static grub_cryptodisk_t -configure_ciphers (grub_disk_t disk, const char *check_uuid, - int check_boot) +luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) { grub_cryptodisk_t newdev; - const char *iptr; struct grub_luks_phdr header; - char *optr; - char uuid[sizeof (header.uuid) + 1]; char ciphername[sizeof (header.cipherName) + 1]; char ciphermode[sizeof (header.cipherMode) + 1]; - char *cipheriv = NULL; char hashspec[sizeof (header.hashSpec) + 1]; - grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL; - grub_crypto_cipher_handle_t essiv_cipher = NULL; - const gcry_md_spec_t *hash = NULL, *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 err; - if (check_boot) + if (cargs->check_boot) return NULL; /* Read the LUKS header. */ @@ -103,18 +89,9 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, || grub_be_to_cpu16 (header.version) != 1) return NULL; - optr = uuid; - for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)]; - iptr++) + if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0) { - if (*iptr != '-') - *optr++ = *iptr; - } - *optr = 0; - - if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) - { - grub_dprintf ("luks", "%s != %s\n", uuid, check_uuid); + grub_dprintf ("luks", "%s != %s\n", header.uuid, cargs->search_uuid); return NULL; } @@ -126,201 +103,53 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec)); hashspec[sizeof (header.hashSpec)] = 0; - ciph = grub_crypto_lookup_cipher_by_name (ciphername); - if (!ciph) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available", - ciphername); + newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); + if (!newdev) return NULL; - } - - /* Configure the cipher used for the bulk data. */ - cipher = grub_crypto_cipher_open (ciph); - if (!cipher) - return NULL; - - if (grub_be_to_cpu32 (header.keyBytes) > 1024) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d", - grub_be_to_cpu32 (header.keyBytes)); - grub_crypto_cipher_close (cipher); - return NULL; - } - - /* 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) - { - grub_crypto_cipher_close (cipher); - return NULL; - } - if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", - cipher->cipher->blocksize); - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (secondary_cipher); - return NULL; - } - if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES) - { - grub_crypto_cipher_close (cipher); - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d", - secondary_cipher->cipher->blocksize); - grub_crypto_cipher_close (secondary_cipher); - return NULL; - } - } - 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) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d", - cipher->cipher->blocksize); - grub_crypto_cipher_close (cipher); - return NULL; - } - } - else - { - grub_crypto_cipher_close (cipher); - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s", - ciphermode); - return NULL; - } - - if (cipheriv == NULL); - else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0) - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN; - else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0) - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64; - 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: %d", - 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) - { - 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) - { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (secondary_cipher); - grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Couldn't load %s hash", hash_str); - return NULL; - } - essiv_cipher = grub_crypto_cipher_open (ciph); - if (!essiv_cipher) - { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (secondary_cipher); - return NULL; - } - } - else - { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (secondary_cipher); - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s", - cipheriv); - 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. */ - hash = grub_crypto_lookup_md_by_name (hashspec); - if (!hash) + newdev->hash = grub_crypto_lookup_md_by_name (hashspec); + if (!newdev->hash) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); - grub_crypto_cipher_close (secondary_cipher); + grub_free (newdev); grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash", hashspec); return NULL; } - newdev = grub_zalloc (sizeof (struct grub_cryptodisk)); - if (!newdev) + err = grub_cryptodisk_setcipher (newdev, ciphername, ciphermode); + if (err) { - grub_crypto_cipher_close (cipher); - grub_crypto_cipher_close (essiv_cipher); - grub_crypto_cipher_close (secondary_cipher); + grub_free (newdev); return NULL; } - newdev->cipher = cipher; - newdev->offset = grub_be_to_cpu32 (header.payloadOffset); - newdev->source_disk = NULL; - newdev->benbi_log = benbi_log; - newdev->mode = mode; - newdev->mode_iv = mode_iv; - newdev->secondary_cipher = secondary_cipher; - newdev->essiv_cipher = essiv_cipher; - newdev->essiv_hash = essiv_hash; - newdev->hash = hash; - newdev->log_sector_size = 9; - newdev->total_length = grub_disk_get_size (disk) - newdev->offset; - grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); - newdev->modname = "luks"; - COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); + + 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_cryptodisk_t dev, + grub_cryptomount_args_t cargs) { struct grub_luks_phdr header; grub_size_t keysize; grub_uint8_t *split_key = NULL; - char passphrase[MAX_PASSPHRASE] = ""; grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; unsigned i; grub_size_t length; grub_err_t err; grub_size_t max_stripes = 1; - char *tmp; + + 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) @@ -336,24 +165,10 @@ luks_recover_key (grub_disk_t source, && grub_be_to_cpu32 (header.keyblock[i].stripes) > max_stripes) max_stripes = grub_be_to_cpu32 (header.keyblock[i].stripes); - split_key = grub_malloc (keysize * max_stripes); + split_key = grub_calloc (keysize, max_stripes); if (!split_key) return grub_errno; - /* Get the passphrase from the user. */ - tmp = NULL; - if (source->partition) - tmp = grub_partition_get_name (source->partition); - grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, - source->partition ? "," : "", tmp ? : "", - dev->uuid); - grub_free (tmp); - if (!grub_password_get (passphrase, MAX_PASSPHRASE)) - { - grub_free (split_key); - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); - } - /* Try to recover master key from each active keyslot. */ for (i = 0; i < ARRAY_SIZE (header.keyblock); i++) { @@ -368,8 +183,8 @@ luks_recover_key (grub_disk_t source, grub_dprintf ("luks", "Trying keyslot %d\n", i); /* Calculate the PBKDF2 of the user supplied passphrase. */ - gcry_err = grub_crypto_pbkdf2 (dev->hash, (grub_uint8_t *) passphrase, - grub_strlen (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]. @@ -384,7 +199,7 @@ luks_recover_key (grub_disk_t source, grub_dprintf ("luks", "PBKDF2 done\n"); - gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); + gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); if (gcry_err) { grub_free (split_key); @@ -404,7 +219,8 @@ luks_recover_key (grub_disk_t source, return err; } - gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0); + gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0, + GRUB_LUKS1_LOG_SECTOR_SIZE); if (gcry_err) { grub_free (split_key); @@ -451,7 +267,7 @@ luks_recover_key (grub_disk_t source, grub_printf_ (N_("Slot %d opened\n"), i); /* Set the master key. */ - gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); + gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); if (gcry_err) { grub_free (split_key); @@ -468,7 +284,7 @@ luks_recover_key (grub_disk_t source, } struct grub_cryptodisk_dev luks_crypto = { - .scan = configure_ciphers, + .scan = luks_scan, .recover_key = luks_recover_key }; diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c new file mode 100644 index 000000000..8036d76ff --- /dev/null +++ b/grub-core/disk/luks2.c @@ -0,0 +1,808 @@ +/* + * 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; + + 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 index 7b265c780..af6a8e93c 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef GRUB_UTIL #include @@ -33,12 +34,19 @@ 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 (char **p, const char *str) +grub_lvm_getvalue (const char ** const p, const char *str) { *p = grub_strstr (*p, str); if (! *p) @@ -63,12 +71,12 @@ grub_lvm_checkvalue (char **p, char *str, char *tmpl) #endif static int -grub_lvm_check_flag (char *p, const char *str, const char *flag) +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) { - char *q; + const char *q; p = grub_strstr (p, str); if (! p) return 0; @@ -95,17 +103,46 @@ grub_lvm_check_flag (char *p, const char *str, const char *flag) } } -static struct grub_diskfilter_vg * +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, *p, *q, *vgname; + 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; @@ -139,6 +176,20 @@ grub_lvm_detect (grub_disk_t disk, 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++) @@ -173,7 +224,7 @@ grub_lvm_detect (grub_disk_t disk, first one. */ /* Allocate buffer space for the circular worst-case scenario. */ - metadatabuf = grub_malloc (2 * mda_size); + metadatabuf = grub_calloc (2, mda_size); if (! metadatabuf) goto fail; @@ -195,9 +246,27 @@ grub_lvm_detect (grub_disk_t disk, } 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, @@ -205,19 +274,31 @@ grub_lvm_detect (grub_disk_t disk, 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) + 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) @@ -242,6 +323,8 @@ grub_lvm_detect (grub_disk_t disk, 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)); @@ -275,19 +358,29 @@ grub_lvm_detect (grub_disk_t disk, while (1) { grub_ssize_t s; - while (grub_isspace (*p)) + 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 != ' ') + 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'; @@ -328,10 +421,13 @@ grub_lvm_detect (grub_disk_t disk, 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) @@ -347,18 +443,26 @@ grub_lvm_detect (grub_disk_t disk, struct grub_diskfilter_segment *seg; int is_pvmove; - while (grub_isspace (*p)) + 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 != ' ') + 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) @@ -367,8 +471,26 @@ grub_lvm_detect (grub_disk_t disk, { const char *iptr; char *optr; - lv->fullname = grub_malloc (sizeof ("lvm/") - 1 + 2 * vgname_len - + 1 + 2 * s + 1); + + /* + * 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; @@ -426,7 +548,9 @@ grub_lvm_detect (grub_disk_t disk, #endif goto lvs_fail; } - lv->segments = grub_zalloc (sizeof (*seg) * lv->segment_count); + 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++) @@ -481,10 +605,21 @@ grub_lvm_detect (grub_disk_t disk, } if (seg->node_count != 1) - seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); + { + 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_zalloc (sizeof (*stripe) - * seg->node_count); + 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 = ["); @@ -501,11 +636,14 @@ grub_lvm_detect (grub_disk_t disk, { p = grub_strchr (p, '"'); if (p == NULL) - continue; + goto lvs_segment_fail2; q = ++p; - while (*q != '"') + while (q < mda_end && *q != '"') q++; + if (q == mda_end) + goto lvs_segment_fail2; + s = q - p; stripe->name = grub_malloc (s + 1); @@ -520,7 +658,10 @@ grub_lvm_detect (grub_disk_t disk, stripe->start = grub_lvm_getvalue (&p, ",") * vg->extent_size; if (p == NULL) - continue; + { + grub_free (stripe->name); + goto lvs_segment_fail2; + } stripe++; } @@ -538,8 +679,9 @@ grub_lvm_detect (grub_disk_t disk, goto lvs_segment_fail; } - seg->nodes = grub_zalloc (sizeof (seg->nodes[0]) - * seg->node_count); + 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) @@ -557,11 +699,14 @@ grub_lvm_detect (grub_disk_t disk, p = grub_strchr (p, '"'); if (p == NULL) - continue; + goto lvs_segment_fail2; q = ++p; - while (*q != '"') + while (q < mda_end && *q != '"') q++; + if (q == mda_end) + goto lvs_segment_fail2; + s = q - p; lvname = grub_malloc (s + 1); @@ -624,8 +769,9 @@ grub_lvm_detect (grub_disk_t disk, } } - seg->nodes = grub_zalloc (sizeof (seg->nodes[0]) - * seg->node_count); + 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) @@ -645,7 +791,7 @@ grub_lvm_detect (grub_disk_t disk, p = p ? grub_strchr (p + 1, '"') : 0; p = p ? grub_strchr (p + 1, '"') : 0; if (p == NULL) - continue; + goto lvs_segment_fail2; q = ++p; while (*q != '"') q++; @@ -671,13 +817,107 @@ grub_lvm_detect (grub_disk_t disk, 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; + *p2 = '\0'; grub_util_info ("unknown LVM type %s", p); if (p2) *p2 ='"'; @@ -721,10 +961,68 @@ grub_lvm_detect (grub_disk_t disk, } } - /* Match lvs. */ + + { + 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++) @@ -741,12 +1039,17 @@ grub_lvm_detect (grub_disk_t disk, } if (lv1->segments[i].nodes[j].pv == NULL) for (lv2 = vg->lvs; lv2; lv2 = lv2->next) - if (grub_strcmp (lv2->name, - lv1->segments[i].nodes[j].name) == 0) - lv1->segments[i].nodes[j].lv = lv2; + { + 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; } diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c index 7cc80d3df..dd5d440a3 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -103,6 +104,9 @@ struct grub_raid_super_1x #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, @@ -111,7 +115,7 @@ grub_mdraid_detect (grub_disk_t disk, grub_uint64_t size; grub_uint8_t minor_version; - size = grub_disk_get_size (disk); + size = grub_disk_native_sectors (disk); /* Check for an 1.x superblock. * It's always aligned to a 4K boundary @@ -129,10 +133,11 @@ grub_mdraid_detect (grub_disk_t disk, 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: @@ -154,6 +159,79 @@ grub_mdraid_detect (grub_disk_t disk, || 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; @@ -177,8 +255,8 @@ grub_mdraid_detect (grub_disk_t disk, /* Spares aren't implemented. */ return NULL; - if (grub_disk_read (disk, sector, - (char *) &sb.dev_roles[grub_le_to_cpu32 (sb.dev_number)] + if (grub_disk_read (disk, sector, + (char *) (sb.dev_roles + grub_le_to_cpu32 (sb.dev_number)) - (char *) &sb, sizeof (role), &role)) return NULL; @@ -203,7 +281,7 @@ grub_mdraid_detect (grub_disk_t disk, grub_le_to_cpu32 (sb.raid_disks), sb.set_name, (sb.size) - ? grub_le_to_cpu64 (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), diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c index 11024ae31..e40216f51 100644 --- a/grub-core/disk/mdraid_linux.c +++ b/grub-core/disk/mdraid_linux.c @@ -190,7 +190,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_diskfilter_vg *ret; /* The sector where the mdraid 0.90 superblock is stored, if available. */ - size = grub_disk_get_size (disk); + size = grub_disk_native_sectors (disk); if (size == GRUB_DISK_SIZE_UNKNOWN) /* not 0.9x raid. */ return NULL; diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c index 613779cf3..2d7afaea3 100644 --- a/grub-core/disk/memdisk.c +++ b/grub-core/disk/memdisk.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -96,8 +97,14 @@ GRUB_MOD_INIT(memdisk) grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr); - memdisk_size = header->size - sizeof (struct grub_module_header); + 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; grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n"); grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size); diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c index 23eef2be1..0578a93e1 100644 --- a/grub-core/disk/pata.c +++ b/grub-core/disk/pata.c @@ -123,7 +123,7 @@ grub_pata_wait (void) 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. */ @@ -331,6 +331,12 @@ grub_pata_device_initialize (int port, int device, int addr) *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 (); diff --git a/grub-core/disk/plainmount.c b/grub-core/disk/plainmount.c new file mode 100644 index 000000000..21ec4072c --- /dev/null +++ b/grub-core/disk/plainmount.c @@ -0,0 +1,463 @@ +/* + * 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/scsi.c b/grub-core/disk/scsi.c index 70767cf00..1c3865fd2 100644 --- a/grub-core/disk/scsi.c +++ b/grub-core/disk/scsi.c @@ -90,7 +90,7 @@ 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; @@ -108,7 +108,7 @@ grub_scsi_test_unit_ready (grub_scsi_t 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; @@ -169,7 +169,7 @@ grub_scsi_read_capacity10 (grub_scsi_t scsi) rc.PMI = 0; rc.control = 0; rc.pad = 0; - + err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, sizeof (rcd), (char *) &rcd); @@ -204,7 +204,7 @@ grub_scsi_read_capacity16 (grub_scsi_t scsi) 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); @@ -620,9 +620,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) grub_free (scsi); return grub_errno; } - for (disk->log_sector_size = 0; - (1U << disk->log_sector_size) < scsi->blocksize; - disk->log_sector_size++); + disk->log_sector_size = grub_log2ull (scsi->blocksize); grub_dprintf ("scsi", "last_block=%" PRIuGRUB_UINT64_T ", blocksize=%u\n", scsi->last_block, scsi->blocksize); diff --git a/grub-core/disk/uboot/ubootdisk.c b/grub-core/disk/uboot/ubootdisk.c index 2d115a94d..0e918d4d1 100644 --- a/grub-core/disk/uboot/ubootdisk.c +++ b/grub-core/disk/uboot/ubootdisk.c @@ -186,9 +186,7 @@ uboot_disk_open (const char *name, struct grub_disk *disk) if (d->block_size == 0) return grub_error (GRUB_ERR_IO, "no block size"); - for (disk->log_sector_size = 0; - (1U << disk->log_sector_size) < d->block_size; - disk->log_sector_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); diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c index 380ca4c4c..b81e3ad9d 100644 --- a/grub-core/disk/usbms.c +++ b/grub-core/disk/usbms.c @@ -104,7 +104,7 @@ grub_usbms_cbi_reset (grub_usb_device_t dev, int interface) { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }; - + return grub_usbms_cbi_cmd (dev, interface, (grub_uint8_t *)&cbicb); } @@ -161,7 +161,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) /* 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_UFI && interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 ) || (interf->protocol != GRUB_USBMS_PROTOCOL_BULK && interf->protocol != GRUB_USBMS_PROTOCOL_CBI @@ -215,7 +215,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) 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. */ @@ -231,7 +231,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) 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, + * LUN number. LUNs are numbered from 0, * i.e. number of LUNs is luns+1 ! */ grub_usbms_devices[curnum]->luns = luns + 1; } @@ -239,7 +239,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) /* 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; @@ -297,7 +297,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, grub_usb_err_t err = GRUB_USB_ERR_NONE; grub_usb_err_t errCSW = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; - + tag++; retry: @@ -314,7 +314,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, 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); @@ -344,7 +344,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, 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); + grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); if (err) { if (err == GRUB_USB_ERR_STALL) @@ -411,7 +411,7 @@ CheckCSW: 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))) @@ -444,7 +444,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, 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) @@ -456,7 +456,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *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], @@ -490,7 +490,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, if (size && (read_write == 0)) { err = grub_usb_bulk_read (dev->dev, dev->in, size, buf); - grub_dprintf ("usb", "read: %d\n", err); + grub_dprintf ("usb", "read: %d\n", err); if (err) { if (err == GRUB_USB_ERR_STALL) @@ -572,7 +572,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, if (err) return grub_error (GRUB_ERR_IO, "USB error %d", err); - + return GRUB_ERR_NONE; } diff --git a/grub-core/disk/xen/xendisk.c b/grub-core/disk/xen/xendisk.c index 48476cbbf..496f1ea7b 100644 --- a/grub-core/disk/xen/xendisk.c +++ b/grub-core/disk/xen/xendisk.c @@ -113,9 +113,7 @@ grub_virtdisk_open (const char *name, grub_disk_t disk) || secsize > GRUB_XEN_PAGE_SIZE) return grub_error (GRUB_ERR_IO, "unsupported sector size %d", secsize); - for (disk->log_sector_size = 0; - (1U << disk->log_sector_size) < secsize; disk->log_sector_size++); - + disk->log_sector_size = grub_log2ull (secsize); disk->total_sectors >>= disk->log_sector_size - 9; return GRUB_ERR_NONE; @@ -426,7 +424,7 @@ grub_xendisk_init (void) if (!ctr) return; - virtdisks = grub_malloc (ctr * sizeof (virtdisks[0])); + virtdisks = grub_calloc (ctr, sizeof (virtdisks[0])); if (!virtdisks) return; if (grub_xenstore_dir ("device/vbd", fill, &ctr)) diff --git a/grub-core/efiemu/i386/loadcore64.c b/grub-core/efiemu/i386/loadcore64.c index 18facf47f..ae476ef2c 100644 --- a/grub-core/efiemu/i386/loadcore64.c +++ b/grub-core/efiemu/i386/loadcore64.c @@ -121,9 +121,14 @@ grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs, 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)); + { + 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); + } } } } diff --git a/grub-core/efiemu/i386/pc/cfgtables.c b/grub-core/efiemu/i386/pc/cfgtables.c index 492c07c46..056ec0bc9 100644 --- a/grub-core/efiemu/i386/pc/cfgtables.c +++ b/grub-core/efiemu/i386/pc/cfgtables.c @@ -22,16 +22,16 @@ #include #include #include +#include grub_err_t grub_machine_efiemu_init_tables (void) { - grub_uint8_t *ptr; void *table; grub_err_t err; - grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID; - grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID; - grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID; + 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; err = grub_efiemu_unregister_configuration_table (smbios); if (err) @@ -57,17 +57,10 @@ grub_machine_efiemu_init_tables (void) if (err) return err; } - - for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; - ptr += 16) - if (grub_memcmp (ptr, "_SM_", 4) == 0 - && grub_byte_checksum (ptr, *(ptr + 5)) == 0) - break; - - if (ptr < (grub_uint8_t *) 0x100000) + table = grub_smbios_get_eps (); + if (table) { - grub_dprintf ("efiemu", "Registering SMBIOS\n"); - err = grub_efiemu_register_configuration_table (smbios, 0, 0, ptr); + err = grub_efiemu_register_configuration_table (smbios, 0, 0, table); if (err) return err; } diff --git a/grub-core/efiemu/loadcore.c b/grub-core/efiemu/loadcore.c index 44085ef81..2b924623f 100644 --- a/grub-core/efiemu/loadcore.c +++ b/grub-core/efiemu/loadcore.c @@ -201,7 +201,7 @@ grub_efiemu_count_symbols (const Elf_Ehdr *e) grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize; grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *) - grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms); + grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym)); /* Relocators */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c index a81934725..e7037f4ed 100644 --- a/grub-core/efiemu/main.c +++ b/grub-core/efiemu/main.c @@ -80,7 +80,7 @@ grub_efiemu_unload (void) /* Remove previously registered table from the list */ grub_err_t -grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid) +grub_efiemu_unregister_configuration_table (grub_guid_t guid) { struct grub_efiemu_configuration_table *cur, *prev; @@ -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_efi_guid_t guid, +grub_efiemu_register_configuration_table (grub_guid_t guid, void * (*get_table) (void *data), void (*unload) (void *data), void *data) diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c index 52a032f7b..9b8e0d0ad 100644 --- a/grub-core/efiemu/mm.c +++ b/grub-core/efiemu/mm.c @@ -554,11 +554,11 @@ 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_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num); + grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2); /* Number of chunks can't increase more than by factor of 2 */ result = (grub_efi_memory_descriptor_t *) - grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num); + grub_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2); if (!result || !scanline_events) { grub_free (result); @@ -660,7 +660,7 @@ grub_efiemu_mm_do_alloc (void) /* Preallocate mmap */ efiemu_mmap = (grub_efi_memory_descriptor_t *) - grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t)); + grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t)); if (!efiemu_mmap) { grub_efiemu_unload (); diff --git a/grub-core/efiemu/pnvram.c b/grub-core/efiemu/pnvram.c index c5c3d4bd3..dd42bc691 100644 --- a/grub-core/efiemu/pnvram.c +++ b/grub-core/efiemu/pnvram.c @@ -39,7 +39,7 @@ static grub_size_t nvramsize; /* Parse signed value */ static int -grub_strtosl (const char *arg, char **end, int base) +grub_strtosl (const char *arg, const char ** const end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); @@ -120,7 +120,8 @@ nvram_set (void * data __attribute__ ((unused))) grub_memset (nvram, 0, nvramsize); FOR_SORTED_ENV (var) { - char *guid, *attr, *name, *varname; + const char *guid; + char *attr, *name, *varname; struct efi_variable *efivar; int len = 0; int i; diff --git a/grub-core/efiemu/runtime/efiemu.c b/grub-core/efiemu/runtime/efiemu.c index 5db1f347b..51dc02114 100644 --- a/grub-core/efiemu/runtime/efiemu.c +++ b/grub-core/efiemu/runtime/efiemu.c @@ -32,17 +32,17 @@ #include #include -grub_efi_status_t +grub_efi_status_t __grub_efi_api efiemu_get_time (grub_efi_time_t *time, grub_efi_time_capabilities_t *capabilities); -grub_efi_status_t +grub_efi_status_t __grub_efi_api efiemu_set_time (grub_efi_time_t *time); -grub_efi_status_t +grub_efi_status_t __grub_efi_api 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_status_t __grub_efi_api efiemu_set_wakeup_time (grub_efi_boolean_t enabled, grub_efi_time_t *time); @@ -52,51 +52,51 @@ efiemu_set_wakeup_time (grub_efi_boolean_t enabled, #define PHYSICAL_ATTRIBUTE __attribute__ ((section(".text-physical"))); #endif -grub_efi_status_t +grub_efi_status_t __grub_efi_api 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_status_t __grub_efi_api efiemu_convert_pointer (grub_efi_uintn_t debug_disposition, void **address) PHYSICAL_ATTRIBUTE; -grub_efi_status_t +grub_efi_status_t __grub_efi_api efiemu_get_variable (grub_efi_char16_t *variable_name, - const grub_efi_guid_t *vendor_guid, + const grub_packed_guid_t *vendor_guid, grub_efi_uint32_t *attributes, grub_efi_uintn_t *data_size, void *data); -grub_efi_status_t +grub_efi_status_t __grub_efi_api efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size, grub_efi_char16_t *variable_name, - grub_efi_guid_t *vendor_guid); + grub_packed_guid_t *vendor_guid); -grub_efi_status_t +grub_efi_status_t __grub_efi_api efiemu_set_variable (grub_efi_char16_t *variable_name, - const grub_efi_guid_t *vendor_guid, + const grub_packed_guid_t *vendor_guid, grub_efi_uint32_t attributes, grub_efi_uintn_t data_size, void *data); -grub_efi_status_t +grub_efi_status_t __grub_efi_api efiemu_get_next_high_monotonic_count (grub_efi_uint32_t *high_count); -void +void __grub_efi_api 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_status_t __grub_efi_api 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_status_t __grub_efi_api EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition, void **address) PHYSICAL_ATTRIBUTE; @@ -202,7 +202,7 @@ bcd_to_hex (grub_uint8_t in) return 10 * ((in & 0xf0) >> 4) + (in & 0x0f); } -grub_efi_status_t +grub_efi_status_t __grub_efi_api EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time, grub_efi_time_capabilities_t *capabilities) { @@ -246,7 +246,7 @@ EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time, return GRUB_EFI_SUCCESS; } -grub_efi_status_t +grub_efi_status_t __grub_efi_api EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time) { LOG ('b'); @@ -265,7 +265,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_status_t __grub_efi_api EFI_FUNC (efiemu_get_wakeup_time) (grub_efi_boolean_t *enabled, grub_efi_boolean_t *pending, grub_efi_time_t *time) @@ -274,7 +274,7 @@ EFI_FUNC (efiemu_get_wakeup_time) (grub_efi_boolean_t *enabled, return GRUB_EFI_UNSUPPORTED; } -grub_efi_status_t +grub_efi_status_t __grub_efi_api EFI_FUNC (efiemu_set_wakeup_time) (grub_efi_boolean_t enabled, grub_efi_time_t *time) { @@ -337,7 +337,7 @@ efiemu_getcrc32 (grub_uint32_t crc, void *buf, int size) } -grub_efi_status_t EFI_FUNC +grub_efi_status_t __grub_efi_api 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, @@ -403,7 +403,7 @@ grub_efi_status_t 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_status_t __grub_efi_api EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition, void **address) { @@ -416,7 +416,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_efi_guid_t *vendor_guid, +find_variable (const grub_packed_guid_t *vendor_guid, grub_efi_char16_t *variable_name) { grub_uint8_t *ptr; @@ -436,9 +436,9 @@ find_variable (const grub_efi_guid_t *vendor_guid, return 0; } -grub_efi_status_t +grub_efi_status_t __grub_efi_api EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name, - const grub_efi_guid_t *vendor_guid, + const grub_packed_guid_t *vendor_guid, grub_efi_uint32_t *attributes, grub_efi_uintn_t *data_size, void *data) @@ -461,10 +461,10 @@ EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name, return GRUB_EFI_SUCCESS; } -grub_efi_status_t EFI_FUNC +grub_efi_status_t __grub_efi_api EFI_FUNC (efiemu_get_next_variable_name) (grub_efi_uintn_t *variable_name_size, grub_efi_char16_t *variable_name, - grub_efi_guid_t *vendor_guid) + grub_packed_guid_t *vendor_guid) { struct efi_variable *efivar; LOG ('l'); @@ -501,9 +501,9 @@ grub_efi_status_t EFI_FUNC return GRUB_EFI_SUCCESS; } -grub_efi_status_t +grub_efi_status_t __grub_efi_api EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name, - const grub_efi_guid_t *vendor_guid, + const grub_packed_guid_t *vendor_guid, grub_efi_uint32_t attributes, grub_efi_uintn_t data_size, void *data) @@ -556,7 +556,7 @@ EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name, return GRUB_EFI_SUCCESS; } -grub_efi_status_t EFI_FUNC +grub_efi_status_t __grub_efi_api EFI_FUNC (efiemu_get_next_high_monotonic_count) (grub_efi_uint32_t *high_count) { LOG ('j'); @@ -570,7 +570,7 @@ grub_efi_status_t EFI_FUNC Besides EFI specification says that this function shouldn't be used on systems supporting ACPI */ -void +void __grub_efi_api 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,9 +597,30 @@ struct grub_efi_runtime_services efiemu_runtime_services = .set_virtual_address_map = efiemu_set_virtual_address_map, .convert_pointer = efiemu_convert_pointer, - .get_variable = efiemu_get_variable, - .get_next_variable_name = efiemu_get_next_variable_name, - .set_variable = efiemu_set_variable, + /* + 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_next_high_monotonic_count = efiemu_get_next_high_monotonic_count, .reset_system = efiemu_reset_system diff --git a/grub-core/font/font.c b/grub-core/font/font.c index 85a292557..18de52562 100644 --- a/grub-core/font/font.c +++ b/grub-core/font/font.c @@ -30,6 +30,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -130,13 +131,18 @@ ascii_glyph_lookup (grub_uint32_t code) { 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; + ascii_font_glyph[current]->font = &null_font; grub_memcpy (ascii_font_glyph[current]->bitmap, &ascii_bitmaps[current * ASCII_BITMAP_SIZE], @@ -171,6 +177,7 @@ grub_font_loader_init (void) 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)); @@ -293,13 +300,14 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct 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)); + 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)); @@ -328,7 +336,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct return 1; } - if (entry->code < 0x10000) + if (entry->code < 0x10000 && i < 0xffff) font->bmp_idx[entry->code] = i; last_code = entry->code; @@ -361,9 +369,13 @@ static char * read_section_as_string (struct font_file_section *section) { char *str; + grub_size_t sz; grub_ssize_t ret; - str = grub_malloc (section->length + 1); + if (grub_add (section->length, 1, &sz)) + return NULL; + + str = grub_malloc (sz); if (!str) return 0; @@ -403,6 +415,27 @@ read_section_as_short (struct font_file_section *section, 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 @@ -421,25 +454,18 @@ grub_font_load (const char *filename) file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024); else { - const char *prefix = grub_env_get ("prefix"); - char *fullname, *ptr; - if (!prefix) + file = try_open_from_prefix ("(memdisk)", filename); + if (!file) { - grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), - "prefix"); - goto fail; + 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); } - fullname = grub_malloc (grub_strlen (prefix) + grub_strlen (filename) + 1 - + sizeof ("/fonts/") + sizeof (".pf2")); - if (!fullname) - goto fail; - 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); } if (!file) goto fail; @@ -528,6 +554,12 @@ grub_font_load (const char *filename) 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; @@ -626,8 +658,8 @@ grub_font_load (const char *filename) font->max_char_width, font->max_char_height, font->num_chars); #endif - if (font->max_char_width == 0 - || font->max_char_height == 0 + 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) { @@ -676,40 +708,47 @@ read_be_int16 (grub_file_t file, grub_int16_t * value) 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; + 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 0; - return &table[font->bmp_idx[code]]; + 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. */ - lo = 0; - hi = font->num_chars - 1; + /* + * 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; - if (!table) - return 0; - - while (lo <= hi) + while (len > 0) { - mid = lo + (hi - lo) / 2; - if (code < table[mid].code) - hi = mid - 1; - else if (code > table[mid].code) - lo = mid + 1; + 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 - return &table[mid]; + len = half; } - return 0; + return (first < end && first->code == code) ? first : NULL; } /* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded @@ -729,7 +768,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) grub_int16_t xoff; grub_int16_t yoff; grub_int16_t dwidth; - int len; + grub_ssize_t len; + grub_size_t sz; if (index_entry->glyph) /* Return cached glyph. */ @@ -750,15 +790,25 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) || 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) + || read_be_int16 (font->file, &dwidth) != 0 + || width > font->max_char_width + || height > font->max_char_height) { remove_font (font); return 0; } - len = (width * height + 7) / 8; - glyph = grub_malloc (sizeof (struct grub_font_glyph) + len); - if (!glyph) + /* 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; @@ -926,7 +976,7 @@ grub_font_get_height (grub_font_t font) } /* 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. + 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) @@ -1034,27 +1084,20 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) return best_glyph; } -#if 0 -static struct grub_font_glyph * -grub_font_dup_glyph (struct grub_font_glyph *glyph) -{ - static struct grub_font_glyph *ret; - ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8); - if (!ret) - return NULL; - grub_memcpy (ret, glyph, sizeof (*ret) - + (glyph->width * glyph->height + 7) / 8); - return ret; -} -#endif - /* 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; @@ -1086,9 +1129,16 @@ 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; @@ -1187,12 +1237,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, ctx.bounds.height = main_glyph->height; above_rightx = main_glyph->offset_x + main_glyph->width; - above_righty = ctx.bounds.y + ctx.bounds.height; + above_righty = ctx.bounds.y + (int) ctx.bounds.height; above_leftx = main_glyph->offset_x; - above_lefty = ctx.bounds.y + ctx.bounds.height; + above_lefty = ctx.bounds.y + (int) ctx.bounds.height; - below_rightx = ctx.bounds.x + ctx.bounds.width; + below_rightx = ctx.bounds.x + (int) ctx.bounds.width; below_righty = ctx.bounds.y; comb = grub_unicode_get_comb (glyph_id); @@ -1205,7 +1255,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, if (!combining_glyphs[i]) continue; - targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; + 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) @@ -1215,8 +1265,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, case GRUB_UNICODE_COMB_OVERLAY: do_blit (combining_glyphs[i], targetx, - (ctx.bounds.height - combining_glyphs[i]->height) / 2 - - (ctx.bounds.height + ctx.bounds.y), &ctx); + ((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; @@ -1289,7 +1339,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, /* Fallthrough. */ case GRUB_UNICODE_STACK_ATTACHED_ABOVE: do_blit (combining_glyphs[i], targetx, - -(ctx.bounds.height + ctx.bounds.y + space + -((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; @@ -1297,7 +1347,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, case GRUB_UNICODE_COMB_HEBREW_DAGESH: do_blit (combining_glyphs[i], targetx, - -(ctx.bounds.height / 2 + ctx.bounds.y + -((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; @@ -1461,14 +1511,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id) if (glyph_id->ncomb <= render_max_comb_glyphs) return; - render_max_comb_glyphs = 2 * glyph_id->ncomb; - if (render_max_comb_glyphs < 8) + 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 = grub_malloc (render_max_comb_glyphs - * sizeof (render_combining_glyphs[0])); + render_combining_glyphs = (render_max_comb_glyphs > 0) ? + grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL; if (!render_combining_glyphs) - grub_errno = 0; + { + render_max_comb_glyphs = 0; + grub_errno = GRUB_ERR_NONE; + } } int @@ -1496,6 +1550,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, 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); @@ -1512,29 +1567,33 @@ grub_font_construct_glyph (grub_font_t hinted_font, if (!glyph_id->ncomb && !glyph_id->attributes) return main_glyph; - if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) + 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); - max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2; - if (max_glyph_size < 8) - max_glyph_size = 8; - glyph = grub_malloc (max_glyph_size); + 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, sizeof (*glyph) - + (bounds.width * bounds.height - + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT); + grub_memset (glyph, 0, cur_glyph_size); glyph->font = main_glyph->font; - glyph->width = bounds.width; - glyph->height = bounds.height; - glyph->offset_x = bounds.x; - glyph->offset_y = bounds.y; + 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, diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 6b6a2bc91..520a001c7 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -301,7 +302,7 @@ grub_affs_read_symlink (grub_fshelp_node_t node) return 0; } latin1[symlink_size] = 0; - utf8 = grub_malloc (symlink_size * GRUB_MAX_UTF8_PER_LATIN1 + 1); + utf8 = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, symlink_size); if (!utf8) { grub_free (latin1); @@ -321,7 +322,6 @@ 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 **hashtable, grub_uint32_t block, const struct grub_affs_file *fil) { struct grub_affs_data *data = dir->data; @@ -332,10 +332,7 @@ grub_affs_create_node (grub_fshelp_node_t dir, *node = grub_zalloc (sizeof (**node)); if (!*node) - { - grub_free (*hashtable); - return 1; - } + return 1; (*node)->data = data; (*node)->block = block; @@ -345,7 +342,7 @@ grub_affs_create_node (grub_fshelp_node_t dir, 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++) { @@ -370,23 +367,31 @@ grub_affs_create_node (grub_fshelp_node_t dir, GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, sizeof ((*node)->di), (char *) &(*node)->di); if (err) - return 1; + { + grub_free (*node); + return 1; + } continue; } default: - return 0; + { + grub_free (*node); + return 0; + } } break; } if (nest == 8) - return 0; + { + grub_free (*node); + return 0; + } type |= GRUB_FSHELP_CASE_INSENSITIVE; if (hook ((char *) name_u8, type, *node, hook_data)) { - grub_free (*hashtable); *node = 0; return 1; } @@ -400,29 +405,26 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, { unsigned int i; struct grub_affs_file file; - struct grub_fshelp_node *node = 0; + 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 = grub_zalloc (sizeof (*node)); + 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 = grub_zalloc (sizeof (*node)); - if (!node) - return 1; *node = *dir->parent; if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) return 1; } - hashtable = grub_zalloc (data->htsize * sizeof (*hashtable)); + hashtable = grub_calloc (data->htsize, sizeof (*hashtable)); if (!hashtable) return 1; @@ -454,19 +456,20 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, if (grub_errno) goto fail; - if (grub_affs_create_node (dir, hook, hook_data, &node, &hashtable, - next, &file)) - return 1; + 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); } } - grub_free (hashtable); - return 0; - fail: - grub_free (node); + grub_free (orig_node); grub_free (hashtable); return 0; } @@ -628,7 +631,7 @@ grub_affs_label (grub_device_t device, char **label) len = file.namelen; if (len > sizeof (file.name)) len = sizeof (file.name); - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); + *label = grub_calloc (GRUB_MAX_UTF8_PER_LATIN1 + 1, len); if (*label) *grub_latin1_to_utf8 ((grub_uint8_t *) *label, file.name, len) = '\0'; } @@ -643,7 +646,7 @@ grub_affs_label (grub_device_t device, char **label) } static grub_err_t -grub_affs_mtime (grub_device_t device, grub_int32_t *t) +grub_affs_mtime (grub_device_t device, grub_int64_t *t) { struct grub_affs_data *data; grub_disk_t disk = device->disk; @@ -701,11 +704,16 @@ static struct grub_fs grub_affs_fs = GRUB_MOD_INIT(affs) { - grub_fs_register (&grub_affs_fs); + if (!grub_is_lockdown ()) + { + grub_affs_fs.mod = mod; + grub_fs_register (&grub_affs_fs); + } my_mod = mod; } GRUB_MOD_FINI(affs) { - grub_fs_unregister (&grub_affs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_affs_fs); } diff --git a/grub-core/fs/archelp.c b/grub-core/fs/archelp.c index 0cf544f6f..0816b28de 100644 --- a/grub-core/fs/archelp.c +++ b/grub-core/fs/archelp.c @@ -21,6 +21,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -68,6 +69,7 @@ handle_symlink (struct grub_archelp_data *data, char *rest; char *linktarget; grub_size_t linktarget_len; + grub_size_t sz; *restart = 0; @@ -75,7 +77,7 @@ handle_symlink (struct grub_archelp_data *data, || !arcops->get_link_target) return GRUB_ERR_NONE; flen = grub_strlen (fn); - if (grub_memcmp (*name, fn, flen) != 0 + if (grub_memcmp (*name, fn, flen) != 0 || ((*name)[flen] != 0 && (*name)[flen] != '/')) return GRUB_ERR_NONE; rest = *name + flen; @@ -98,7 +100,12 @@ handle_symlink (struct grub_archelp_data *data, if (linktarget[0] == '\0') return GRUB_ERR_NONE; linktarget_len = grub_strlen (linktarget); - target = grub_malloc (linktarget_len + grub_strlen (*name) + 2); + + 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; @@ -180,6 +187,14 @@ grub_archelp_dir (struct grub_archelp_data *data, 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; @@ -251,7 +266,7 @@ grub_archelp_open (struct grub_archelp_data *data, grub_uint32_t mode; grub_int32_t mtime; int restart; - + if (arcops->find_file (data, &fn, &mtime, &mode)) goto fail; diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index 47dbe2011..78aeb051f 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -30,6 +30,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -416,6 +417,8 @@ read_bfs_file (grub_disk_t disk, len -= read_size; buf = (char *) buf + read_size; } + grub_free (l1_entries); + grub_free (l2_entries); return GRUB_ERR_NONE; } } @@ -530,13 +533,13 @@ iterate_in_b_tree (grub_disk_t disk, err = read_b_node (disk, sb, ino, node_off, &node, - &key_data, + &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; @@ -682,7 +685,7 @@ find_in_b_tree (grub_disk_t disk, level--; grub_free (node); continue; - } + } } else if (level != 0 && i + 1 < grub_bfs_to_cpu_treehead (node->count_keys)) @@ -806,7 +809,7 @@ find_file (const char *path, grub_disk_t disk, .disk = disk, .sb = sb, }; - struct grub_fshelp_node *found; + struct grub_fshelp_node *found = NULL; err = read_extent (disk, sb, &sb->root_dir, 0, 0, &root.ino, sizeof (root.ino)); @@ -827,7 +830,7 @@ 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, + return grub_error (GRUB_ERR_BAD_FS, #ifdef MODE_AFS "not an AFS filesystem" #else @@ -843,7 +846,7 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) || (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, + return grub_error (GRUB_ERR_BAD_FS, #ifdef MODE_AFS "not an AFS filesystem" #else @@ -1104,7 +1107,11 @@ GRUB_MOD_INIT (bfs) { COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == sizeof (struct grub_bfs_extent)); - grub_fs_register (&grub_bfs_fs); + if (!grub_is_lockdown ()) + { + grub_bfs_fs.mod = mod; + grub_fs_register (&grub_bfs_fs); + } } #ifdef MODE_AFS @@ -1113,5 +1120,6 @@ GRUB_MOD_FINI (afs) GRUB_MOD_FINI (bfs) #endif { - grub_fs_unregister (&grub_bfs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_bfs_fs); } diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 48bd3d04a..7bf8d922f 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -40,6 +40,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -136,6 +137,8 @@ struct grub_btrfs_chunk_item #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; @@ -329,9 +332,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, if (desc->allocated < desc->depth) { void *newdata; - desc->allocated *= 2; - newdata = grub_realloc (desc->data, sizeof (desc->data[0]) - * desc->allocated); + 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; @@ -376,9 +383,9 @@ next (struct grub_btrfs_data *data, err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr), &head, sizeof (head), 0); - check_btrfs_header (data, &head, grub_le_to_cpu64 (node.addr)); 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); @@ -413,7 +420,7 @@ lower_bound (struct grub_btrfs_data *data, { desc->allocated = 16; desc->depth = 0; - desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated); + desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0])); if (!desc->data) return grub_errno; } @@ -438,9 +445,9 @@ lower_bound (struct grub_btrfs_data *data, /* FIXME: preread few nodes into buffer. */ err = grub_btrfs_read_logical (data, addr, &head, sizeof (head), recursion_depth + 1); - check_btrfs_header (data, &head, addr); if (err) return err; + check_btrfs_header (data, &head, addr); addr += sizeof (head); if (head.level) { @@ -622,16 +629,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id) if (data->n_devices_attached > data->n_devices_allocated) { void *tmp; - data->n_devices_allocated = 2 * data->n_devices_attached + 1; - data->devices_attached - = grub_realloc (tmp = data->devices_attached, - data->n_devices_allocated - * sizeof (data->devices_attached[0])); + 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); - data->devices_attached = tmp; return NULL; } } @@ -752,7 +764,7 @@ raid56_read_retry (struct grub_btrfs_data *data, grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY; grub_uint64_t i, failed_devices; - buffers = grub_zalloc (sizeof(*buffers) * nstripes); + buffers = grub_calloc (nstripes, sizeof (*buffers)); if (!buffers) goto cleanup; @@ -900,6 +912,23 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t 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; @@ -958,20 +987,48 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, 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\n"); + grub_dprintf ("btrfs", "RAID1 (copies: %d)\n", ++redundancy); stripen = 0; stripe_offset = off; csize = grub_le_to_cpu64 (chunk->size) - off; - redundancy = 2; + + /* + * 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: @@ -1008,6 +1065,20 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, 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: @@ -1066,6 +1137,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, * 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); /* @@ -1102,8 +1176,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, 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 %" @@ -1116,6 +1199,22 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, 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, @@ -1177,8 +1276,8 @@ grub_btrfs_mount (grub_device_t dev) } data->n_devices_allocated = 16; - data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) - * data->n_devices_allocated); + data->devices_attached = grub_calloc (data->n_devices_allocated, + sizeof (data->devices_attached[0])); if (!data->devices_attached) { grub_free (data); @@ -1423,6 +1522,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, 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) { @@ -1435,9 +1536,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, 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, NULL, 0); + &elemaddr, &elemsize, &desc, 0); if (err) - return -1; + { + grub_free (desc.data); + return -1; + } if (key_out.object_id != ino || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) { @@ -1474,10 +1578,40 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, 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) { - grub_error (GRUB_ERR_BAD_FS, "extent not found"); - return -1; + 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; @@ -1670,6 +1804,7 @@ find_path (struct grub_btrfs_data *data, char *path_alloc = NULL; char *origpath = NULL; unsigned symlinks_max = 32; + grub_size_t sz; err = get_root (data, key, tree, type); if (err) @@ -1760,9 +1895,15 @@ find_path (struct grub_btrfs_data *data, struct grub_btrfs_dir_item *cdirel; if (elemsize > allocated) { - allocated = 2 * elemsize; + 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 (allocated + 1); + direl = grub_malloc (sz); if (!direl) { grub_free (path_alloc); @@ -1824,8 +1965,16 @@ find_path (struct grub_btrfs_data *data, grub_free (origpath); return err; } - tmp = grub_malloc (grub_le_to_cpu64 (inode.size) - + grub_strlen (path) + 1); + + 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); @@ -1853,7 +2002,12 @@ find_path (struct grub_btrfs_data *data, { err = get_root (data, key, tree, type); if (err) - return err; + { + grub_free (direl); + grub_free (path_alloc); + grub_free (origpath); + return err; + } } continue; } @@ -1941,6 +2095,8 @@ grub_btrfs_dir (grub_device_t device, const char *path, 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; @@ -1962,6 +2118,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, if (err) { grub_btrfs_unmount (data); + grub_free (desc.data); return err; } if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM @@ -1982,9 +2139,15 @@ grub_btrfs_dir (grub_device_t device, const char *path, } if (elemsize > allocated) { - allocated = 2 * elemsize; + 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 (allocated + 1); + direl = grub_malloc (sz); if (!direl) { r = -grub_errno; @@ -1999,6 +2162,18 @@ grub_btrfs_dir (grub_device_t device, const char *path, 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; @@ -2009,6 +2184,19 @@ grub_btrfs_dir (grub_device_t device, const char *path, 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)); @@ -2139,6 +2327,33 @@ grub_btrfs_label (grub_device_t device, char **label) } #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, @@ -2146,25 +2361,62 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), grub_embed_type_t embed_type, grub_disk_addr_t **sectors) { - unsigned i; + 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"); - if (64 * 2 - 1 < *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 = 64 * 2 - 1; - if (*nsectors > max_nsectors) - *nsectors = max_nsectors; - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); - if (!*sectors) + map = grub_calloc (btrfs_head.available.secs, sizeof (*map)); + if (map == NULL) return grub_errno; - for (i = 0; i < *nsectors; i++) - (*sectors)[i] = i + 1; + + /* + * 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; } @@ -2187,6 +2439,7 @@ static struct grub_fs grub_btrfs_fs = { GRUB_MOD_INIT (btrfs) { + grub_btrfs_fs.mod = mod; grub_fs_register (&grub_btrfs_fs); } diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c index 857bea991..b62c8777c 100644 --- a/grub-core/fs/cbfs.c +++ b/grub-core/fs/cbfs.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -148,16 +149,16 @@ grub_cbfs_mount (grub_disk_t disk) grub_off_t header_off; struct cbfs_header head; - if (grub_disk_get_size (disk) == GRUB_DISK_SIZE_UNKNOWN) + if (grub_disk_native_sectors (disk) == GRUB_DISK_SIZE_UNKNOWN) goto fail; - if (grub_disk_read (disk, grub_disk_get_size (disk) - 1, + 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_get_size (disk) << GRUB_DISK_SECTOR_BITS) + header_off = (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS) + (grub_int32_t) ptr; if (grub_disk_read (disk, 0, header_off, @@ -171,16 +172,16 @@ grub_cbfs_mount (grub_disk_t disk) if (!data) goto fail; - data->cbfs_start = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS) + 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_get_size (disk) << GRUB_DISK_SECTOR_BITS) + 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_get_size (disk) << GRUB_DISK_SECTOR_BITS)) + if (data->cbfs_start >= (grub_disk_native_sectors (disk) << GRUB_DISK_SECTOR_BITS)) goto fail; - if (data->cbfs_end > (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS)) - data->cbfs_end = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS); + 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; @@ -342,7 +343,7 @@ init_cbfsdisk (void) grub_uint32_t ptr; struct cbfs_header *head; - ptr = *(grub_uint32_t *) 0xfffffffc; + ptr = *((grub_uint32_t *) grub_absolute_pointer (0xfffffffc)); head = (struct cbfs_header *) (grub_addr_t) ptr; grub_dprintf ("cbfs", "head=%p\n", head); @@ -390,12 +391,17 @@ GRUB_MOD_INIT (cbfs) #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) init_cbfsdisk (); #endif - grub_fs_register (&grub_cbfs_fs); + if (!grub_is_lockdown ()) + { + grub_cbfs_fs.mod = mod; + grub_fs_register (&grub_cbfs_fs); + } } GRUB_MOD_FINI (cbfs) { - grub_fs_unregister (&grub_cbfs_fs); + 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 index dab5f9898..1799f7ff5 100644 --- a/grub-core/fs/cpio.c +++ b/grub-core/fs/cpio.c @@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size) GRUB_MOD_INIT (cpio) { + grub_cpio_fs.mod = mod; grub_fs_register (&grub_cpio_fs); } diff --git a/grub-core/fs/cpio_be.c b/grub-core/fs/cpio_be.c index 846548892..7bed1b848 100644 --- a/grub-core/fs/cpio_be.c +++ b/grub-core/fs/cpio_be.c @@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size) GRUB_MOD_INIT (cpio_be) { + grub_cpio_fs.mod = mod; grub_fs_register (&grub_cpio_fs); } diff --git a/grub-core/fs/cpio_common.c b/grub-core/fs/cpio_common.c index 4e885d623..45ac119a8 100644 --- a/grub-core/fs/cpio_common.c +++ b/grub-core/fs/cpio_common.c @@ -24,6 +24,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -48,6 +49,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, struct head hd; grub_size_t namesize; grub_uint32_t modeval; + grub_size_t sz; data->hofs = data->next_hofs; @@ -60,11 +62,21 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, #endif ) return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); - data->size = read_number (hd.filesize, ARRAY_SIZE (hd.filesize)); + + 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) - *mtime = read_number (hd.mtime, ARRAY_SIZE (hd.mtime)); - modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode)); - namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize)); + { + 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) @@ -76,7 +88,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, *mode = modeval; - *name = grub_malloc (namesize + 1); + 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; @@ -110,14 +125,21 @@ 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 (""); - ret = grub_malloc (data->size + 1); + + 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, + err = grub_disk_read (data->disk, 0, data->dofs, data->size, ret); if (err) { diff --git a/grub-core/fs/erofs.c b/grub-core/fs/erofs.c new file mode 100644 index 000000000..82a05051d --- /dev/null +++ b/grub-core/fs/erofs.c @@ -0,0 +1,1006 @@ +/* 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/ext2.c b/grub-core/fs/ext2.c index 9b389802a..2f262dc34 100644 --- a/grub-core/fs/ext2.c +++ b/grub-core/fs/ext2.c @@ -46,6 +46,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -102,6 +103,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); #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) @@ -122,10 +125,22 @@ GRUB_MOD_LICENSE ("GPLv3+"); * 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_MMP \ + | EXT4_FEATURE_INCOMPAT_CSUM_SEED \ + | EXT4_FEATURE_INCOMPAT_LARGEDIR) #define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U @@ -406,13 +421,15 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, grub_uint64_t group, sizeof (struct grub_ext2_block_group), blkgrp); } -static struct grub_ext4_extent_header * +static grub_err_t grub_ext4_find_leaf (struct grub_ext2_data *data, struct grub_ext4_extent_header *ext_block, - grub_uint32_t fileblock) + grub_uint32_t fileblock, + struct grub_ext4_extent_header **leaf) { struct grub_ext4_extent_idx *index; void *buf = NULL; + *leaf = NULL; while (1) { @@ -425,7 +442,10 @@ grub_ext4_find_leaf (struct grub_ext2_data *data, goto fail; if (ext_block->depth == 0) - return ext_block; + { + *leaf = ext_block; + return GRUB_ERR_NONE; + } for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++) { @@ -434,7 +454,10 @@ grub_ext4_find_leaf (struct grub_ext2_data *data, } if (--i < 0) - goto fail; + { + grub_free (buf); + return GRUB_ERR_NONE; + } block = grub_le_to_cpu16 (index[i].leaf_hi); block = (block << 32) | grub_le_to_cpu32 (index[i].leaf); @@ -451,7 +474,7 @@ grub_ext4_find_leaf (struct grub_ext2_data *data, } fail: grub_free (buf); - return 0; + return GRUB_ERR_BAD_FS; } static grub_disk_addr_t @@ -472,16 +495,41 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) 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. */ - leaf = grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, fileblock); - if (! leaf) + if (grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, + fileblock, &leaf) != GRUB_ERR_NONE) { 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); - for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++) + + 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++) { if (fileblock < grub_le_to_cpu32 (ext[i].block)) break; @@ -703,6 +751,7 @@ 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) { @@ -717,14 +766,21 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) } } - symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); + 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); if (! symlink) return 0; - /* If the filesize of the symlink is bigger than - 60 the symlink is stored in a separate block, - otherwise it is stored in the inode. */ - if (grub_le_to_cpu32 (diro->inode.size) <= sizeof (diro->inode.symlink)) + /* + * 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)); @@ -1046,7 +1102,7 @@ grub_ext2_uuid (grub_device_t device, char **uuid) /* Get mtime. */ static grub_err_t -grub_ext2_mtime (grub_device_t device, grub_int32_t *tm) +grub_ext2_mtime (grub_device_t device, grub_int64_t *tm) { struct grub_ext2_data *data; grub_disk_t disk = device->disk; @@ -1088,6 +1144,7 @@ static struct grub_fs grub_ext2_fs = GRUB_MOD_INIT(ext2) { + grub_ext2_fs.mod = mod; grub_fs_register (&grub_ext2_fs); my_mod = mod; } diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c index 8a9992ca9..72b4aa1e6 100644 --- a/grub-core/fs/f2fs.c +++ b/grub-core/fs/f2fs.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -122,6 +123,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define F2FS_INLINE_DOTS 0x10 /* File having implicit dot dentries. */ #define MAX_VOLUME_NAME 512 +#define MAX_NAT_BITMAP_SIZE 3900 enum FILE_TYPE { @@ -183,7 +185,7 @@ struct grub_f2fs_checkpoint 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[3900]; + grub_uint8_t sit_nat_version_bitmap[MAX_NAT_BITMAP_SIZE]; grub_uint32_t checksum; } GRUB_PACKED; @@ -302,6 +304,7 @@ struct grub_f2fs_data 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; @@ -377,15 +380,20 @@ sum_blk_addr (struct grub_f2fs_data *data, int base, int type) } static void * -nat_bitmap_ptr (struct grub_f2fs_data *data) +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; } @@ -438,11 +446,15 @@ grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32_t len) } static int -grub_f2fs_test_bit (grub_uint32_t nr, const char *p) +grub_f2fs_test_bit (grub_uint32_t nr, const char *p, grub_uint32_t len) { int mask; + grub_uint32_t shifted_nr = (nr >> 3); - p += (nr >> 3); + if (shifted_nr >= len) + return -1; + + p += shifted_nr; mask = 1 << (7 - (nr & 0x07)); return mask & *p; @@ -632,23 +644,27 @@ get_nat_journal (struct grub_f2fs_data *data) return err; } -static grub_uint32_t -get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid) +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_uint32_t blkaddr = 0; 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); + *blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr); break; } } - return blkaddr; + return GRUB_ERR_NONE; } static grub_uint32_t @@ -656,10 +672,14 @@ 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; + 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; - blkaddr = get_blkaddr_from_nat_journal (data, nid); if (blkaddr) return blkaddr; @@ -675,8 +695,15 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid) ((seg_off * data->blocks_per_seg) << 1) + (block_off & (data->blocks_per_seg - 1)); - if (grub_f2fs_test_bit (block_off, data->nat_bitmap)) + 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) @@ -826,7 +853,9 @@ grub_f2fs_mount (grub_disk_t disk) if (err) goto fail; - data->nat_bitmap = nat_bitmap_ptr (data); + 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) @@ -844,6 +873,9 @@ grub_f2fs_mount (grub_disk_t disk) return data; fail: + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, "not a F2FS filesystem"); + grub_free (data); return NULL; @@ -927,6 +959,7 @@ 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) { @@ -937,7 +970,12 @@ grub_f2fs_read_symlink (grub_fshelp_node_t node) filesize = grub_f2fs_file_size(&diro->inode.i); - symlink = grub_malloc (filesize + 1); + 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; @@ -966,6 +1004,7 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx) enum FILE_TYPE ftype; int name_len; int ret; + int sz; if (grub_f2fs_test_bit_le (i, ctx->bitmap) == 0) { @@ -975,7 +1014,16 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx) ftype = ctx->dentry[i].file_type; name_len = grub_le_to_cpu16 (ctx->dentry[i].name_len); - filename = grub_malloc (name_len + 1); + + 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; @@ -1318,6 +1366,7 @@ static struct grub_fs grub_f2fs_fs = { GRUB_MOD_INIT (f2fs) { + grub_f2fs_fs.mod = mod; grub_fs_register (&grub_f2fs_fs); my_mod = mod; } diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index d544e0af1..6e62b915d 100644 --- a/grub-core/fs/fat.c +++ b/grub-core/fs/fat.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifndef MODE_EXFAT #include #else @@ -245,7 +246,7 @@ grub_fat_mount (grub_disk_t disk) #ifdef MODE_EXFAT if (grub_memcmp ((const char *) bpb.oem_name, "EXFAT ", sizeof (bpb.oem_name)) != 0) - goto fail; + goto fail; #endif /* Get the sizes of logical sectors and clusters. */ @@ -320,7 +321,7 @@ grub_fat_mount (grub_disk_t disk) #endif #ifdef MODE_EXFAT - data->cluster_sector = (grub_le_to_cpu32 (bpb.cluster_offset) + 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); @@ -596,6 +597,7 @@ 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 @@ -642,27 +644,27 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node, grub_memset (&ctxt->dir, 0, sizeof (ctxt->dir)); while (1) { - struct grub_fat_dir_entry dir; + struct grub_fat_dir_entry *dir = &ctxt->entry; - ctxt->offset += sizeof (dir); + ctxt->offset += sizeof (*dir); - if (grub_fat_read_data (node->disk, node, 0, 0, ctxt->offset, sizeof (dir), - (char *) &dir) - != 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) + if (dir->entry_type == 0) break; - if (!(dir.entry_type & 0x80)) + if (!(dir->entry_type & 0x80)) continue; - if (dir.entry_type == 0x85) + if (dir->entry_type == 0x85) { unsigned i, nsec, slots = 0; - nsec = dir.type_specific.file.secondary_count; + nsec = dir->type_specific.file.secondary_count; - ctxt->dir.attr = grub_cpu_to_le16 (dir.type_specific.file.attr); + ctxt->dir.attr = grub_cpu_to_le16 (dir->type_specific.file.attr); ctxt->dir.have_stream = 0; for (i = 0; i < nsec; i++) { @@ -692,7 +694,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node, { int j; for (j = 0; j < 15; j++) - ctxt->unibuf[slots * 15 + j] + ctxt->unibuf[slots * 15 + j] = grub_le_to_cpu16 (sec.type_specific.file_name.str[j]); slots++; } @@ -705,7 +707,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node, if (i != nsec) { - ctxt->offset -= sizeof (dir); + ctxt->offset -= sizeof (*dir); continue; } @@ -715,20 +717,47 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node, return 0; } /* Allocation bitmap. */ - if (dir.entry_type == 0x81) + if (dir->entry_type == 0x81) continue; /* Upcase table. */ - if (dir.entry_type == 0x82) + if (dir->entry_type == 0x82) continue; /* Volume label. */ - if (dir.entry_type == 0x83) + if (dir->entry_type == 0x83) continue; grub_dprintf ("exfat", "unknown primary type 0x%02x\n", - dir.entry_type); + 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 @@ -856,6 +885,29 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node, 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, @@ -965,9 +1017,15 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, #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)) @@ -1254,6 +1312,7 @@ 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; } diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c index 4c902adf3..cb41934b4 100644 --- a/grub-core/fs/fshelp.c +++ b/grub-core/fs/fshelp.c @@ -215,7 +215,7 @@ find_file (char *currpath, break; push_node (ctx, foundnode, foundtype); - + /* Read in the symlink and follow it. */ if (ctx->currnode->type == GRUB_FSHELP_SYMLINK) { @@ -326,7 +326,7 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, enum grub_fshelp_filetype expecttype) { return grub_fshelp_find_file_real (path, rootnode, foundnode, - iterate_dir, NULL, + iterate_dir, NULL, read_symlink, expecttype); } @@ -339,7 +339,7 @@ grub_fshelp_find_file_lookup (const char *path, grub_fshelp_node_t rootnode, enum grub_fshelp_filetype expecttype) { return grub_fshelp_find_file_real (path, rootnode, foundnode, - NULL, lookup_file, + NULL, lookup_file, read_symlink, expecttype); } @@ -362,6 +362,18 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, 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, diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index ac0a40990..ce7581dd5 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -30,6 +30,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -378,7 +379,7 @@ grub_hfs_mount (grub_disk_t disk) volume name. */ key.parent_dir = grub_cpu_to_be32_compile_time (1); key.strlen = data->sblock.volname[0]; - grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1)); + grub_strlcpy ((char *) key.str, (char *) (data->sblock.volname + 1), sizeof (key.str)); if (grub_hfs_find_node (data, (char *) &key, data->cat_root, 0, (char *) &dir, sizeof (dir)) == 0) @@ -882,7 +883,7 @@ grub_hfs_iterate_dir_it_dir (struct grub_hfs_node *hnd __attribute ((unused)), { 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; @@ -1076,7 +1077,7 @@ macroman_to_utf8 (char *to, const grub_uint8_t *from, grub_size_t len, { *optr++ = ':'; continue; - } + } if (!(*iptr & 0x80)) { *optr++ = *iptr; @@ -1093,7 +1094,7 @@ 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; @@ -1103,7 +1104,7 @@ utf8_to_macroman (grub_uint8_t *to, const char *from) *optr++ = '/'; iptr++; continue; - } + } if (!(*iptr & 0x80)) { *optr++ = *iptr++; @@ -1164,7 +1165,7 @@ lookup_file (grub_fshelp_node_t dir, *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; @@ -1265,7 +1266,7 @@ grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, .hook_data = hook_data }; grub_fshelp_node_t found = NULL; - + grub_dl_ref (my_mod); data = grub_hfs_mount (device->disk); @@ -1294,7 +1295,7 @@ grub_hfs_open (struct grub_file *file, const char *name) { struct grub_hfs_data *data; grub_fshelp_node_t found = NULL; - + grub_dl_ref (my_mod); data = grub_hfs_mount (file->device->disk); @@ -1360,7 +1361,7 @@ grub_hfs_label (grub_device_t device, char **label) grub_size_t len = data->sblock.volname[0]; if (len > sizeof (data->sblock.volname) - 1) len = sizeof (data->sblock.volname) - 1; - *label = grub_malloc (len * MAX_UTF8_PER_MAC_ROMAN + 1); + *label = grub_calloc (MAX_UTF8_PER_MAC_ROMAN + 1, len); if (*label) macroman_to_utf8 (*label, data->sblock.volname + 1, len + 1, 0); @@ -1373,7 +1374,7 @@ grub_hfs_label (grub_device_t device, char **label) } static grub_err_t -grub_hfs_mtime (grub_device_t device, grub_int32_t *tm) +grub_hfs_mtime (grub_device_t device, grub_int64_t *tm) { struct grub_hfs_data *data; @@ -1433,11 +1434,14 @@ static struct grub_fs grub_hfs_fs = GRUB_MOD_INIT(hfs) { - grub_fs_register (&grub_hfs_fs); + grub_hfs_fs.mod = mod; + if (!grub_is_lockdown ()) + grub_fs_register (&grub_hfs_fs); my_mod = mod; } GRUB_MOD_FINI(hfs) { - grub_fs_unregister (&grub_hfs_fs); + if (!grub_is_lockdown()) + grub_fs_unregister (&grub_hfs_fs); } diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 54786bb1c..3f203abcc 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -19,7 +19,7 @@ /* HFS+ is documented at http://developer.apple.com/technotes/tn/tn1150.html */ -#define grub_fshelp_node grub_hfsplus_file +#define grub_fshelp_node grub_hfsplus_file #include #include #include @@ -31,6 +31,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -83,6 +84,12 @@ 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 { @@ -145,7 +152,7 @@ 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 + struct grub_hfsplus_extent *extents = node->compressed ? &node->resource_extents[0] : &node->extents[0]; while (1) @@ -176,6 +183,17 @@ 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; @@ -187,7 +205,8 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) || !nnode) { grub_error (GRUB_ERR_READ_ERROR, - "no block found for the file id 0x%x and the block offset 0x%x", + "no block found for the file id 0x%x and the block" + " offset 0x%" PRIuGRUB_UINT64_T, node->fileid, fileblock); break; } @@ -240,6 +259,7 @@ 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), @@ -337,7 +357,10 @@ grub_hfsplus_mount (grub_disk_t disk) (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE)); if (data->catalog_tree.nodesize < 2) - goto fail; + { + grub_error (GRUB_ERR_BAD_FS, "invalid catalog node size"); + goto fail; + } if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, sizeof (struct grub_hfsplus_btnode), @@ -354,7 +377,12 @@ grub_hfsplus_mount (grub_disk_t disk) data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize); if (data->extoverflow_tree.nodesize < 2) - goto fail; + { + 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), @@ -377,7 +405,7 @@ grub_hfsplus_mount (grub_disk_t disk) fail: - if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); grub_free (data); @@ -461,7 +489,7 @@ grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya, if (extkey_a->type < extkey_b->type) return -1; - + akey = grub_be_to_cpu32 (extkey_a->start); if (akey > extkey_b->start) return 1; @@ -475,8 +503,12 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node) { char *symlink; grub_ssize_t numread; + grub_size_t sz = node->size; - symlink = grub_malloc (node->size + 1); + if (grub_add (sz, 1, &sz)) + return NULL; + + symlink = grub_malloc (sz); if (!symlink) return 0; @@ -548,7 +580,7 @@ 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, + struct grub_hfsplus_btnode **matchnode, grub_off_t *keyoffset) { grub_uint64_t currnode; @@ -564,6 +596,10 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, 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"); + node = grub_malloc (btree->nodesize); if (! node) return grub_errno; @@ -630,6 +666,13 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, 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)); match = 1; } @@ -668,6 +711,13 @@ list_nodes (void *record, void *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) @@ -715,12 +765,12 @@ list_nodes (void *record, void *hook_arg) if (type == GRUB_FSHELP_UNKNOWN) return 0; - filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) - * GRUB_MAX_UTF8_PER_UTF16 + 1); + filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen), + GRUB_MAX_UTF8_PER_UTF16 + 1); if (! filename) return 0; - keyname = grub_malloc (grub_be_to_cpu16 (catkey->namelen) * sizeof (*keyname)); + keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname)); if (!keyname) { grub_free (filename); @@ -1007,7 +1057,16 @@ grub_hfsplus_label (grub_device_t device, char **label) grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr); label_len = grub_be_to_cpu16 (catkey->namelen); - label_name = grub_malloc (label_len * sizeof (*label_name)); + + /* 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); @@ -1029,7 +1088,7 @@ grub_hfsplus_label (grub_device_t device, char **label) } } - *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1); + *label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1); if (! *label) { grub_free (label_name); @@ -1050,7 +1109,7 @@ grub_hfsplus_label (grub_device_t device, char **label) /* Get mtime. */ static grub_err_t -grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm) +grub_hfsplus_mtime (grub_device_t device, grub_int64_t *tm) { struct grub_hfsplus_data *data; grub_disk_t disk = device->disk; @@ -1117,6 +1176,7 @@ static struct grub_fs grub_hfsplus_fs = GRUB_MOD_INIT(hfsplus) { + grub_hfsplus_fs.mod = mod; grub_fs_register (&grub_hfsplus_fs); my_mod = mod; } diff --git a/grub-core/fs/hfspluscomp.c b/grub-core/fs/hfspluscomp.c index d76f3f137..a80954ee6 100644 --- a/grub-core/fs/hfspluscomp.c +++ b/grub-core/fs/hfspluscomp.c @@ -123,7 +123,7 @@ hfsplus_read_compressed_real (struct grub_hfsplus_file *node, { grub_memcpy (buf, node->cbuf + pos, len); if (grub_file_progress_hook && node->file) - grub_file_progress_hook (0, 0, len, node->file); + grub_file_progress_hook (0, 0, len, NULL, node->file); return len; } @@ -170,7 +170,7 @@ hfsplus_read_compressed_real (struct grub_hfsplus_file *node, 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, node->file); + grub_file_progress_hook (0, 0, curlen, NULL, node->file); buf += curlen; pos += curlen; len -= curlen; @@ -179,7 +179,7 @@ hfsplus_read_compressed_real (struct grub_hfsplus_file *node, return len0; } -static grub_err_t +static grub_err_t hfsplus_open_compressed_real (struct grub_hfsplus_file *node) { grub_err_t err; @@ -244,14 +244,19 @@ hfsplus_open_compressed_real (struct grub_hfsplus_file *node) return 0; } node->compress_index_size = grub_le_to_cpu32 (index_size); - node->compress_index = grub_malloc (node->compress_index_size - * sizeof (node->compress_index[0])); + 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 @@ -306,8 +311,8 @@ hfsplus_open_compressed_real (struct grub_hfsplus_file *node) GRUB_MOD_INIT(hfspluscomp) { - grub_hfsplus_open_compressed = hfsplus_open_compressed_real; - grub_hfsplus_read_compressed = hfsplus_read_compressed_real; + grub_hfsplus_open_compressed = hfsplus_open_compressed_real; + grub_hfsplus_read_compressed = hfsplus_read_compressed_real; } GRUB_MOD_FINI(hfspluscomp) diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 49c0c632b..c73cb9ce0 100644 --- a/grub-core/fs/iso9660.c +++ b/grub-core/fs/iso9660.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -48,6 +49,9 @@ GRUB_MOD_LICENSE ("GPLv3+"); #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 { @@ -177,10 +181,10 @@ static grub_dl_t my_mod; static grub_err_t -iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) +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] @@ -197,7 +201,7 @@ iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) 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; @@ -205,7 +209,7 @@ iso9660_to_unixtime (const struct grub_iso9660_date *i, grub_int32_t *nix) } static int -iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) +iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int64_t *nix) { struct grub_datetime datetime; @@ -215,7 +219,7 @@ iso9660_to_unixtime2 (const struct grub_iso9660_date2 *i, grub_int32_t *nix) datetime.hour = i->hour; datetime.minute = i->minute; datetime.second = i->second; - + if (!grub_datetime2unixtime (&datetime, nix)) return 0; *nix -= i->offset * 60 * 15; @@ -267,10 +271,17 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, 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; @@ -278,12 +289,20 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, /* Load a part of the System Usage Area. */ err = read_node (node, off, sua_size, sua); if (err) - return err; - - for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; - entry = (struct grub_iso9660_susp_entry *) - ((char *) entry + entry->len)) { + 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; @@ -292,32 +311,62 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0) { struct grub_iso9660_susp_ce *ce; - grub_disk_addr_t ce_block; + 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; - sua_size = grub_le_to_cpu32 (ce->len); - off = grub_le_to_cpu32 (ce->off); + 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; - - grub_free (sua); - sua = grub_malloc (sua_size); - if (!sua) - return grub_errno; - - /* Load a part of the System Usage Area. */ - err = grub_disk_read (node->data->disk, ce_block, off, - sua_size, sua); - if (err) - return err; - - entry = (struct grub_iso9660_susp_entry *) sua; } - - if (hook (entry, hook_arg)) + 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); @@ -331,7 +380,7 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len) int i; grub_uint16_t t[MAX_NAMELEN / 2 + 1]; - p = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); + p = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); if (! p) return NULL; @@ -384,6 +433,9 @@ set_rockridge (struct grub_iso9660_data *data) 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; @@ -410,8 +462,17 @@ set_rockridge (struct grub_iso9660_data *data) rootnode.have_symlink = 0; rootnode.dirents[0] = data->voldesc.rootdir; - /* The 2nd data byte stored how many bytes are skipped every time - to get to the SUA (System Usage Area). */ + /* 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); @@ -490,6 +551,9 @@ grub_iso9660_mount (grub_disk_t disk) return data; fail: + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); + grub_free (data); return 0; } @@ -498,7 +562,7 @@ grub_iso9660_mount (grub_disk_t disk) static char * grub_iso9660_read_symlink (grub_fshelp_node_t node) { - return node->have_symlink + return node->have_symlink ? grub_strdup (node->symlink + (node->have_dirents) * sizeof (node->dirents[0]) - sizeof (node->dirents)) : grub_strdup (""); @@ -531,13 +595,24 @@ add_part (struct iterate_dir_ctx *ctx, int len2) { int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; + grub_size_t sz; + char *new; - ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); - if (! ctx->symlink) + 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; + ctx->symlink[size + len2] = 0; } static grub_err_t @@ -553,24 +628,41 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, filename type is stored. */ /* FIXME: Fix this slightly improper cast. */ if (entry->data[0] & GRUB_ISO9660_RR_DOT) - ctx->filename = (char *) "."; + { + if (ctx->filename_alloc) + grub_free (ctx->filename); + ctx->filename_alloc = 0; + ctx->filename = (char *) "."; + } else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) - ctx->filename = (char *) ".."; + { + 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); - ctx->filename = grub_realloc (ctx->filename, csize + off + 1); + 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; - ctx->filename = grub_zalloc (csize + 1); + if (grub_add (csize, 1, &sz)) + return GRUB_ERR_OUT_OF_RANGE; + ctx->filename = grub_zalloc (sz); } if (!ctx->filename) { @@ -608,10 +700,23 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, 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 + sizeof (*entry) < entry->len) + /* 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) { @@ -621,7 +726,12 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, is the length. Both are part of the `Component Record'. */ if (ctx->symlink && !ctx->was_continue) - add_part (ctx, "/", 1); + { + 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); @@ -640,6 +750,11 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, 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; @@ -766,6 +881,16 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, 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) @@ -773,17 +898,33 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, 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; - node->alloc_dirents *= 2; - new_node = grub_realloc (node, - sizeof (struct grub_fshelp_node) - + ((node->alloc_dirents - - ARRAY_SIZE (node->dirents)) - * sizeof (node->dirents[0]))); + 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); @@ -799,14 +940,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) { struct grub_fshelp_node *new_node; - new_node = grub_realloc (node, - sizeof (struct grub_fshelp_node) - + ((node->alloc_dirents - - ARRAY_SIZE (node->dirents)) - * sizeof (node->dirents[0])) - + grub_strlen (ctx.symlink) + 1); + 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); @@ -1069,8 +1214,8 @@ grub_iso9660_uuid (grub_device_t device, char **uuid) } /* Get writing time of filesystem. */ -static grub_err_t -grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf) +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; @@ -1115,6 +1260,7 @@ static struct grub_fs grub_iso9660_fs = GRUB_MOD_INIT(iso9660) { + grub_iso9660_fs.mod = mod; grub_fs_register (&grub_iso9660_fs); my_mod = mod; } diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index d5a6d6527..03be9ef4c 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -41,6 +42,13 @@ 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". */ @@ -203,9 +211,9 @@ struct grub_jfs_inode grub_uint8_t freecnt; grub_uint8_t freelist; grub_uint32_t idotdot; - grub_uint8_t sorted[8]; + grub_uint8_t sorted[GRUB_JFS_INODE_INLINE_ENTRIES]; } header; - struct grub_jfs_leaf_dirent dirents[8]; + struct grub_jfs_leaf_dirent dirents[GRUB_JFS_INODE_INLINE_ENTRIES]; } GRUB_PACKED dir; /* Fast symlink. */ struct @@ -258,35 +266,56 @@ static grub_dl_t my_mod; static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino); -static grub_int64_t +/* + * 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; - for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++) + 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 (grub_le_to_cpu32 (extents[i].offset2) <= blk + if (ext_offset <= blk && ((grub_le_to_cpu16 (extents[i].extent.length)) + (extents[i].extent.length2 << 16) - + 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)); + + ext_offset) > blk) + return (blk - ext_offset + ext_blk); } else - if (blk >= grub_le_to_cpu32 (extents[i].offset2)) + if (blk >= ext_offset) found = i; } if (found != -1) { - grub_int64_t ret = -1; + grub_uint64_t ret = 0; struct { struct grub_jfs_treehead treehead; @@ -295,28 +324,37 @@ getblk (struct grub_jfs_treehead *treehead, tree = grub_zalloc (sizeof (*tree)); if (!tree) - return -1; + return 0; if (!grub_disk_read (data->disk, - ((grub_disk_addr_t) 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)) - ret = getblk (&tree->treehead, &tree->extents[0], data, blk); + (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; } - return -1; + grub_error (GRUB_ERR_READ_ERROR, "jfs: block %" PRIuGRUB_UINT64_T " not found", blk); + return 0; } /* Get the block number for the block BLK in the node INODE in the mounted filesystem DATA. */ -static grub_int64_t +static grub_uint64_t grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, grub_uint64_t blk) { - return getblk (&inode->file.tree, &inode->file.extents[0], data, blk); + return getblk (&inode->file.tree, &inode->file.extents[0], 16, data, blk); } @@ -343,7 +381,7 @@ grub_jfs_read_inode (struct grub_jfs_data *data, grub_uint32_t ino, sizeof (iag_inodes), &iag_inodes)) return grub_errno; - inoblk = grub_le_to_cpu32 (iag_inodes[inoext].blk2); + inoblk = get_ext_offset (iag_inodes[inoext].blk1, iag_inodes[inoext].blk2); inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS); inoblk += inonum; @@ -442,6 +480,13 @@ 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; @@ -457,7 +502,16 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode) return 0; } - blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2); + 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_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS); /* Read in the nodes until we are on the leaf node level. */ @@ -475,7 +529,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 = (grub_le_to_cpu32 (de[index].ex.blk2) + blk = (get_ext_offset (de[index].ex.blk1, 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)); @@ -567,7 +621,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) /* Move down to the leaf level. */ nextent = leaf->next; - if (leaf->next != 255) + if (leaf->next != 255 && len > 0) do { next_leaf = &diro->next_leaf[nextent]; @@ -705,7 +759,6 @@ grub_jfs_find_file (struct grub_jfs_data *data, const char *path, grub_uint32_t dirino = grub_le_to_cpu32 (data->currinode.inode); grub_jfs_closedir (diro); - diro = 0; if (grub_jfs_read_inode (data, ino, &data->currinode)) break; @@ -952,11 +1005,16 @@ static struct grub_fs grub_jfs_fs = GRUB_MOD_INIT(jfs) { - grub_fs_register (&grub_jfs_fs); + if (!grub_is_lockdown ()) + { + grub_jfs_fs.mod = mod; + grub_fs_register (&grub_jfs_fs); + } my_mod = mod; } GRUB_MOD_FINI(jfs) { - grub_fs_unregister (&grub_jfs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_jfs_fs); } diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index d0d08363c..4440fcca8 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -38,6 +39,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); #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 @@ -96,10 +99,10 @@ struct grub_minix_sblock 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; + grub_uint8_t disk_version; }; #else struct grub_minix_sblock @@ -349,7 +352,7 @@ grub_minix_read_inode (struct grub_minix_data *data, grub_minix_ino_t ino) 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); @@ -372,7 +375,7 @@ grub_minix_lookup_symlink (struct grub_minix_data *data, grub_minix_ino_t ino) if (!symlink) return grub_errno; if (grub_minix_read_file (data, 0, 0, 0, sz, symlink) < 0) - return grub_errno; + goto fail; symlink[sz] = '\0'; @@ -382,10 +385,12 @@ grub_minix_lookup_symlink (struct grub_minix_data *data, grub_minix_ino_t ino) /* Now load in the old inode. */ if (grub_minix_read_inode (data, ino)) - return grub_errno; + goto fail; grub_minix_find_file (data, symlink); + fail: + grub_free(symlink); return grub_errno; } @@ -466,7 +471,21 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path) static struct grub_minix_data * grub_minix_mount (grub_disk_t disk) { - struct grub_minix_data *data; + 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) @@ -716,7 +735,11 @@ GRUB_MOD_INIT(minix) #endif #endif { - grub_fs_register (&grub_minix_fs); + if (!grub_is_lockdown ()) + { + grub_minix_fs.mod = mod; + grub_fs_register (&grub_minix_fs); + } my_mod = mod; } @@ -738,5 +761,6 @@ GRUB_MOD_FINI(minix) #endif #endif { - grub_fs_unregister (&grub_minix_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_minix_fs); } diff --git a/grub-core/fs/newc.c b/grub-core/fs/newc.c index 4fb8b2e3d..43b7f8b64 100644 --- a/grub-core/fs/newc.c +++ b/grub-core/fs/newc.c @@ -64,6 +64,7 @@ read_number (const char *str, grub_size_t size) GRUB_MOD_INIT (newc) { + grub_cpio_fs.mod = mod; grub_fs_register (&grub_cpio_fs); } diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c index 7ed148d3b..26e6077ff 100644 --- a/grub-core/fs/nilfs2.c +++ b/grub-core/fs/nilfs2.c @@ -1,5 +1,5 @@ -/* - * nilfs2.c - New Implementation of Log filesystem +/* + * nilfs2.c - New Implementation of Log filesystem * * Written by Jiro SEKIBA * @@ -34,6 +34,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -416,15 +417,35 @@ grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node, } static inline int -grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, +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, low, high, s; + int index = 0, low, high, s; low = 0; + high = grub_le_to_cpu16 (node->bn_nchildren) - 1; - index = 0; + 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) { @@ -459,18 +480,6 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, return s == 0; } -static inline int -grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, - struct grub_nilfs2_btree_node *node) -{ - int node_children_max = ((NILFS2_BLOCK_SIZE (data) - - sizeof (struct grub_nilfs2_btree_node) - - NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / - (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); - - return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; -} - static inline grub_uint64_t * grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data, struct grub_nilfs2_btree_node *node) @@ -517,7 +526,11 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, node = grub_nilfs2_btree_get_root (inode); level = grub_nilfs2_btree_get_level (node); - found = grub_nilfs2_btree_node_lookup (node, key, &index); + 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); @@ -538,11 +551,12 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, } if (!found) - found = grub_nilfs2_btree_node_lookup (node, key, &index); + found = grub_nilfs2_btree_node_lookup (data, node, key, &index); else index = 0; - if (index < grub_nilfs2_btree_node_nchildren_max (data, node)) + 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) @@ -569,6 +583,11 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, 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]); } @@ -584,7 +603,7 @@ grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data, { grub_uint64_t ptr; ptr = grub_nilfs2_direct_lookup (inode, key); - if (need_translate) + if (ptr != ((grub_uint64_t) 0xffffffffffffffff) && need_translate) ptr = grub_nilfs2_dat_translate (data, ptr); return ptr; } @@ -662,12 +681,12 @@ grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data, grub_disk_t disk = data->disk; unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); - /* Assume sizeof(struct grub_nilfs2_cpfile_header) < + /* 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) { @@ -753,7 +772,7 @@ grub_nilfs2_load_sb (struct grub_nilfs2_data *data) partition_size = (grub_le_to_cpu64 (data->sblock.s_dev_size) >> GRUB_DISK_SECTOR_BITS); else - partition_size = grub_disk_get_size (disk); + partition_size = grub_disk_native_sectors (disk); if (partition_size != GRUB_DISK_SIZE_UNKNOWN) { /* Read second super block. */ @@ -1168,7 +1187,7 @@ grub_nilfs2_uuid (grub_device_t device, char **uuid) /* Get mtime. */ static grub_err_t -grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm) +grub_nilfs2_mtime (grub_device_t device, grub_int64_t * tm) { struct grub_nilfs2_data *data; grub_disk_t disk = device->disk; @@ -1213,11 +1232,16 @@ GRUB_MOD_INIT (nilfs2) grub_nilfs2_dat_entry)); COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE == sizeof (struct grub_nilfs2_inode)); - grub_fs_register (&grub_nilfs2_fs); + if (!grub_is_lockdown ()) + { + grub_nilfs2_fs.mod = mod; + grub_fs_register (&grub_nilfs2_fs); + } my_mod = mod; } GRUB_MOD_FINI (nilfs2) { - grub_fs_unregister (&grub_nilfs2_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_nilfs2_fs); } diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index fc4e1f678..b3117bf92 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -#define grub_fshelp_node grub_ntfs_file +#define grub_fshelp_node grub_ntfs_file #include #include @@ -27,12 +27,13 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; -#define grub_fshelp_node grub_ntfs_file +#define grub_fshelp_node grub_ntfs_file static inline grub_uint16_t u16at (void *ptr, grub_size_t ofs) @@ -52,6 +53,188 @@ 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 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. + */ + min_size += (attr[curr] & 0x7) + ((attr[curr] >> 4) & 0x7); + curr += min_size; + min_size++; + 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) +{ + 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_attribute (next, end) == false) + return NULL; + + return next; +} + + grub_ntfscomp_func_t grub_ntfscomp_func; static grub_err_t @@ -101,13 +284,20 @@ static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_disk_read_hook_t read_hook, void *read_hook_data); -static void +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 + u16at (mft->buf, 0x14); + 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 @@ -121,16 +311,18 @@ free_attr (struct grub_ntfs_attr *at) static grub_uint8_t * find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) { + grub_uint8_t *mft_end; + if (at->flags & GRUB_NTFS_AF_ALST) { retry: - while (at->attr_nxt < at->attr_end) + while (at->attr_nxt) { at->attr_cur = at->attr_nxt; - at->attr_nxt += u16at (at->attr_cur, 4); + at->attr_nxt = next_attribute (at->attr_cur, at->attr_end); if ((*at->attr_cur == attr) || (attr == 0)) { - grub_uint8_t *new_pos; + grub_uint8_t *new_pos, *end; if (at->flags & GRUB_NTFS_AF_MMFT) { @@ -154,15 +346,36 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) return NULL; } - new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)]; - while (*new_pos != 0xFF) + /* + * 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]; + + while (new_pos && *new_pos != 0xFF) { if ((*new_pos == *at->attr_cur) && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18))) { return new_pos; } - new_pos += u16at (new_pos, 4); + new_pos = next_attribute (new_pos, end); } grub_error (GRUB_ERR_BAD_FS, "can\'t find 0x%X in attribute list", @@ -173,9 +386,10 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) return NULL; } at->attr_cur = at->attr_nxt; - while (*at->attr_cur != 0xFF) + 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 && *at->attr_cur != 0xFF) { - at->attr_nxt += u16at (at->attr_cur, 4); + at->attr_nxt = next_attribute (at->attr_cur, at->end); if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) at->attr_end = at->attr_cur; if ((*at->attr_cur == attr) || (attr == 0)) @@ -184,7 +398,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) } if (at->attr_end) { - grub_uint8_t *pa; + 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) @@ -209,20 +423,30 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) } at->attr_nxt = at->edat_buf; at->attr_end = at->edat_buf + u32at (pa, 0x30); + pa_end = at->edat_buf + n; } else { - at->attr_nxt = at->attr_end + u16at (pa, 0x14); + at->attr_nxt = at->attr_end + res_attr_data_off (pa); at->attr_end = at->attr_end + u32at (pa, 4); + pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); } at->flags |= GRUB_NTFS_AF_ALST; - while (at->attr_nxt < at->attr_end) + + /* From this point on pa_end is the end of the buffer */ + at->end = pa_end; + + if (validate_attribute (at->attr_nxt, pa_end) == false) + return NULL; + + while (at->attr_nxt) { if ((*at->attr_nxt == attr) || (attr == 0)) break; - at->attr_nxt += u16at (at->attr_nxt, 4); + at->attr_nxt = next_attribute (at->attr_nxt, pa_end); } - if (at->attr_nxt >= at->attr_end) + + if (at->attr_nxt >= at->attr_end || at->attr_nxt == NULL) return NULL; if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA)) @@ -230,22 +454,40 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) 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); - while (pa < at->attr_end) + + if (validate_attribute (pa, pa_end) == true) + 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); + pa = next_attribute (pa, pa_end); } at->attr_nxt = at->attr_cur; at->flags &= ~GRUB_NTFS_AF_GPOS; @@ -261,7 +503,9 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, { grub_uint8_t *pa; - init_attr (at, mft); + if (init_attr (at, mft) != GRUB_ERR_NONE) + return NULL; + pa = find_attr (at, attr); if (pa == NULL) return NULL; @@ -277,7 +521,8 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, } grub_errno = GRUB_ERR_NONE; free_attr (at); - init_attr (at, mft); + if (init_attr (at, mft) != GRUB_ERR_NONE) + return NULL; pa = find_attr (at, attr); } return pa; @@ -329,7 +574,7 @@ retry: goto retry; } } - return grub_error (GRUB_ERR_BAD_FS, "run list overflown"); + 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 */ @@ -383,9 +628,20 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, if (pa[8] == 0) { - if (ofs + len > u32at (pa, 0x10)) + if (ofs + len > res_attr_data_len (pa)) return grub_error (GRUB_ERR_BAD_FS, "read out of range"); - grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len); + + 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; } @@ -468,14 +724,17 @@ read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, else vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR); pa = at->attr_nxt + u16at (at->attr_nxt, 4); - while (pa < at->attr_end) + 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 += u16at (pa, 4); + pa = next_attribute (pa, at->attr_end); } } pp = find_attr (at, attr); @@ -529,7 +788,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno) (unsigned long long) mftno); if (!pa[8]) - mft->size = u32at (pa, 0x10); + mft->size = res_attr_data_len (pa); else mft->size = u64at (pa, 0x30); @@ -537,7 +796,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno) mft->attr.attr_end = 0; /* Don't jump to attribute list */ } else - init_attr (&mft->attr, mft); + return init_attr (&mft->attr, mft); return 0; } @@ -556,8 +815,8 @@ get_utf8 (grub_uint8_t *in, grub_size_t len) grub_uint16_t *tmp; grub_size_t i; - buf = grub_malloc (len * GRUB_MAX_UTF8_PER_UTF16 + 1); - tmp = grub_malloc (len * sizeof (tmp[0])); + buf = grub_calloc (len, GRUB_MAX_UTF8_PER_UTF16 + 1); + tmp = grub_calloc (len, sizeof (tmp[0])); if (!buf || !tmp) { grub_free (buf); @@ -572,7 +831,7 @@ get_utf8 (grub_uint8_t *in, grub_size_t len) } static int -list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, +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; @@ -583,6 +842,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t namespace; char *ustr; + if ((pos >= end_pos) || (end_pos - pos < 0x52)) + break; + if (pos[0xC] & 2) /* end signature */ break; @@ -590,6 +852,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, ns = *(np++); namespace = *(np++); + if (2 * ns > end_pos - pos - 0x52) + break; + /* * Ignore files in DOS namespace, as they will reappear as Win32 * names. @@ -654,7 +919,7 @@ 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; + grub_uint8_t *buf16 = NULL; char *buf, *end; grub_size_t len; grub_uint8_t *pa; @@ -667,20 +932,20 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) return NULL; if (read_mft (mft->data, mft->buf, mft->ino)) - return NULL; + 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); - return NULL; + goto fail; } err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0, sizeof (struct symlink_descriptor), 1, 0, 0); if (err) - return NULL; + goto fail; switch (grub_cpu_to_le32 (symdesc.type)) { @@ -697,23 +962,22 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) default: grub_error (GRUB_ERR_BAD_FS, "symlink type invalid (%x)", grub_cpu_to_le32 (symdesc.type)); - return NULL; + goto fail; } buf16 = grub_malloc (len); if (!buf16) - return NULL; + goto fail; err = read_attr (&mft->attr, buf16, off, len, 1, 0, 0); if (err) - return NULL; + goto fail; buf = get_utf8 (buf16, len / 2); if (!buf) - { - grub_free (buf16); - return NULL; - } + goto fail; + + grub_free (mft->buf); grub_free (buf16); for (end = buf; *end; end++) @@ -725,9 +989,14 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) && grub_isalpha (buf[4])) { grub_memmove (buf, buf + 6, end - buf + 1 - 6); - end -= 6; + end -= 6; } return buf; + + fail: + grub_free (mft->buf); + grub_free (buf16); + return NULL; } static int @@ -753,7 +1022,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, bmp = NULL; at = &attr; - init_attr (at, mft); + if (init_attr (at, mft) != GRUB_ERR_NONE) + return 0; + while (1) { cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT); @@ -768,21 +1039,25 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, (u32at (cur_pos, 0x18) != 0x490024) || (u32at (cur_pos, 0x1C) != 0x300033)) continue; - cur_pos += u16at (cur_pos, 0x14); + cur_pos += res_attr_data_off (cur_pos); 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, hook_data); + 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); + while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL) { int ofs; @@ -795,7 +1070,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, { int is_resident = (cur_pos[8] == 0); - bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) : + bitmap_len = ((is_resident) ? res_attr_data_len (cur_pos) : u32at (cur_pos, 0x28)); bmp = grub_malloc (bitmap_len); @@ -804,7 +1079,26 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, if (is_resident) { - grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14), + 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 @@ -862,6 +1156,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, (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; @@ -992,7 +1287,7 @@ grub_ntfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, 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) + info.mtime = grub_divmod64 (node->mtime, 10000000, 0) - 86400ULL * 365 * (1970 - 1601) - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); grub_free (node); @@ -1127,6 +1422,7 @@ 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); @@ -1152,15 +1448,34 @@ grub_ntfs_label (grub_device_t device, char **label) goto fail; } - init_attr (&mft->attr, mft); + 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) && (pa[8] == 0) && (u32at (pa, 0x10))) + + if (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 = u32at (pa, 0x10) / 2; - pa += u16at (pa, 0x14); - *label = get_utf8 (pa, 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) + *label = get_utf8 (pa, len); + else + grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); } fail: @@ -1227,11 +1542,16 @@ static struct grub_fs grub_ntfs_fs = GRUB_MOD_INIT (ntfs) { - grub_fs_register (&grub_ntfs_fs); + if (!grub_is_lockdown ()) + { + grub_ntfs_fs.mod = mod; + grub_fs_register (&grub_ntfs_fs); + } my_mod = mod; } GRUB_MOD_FINI (ntfs) { - grub_fs_unregister (&grub_ntfs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_ntfs_fs); } diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c index 3cd97d337..b68bf5e40 100644 --- a/grub-core/fs/ntfscomp.c +++ b/grub-core/fs/ntfscomp.c @@ -22,6 +22,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -29,7 +30,7 @@ static grub_err_t decomp_nextvcn (struct grub_ntfs_comp *cc) { if (cc->comp_head >= cc->comp_tail) - return grub_error (GRUB_ERR_BAD_FS, "compression block overflown"); + return grub_error (GRUB_ERR_BAD_FS, "compression block overflow"); if (grub_disk_read (cc->disk, (cc->comp_table[cc->comp_head].next_lcn - @@ -227,7 +228,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) 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, + grub_file_progress_hook (0, 0, nn * GRUB_NTFS_COM_LEN, NULL, ctx->file); } } @@ -240,7 +241,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) if (buf) buf += GRUB_NTFS_COM_LEN; if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, GRUB_NTFS_COM_LEN, + grub_file_progress_hook (0, 0, GRUB_NTFS_COM_LEN, NULL, ctx->file); nn--; } @@ -271,7 +272,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) if (grub_file_progress_hook && ctx->file) grub_file_progress_hook (0, 0, tt << (ctx->comp.log_spc - + GRUB_NTFS_BLK_SHR), + + GRUB_NTFS_BLK_SHR), NULL, ctx->file); buf += tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); } @@ -294,7 +295,7 @@ read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) if (grub_file_progress_hook && ctx->file) grub_file_progress_hook (0, 0, nn << (ctx->comp.log_spc - + GRUB_NTFS_BLK_SHR), + + GRUB_NTFS_BLK_SHR), NULL, ctx->file); } ctx->target_vcn += nn; @@ -310,6 +311,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs, { grub_err_t ret; grub_disk_addr_t vcn; + int log_sz; if (ctx->attr->sbuf) { @@ -323,7 +325,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs, 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, ctx->file); + grub_file_progress_hook (0, 0, n, NULL, ctx->file); if (n == len) return 0; @@ -349,7 +351,12 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs, } ctx->comp.comp_head = ctx->comp.comp_tail = 0; - ctx->comp.cbuf = grub_malloc (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR)); + 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); if (!ctx->comp.cbuf) return 0; @@ -390,7 +397,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs, n = len; grub_memcpy (dest, &ctx->attr->sbuf[o], n); if (grub_file_progress_hook && ctx->file) - grub_file_progress_hook (0, 0, n, ctx->file); + grub_file_progress_hook (0, 0, n, NULL, ctx->file); if (n == len) goto quit; dest += n; @@ -422,7 +429,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs, grub_memcpy (dest, ctx->attr->sbuf, len); if (grub_file_progress_hook && file) - grub_file_progress_hook (0, 0, len, file); + grub_file_progress_hook (0, 0, len, NULL, file); } quit: diff --git a/grub-core/fs/odc.c b/grub-core/fs/odc.c index 790000622..8e4e8aeac 100644 --- a/grub-core/fs/odc.c +++ b/grub-core/fs/odc.c @@ -52,6 +52,7 @@ read_number (const char *str, grub_size_t size) GRUB_MOD_INIT (odc) { + grub_cpio_fs.mod = mod; grub_fs_register (&grub_cpio_fs); } diff --git a/grub-core/fs/proc.c b/grub-core/fs/proc.c index 5f516502d..bcde43349 100644 --- a/grub-core/fs/proc.c +++ b/grub-core/fs/proc.c @@ -192,6 +192,7 @@ static struct grub_fs grub_procfs_fs = GRUB_MOD_INIT (procfs) { + grub_procfs_fs.mod = mod; grub_disk_dev_register (&grub_procfs_dev); grub_fs_register (&grub_procfs_fs); } diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c index af6a226a7..5d3c85950 100644 --- a/grub-core/fs/reiserfs.c +++ b/grub-core/fs/reiserfs.c @@ -39,6 +39,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -785,7 +786,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, char *entry_name; char *entry_name_end = 0; char c; - + if (!(entry_state & GRUB_REISERFS_VISIBLE_MASK)) continue; @@ -1417,11 +1418,16 @@ static struct grub_fs grub_reiserfs_fs = GRUB_MOD_INIT(reiserfs) { - grub_fs_register (&grub_reiserfs_fs); + if (!grub_is_lockdown ()) + { + grub_reiserfs_fs.mod = mod; + grub_fs_register (&grub_reiserfs_fs); + } my_mod = mod; } GRUB_MOD_FINI(reiserfs) { - grub_fs_unregister (&grub_reiserfs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_reiserfs_fs); } diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index d97b8fbb8..eafab03b2 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -112,7 +113,7 @@ grub_romfs_mount (grub_device_t dev) { 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) @@ -271,7 +272,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, while (1) { char buf[16]; - err = grub_disk_read (dir->data->disk, + err = grub_disk_read (dir->data->disk, laddr >> GRUB_DISK_SECTOR_BITS, laddr & (GRUB_DISK_SECTOR_SIZE - 1), 16, buf); @@ -298,7 +299,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, node->data_addr = grub_be_to_cpu32 (node->file.spec); filetype = GRUB_FSHELP_DIR; } - + break; } } @@ -402,7 +403,7 @@ grub_romfs_read (grub_file_t file, char *buf, grub_size_t len) 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), + (data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 1), len, buf); data->data->disk->read_hook = NULL; @@ -475,10 +476,15 @@ static struct grub_fs grub_romfs_fs = GRUB_MOD_INIT(romfs) { - grub_fs_register (&grub_romfs_fs); + if (!grub_is_lockdown ()) + { + grub_romfs_fs.mod = mod; + grub_fs_register (&grub_romfs_fs); + } } GRUB_MOD_FINI(romfs) { - grub_fs_unregister (&grub_romfs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_romfs_fs); } diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index 50c1fe72f..bad4ae8d1 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -266,7 +268,7 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) node->next_extent = node->block; node->cache_size = 0; - node->cache = grub_malloc (sizeof (node->cache[0]) * cache_size); + node->cache = grub_calloc (cache_size, sizeof (node->cache[0])); if (!node->cache) { grub_errno = 0; @@ -307,10 +309,15 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) if (node->cache && node->cache_size >= node->cache_allocated) { struct cache_entry *e = node->cache; - e = grub_realloc (node->cache,node->cache_allocated * 2 - * sizeof (e[0])); + grub_size_t sz; + + 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; @@ -367,6 +374,7 @@ grub_sfs_mount (grub_disk_t disk) struct grub_sfs_objc *rootobjc; char *rootobjc_data = 0; grub_uint32_t blk; + unsigned int max_len; data = grub_malloc (sizeof (*data)); if (!data) @@ -415,7 +423,16 @@ grub_sfs_mount (grub_disk_t disk) 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; @@ -477,10 +494,16 @@ grub_sfs_create_node (struct grub_fshelp_node **node, 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 (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); + name_u8 = grub_malloc (sz); if (!name_u8) { grub_free (*node); @@ -724,8 +747,13 @@ grub_sfs_label (grub_device_t device, char **label) data = grub_sfs_mount (disk); if (data) { - grub_size_t len = grub_strlen (data->label); - *label = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); + grub_size_t sz, len = grub_strlen (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, @@ -755,11 +783,16 @@ static struct grub_fs grub_sfs_fs = GRUB_MOD_INIT(sfs) { - grub_fs_register (&grub_sfs_fs); + if (!grub_is_lockdown ()) + { + grub_sfs_fs.mod = mod; + grub_fs_register (&grub_sfs_fs); + } my_mod = mod; } GRUB_MOD_FINI(sfs) { - grub_fs_unregister (&grub_sfs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_sfs_fs); } diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 95d5c1e1f..cf2bca822 100644 --- a/grub-core/fs/squash4.c +++ b/grub-core/fs/squash4.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "xz.h" @@ -209,7 +210,7 @@ struct grub_fshelp_node struct grub_squash_data *data; struct grub_squash_inode ino; grub_size_t stsize; - struct + struct { grub_disk_addr_t ino_chunk; grub_uint16_t ino_offset; @@ -242,7 +243,7 @@ read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len, 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; @@ -255,7 +256,7 @@ read_chunk (struct grub_squash_data *data, void *buf, grub_size_t len, else { char *tmp; - grub_size_t bsize = grub_le_to_cpu16 (d) & ~SQUASH_CHUNK_FLAGS; + 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) @@ -338,7 +339,7 @@ xz_decompress (char *inbuf, grub_size_t insize, grub_off_t off, while (len) { enum xz_ret xzret; - + buf.out_pos = 0; xzret = xz_dec_run (data->xzdec, &buf); @@ -398,9 +399,9 @@ squash_mount (grub_disk_t disk) return NULL; } - err = grub_disk_read (disk, + err = grub_disk_read (disk, grub_le_to_cpu64 (sb.unk1offset) - >> GRUB_DISK_SECTOR_BITS, + >> 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) @@ -447,7 +448,7 @@ squash_mount (grub_disk_t disk) } data->blksz = grub_le_to_cpu32 (data->sb.block_size); - for (data->log2_blksz = 0; + for (data->log2_blksz = 0; (1U << data->log2_blksz) < data->blksz; data->log2_blksz++); @@ -459,7 +460,17 @@ grub_squash_read_symlink (grub_fshelp_node_t node) { char *ret; grub_err_t err; - ret = grub_malloc (grub_le_to_cpu32 (node->ino.symlink.namelen) + 1); + 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), @@ -506,11 +517,16 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, { grub_fshelp_node_t node; - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + 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, - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + grub_memcpy (node, dir, sz); if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) return 1; @@ -518,12 +534,15 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, { grub_err_t err; - node = grub_malloc (sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + 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, - sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); + grub_memcpy (node, dir, sz); node->stsize--; err = read_chunk (dir->data, &node->ino, sizeof (node->ino), @@ -531,7 +550,10 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, + node->stack[node->stsize - 1].ino_chunk, node->stack[node->stsize - 1].ino_offset); if (err) - return 0; + { + grub_free (node); + return 0; + } if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) return 1; @@ -557,6 +579,8 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, 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) @@ -572,7 +596,12 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, if (err) return 0; - buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2); + 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, @@ -580,7 +609,10 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, grub_le_to_cpu64 (dir->data->sb.diroffset) + chunk, off); if (err) - return 0; + { + grub_free (buf); + return 0; + } off += grub_le_to_cpu16 (di.namelen) + 1; buf[grub_le_to_cpu16 (di.namelen) + 1] = 0; @@ -589,13 +621,22 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, if (grub_le_to_cpu16 (di.type) == SQUASH_TYPE_SYMLINK) filetype = GRUB_FSHELP_SYMLINK; - node = grub_malloc (sizeof (*node) - + (dir->stsize + 1) * sizeof (dir->stack[0])); - if (! node) - return 0; + 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; + } - grub_memcpy (node, dir, - sizeof (*node) + dir->stsize * sizeof (dir->stack[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); @@ -620,7 +661,7 @@ make_root_node (struct grub_squash_data *data, struct grub_fshelp_node *root) 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) + grub_le_to_cpu64 (data->sb.inodeoffset) + root->stack[0].ino_chunk, root->stack[0].ino_offset); } @@ -742,11 +783,11 @@ grub_squash_open (struct grub_file *file, const char *name) } static grub_ssize_t -direct_read (struct grub_squash_data *data, +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_t err = GRUB_ERR_NONE; grub_off_t cumulated_uncompressed_size = 0; grub_uint64_t a = 0; grub_size_t i; @@ -781,10 +822,10 @@ direct_read (struct grub_squash_data *data, break; } total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz); - ino->block_sizes = grub_malloc (total_blocks - * sizeof (ino->block_sizes[0])); - ino->cumulated_block_sizes = grub_malloc (total_blocks - * sizeof (ino->cumulated_block_sizes[0])); + 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); @@ -859,7 +900,7 @@ direct_read (struct grub_squash_data *data, grub_free (block); } else - err = grub_disk_read (data->disk, + err = grub_disk_read (data->disk, (ino->cumulated_block_sizes[i] + a + boff) >> GRUB_DISK_SECTOR_BITS, (ino->cumulated_block_sizes[i] + a + boff) @@ -923,7 +964,7 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) } else off -= direct_len; - + err = read_chunk (data, &frag, sizeof (frag), data->fragments, sizeof (frag) * fragment); if (err) @@ -934,7 +975,7 @@ grub_squash_read (grub_file_t file, char *buf, grub_size_t len) 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) { @@ -980,7 +1021,7 @@ grub_squash_close (grub_file_t file) } static grub_err_t -grub_squash_mtime (grub_device_t dev, grub_int32_t *tm) +grub_squash_mtime (grub_device_t dev, grub_int64_t *tm) { struct grub_squash_data *data = 0; @@ -990,7 +1031,7 @@ grub_squash_mtime (grub_device_t dev, grub_int32_t *tm) *tm = grub_le_to_cpu32 (data->sb.creation_time); squash_unmount (data); return GRUB_ERR_NONE; -} +} static struct grub_fs grub_squash_fs = { @@ -1009,6 +1050,7 @@ static struct grub_fs grub_squash_fs = GRUB_MOD_INIT(squash4) { + grub_squash_fs.mod = mod; grub_fs_register (&grub_squash_fs); } diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c index 7d63e0c99..1eaa5349f 100644 --- a/grub-core/fs/tar.c +++ b/grub-core/fs/tar.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -76,8 +77,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, { 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++) { @@ -96,8 +99,13 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, if (hd.typeflag == 'L') { grub_err_t err; - grub_size_t namesize = read_number (hd.size, sizeof (hd.size)); - *name = grub_malloc (namesize + 1); + 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, @@ -116,16 +124,21 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, if (hd.typeflag == 'K') { grub_err_t err; - grub_size_t linksize = read_number (hd.size, sizeof (hd.size)); - if (data->linkname_alloc < linksize + 1) + 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_malloc (2 * (linksize + 1)); + n = grub_calloc (2, sz); if (!n) return grub_errno; grub_free (data->linkname); data->linkname = n; - data->linkname_alloc = 2 * (linksize + 1); + data->linkname_alloc = 2 * (sz); } err = grub_disk_read (data->disk, 0, @@ -148,7 +161,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, while (extra_size < sizeof (hd.prefix) && hd.prefix[extra_size]) extra_size++; - *name = grub_malloc (sizeof (hd.name) + extra_size + 2); + + 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]) @@ -160,15 +176,22 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, (*name)[extra_size + sizeof (hd.name)] = 0; } - data->size = read_number (hd.size, sizeof (hd.size)); + 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) - *mtime = read_number (hd.mtime, sizeof (hd.mtime)); + { + if (grub_cast (read_number (hd.mtime, sizeof (hd.mtime)), mtime)) + return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow")); + } if (mode) { - *mode = read_number (hd.mode, sizeof (hd.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. */ @@ -202,6 +225,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, } return GRUB_ERR_NONE; } + + if (*name == NULL) + return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); + return GRUB_ERR_NONE; } @@ -336,6 +363,7 @@ static struct grub_fs grub_cpio_fs = { GRUB_MOD_INIT (tar) { + grub_cpio_fs.mod = mod; grub_fs_register (&grub_cpio_fs); } diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index dc8b6e2d1..3d5ee5af5 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -113,6 +115,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); #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; @@ -457,6 +463,7 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) char *ptr; grub_ssize_t len; grub_disk_addr_t filebytes; + char *end_ptr; switch (U16 (node->block.fe.tag.tag_ident)) { @@ -475,9 +482,17 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) 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); @@ -509,6 +524,20 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) } 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; @@ -527,10 +556,22 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) 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); @@ -562,11 +603,25 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) } 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; @@ -582,6 +637,12 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) 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; + } } } @@ -601,6 +662,7 @@ grub_udf_read_file (grub_fshelp_node_t node, 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] @@ -608,6 +670,12 @@ grub_udf_read_file (grub_fshelp_node_t node, ((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; @@ -873,7 +941,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) { unsigned i; utf16len = sz - 1; - utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + utf16 = grub_calloc (utf16len, sizeof (utf16[0])); if (!utf16) return NULL; for (i = 0; i < utf16len; i++) @@ -883,16 +951,26 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) { unsigned i; utf16len = (sz - 1) / 2; - utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + 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) - outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1); + { + 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; } @@ -954,8 +1032,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, return 0; if (grub_udf_read_icb (dir->data, &dirent.icb, child)) - return 0; - + { + grub_free (child); + return 0; + } if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) { /* This is the parent directory. */ @@ -977,11 +1057,18 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, dirent.file_ident_length, (char *) raw)) != dirent.file_ident_length) - return 0; + { + grub_free (child); + return 0; + } filename = read_string (raw, dirent.file_ident_length, 0); if (!filename) - grub_print_error (); + { + /* As the hook won't get called. */ + grub_free (child); + grub_print_error (); + } if (filename && hook (filename, type, child, hook_data)) { @@ -1002,10 +1089,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, static char * grub_udf_read_symlink (grub_fshelp_node_t node) { - grub_size_t sz = U64 (node->block.fe.file_size); + grub_size_t s, sz = U64 (node->block.fe.file_size); grub_uint8_t *raw; const grub_uint8_t *ptr; - char *out, *optr; + char *out = NULL, *optr; if (sz < 4) return NULL; @@ -1013,14 +1100,24 @@ grub_udf_read_symlink (grub_fshelp_node_t node) if (!raw) return NULL; if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0) - { - grub_free (raw); - return NULL; - } + goto fail_1; - out = grub_malloc (sz * 2 + 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; } @@ -1029,19 +1126,18 @@ grub_udf_read_symlink (grub_fshelp_node_t node) for (ptr = raw; ptr < raw + sz; ) { - grub_size_t s; if ((grub_size_t) (ptr - raw + 4) > sz) - goto fail; + goto fail_1; if (!(ptr[2] == 0 && ptr[3] == 0)) - goto fail; + goto fail_1; s = 4 + ptr[1]; if ((grub_size_t) (ptr - raw + s) > sz) - goto fail; + goto fail_1; switch (*ptr) { case 1: if (ptr[1]) - goto fail; + goto fail_1; /* Fallthrough. */ case 2: /* in 4 bytes. out: 1 byte. */ @@ -1066,11 +1162,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node) if (optr != out) *optr++ = '/'; if (!read_string (ptr + 4, s - 4, optr)) - goto fail; + goto fail_1; optr += grub_strlen (optr); break; default: - goto fail; + goto fail_1; } ptr += s; } @@ -1078,7 +1174,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node) grub_free (raw); return out; - fail: + fail_1: grub_free (raw); grub_free (out); grub_error (GRUB_ERR_BAD_FS, "invalid symlink"); @@ -1360,11 +1456,16 @@ static struct grub_fs grub_udf_fs = { GRUB_MOD_INIT (udf) { - grub_fs_register (&grub_udf_fs); + if (!grub_is_lockdown ()) + { + grub_udf_fs.mod = mod; + grub_fs_register (&grub_udf_fs); + } my_mod = mod; } GRUB_MOD_FINI (udf) { - grub_fs_unregister (&grub_udf_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_udf_fs); } diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c index fca46baa1..8b5adbd48 100644 --- a/grub-core/fs/ufs.c +++ b/grub-core/fs/ufs.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -463,7 +464,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) /* Check against zero is paylindromic, no need to swap. */ if (data->inode.nblocks == 0 && INODE_SIZE (data) <= sizeof (data->inode.symlink)) - grub_strcpy (symlink, (char *) data->inode.symlink); + grub_strlcpy (symlink, (char *) data->inode.symlink, sz); else { if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0) @@ -568,7 +569,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path) { 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) { @@ -613,7 +614,7 @@ grub_ufs_mount (grub_disk_t disk) && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0) && data->sblock.ino_per_group != 0) { - for (data->log2_blksz = 0; + for (data->log2_blksz = 0; (1U << data->log2_blksz) < grub_ufs_to_cpu32 (data->sblock.bsize); data->log2_blksz++); @@ -837,7 +838,7 @@ grub_ufs_uuid (grub_device_t device, char **uuid) /* Get mtime. */ static grub_err_t -grub_ufs_mtime (grub_device_t device, grub_int32_t *tm) +grub_ufs_mtime (grub_device_t device, grub_int64_t *tm) { struct grub_ufs_data *data = 0; @@ -899,7 +900,11 @@ GRUB_MOD_INIT(ufs1) #endif #endif { - grub_fs_register (&grub_ufs_fs); + if (!grub_is_lockdown ()) + { + grub_ufs_fs.mod = mod; + grub_fs_register (&grub_ufs_fs); + } my_mod = mod; } @@ -913,6 +918,7 @@ GRUB_MOD_FINI(ufs1) #endif #endif { - grub_fs_unregister (&grub_ufs_fs); + if (!grub_is_lockdown ()) + grub_fs_unregister (&grub_ufs_fs); } diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 96ffecbfc..1bc4017ca 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -23,8 +23,10 @@ #include #include #include +#include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -74,10 +76,22 @@ GRUB_MOD_LICENSE ("GPLv3+"); 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. @@ -87,11 +101,26 @@ GRUB_MOD_LICENSE ("GPLv3+"); * * 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_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 { @@ -176,33 +205,49 @@ struct grub_xfs_btree_root grub_uint64_t keys[1]; } GRUB_PACKED; -struct grub_xfs_time +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[26]; - struct grub_xfs_time atime; - struct grub_xfs_time mtime; - struct grub_xfs_time ctime; + 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]; + 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_V2_INODE_SIZE sizeof(struct grub_xfs_inode) -#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76) +#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 { @@ -220,6 +265,7 @@ struct grub_fshelp_node struct grub_xfs_data { + grub_size_t data_size; struct grub_xfs_sblock sblock; grub_disk_t disk; int pos; @@ -296,9 +342,21 @@ static int grub_xfs_sb_valid(struct grub_xfs_data *data) } 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 @@ -489,7 +547,7 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, 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", + 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), @@ -509,11 +567,26 @@ get_fsb (const void *keys, int 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; - int ex, nrec; + grub_uint64_t ex, nrec; struct grub_xfs_extent *exts; grub_uint64_t ret = 0; @@ -538,7 +611,18 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) / (2 * sizeof (grub_uint64_t)); do { - int i; + 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++) { @@ -556,7 +640,10 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) 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)) - return 0; + { + grub_free (leaf); + return 0; + } if ((!node->data->hascrc && grub_strncmp ((char *) leaf->magic, "BMAP", 4)) || @@ -579,8 +666,20 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) } else if (node->inode.format == XFS_INODE_FORMAT_EXT) { - nrec = grub_be_to_cpu32 (node->inode.nextents); + 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 { @@ -634,6 +733,7 @@ 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) { @@ -655,7 +755,12 @@ grub_xfs_read_symlink (grub_fshelp_node_t node) if (node->data->hascrc) off = 56; - symlink = grub_malloc (size + 1); + 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; @@ -705,8 +810,15 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename, { struct grub_fshelp_node *fdiro; grub_err_t err; + grub_size_t sz; - fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1); + 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 (); @@ -722,6 +834,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename, if (err) { grub_print_error (); + grub_free (fdiro); return 0; } @@ -764,12 +877,20 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, if (iterate_dir_call_hook (parent, "..", &ctx)) return 1; - for (i = 0; i < head->count; i++) + 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) @@ -824,24 +945,49 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, { struct grub_xfs_dir2_entry *direntry = grub_xfs_first_de(dir->data, dirblock); - int entries; - struct grub_xfs_dirblock_tail *tail = - grub_xfs_dir_tail(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) - return 0; + { + grub_free (dirblock); + return 0; + } - entries = (grub_be_to_cpu32 (tail->leaf_count) - - grub_be_to_cpu32 (tail->leaf_stale)); - - if (!entries) + /* + * 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 *)tail) + while ((char *) direntry < (char *) end) { grub_uint8_t *freetag; char *filename; @@ -861,22 +1007,34 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, } 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), + if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode), filename, &ctx)) { grub_free (dirblock); return 1; } - /* Check if last direntry in this block is - reached. */ - entries--; - if (!entries) - break; + /* + * 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); @@ -899,11 +1057,14 @@ 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, @@ -913,14 +1074,19 @@ grub_xfs_mount (grub_disk_t disk) if (!grub_xfs_sb_valid(data)) goto fail; - data = grub_realloc (data, - sizeof (struct grub_xfs_data) - - sizeof (struct grub_xfs_inode) - + grub_xfs_inode_size(data) + 1); + 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; @@ -931,7 +1097,7 @@ grub_xfs_mount (grub_disk_t disk) data->disk = disk; data->pos = 0; - grub_dprintf("xfs", "Reading root ino %"PRIuGRUB_UINT64_T"\n", + 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); @@ -939,7 +1105,7 @@ grub_xfs_mount (grub_disk_t disk) return data; fail: - if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + 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); @@ -955,6 +1121,27 @@ struct grub_xfs_dir_ctx 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, @@ -967,7 +1154,7 @@ grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, if (node->inode_read) { info.mtimeset = 1; - info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec); + info.mtime = grub_xfs_get_inode_time (&node->inode); } info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); grub_free (node); @@ -1152,6 +1339,7 @@ static struct grub_fs grub_xfs_fs = GRUB_MOD_INIT(xfs) { + grub_xfs_fs.mod = mod; grub_fs_register (&grub_xfs_fs); my_mod = mod; } diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 2f72e42bf..bff9d0208 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -55,6 +55,9 @@ #include #include #include +#include + +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -72,6 +75,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); #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 @@ -141,7 +146,10 @@ ZAP_LEAF_NUMCHUNKS (int bs) static inline zap_leaf_chunk_t * ZAP_LEAF_CHUNK (zap_leaf_phys_t *l, int bs, int idx) { - return &((zap_leaf_chunk_t *) (l->l_entries + 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]; } @@ -172,7 +180,7 @@ typedef struct decomp_entry /* * Signature for checksum functions. */ -typedef void zio_checksum_t(const void *data, grub_uint64_t size, +typedef void zio_checksum_t(const void *data, grub_uint64_t size, grub_zfs_endian_t endian, zio_cksum_t *zcp); /* @@ -285,6 +293,9 @@ static const char *spa_feature_names[] = { "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 }; @@ -293,7 +304,7 @@ 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 +static grub_err_t zlib_decompress (void *s, void *d, grub_size_t slen, grub_size_t dlen) { @@ -306,7 +317,41 @@ zlib_decompress (void *s, void *d, return grub_errno; } -static grub_err_t +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) { @@ -356,6 +401,7 @@ static decomp_entry_t decomp_table[ZIO_COMPRESS_FUNCTIONS] = { {"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, @@ -411,7 +457,7 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = { */ static grub_err_t zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, - grub_zfs_endian_t endian, + grub_zfs_endian_t endian, char *buf, grub_size_t size) { zio_eck_t *zec = (zio_eck_t *) (buf + size) - 1; @@ -421,14 +467,14 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, 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, + 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; + 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; @@ -441,14 +487,14 @@ zio_checksum_verify (zio_cksum_t zc, grub_uint32_t checksum, { 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[0], (unsigned long long) actual_cksum.zc_word[1], - (unsigned long long) actual_cksum.zc_word[2], + (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[0], (unsigned long long) zc.zc_word[1], - (unsigned long long) zc.zc_word[2], + (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")); } @@ -481,17 +527,17 @@ vdev_uberblock_compare (uberblock_t * ub1, uberblock_t * ub2) else ub2_endian = GRUB_ZFS_BIG_ENDIAN; - if (grub_zfs_to_cpu64 (ub1->ub_txg, ub1_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) + 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) + 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) + if (grub_zfs_to_cpu64 (ub1->ub_timestamp, ub1_endian) > grub_zfs_to_cpu64 (ub2->ub_timestamp, ub2_endian)) return 1; @@ -563,13 +609,13 @@ find_bestub (uberblock_phys_t * ub_array, ubptr = (uberblock_phys_t *) ((grub_properly_aligned_t *) ub_array + ((i << ub_shift) / sizeof (grub_properly_aligned_t))); - err = uberblock_verify (ubptr, offset, 1 << ub_shift); + err = uberblock_verify (ubptr, offset, (grub_size_t) 1 << ub_shift); if (err) { grub_errno = GRUB_ERR_NONE; continue; } - if (ubbest == NULL + if (ubbest == NULL || vdev_uberblock_compare (&(ubptr->ubp_uberblock), &(ubbest->ubp_uberblock)) > 0) ubbest = ubptr; @@ -590,10 +636,10 @@ get_psize (blkptr_t * bp, grub_zfs_endian_t endian) 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], + 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], + return grub_zfs_to_cpu64 ((dva)->dva_word[1], endian) << SPA_MINBLOCKSHIFT; } @@ -608,6 +654,8 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist) 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, @@ -716,9 +764,14 @@ fill_vdev_info_real (struct grub_zfs_data *data, if (!fill->children) { fill->n_children = nelm; - - fill->children = grub_zalloc (fill->n_children - * sizeof (fill->children[0])); + + 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++) @@ -773,11 +826,14 @@ fill_vdev_info (struct grub_zfs_data *data, if (data->n_devices_attached > data->n_devices_allocated) { void *tmp; - data->n_devices_allocated = 2 * data->n_devices_attached + 1; - data->devices_attached - = grub_realloc (tmp = data->devices_attached, - data->n_devices_allocated - * sizeof (data->devices_attached[0])); + 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; @@ -832,7 +888,7 @@ nvlist_next_nvpair (const char *nvl, const char *nvpair) { /* skip over header, nvl_version and nvl_nvflag */ nvpair = nvl + 4 * 3; - } + } else { /* skip to the next nvpair */ @@ -866,10 +922,10 @@ nvlist_next_nvpair (const char *nvl, const char *nvpair) 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 + 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) + || nvp + 4 + encode_size > nvl + VDEV_PHYS_SIZE) { grub_dprintf ("zfs", "nvlist overflow\n"); grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist"); @@ -889,7 +945,7 @@ 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)); @@ -936,7 +992,7 @@ nvpair_value (const char *nvp,char **val, /* skip over name */ nvp = nvp + ((name_len + 3) & ~3); /* align */ - + /* skip over type */ nvp += 4; nelm = grub_be_to_cpu32 (grub_get_unaligned32 (nvp)); @@ -950,7 +1006,7 @@ nvpair_value (const char *nvp,char **val, *size_out = encode_size; if (nelm_out) *nelm_out = nelm; - + return 1; } @@ -1001,8 +1057,10 @@ check_pool_label (struct grub_zfs_data *data, 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) + if (err) { + grub_free (nvlist); return err; + } grub_dprintf ("zfs", "check 2 passed\n"); @@ -1088,8 +1146,10 @@ check_pool_label (struct grub_zfs_data *data, if (original) data->guid = poolguid; - if (data->guid != poolguid) + if (data->guid != poolguid) { + grub_free (nvlist); return grub_error (GRUB_ERR_BAD_FS, "another zpool"); + } { char *nv; @@ -1130,9 +1190,12 @@ check_pool_label (struct grub_zfs_data *data, { 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); @@ -1168,7 +1231,7 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, desc.original = original; /* Don't check back labels on CDROM. */ - if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) + if (grub_disk_native_sectors (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) vdevnum = VDEV_LABELS / 2; for (label = 0; ubbest == NULL && label < vdevnum; label++) @@ -1176,8 +1239,8 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, 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_get_size (dev->disk), sizeof (vdev_label_t)) + + (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). */ @@ -1222,7 +1285,7 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, grub_free (bh); return GRUB_ERR_NONE; } - + grub_free (ub_array); grub_free (bh); @@ -1262,7 +1325,7 @@ scan_devices_iter (const char *name, void *hook_data) if (!inserted) grub_device_close (dev); - + return 0; } @@ -1379,7 +1442,7 @@ recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, for (i = 0; i < nbufs; i++) { grub_uint8_t mul; - for (j = i; j < nbufs; j++) + for (j = i; j < nbufs; j++) if (matrix1[i][j]) break; if (j == nbufs) @@ -1446,7 +1509,7 @@ recovery (grub_uint8_t *bufs[4], grub_size_t s, const int nbufs, } default: return grub_error (GRUB_ERR_BUG, "too big matrix"); - } + } } static grub_err_t @@ -1503,7 +1566,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, int idx, orig_idx; if (desc->nparity < 1 || desc->nparity > 3) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + 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) @@ -1539,7 +1602,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, high = grub_divmod64 ((offset >> desc->ashift) + c, desc->n_children, &devn); - csize = bsize << desc->ashift; + csize = (grub_size_t) bsize << desc->ashift; if (csize > len) csize = len; @@ -1631,8 +1694,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, while (len > 0) { - grub_size_t csize; - csize = ((s / (desc->n_children - desc->nparity)) + grub_size_t csize = s; + csize = ((csize / (desc->n_children - desc->nparity)) << desc->ashift); if (csize > len) csize = len; @@ -1652,7 +1715,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc, len -= csize; idx--; } - for (i = 0; i < failed_devices + for (i = 0; i < failed_devices && recovery_len[i] == recovery_len[0]; i++); /* Since the chunks have variable length handle the last block @@ -1775,7 +1838,7 @@ zio_read_gang (blkptr_t * bp, grub_zfs_endian_t endian, dva_t * dva, void *buf, * 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, +zio_read_data (blkptr_t * bp, grub_zfs_endian_t endian, void *buf, struct grub_zfs_data *data) { int i, psize; @@ -1843,7 +1906,7 @@ decode_embedded_bp_compressed(const blkptr_t *bp, void *buf) * and put the uncompressed data in buf. */ static grub_err_t -zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, +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; @@ -1862,8 +1925,9 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, { if (BPE_GET_ETYPE(bp) != BP_EMBEDDED_TYPE_DATA) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "unsupported embedded BP (type=%u)\n", - BPE_GET_ETYPE(bp)); + "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); } @@ -1929,7 +1993,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, if (encrypted) { if (!grub_zfs_decrypt) - err = grub_error (GRUB_ERR_BAD_FS, + err = grub_error (GRUB_ERR_BAD_FS, N_("module `%s' isn't loaded"), "zfscrypt"); else @@ -1953,7 +2017,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, endian)); return grub_error (GRUB_ERR_BAD_FS, "no key found in keychain"); } - grub_dprintf ("zfs", "using key %u (%" PRIxGRUB_UINT64_T + 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, @@ -2001,7 +2065,7 @@ zio_read (blkptr_t *bp, grub_zfs_endian_t endian, void **buf, * */ static grub_err_t -dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, +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; @@ -2031,8 +2095,8 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf, if (BP_IS_HOLE (bp)) { - grub_size_t size = grub_zfs_to_cpu16 (dn->dn.dn_datablkszsec, - dn->endian) + grub_size_t size = grub_zfs_to_cpu16 (dn->dn.dn_datablkszsec, + dn->endian) << SPA_MINBLOCKSHIFT; *buf = grub_malloc (size); if (!*buf) @@ -2096,7 +2160,7 @@ mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, } static int -mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, +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) @@ -2110,7 +2174,7 @@ mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, 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, + if (hook (mzap_ent[i].mze_name, grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian), ctx)) return 1; } @@ -2171,12 +2235,12 @@ name_cmp (const char *s1, const char *s2, grub_size_t n, 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++; } @@ -2214,14 +2278,14 @@ zap_leaf_array_equal (zap_leaf_phys_t * l, grub_zfs_endian_t endian, /* XXX */ static grub_err_t -zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int blksft, +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 = &ZAP_LEAF_CHUNK (l, blksft, chunk)->l_array; + struct zap_leaf_array *la; grub_size_t toread = array_len - bseen; if (toread > ZAP_LEAF_ARRAY_BYTES) @@ -2231,6 +2295,7 @@ zap_leaf_array_get (zap_leaf_phys_t * l, grub_zfs_endian_t endian, int 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; @@ -2278,7 +2343,7 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian, grub_dprintf ("zfs", "fzap: length %d\n", (int) le->le_name_length); - if (zap_leaf_array_equal (l, endian, blksft, + 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)) @@ -2327,7 +2392,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, { void *l; grub_uint64_t hash, idx, blkid; - int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, + 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; @@ -2340,7 +2405,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, /* get block id from index */ if (zap->zap_ptrtbl.zt_numblks != 0) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + 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); @@ -2372,10 +2437,11 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, 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, + 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; @@ -2383,7 +2449,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, /* get block id from index */ if (zap->zap_ptrtbl.zt_numblks != 0) { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "external pointer tables not supported"); return 0; } @@ -2437,8 +2503,19 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, if (le->le_type != ZAP_CHUNK_ENTRY) continue; - buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian) - * name_elem_length + 1); + 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), @@ -2454,6 +2531,12 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, 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), @@ -2510,7 +2593,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val, grub_dprintf ("zfs", "micro zap\n"); err = mzap_lookup (zapbuf, endian, size, name, val, case_insensitive); - grub_dprintf ("zfs", "returned %d\n", err); + grub_dprintf ("zfs", "returned %d\n", err); grub_free (zapbuf); return err; } @@ -2520,11 +2603,12 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val, /* this is a fat zap */ err = fzap_lookup (zap_dnode, zapbuf, name, val, data, case_insensitive); - grub_dprintf ("zfs", "returned %d\n", err); + 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"); } @@ -2553,7 +2637,7 @@ zap_iterate_u64_transform (const void *name, } static int -zap_iterate_u64 (dnode_end_t * zap_dnode, +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) @@ -2595,12 +2679,13 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, 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, +zap_iterate (dnode_end_t * zap_dnode, grub_size_t nameelemlen, int (*hook) (const void *name, grub_size_t namelen, const void *val_in, @@ -2625,6 +2710,7 @@ zap_iterate (dnode_end_t * zap_dnode, 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) @@ -2636,6 +2722,7 @@ zap_iterate (dnode_end_t * zap_dnode, grub_free (zapbuf); return ret; } + grub_free (zapbuf); grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); return 0; } @@ -2660,24 +2747,31 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, grub_err_t err; grub_zfs_endian_t endian; - blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec, + 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, - sizeof (*mdn)) == 0 + 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"); + 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, + grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian, (unsigned long long) blkid); err = dmu_read (mdn, blkid, &dnbuf, &endian, data); if (err) @@ -2702,9 +2796,12 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, } 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"); + if (type && buf->dn.dn_type != type) + return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); return GRUB_ERR_NONE; } @@ -2728,7 +2825,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, struct dnode_chain { struct dnode_chain *next; - dnode_end_t dn; + dnode_end_t dn; }; struct dnode_chain *dnode_path = 0, *dn_new, *root; @@ -2738,7 +2835,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, dn_new->next = 0; dnode_path = root = dn_new; - err = dnode_get (&subvol->mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, + err = dnode_get (&subvol->mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, &(dnode_path->dn), data); if (err) { @@ -2789,7 +2886,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, grub_free (dn_new); return grub_errno; } - + while (1) { /* skip leading slashes */ @@ -2815,7 +2912,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, } else { - err = grub_error (GRUB_ERR_FILE_NOT_FOUND, + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "can't resolve .."); break; } @@ -2827,8 +2924,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS) { - grub_free (path_buf); - return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + 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); @@ -2854,6 +2951,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, && ((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; @@ -2865,16 +2963,23 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, { grub_size_t block; grub_size_t blksz; - blksz = (grub_zfs_to_cpu16 (dnode_path->dn.dn.dn_datablkszsec, + blksz = (grub_zfs_to_cpu16 (dnode_path->dn.dn.dn_datablkszsec, dnode_path->dn.endian) << SPA_MINBLOCKSHIFT); if (blksz == 0) - return grub_error(GRUB_ERR_BAD_FS, "0-sized block"); + { + err = grub_error (GRUB_ERR_BAD_FS, "0-sized block"); + break; + } sym_value = grub_malloc (sym_sz); if (!sym_value) - return grub_errno; + { + err = grub_errno; + break; + } + for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++) { void *t; @@ -2884,7 +2989,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, if (err) { grub_free (sym_value); - return err; + break; } movesize = sym_sz - block * blksz; @@ -2894,24 +2999,40 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, grub_memcpy (sym_value + block * blksz, t, movesize); grub_free (t); } + if (err) + break; free_symval = 1; - } - path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 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); - return grub_errno; + 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_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; @@ -2924,12 +3045,14 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, 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; + if (dnode_path->dn.dn.dn_bonuslen != 0) { sahdrp = DN_BONUS (&dnode_path->dn.dn); @@ -2937,14 +3060,15 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *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) - return err; + break; } else { - return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + err = grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); + break; } hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); @@ -2955,24 +3079,35 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, dnode_path->dn.endian) >> 12) & 0xf) == 0xa) { char *sym_value = (char *) sahdrp + hdrsize + SA_SYMLINK_OFFSET; - grub_size_t sym_sz = + 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; - path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 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); + err = grub_errno; + break; + } + path = path_buf = grub_malloc (sz); if (!path_buf) { grub_free (oldpathbuf); - return grub_errno; + err = grub_errno; + break; } grub_memcpy (path, sym_value, sym_sz); path [sym_sz] = 0; - grub_memcpy (path + grub_strlen (path), oldpath, + 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; @@ -2985,6 +3120,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn, dnode_path = dn_new->next; grub_free (dn_new); } + dn_new = dnode_path; } } } @@ -3072,7 +3208,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, grub_dprintf ("zfs", "endian = %d\n", mosmdn->endian); - err = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, + err = dnode_get (mosmdn, DMU_POOL_DIRECTORY_OBJECT, DMU_OT_OBJECT_DIRECTORY, mdn, data); if (err) return err; @@ -3095,7 +3231,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, { grub_uint64_t childobj; char *cname, ch; - + while (*fsname == '/') fsname++; @@ -3130,7 +3266,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname, static grub_err_t make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) { - void *osp; + objset_phys_t *osp; blkptr_t *bp; grub_size_t ospsize = 0; grub_err_t err; @@ -3138,7 +3274,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) 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, &osp, &ospsize, data); + err = zio_read (bp, mdn->endian, (void **) &osp, &ospsize, data); if (err) return err; if (ospsize < OBJSET_PHYS_SIZE_V14) @@ -3149,7 +3285,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1; grub_memmove ((char *) &(mdn->dn), - (char *) &((objset_phys_t *) osp)->os_meta_dnode, DNODE_SIZE); + (char *) &(osp)->os_meta_dnode, DNODE_SIZE); grub_free (osp); return GRUB_ERR_NONE; } @@ -3227,6 +3363,8 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, filename = 0; snapname = 0; fsname = grub_strdup (fullpath); + if (!fsname) + return grub_errno; } else { @@ -3255,7 +3393,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, filename = ptr_slash; else filename = "/"; - grub_dprintf ("zfs", "fsname = '%s' snapname='%s' filename = '%s'\n", + grub_dprintf ("zfs", "fsname = '%s' snapname='%s' filename = '%s'\n", fsname, snapname, filename); } grub_dprintf ("zfs", "alive\n"); @@ -3312,6 +3450,8 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, if (err) { grub_dprintf ("zfs", "failed here\n"); + grub_free (fsname); + grub_free (snapname); return err; } @@ -3325,7 +3465,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, } subvol->nkeys = 0; zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data); - subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0])); + subvol->keyring = grub_calloc (subvol->nkeys, sizeof (subvol->keyring[0])); if (!subvol->keyring) { grub_free (fsname); @@ -3341,13 +3481,19 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, 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, + 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, DMU_OT_DSL_DATASET, + 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); @@ -3359,13 +3505,13 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, 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); + grub_free (snapname); return GRUB_ERR_NONE; } err = dnode_get_path (subvol, filename, dn, data); @@ -3385,9 +3531,9 @@ nvlist_find_value (const char *nvlist_in, const char *name, char *nvp_name; /* Verify if the 1st and 2nd byte in the nvlist are valid. */ - /* NOTE: independently of what endianness header announces all + /* NOTE: independently of what endianness header announces all subsequent values are big-endian. */ - if (nvlist[0] != NV_ENCODE_XDR || (nvlist[1] != NV_LITTLE_ENDIAN + if (nvlist[0] != NV_ENCODE_XDR || (nvlist[1] != NV_LITTLE_ENDIAN && nvlist[1] != NV_BIG_ENDIAN)) { grub_dprintf ("zfs", "incorrect nvlist header\n"); @@ -3468,14 +3614,18 @@ grub_zfs_nvlist_lookup_nvlist (const char *nvlist, const char *name) { char *nvpair; char *ret; - grub_size_t size; + grub_size_t size, sz; int found; found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair, &size, 0); if (!found) return 0; - ret = grub_zalloc (size + 3 * sizeof (grub_uint32_t)); + + 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)); @@ -3504,13 +3654,13 @@ 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; + ptr += 8; return (ptr > limit) ? -1 : (ptr - beg); } @@ -3525,6 +3675,7 @@ grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name, unsigned i; grub_size_t nelm; int elemsize = 0; + int sz; found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair, &size, &nelm); @@ -3559,7 +3710,12 @@ grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name, return 0; } - ret = grub_zalloc (elemsize + sizeof (grub_uint32_t)); + 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)); @@ -3613,7 +3769,7 @@ zfs_mount (grub_device_t dev) { struct grub_zfs_data *data = 0; grub_err_t err; - void *osp = 0; + objset_phys_t *osp = 0; grub_size_t ospsize; grub_zfs_endian_t ub_endian = GRUB_ZFS_UNKNOWN_ENDIAN; uberblock_t *ub; @@ -3635,8 +3791,13 @@ zfs_mount (grub_device_t dev) #endif data->n_devices_allocated = 16; - data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) - * data->n_devices_allocated); + 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) @@ -3646,12 +3807,12 @@ zfs_mount (grub_device_t dev) } ub = &(data->current_uberblock); - ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC + 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, - &osp, &ospsize, data); + (void **) &osp, &ospsize, data); if (err) { zfs_unmount (data); @@ -3667,8 +3828,7 @@ zfs_mount (grub_device_t dev) } if (ub->ub_version >= SPA_VERSION_FEATURES && - check_mos_features(&((objset_phys_t *) osp)->os_meta_dnode,ub_endian, - data) != 0) + check_mos_features(&osp->os_meta_dnode, ub_endian, data) != 0) { grub_error (GRUB_ERR_BAD_FS, "Unsupported features in pool"); grub_free (osp); @@ -3677,8 +3837,7 @@ zfs_mount (grub_device_t dev) } /* Got the MOS. Save it at the memory addr MOS. */ - grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode, - DNODE_SIZE); + 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); @@ -3700,7 +3859,7 @@ grub_zfs_fetch_nvlist (grub_device_t dev, char **nvlist) return err; } -static grub_err_t +static grub_err_t zfs_label (grub_device_t device, char **label) { char *nvlist; @@ -3712,7 +3871,7 @@ zfs_label (grub_device_t device, char **label) return grub_errno; err = zfs_fetch_nvlist (data->device_original, &nvlist); - if (err) + if (err) { zfs_unmount (data); return err; @@ -3724,7 +3883,7 @@ zfs_label (grub_device_t device, char **label) return grub_errno; } -static grub_err_t +static grub_err_t zfs_uuid (grub_device_t device, char **uuid) { struct grub_zfs_data *data; @@ -3742,8 +3901,8 @@ zfs_uuid (grub_device_t device, char **uuid) return GRUB_ERR_NONE; } -static grub_err_t -zfs_mtime (grub_device_t device, grub_int32_t *mt) +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; @@ -3756,8 +3915,8 @@ zfs_mtime (grub_device_t device, grub_int32_t *mt) return grub_errno; ub = &(data->current_uberblock); - ub_endian = (grub_zfs_to_cpu64 (ub->ub_magic, - GRUB_ZFS_LITTLE_ENDIAN) == UBERBLOCK_MAGIC + 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); @@ -3795,7 +3954,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) } /* 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) + 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")); @@ -3812,6 +3971,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) { void *sahdrp; int hdrsize; + bool free_sahdrp = false; if (data->dnode.dn.dn_bonuslen != 0) { @@ -3824,6 +3984,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data); if (err) return err; + free_sahdrp = true; } else { @@ -3832,6 +3993,8 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) 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) { @@ -3870,7 +4033,7 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len) return len; } - blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec, + blksz = grub_zfs_to_cpu16 (data->dnode.dn.dn_datablkszsec, data->dnode.endian) << SPA_MINBLOCKSHIFT; if (blksz == 0) @@ -3955,20 +4118,29 @@ grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, 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, - dnode_end_t mdn, struct grub_zfs_data *data) + 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) + + 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); @@ -3982,32 +4154,33 @@ fill_fs_info (struct grub_dirhook_info *info, err = make_mdn (&mdn, data); if (err) return err; - err = dnode_get (&mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, + 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) { @@ -4020,6 +4193,7 @@ fill_fs_info (struct grub_dirhook_info *info, err = zio_read (bp, dn.endian, &sahdrp, NULL, data); if (err) return err; + free_sahdrp = true; } else { @@ -4030,6 +4204,8 @@ fill_fs_info (struct grub_dirhook_info *info, 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) @@ -4061,6 +4237,7 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) { void *sahdrp; int hdrsize; + bool free_sahdrp = false; if (dn.dn.dn_bonuslen != 0) { @@ -4076,6 +4253,7 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) grub_print_error (); return 0; } + free_sahdrp = true; } else { @@ -4088,16 +4266,18 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) 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", + grub_dprintf ("zfs", "type=%d, name=%s\n", (int)dn.dn.dn_type, (char *)name); return ctx->hook (name, &info, ctx->hook_data); } @@ -4110,6 +4290,9 @@ iterate_zap_fs (const char *name, grub_uint64_t val, 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) @@ -4117,10 +4300,12 @@ iterate_zap_fs (const char *name, grub_uint64_t val, grub_errno = 0; return 0; } - if (mdn.dn.dn_type != DMU_OT_DSL_DIR) + 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); + err = fill_fs_info (&info, &mdn, ctx->data); if (err) { grub_errno = 0; @@ -4138,6 +4323,7 @@ iterate_zap_snap (const char *name, grub_uint64_t val, struct grub_dirhook_info info; char *name2; int ret; + grub_size_t sz; dnode_end_t mdn; @@ -4148,17 +4334,23 @@ iterate_zap_snap (const char *name, grub_uint64_t val, return 0; } - if (mdn.dn.dn_type != DMU_OT_DSL_DATASET) + 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); + err = fill_fs_info (&info, &mdn, ctx->data); if (err) { grub_errno = 0; return 0; } - name2 = grub_malloc (grub_strlen (name) + 2); + 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); @@ -4191,12 +4383,12 @@ grub_zfs_dir (grub_device_t device, const char *path, if (isfs) { - grub_uint64_t childobj, headobj; + 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); + err = fill_fs_info (&info, &data->dnode, data); if (err) { zfs_unmount (data); @@ -4219,8 +4411,11 @@ grub_zfs_dir (grub_device_t device, const char *path, } zap_iterate_u64 (&dn, iterate_zap_fs, data, &ctx); - - err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data); + + 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); @@ -4261,8 +4456,8 @@ check_feature (const char *name, grub_uint64_t val, 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) + for (i = 0; spa_feature_names[i] != NULL; i++) + if (grub_strcmp (name, spa_feature_names[i]) == 0) return 0; return 1; } @@ -4275,7 +4470,7 @@ check_feature (const char *name, grub_uint64_t val, * 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 ) { @@ -4284,7 +4479,7 @@ check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct gru dnode_end_t dn,mosmdn; mzap_phys_t* mzp; grub_zfs_endian_t endianzap; - int size; + int size, ret; grub_memmove(&(mosmdn.dn),mosmdn_phys,sizeof(dnode_phys_t)); mosmdn.endian=endian; errnum = dnode_get(&mosmdn, DMU_POOL_DIRECTORY_OBJECT, @@ -4300,7 +4495,7 @@ check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct gru 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; @@ -4310,7 +4505,9 @@ check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct gru return errnum; size = grub_zfs_to_cpu16 (dn.dn.dn_datablkszsec, dn.endian) << SPA_MINBLOCKSHIFT; - return mzap_iterate (mzp,endianzap, size, check_feature,NULL); + ret = mzap_iterate (mzp,endianzap, size, check_feature,NULL); + grub_free(mzp); + return ret; } @@ -4336,7 +4533,7 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)), *nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS); if (*nsectors > max_nsectors) *nsectors = max_nsectors; - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); if (!*sectors) return grub_errno; for (i = 0; i < *nsectors; i++) @@ -4366,6 +4563,7 @@ static struct grub_fs grub_zfs_fs = { 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; diff --git a/grub-core/fs/zfs/zfs_fletcher.c b/grub-core/fs/zfs/zfs_fletcher.c index 7d27b053d..ad3be6705 100644 --- a/grub-core/fs/zfs/zfs_fletcher.c +++ b/grub-core/fs/zfs/zfs_fletcher.c @@ -39,14 +39,14 @@ #include void -fletcher_2(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, +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) + + 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); @@ -61,14 +61,14 @@ fletcher_2(const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, } void -fletcher_4 (const void *buf, grub_uint64_t size, grub_zfs_endian_t endian, +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++) + + for (a = b = c = d = 0; ip < ipend; ip++) { a += grub_zfs_to_cpu32 (ip[0], endian);; b += a; diff --git a/grub-core/fs/zfs/zfs_sha256.c b/grub-core/fs/zfs/zfs_sha256.c index a181f076c..f042fa61a 100644 --- a/grub-core/fs/zfs/zfs_sha256.c +++ b/grub-core/fs/zfs/zfs_sha256.c @@ -116,23 +116,23 @@ zio_checksum_SHA256(const void *buf, grub_uint64_t size, 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], + + 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); diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 1402e0bc2..da30e9ab3 100644 --- a/grub-core/fs/zfs/zfscrypt.c +++ b/grub-core/fs/zfs/zfscrypt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* - Mostly based on following article: + Mostly based on following article: https://blogs.oracle.com/darren/entry/zfs_encryption_what_is_on */ @@ -82,9 +83,13 @@ grub_zfs_add_key (grub_uint8_t *key_in, int passphrase) { struct grub_zfs_wrap_key *key; + grub_size_t sz; + if (!passphrase && keylen > 32) keylen = 32; - key = grub_malloc (sizeof (*key) + keylen); + 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; @@ -174,7 +179,7 @@ grub_gcm_mul (grub_uint8_t *a, const grub_uint8_t *b) grub_crypto_xor (res, res, bs, 16); grub_gcm_mul_x (bs); } - + grub_memcpy (a, res, 16); } @@ -270,7 +275,7 @@ algo_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo, } static grub_err_t -grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, +grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo, void *nonce, char *buf, grub_size_t size, @@ -281,7 +286,7 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, 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++) @@ -297,7 +302,7 @@ grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher, 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])) @@ -357,7 +362,7 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, grub_crypto_cipher_close (cipher); continue; } - + err = grub_crypto_cipher_set_key (cipher, wrap_key_real, keylen); if (err) @@ -366,7 +371,7 @@ grub_zfs_load_key_real (const struct grub_zfs_key *key, 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) diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c index c8a28acf5..31d767bbd 100644 --- a/grub-core/fs/zfs/zfsinfo.c +++ b/grub-core/fs/zfs/zfsinfo.c @@ -379,14 +379,17 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, grub_device_close (dev); - if (err) + 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; } diff --git a/grub-core/gdb/gdb.c b/grub-core/gdb/gdb.c index 847a1e1e3..9e091ee1b 100644 --- a/grub-core/gdb/gdb.c +++ b/grub-core/gdb/gdb.c @@ -75,25 +75,30 @@ static grub_command_t cmd, cmd_stop, cmd_break; GRUB_MOD_INIT (gdb) { grub_gdb_idtinit (); - cmd = grub_register_command ("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 ("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 ("gdbstub_stop", grub_cmd_gdbstop, - 0, N_("Stop GDB stub")); + 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 index 69bfcb089..43bde51a0 100644 --- a/grub-core/gdb/i386/idt.c +++ b/grub-core/gdb/i386/idt.c @@ -1,4 +1,4 @@ -/* idt.c - routines for constructing IDT fot the GDB stub */ +/* idt.c - routines for constructing IDT for the GDB stub */ /* * Copyright (C) 2006 Lubomir Kundrak * diff --git a/grub-core/gdb/i386/signal.c b/grub-core/gdb/i386/signal.c index 1ac3bbd18..b169c6b23 100644 --- a/grub-core/gdb/i386/signal.c +++ b/grub-core/gdb/i386/signal.c @@ -1,4 +1,4 @@ -/* idt.c - routines for constructing IDT fot the GDB stub */ +/* idt.c - routines for constructing IDT for the GDB stub */ /* * Copyright (C) 2006 Lubomir Kundrak * diff --git a/grub-core/gdb_grub.in b/grub-core/gdb_grub.in index e322d3dc1..f188a842a 100644 --- a/grub-core/gdb_grub.in +++ b/grub-core/gdb_grub.in @@ -1,6 +1,6 @@ ### ### Load debuging information about GNU GRUB 2 modules into GDB -### automatically. Needs readelf, Perl and gmodule.pl script +### automatically. Needs readelf, objdump, Python and gdb_helper.py script ### ### Has to be launched from the writable and trusted ### directory containing *.image and *.module @@ -9,77 +9,128 @@ ### Lubomir Kundrak ### -# Add section numbers and addresses to .segments.tmp -define dump_module_sections - set $mod = $arg0 +source gdb_helper.py - # FIXME: save logging status - set logging file .segments.tmp - set logging redirect on - set logging overwrite off - set logging on - printf "%s", $mod->name - set $segment = $mod->segment - while ($segment) - printf " %i 0x%lx", $segment->section, $segment->addr - set $segment = $segment->next +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 - printf "\n" - - set logging off - # FIXME: restore logging status end -document dump_module_sections - Gather information about module whose mod structure was - given for use with match_and_load_symbols -end - -# Generate and execute GDB commands and delete temporary files -# afterwards -define match_and_load_symbols - shell perl gmodule.pl <.segments.tmp >.loadsym.gdb - source .loadsym.gdb - shell rm -f .segments.tmp .loadsym.gdb -end -document match_and_load_symbols - Launch script, that matches section names with information - generated by dump_module_sections and load debugging info - apropriately -end - -### - -define load_module - dump_module_sections $arg0 - match_and_load_symbols -end -document load_module - Load debugging information for module given as argument. +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) - dump_module_sections $this + load_module $this set $this = $this->next end - match_and_load_symbols 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 -file kernel.exec -target remote :1234 -# inform when module is loaded -break grub_dl_add -commands - silent - load_module mod - cont +# 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 new file mode 100644 index 000000000..a2cab416a --- /dev/null +++ b/grub-core/gdb_helper.py.in @@ -0,0 +1,173 @@ +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 index 1250589b3..337753c57 100644 --- a/grub-core/genmod.sh.in +++ b/grub-core/genmod.sh.in @@ -57,8 +57,11 @@ if test x@TARGET_APPLE_LINKER@ != x1; then @TARGET_STRIP@ --strip-unneeded \ -K grub_mod_init -K grub_mod_fini \ -K _grub_mod_init -K _grub_mod_fini \ - -R .note.gnu.gold-version -R .note.GNU-stack \ + -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 \ @@ -83,9 +86,9 @@ else 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,-d + @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,-d + @TARGET_CC@ @TARGET_LDFLAGS@ -ffreestanding -nostdlib -o $tmpfile2 $t1 $tmpfile -Wl,-r fi rm -f $t1 $t2 $tmpfile mv $tmpfile2 $tmpfile diff --git a/grub-core/genmoddep.awk b/grub-core/genmoddep.awk index 04c2863e5..ab457cb2b 100644 --- a/grub-core/genmoddep.awk +++ b/grub-core/genmoddep.awk @@ -31,7 +31,11 @@ BEGIN { 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++; @@ -59,7 +63,9 @@ END { } modlist = "" depcount[mod] = 0 - for (depmod in uniqmods) { + 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]++ diff --git a/grub-core/gensymlist.sh b/grub-core/gensymlist.sh index 5beaabdd6..5074ef6aa 100644 --- a/grub-core/gensymlist.sh +++ b/grub-core/gensymlist.sh @@ -31,6 +31,7 @@ cat <. */ +#include <../config-util.h> EOF for i in $*; do diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c index 4d02e62c1..9ffc73428 100644 --- a/grub-core/gettext/gettext.c +++ b/grub-core/gettext/gettext.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -51,7 +52,7 @@ struct header grub_uint32_t offset_translation; }; -struct string_descriptor +struct string_descriptor { grub_uint32_t length; grub_uint32_t offset; @@ -99,6 +100,7 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, char *translation; struct string_descriptor desc; grub_err_t err; + grub_size_t alloc_sz; internal_position = (off + position * sizeof (desc)); @@ -109,7 +111,10 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, length = grub_cpu_to_le32 (desc.length); offset = grub_cpu_to_le32 (desc.offset); - translation = grub_malloc (length + 1); + if (grub_add (length, 1, &alloc_sz)) + return NULL; + + translation = grub_malloc (alloc_sz); if (!translation) return NULL; @@ -206,7 +211,7 @@ grub_gettext_translate_real (struct grub_gettext_context *ctx, } grub_error_pop (); depth--; - return ret; + return ret; } } @@ -235,7 +240,7 @@ grub_gettext_translate_real (struct grub_gettext_context *ctx, } grub_error_pop (); depth--; - return ret; + return ret; } } @@ -323,8 +328,8 @@ grub_mofile_open (struct grub_gettext_context *ctx, 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_zalloc (ctx->grub_gettext_max - * sizeof (ctx->grub_gettext_msg_list[0])); + 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); @@ -452,7 +457,7 @@ void grub_gettext_reread_prefix (const char *val) { grub_err_t err; - err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), + err = grub_gettext_init_ext (&main_context, grub_env_get ("lang"), grub_env_get ("locale_dir"), val); if (err) @@ -519,7 +524,7 @@ GRUB_MOD_INIT (gettext) 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 + So it's "translate" in the same meaning as in what you're doing now. */ N_("Translates the string with the current settings.")); @@ -535,6 +540,10 @@ GRUB_MOD_INIT (gettext) 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); diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c index 8a17dda2c..72b39f90f 100644 --- a/grub-core/gfxmenu/gfxmenu.c +++ b/grub-core/gfxmenu/gfxmenu.c @@ -42,7 +42,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_gfxmenu_view_t cached_view; -static void +static void grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) { } diff --git a/grub-core/gfxmenu/gui_circular_progress.c b/grub-core/gfxmenu/gui_circular_progress.c index 354dd7b73..db1edb8f4 100644 --- a/grub-core/gfxmenu/gui_circular_progress.c +++ b/grub-core/gfxmenu/gui_circular_progress.c @@ -220,7 +220,7 @@ static void circprog_set_state (void *vself, int visible, int start, int current, int end) { - circular_progress_t self = vself; + circular_progress_t self = vself; self->visible = visible; self->start = start; self->value = current; @@ -230,7 +230,7 @@ circprog_set_state (void *vself, int visible, int start, static int parse_angle (const char *value) { - char *ptr; + const char *ptr; int angle; angle = grub_strtol (value, &ptr, 10); diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c index 29784ed2d..eed4b6b87 100644 --- a/grub-core/gfxmenu/gui_image.c +++ b/grub-core/gfxmenu/gui_image.c @@ -199,6 +199,12 @@ 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); } diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c index a4c817891..ffd50223c 100644 --- a/grub-core/gfxmenu/gui_label.c +++ b/grub-core/gfxmenu/gui_label.c @@ -160,7 +160,7 @@ 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; + grub_gui_label_t self = vself; self->value = -current; self->visible = visible; grub_free (self->text); @@ -193,6 +193,10 @@ label_set_property (void *vself, const char *name, const char *value) 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); } diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index 01477cdf2..2ccd4345f 100644 --- a/grub-core/gfxmenu/gui_list.c +++ b/grub-core/gfxmenu/gui_list.c @@ -118,7 +118,7 @@ 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); @@ -353,7 +353,7 @@ draw_menu (list_impl_t self, int num_shown_items) grub_video_get_viewport (&oviewport.x, &oviewport.y, &oviewport.width, &oviewport.height); - grub_video_set_viewport (oviewport.x + boxpad, + grub_video_set_viewport (oviewport.x + boxpad, oviewport.y + boxpad, oviewport.width - 2 * boxpad, oviewport.height - 2 * boxpad); @@ -771,7 +771,7 @@ list_set_property (void *vself, const char *name, const char *value) { self->need_to_recreate_boxes = 1; grub_free (self->selected_item_box_pattern); - self->selected_item_box_pattern = value ? grub_strdup (value) : 0; + self->selected_item_box_pattern = grub_strdup (value); self->selected_item_box_pattern_inherit = 0; } } diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c index b128f0866..c4cd1859b 100644 --- a/grub-core/gfxmenu/gui_progress_bar.c +++ b/grub-core/gfxmenu/gui_progress_bar.c @@ -320,7 +320,7 @@ 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 +335,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,6 +348,9 @@ 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) diff --git a/grub-core/gfxmenu/gui_string_util.c b/grub-core/gfxmenu/gui_string_util.c index a9a415e31..ba1e1eab3 100644 --- a/grub-core/gfxmenu/gui_string_util.c +++ b/grub-core/gfxmenu/gui_string_util.c @@ -55,7 +55,7 @@ canonicalize_path (const char *path) if (*p == '/') components++; - char **path_array = grub_malloc (components * sizeof (*path_array)); + char **path_array = grub_calloc (components, sizeof (*path_array)); if (! path_array) return 0; diff --git a/grub-core/gfxmenu/theme_loader.c b/grub-core/gfxmenu/theme_loader.c index d6829bb5e..9eabf501a 100644 --- a/grub-core/gfxmenu/theme_loader.c +++ b/grub-core/gfxmenu/theme_loader.c @@ -419,7 +419,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); @@ -484,7 +484,7 @@ parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *pr ptr++; } - num = grub_strtoul (ptr, (char **) &ptr, 0); + num = grub_strtoul (ptr, &ptr, 0); if (grub_errno) return grub_errno; if (sig) diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c index ad5e82b81..e02eba8b0 100644 --- a/grub-core/gfxmenu/view.c +++ b/grub-core/gfxmenu/view.c @@ -218,7 +218,7 @@ redraw_timeouts (struct grub_gfxmenu_view *view) } } -void +void grub_gfxmenu_print_timeout (int timeout, void *data) { struct grub_gfxmenu_view *view = data; @@ -233,7 +233,7 @@ grub_gfxmenu_print_timeout (int timeout, void *data) redraw_timeouts (view); } -void +void grub_gfxmenu_clear_timeout (void *data) { struct grub_gfxmenu_view *view = data; @@ -401,7 +401,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; @@ -423,7 +423,7 @@ grub_gfxmenu_draw_terminal_box (void) term_box->set_content_size (term_box, term_view->terminal_rect.width, term_view->terminal_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)); @@ -553,10 +553,18 @@ init_terminal (grub_gfxmenu_view_t view) 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; - struct grub_video_bitmap *scaled_bitmap; if (view->desktop_image_scale_method == GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH) grub_video_bitmap_create_scaled (&scaled_bitmap, diff --git a/grub-core/gfxmenu/widget-box.c b/grub-core/gfxmenu/widget-box.c index b60602889..470597ded 100644 --- a/grub-core/gfxmenu/widget-box.c +++ b/grub-core/gfxmenu/widget-box.c @@ -303,10 +303,10 @@ grub_gfxmenu_create_box (const char *pixmaps_prefix, box->content_height = 0; box->raw_pixmaps = (struct grub_video_bitmap **) - grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); + grub_calloc (BOX_NUM_PIXMAPS, sizeof (struct grub_video_bitmap *)); box->scaled_pixmaps = (struct grub_video_bitmap **) - grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); + grub_calloc (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. */ diff --git a/grub-core/gmodule.pl.in b/grub-core/gmodule.pl.in deleted file mode 100644 index 78aa1e64e..000000000 --- a/grub-core/gmodule.pl.in +++ /dev/null @@ -1,30 +0,0 @@ -### -### Generate GDB commands, that load symbols for specified module, -### with proper section relocations. See .gdbinit -### -### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $ -### Lubomir Kundrak -### - -use strict; - -while (<>) { - my ($name, %sections) = split; - - print "add-symbol-file $name.module"; - - open (READELF, "readelf -S $name.mod |") or die; - while () { - /\[\s*(\d+)\]\s+(\.\S+)/ or next; - - if ($2 eq '.text') { - print " $sections{$1}"; - next; - } - - print " -s $2 $sections{$1}" - if ($sections{$1} ne '0x0' and $sections{$1} ne ''); - }; - close (READELF); - print "\n"; -} diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 6208a9763..cb7eb1fe3 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -366,6 +366,10 @@ 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[] = @@ -377,10 +381,14 @@ static ush mask_bits[] = #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) { + grub_ssize_t bytes_read; if (gzio->mem_input) { if (gzio->mem_input_off < gzio->mem_input_size) @@ -393,7 +401,16 @@ get_byte (grub_gzio_t gzio) || gzio->inbuf_d == INBUFSIZ)) { gzio->inbuf_d = 0; - grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ); + 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; + } } return gzio->inbuf[gzio->inbuf_d++]; @@ -447,7 +464,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; /* table entry for structure assignment */ + struct huft r = {0}; /* 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) */ @@ -507,6 +524,7 @@ 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 @@ -554,7 +572,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_zalloc ((z + 1) * sizeof (struct huft)); + q = (struct huft *) grub_calloc (z + 1, sizeof (struct huft)); if (! q) { if (h) @@ -588,11 +606,18 @@ 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 + else if (*p < N_MAX) { 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); @@ -669,7 +694,14 @@ inflate_codes_in_window (grub_gzio_t gzio) { if (! gzio->code_state) { - NEEDBITS ((unsigned) gzio->bl); + + if (gzio->tl == NULL) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl"); + return 1; + } + + NEEDBITS ((unsigned) gzio->bl); RETURN1IFERROR; if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16) do { @@ -681,7 +713,7 @@ inflate_codes_in_window (grub_gzio_t gzio) } DUMPBITS (t->b); e -= 16; - NEEDBITS (e); + NEEDBITS (e); RETURN1IFERROR; } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); DUMPBITS (t->b); @@ -703,12 +735,18 @@ inflate_codes_in_window (grub_gzio_t gzio) } /* get length of block to copy */ - NEEDBITS (e); + NEEDBITS (e); RETURN1IFERROR; 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); + NEEDBITS ((unsigned) gzio->bd); RETURN1IFERROR; if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16) do { @@ -720,12 +758,12 @@ inflate_codes_in_window (grub_gzio_t gzio) } DUMPBITS (t->b); e -= 16; - NEEDBITS (e); + NEEDBITS (e); RETURN1IFERROR; } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); DUMPBITS (t->b); - NEEDBITS (e); + NEEDBITS (e); RETURN1IFERROR; d = w - t->v.n - ((unsigned) b & mask_bits[e]); DUMPBITS (e); gzio->code_state++; @@ -794,10 +832,10 @@ init_stored_block (grub_gzio_t gzio) DUMPBITS (k & 7); /* get the length and its complement */ - NEEDBITS (16); + NEEDBITS (16); RETURNIFERROR; gzio->block_len = ((unsigned) b & 0xffff); DUMPBITS (16); - NEEDBITS (16); + NEEDBITS (16); RETURNIFERROR; if (gzio->block_len != (int) ((~b) & 0xffff)) grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "the length of a stored block does not match"); @@ -879,13 +917,13 @@ init_dynamic_block (grub_gzio_t gzio) k = gzio->bk; /* read in table lengths */ - NEEDBITS (5); + NEEDBITS (5); RETURNIFERROR; nl = 257 + ((unsigned) b & 0x1f); /* number of literal/length codes */ DUMPBITS (5); - NEEDBITS (5); + NEEDBITS (5); RETURNIFERROR; nd = 1 + ((unsigned) b & 0x1f); /* number of distance codes */ DUMPBITS (5); - NEEDBITS (4); + NEEDBITS (4); RETURNIFERROR; nb = 4 + ((unsigned) b & 0xf); /* number of bit length codes */ DUMPBITS (4); if (nl > 286 || nd > 30) @@ -897,7 +935,7 @@ init_dynamic_block (grub_gzio_t gzio) /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { - NEEDBITS (3); + NEEDBITS (3); RETURNIFERROR; ll[bitorder[j]] = (unsigned) b & 7; DUMPBITS (3); } @@ -917,9 +955,16 @@ 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); + NEEDBITS ((unsigned) gzio->bl); GOTOFAILIFERROR; j = (gzio->td = gzio->tl + ((unsigned) b & m))->b; DUMPBITS (j); j = gzio->td->v.n; @@ -927,26 +972,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); + NEEDBITS (2); GOTOFAILIFERROR; j = 3 + ((unsigned) b & 3); DUMPBITS (2); if ((unsigned) i + j > n) { grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); - return; + goto fail; } while (j--) ll[i++] = l; } else if (j == 17) /* 3 to 10 zero length codes */ { - NEEDBITS (3); + NEEDBITS (3); GOTOFAILIFERROR; j = 3 + ((unsigned) b & 7); DUMPBITS (3); if ((unsigned) i + j > n) { grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); - return; + goto fail; } while (j--) ll[i++] = 0; @@ -955,13 +1000,13 @@ init_dynamic_block (grub_gzio_t gzio) else /* j == 18: 11 to 138 zero length codes */ { - NEEDBITS (7); + NEEDBITS (7); GOTOFAILIFERROR; j = 11 + ((unsigned) b & 0x7f); DUMPBITS (7); if ((unsigned) i + j > n) { grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found"); - return; + goto fail; } while (j--) ll[i++] = 0; @@ -982,6 +1027,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, "failed in building a Huffman code table"); return; @@ -991,6 +1037,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, "failed in building a Huffman code table"); return; @@ -999,6 +1046,12 @@ 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; } @@ -1013,12 +1066,12 @@ get_new_block (grub_gzio_t gzio) k = gzio->bk; /* read in last block bit */ - NEEDBITS (1); + NEEDBITS (1); RETURNIFERROR; gzio->last_block = (int) b & 1; DUMPBITS (1); /* read in block type */ - NEEDBITS (2); + NEEDBITS (2); RETURNIFERROR; gzio->block_type = (unsigned) b & 3; DUMPBITS (2); @@ -1152,9 +1205,10 @@ initialize_tables (grub_gzio_t gzio) } -/* 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. */ +/* + * 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) { @@ -1216,7 +1270,7 @@ static int test_zlib_header (grub_gzio_t gzio) { grub_uint8_t cmf, flg; - + cmf = get_byte (gzio); flg = get_byte (gzio); diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index 30144857d..a7d442543 100644 --- a/grub-core/io/lzopio.c +++ b/grub-core/io/lzopio.c @@ -125,8 +125,6 @@ read_block_header (struct grub_lzopio *lzopio) sizeof (lzopio->block.ucheck)) != sizeof (lzopio->block.ucheck)) return -1; - - lzopio->block.ucheck = lzopio->block.ucheck; } /* Read checksum of compressed data. */ @@ -143,8 +141,6 @@ read_block_header (struct grub_lzopio *lzopio) sizeof (lzopio->block.ccheck)) != sizeof (lzopio->block.ccheck)) return -1; - - lzopio->block.ccheck = lzopio->block.ccheck; } } diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c index 516c4dfca..63d8cda6a 100644 --- a/grub-core/io/xzio.c +++ b/grub-core/io/xzio.c @@ -283,7 +283,7 @@ grub_xzio_read (grub_file_t file, char *buf, grub_size_t len) { grub_off_t new_offset = current_offset + xzio->buf.out_pos; - + if (file->offset <= new_offset) /* Store first chunk of data in buffer. */ { diff --git a/grub-core/kern/acpi.c b/grub-core/kern/acpi.c index 5746ac00c..8ff0835d5 100644 --- a/grub-core/kern/acpi.c +++ b/grub-core/kern/acpi.c @@ -1,4 +1,4 @@ -/* +/* * GRUB -- GRand Unified Bootloader * Copyright (C) 2012 Free Software Foundation, Inc. * @@ -19,6 +19,7 @@ #include #include #include +#include #include /* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */ @@ -50,6 +51,10 @@ grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig) 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; @@ -70,10 +75,14 @@ grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig) return 0; ptr = (grub_unaligned_uint64_t *) (xsdt + 1); - s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t); + 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; @@ -85,35 +94,42 @@ grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig) return 0; } -struct grub_acpi_fadt * -grub_acpi_find_fadt (void) +void * +grub_acpi_find_table (const char *sig) { - struct grub_acpi_fadt *fadt = 0; + 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) - fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv1->rsdt_addr, - GRUB_ACPI_FADT_SIGNATURE); - if (fadt) - return fadt; + 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) - fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv2->rsdpv1.rsdt_addr, - GRUB_ACPI_FADT_SIGNATURE); - if (fadt) - return fadt; if (rsdpv2 #if GRUB_CPU_SIZEOF_VOID_P != 8 && !(rsdpv2->xsdt_addr >> 32) #endif ) - fadt = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv2->xsdt_addr, - GRUB_ACPI_FADT_SIGNATURE); - if (fadt) - return fadt; + 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.c b/grub-core/kern/arm/cache.c index af1c4bbf5..6c75193e4 100644 --- a/grub-core/kern/arm/cache.c +++ b/grub-core/kern/arm/cache.c @@ -93,13 +93,16 @@ probe_caches (void) grub_arch_cache_ilinesz = 8 << (cache_type & 3); type = ARCH_ARMV6; break; - case 0x80 ... 0x8f: + 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; - break; - default: - grub_fatal ("Unsupported cache type 0x%x", cache_type); } if (grub_arch_cache_dlinesz > grub_arch_cache_ilinesz) grub_arch_cache_max_linesz = grub_arch_cache_dlinesz; diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c index 06df60e2f..809f69c8c 100644 --- a/grub-core/kern/arm/efi/init.c +++ b/grub-core/kern/arm/efi/init.c @@ -34,7 +34,7 @@ grub_efi_get_time_ms (void) return tmr; } -static void +static void __grub_efi_api increment_timer (grub_efi_event_t event __attribute__ ((unused)), void *context __attribute__ ((unused))) { @@ -50,9 +50,9 @@ grub_machine_init (void) b = grub_efi_system_table->boot_services; - efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, - GRUB_EFI_TPL_CALLBACK, increment_timer, NULL, &tmr_evt); - efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); + 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); } @@ -67,8 +67,11 @@ grub_machine_fini (int flags) b = grub_efi_system_table->boot_services; - efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); - efi_call_1 (b->close_event, tmr_evt); + 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/arm64/dl.c b/grub-core/kern/arm64/dl.c index fb0337319..a2b5789a9 100644 --- a/grub-core/kern/arm64/dl.c +++ b/grub-core/kern/arm64/dl.c @@ -49,7 +49,7 @@ grub_arch_dl_check_header (void *ehdr) #pragma GCC diagnostic ignored "-Wcast-align" /* - * Unified function for both REL and RELA + * Unified function for both REL and RELA */ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, @@ -183,9 +183,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, break; default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); + { + 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); + } } } diff --git a/grub-core/kern/arm64/dl_helper.c b/grub-core/kern/arm64/dl_helper.c index e00c198db..10e3d1ec2 100644 --- a/grub-core/kern/arm64/dl_helper.c +++ b/grub-core/kern/arm64/dl_helper.c @@ -46,9 +46,9 @@ 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%llx\n", + grub_dprintf ("dl", " reloc_xxxx64 %p %c= 0x%" PRIxGRUB_INT64_T "\n", place, offset > 0 ? '+' : '-', - offset < 0 ? (long long) -(unsigned long long) offset : offset); + offset < 0 ? -offset : offset); *place &= insmask; *place |= grub_cpu_to_le32 (offset >> 2) & ~insmask; @@ -69,9 +69,9 @@ grub_arm64_set_hi21 (grub_uint32_t *place, grub_int64_t offset) grub_uint32_t val; offset >>= 12; - + val = ((offset & 3) << 29) | (((offset >> 2) & 0x7ffff) << 5); - + *place &= insmask; *place |= grub_cpu_to_le32 (val) & ~insmask; } diff --git a/grub-core/kern/arm64/efi/init.c b/grub-core/kern/arm64/efi/init.c index 6224999ec..5010caefd 100644 --- a/grub-core/kern/arm64/efi/init.c +++ b/grub-core/kern/arm64/efi/init.c @@ -57,4 +57,7 @@ grub_machine_fini (int flags) return; grub_efi_fini (); + + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) + grub_efi_memory_fini (); } diff --git a/grub-core/kern/buffer.c b/grub-core/kern/buffer.c new file mode 100644 index 000000000..a2587729c --- /dev/null +++ b/grub-core/kern/buffer.c @@ -0,0 +1,120 @@ +/* + * 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 index acd721879..5812e131c 100644 --- a/grub-core/kern/command.c +++ b/grub-core/kern/command.c @@ -17,6 +17,7 @@ * along with GRUB. If not, see . */ +#include #include #include @@ -45,7 +46,7 @@ grub_register_command_prio (const char *name, cmd->flags = 0; cmd->prio = prio; - + for (p = &grub_command_list, q = *p; q; p = &(q->next), q = q->next) { int r; @@ -77,6 +78,29 @@ grub_register_command_prio (const char *name, 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) { diff --git a/grub-core/kern/compiler-rt.c b/grub-core/kern/compiler-rt.c index a464200c6..eda689a0c 100644 --- a/grub-core/kern/compiler-rt.c +++ b/grub-core/kern/compiler-rt.c @@ -194,16 +194,6 @@ __ctzsi2 (grub_uint32_t x) #endif - -#if defined (__clang__) && !defined(GRUB_EMBED_DECOMPRESSOR) -/* clang emits references to abort(). */ -void __attribute__ ((noreturn)) -abort (void) -{ - grub_fatal ("compiler abort"); -} -#endif - #if (defined (__MINGW32__) || defined (__CYGWIN__)) void __register_frame_info (void) { @@ -431,7 +421,7 @@ __clzsi2 (grub_uint32_t val) for (; j; j >>= 1) { - if ((temp = val) >> j) + if ((temp = val >> j)) { if (j == 1) { @@ -448,7 +438,7 @@ __clzsi2 (grub_uint32_t val) } #endif -#if defined(__riscv) || defined(__sparc__) +#if defined(__mips__) || defined(__riscv) || defined(__sparc__) int __clzdi2 (grub_uint64_t val) { diff --git a/grub-core/kern/coreboot/cbtable.c b/grub-core/kern/coreboot/cbtable.c index aec63dbd1..b6d0801c1 100644 --- a/grub-core/kern/coreboot/cbtable.c +++ b/grub-core/kern/coreboot/cbtable.c @@ -62,7 +62,7 @@ signature_found: { table_header = (grub_linuxbios_table_header_t) (grub_addr_t) *(grub_uint64_t *) (table_item + 1); - goto signature_found; + goto signature_found; } if (hook (table_item, hook_data)) return 1; diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c index fc54f43f2..62d434ba9 100644 --- a/grub-core/kern/corecmd.c +++ b/grub-core/kern/corecmd.c @@ -40,7 +40,10 @@ grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)), { struct grub_env_var *env; FOR_SORTED_ENV (env) - grub_printf ("%s=%s\n", env->name, grub_env_get (env->name)); + { + val = (char *) grub_env_get (env->name); + grub_printf ("%s='%s'\n", env->name, val == NULL ? "" : val); + } return 0; } diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c index 73b8ecc0c..670e213cf 100644 --- a/grub-core/kern/device.c +++ b/grub-core/kern/device.c @@ -56,7 +56,7 @@ grub_device_open (const char *name) if (grub_net_open && grub_errno == GRUB_ERR_UNKNOWN_DEVICE) { grub_errno = GRUB_ERR_NONE; - dev->net = grub_net_open (name); + dev->net = grub_net_open (name); } if (dev->net) @@ -71,6 +71,9 @@ grub_device_open (const char *name) 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); diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c index ffb09c8ee..82e04fd00 100644 --- a/grub-core/kern/disk.c +++ b/grub-core/kern/disk.c @@ -28,6 +28,10 @@ #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; @@ -292,6 +296,10 @@ 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) @@ -341,7 +349,7 @@ grub_disk_read_small_real (grub_disk_t disk, grub_disk_addr_t sector, < (disk->total_sectors << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) { grub_err_t err; - err = (disk->dev->disk_read) (disk, transform_sector (disk, sector), + 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); @@ -376,8 +384,8 @@ grub_disk_read_small_real (grub_disk_t disk, grub_disk_addr_t sector, tmp_buf = grub_malloc (num << disk->log_sector_size); if (!tmp_buf) return grub_errno; - - if ((disk->dev->disk_read) (disk, transform_sector (disk, aligned_sector), + + if ((disk->dev->disk_read) (disk, grub_disk_to_native_sector (disk, aligned_sector), num, tmp_buf)) { grub_error_push (); @@ -402,10 +410,10 @@ grub_disk_read_small (grub_disk_t disk, grub_disk_addr_t sector, if (err) return err; if (disk->read_hook) - (disk->read_hook) (sector + (offset >> GRUB_DISK_SECTOR_BITS), - offset & (GRUB_DISK_SECTOR_SIZE - 1), - size, disk->read_hook_data); - return GRUB_ERR_NONE; + 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. */ @@ -413,6 +421,8 @@ 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) { @@ -423,12 +433,17 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, 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_err_t err; grub_size_t len; start_sector = sector & ~((grub_disk_addr_t) GRUB_DISK_CACHE_SIZE - 1); @@ -440,7 +455,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, err = grub_disk_read_small (disk, start_sector, offset + pos, len, buf); if (err) - return err; + goto error; buf = (char *) buf + len; size -= len; offset += len; @@ -453,7 +468,6 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, { char *data = NULL; grub_disk_addr_t agglomerate; - grub_err_t err; /* agglomerate read until we find a first cached entry. */ for (agglomerate = 0; agglomerate @@ -483,14 +497,14 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, { grub_disk_addr_t i; - err = (disk->dev->disk_read) (disk, transform_sector (disk, sector), + 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) - return err; - + goto error; + for (i = 0; i < agglomerate; i ++) grub_disk_cache_store (disk->dev->id, disk->id, sector + (i << GRUB_DISK_CACHE_BITS), @@ -501,11 +515,11 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, if (disk->read_hook) (disk->read_hook) (sector, 0, agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS), - disk->read_hook_data); + buf, disk->read_hook_data); sector += agglomerate << GRUB_DISK_CACHE_BITS; size -= agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS); - buf = (char *) buf + buf = (char *) buf + (agglomerate << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS)); } @@ -513,7 +527,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, { if (disk->read_hook) (disk->read_hook) (sector, 0, (GRUB_DISK_CACHE_SIZE << GRUB_DISK_SECTOR_BITS), - disk->read_hook_data); + 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); @@ -523,17 +537,20 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, /* And now read the last part. */ if (size) { - grub_err_t err; err = grub_disk_read_small (disk, sector, 0, size, buf); if (err) - return err; + goto error; } - return grub_errno; + err = grub_errno; + + error: + read_recursion_depth--; + return err; } grub_uint64_t -grub_disk_get_size (grub_disk_t disk) +grub_disk_native_sectors (grub_disk_t disk) { if (disk->partition) return grub_partition_get_len (disk->partition); diff --git a/grub-core/kern/disk_common.c b/grub-core/kern/disk_common.c index 2ca12b5f8..ab6cd0c2b 100644 --- a/grub-core/kern/disk_common.c +++ b/grub-core/kern/disk_common.c @@ -32,13 +32,14 @@ grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector, /* 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. - Treat unknown as 1EiB disk. While on it, clamp the size to 1EiB. - Just one condition is enough since GRUB_DISK_UNKNOWN_SIZE << ls is always - above 9EiB. - */ - if (total_sectors > (1ULL << 51)) - total_sectors = (1ULL << 51); + /* + * 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) @@ -49,12 +50,6 @@ grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector, return GRUB_ERR_NONE; } -static inline grub_disk_addr_t -transform_sector (grub_disk_t disk, grub_disk_addr_t sector) -{ - return sector >> (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); -} - static unsigned grub_disk_cache_get_index (unsigned long dev_id, unsigned long disk_id, grub_disk_addr_t sector) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 48eb5e7b6..de8c3aa8d 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -32,13 +32,22 @@ #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" @@ -224,33 +233,47 @@ 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; -#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) + 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)) { - tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size; - if (talign < s->sh_addralign) - talign = s->sh_addralign; + 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) +#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; - tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); - if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) - talign = GRUB_ARCH_DL_TRAMP_ALIGN; - tsize += ALIGN_UP (got, GRUB_ARCH_DL_GOT_ALIGN); - if (talign < GRUB_ARCH_DL_GOT_ALIGN) - talign = GRUB_ARCH_DL_GOT_ALIGN; + 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 @@ -267,6 +290,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) 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; @@ -279,17 +305,18 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) { void *addr; - ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign); + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign); addr = ptr; - ptr += s->sh_size; + ptr += sh_size; 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, s->sh_size); + grub_memset (addr, 0, sh_size); break; } @@ -298,18 +325,19 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) else seg->addr = 0; - seg->size = s->sh_size; + seg->size = sh_size; seg->section = i; seg->next = mod->segment; mod->segment = seg; } } -#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) - ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); +#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, GRUB_ARCH_DL_GOT_ALIGN); + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, got_align); mod->got = ptr; mod->gotptr = ptr; ptr += got; @@ -457,14 +485,22 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name) Be sure to understand your license obligations. */ static grub_err_t -grub_dl_check_license (Elf_Ehdr *e) +grub_dl_check_license (grub_dl_t mod, Elf_Ehdr *e) { Elf_Shdr *s = grub_dl_find_section (e, ".module_license"); - if (s && (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)) + + 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"); + + return grub_error (GRUB_ERR_BAD_MODULE, + "incompatible license in module %.63s: %.63s", mod->name, + (char *) e + s->sh_offset); } static grub_err_t @@ -475,7 +511,7 @@ grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e) s = grub_dl_find_section (e, ".modname"); if (!s) 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; @@ -521,7 +557,7 @@ grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) return GRUB_ERR_NONE; } -int +grub_uint64_t grub_dl_ref (grub_dl_t mod) { grub_dl_dep_t dep; @@ -532,10 +568,13 @@ grub_dl_ref (grub_dl_t mod) for (dep = mod->dep; dep; dep = dep->next) grub_dl_ref (dep->mod); - return ++mod->ref_count; + if (grub_add (mod->ref_count, 1, &mod->ref_count)) + grub_fatal ("Module reference count overflow"); + + return mod->ref_count; } -int +grub_uint64_t grub_dl_unref (grub_dl_t mod) { grub_dl_dep_t dep; @@ -546,7 +585,19 @@ grub_dl_unref (grub_dl_t mod) for (dep = mod->dep; dep; dep = dep->next) grub_dl_unref (dep->mod); - return --mod->ref_count; + 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 @@ -572,6 +623,9 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) grub_dl_segment_t seg; grub_err_t err; + 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) @@ -591,6 +645,94 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) 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) +{ + 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 + + 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 (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; +} +#else +static grub_err_t +grub_dl_set_mem_attrs (grub_dl_t mod __attribute__ ((unused)), void *ehdr __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} +#endif + /* Load a module from core memory. */ grub_dl_t grub_dl_load_core_noinit (void *addr, grub_size_t size) @@ -632,12 +774,13 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) constitutes linking) and GRUB core being licensed under GPLv3+. Be sure to understand your license obligations. */ - if (grub_dl_check_license (e) - || grub_dl_resolve_name (mod, e) + 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_relocate_symbols (mod, e) + || grub_dl_set_mem_attrs (mod, e)) { mod->fini = 0; grub_dl_unload (mod); @@ -794,23 +937,3 @@ 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_t p = grub_dl_head; - - while (p) - { - if (grub_dl_unload (p)) - { - p = grub_dl_head; - continue; - } - - p = p->next; - } -} diff --git a/grub-core/kern/efi/acpi.c b/grub-core/kern/efi/acpi.c index 74f8cd1a9..828e6dbb2 100644 --- a/grub-core/kern/efi/acpi.c +++ b/grub-core/kern/efi/acpi.c @@ -18,42 +18,20 @@ */ #include -#include #include -#include struct grub_acpi_rsdp_v10 * grub_machine_acpi_get_rsdpv1 (void) { - unsigned i; - static grub_efi_packed_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; + static grub_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; - for (i = 0; i < grub_efi_system_table->num_table_entries; i++) - { - grub_efi_packed_guid_t *guid = - &grub_efi_system_table->configuration_table[i].vendor_guid; - - if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_packed_guid_t))) - return (struct grub_acpi_rsdp_v10 *) - grub_efi_system_table->configuration_table[i].vendor_table; - } - return 0; + return (struct grub_acpi_rsdp_v10 *) grub_efi_find_configuration_table (&acpi_guid); } struct grub_acpi_rsdp_v20 * grub_machine_acpi_get_rsdpv2 (void) { - unsigned i; - static grub_efi_packed_guid_t acpi20_guid = GRUB_EFI_ACPI_20_TABLE_GUID; + static grub_guid_t acpi20_guid = GRUB_EFI_ACPI_20_TABLE_GUID; - for (i = 0; i < grub_efi_system_table->num_table_entries; i++) - { - grub_efi_packed_guid_t *guid = - &grub_efi_system_table->configuration_table[i].vendor_guid; - - if (! grub_memcmp (guid, &acpi20_guid, sizeof (grub_efi_packed_guid_t))) - return (struct grub_acpi_rsdp_v20 *) - grub_efi_system_table->configuration_table[i].vendor_table; - } - return 0; + return (struct grub_acpi_rsdp_v20 *) grub_efi_find_configuration_table (&acpi20_guid); } diff --git a/grub-core/kern/efi/debug.c b/grub-core/kern/efi/debug.c new file mode 100644 index 000000000..5d2ab1a36 --- /dev/null +++ b/grub-core/kern/efi/debug.c @@ -0,0 +1,38 @@ +/* + * 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 index 6e1ceb905..b93ae3aba 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -35,18 +35,19 @@ 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; +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_efi_guid_t *protocol, void *registration) +grub_efi_locate_protocol (grub_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); + status = grub_efi_system_table->boot_services->locate_protocol (protocol, + registration, + &interface); if (status != GRUB_EFI_SUCCESS) return 0; @@ -58,7 +59,7 @@ grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration) from the heap. */ grub_efi_handle_t * grub_efi_locate_handle (grub_efi_locate_search_type_t search_type, - grub_efi_guid_t *protocol, + grub_guid_t *protocol, void *search_key, grub_efi_uintn_t *num_handles) { @@ -72,7 +73,7 @@ grub_efi_locate_handle (grub_efi_locate_search_type_t search_type, return 0; b = grub_efi_system_table->boot_services; - status = efi_call_5 (b->locate_handle, search_type, protocol, search_key, + status = b->locate_handle (search_type, protocol, search_key, &buffer_size, buffer); if (status == GRUB_EFI_BUFFER_TOO_SMALL) { @@ -81,7 +82,7 @@ grub_efi_locate_handle (grub_efi_locate_search_type_t search_type, if (! buffer) return 0; - status = efi_call_5 (b->locate_handle, search_type, protocol, search_key, + status = b->locate_handle (search_type, protocol, search_key, &buffer_size, buffer); } @@ -97,7 +98,7 @@ grub_efi_locate_handle (grub_efi_locate_search_type_t search_type, void * grub_efi_open_protocol (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, + grub_guid_t *protocol, grub_efi_uint32_t attributes) { grub_efi_boot_services_t *b; @@ -105,18 +106,26 @@ grub_efi_open_protocol (grub_efi_handle_t handle, 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); + 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) { @@ -129,12 +138,12 @@ grub_efi_set_text_mode (int on) already in text mode. */ return 1; - if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS) + 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 (efi_call_2 (c->set_mode, c, new_mode) != GRUB_EFI_SUCCESS) + if (c->set_mode (c, new_mode) != GRUB_EFI_SUCCESS) return 0; return 1; @@ -143,7 +152,7 @@ grub_efi_set_text_mode (int on) void grub_efi_stall (grub_efi_uintn_t microseconds) { - efi_call_1 (grub_efi_system_table->boot_services->stall, microseconds); + grub_efi_system_table->boot_services->stall (microseconds); } grub_efi_loaded_image_t * @@ -157,9 +166,11 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle) void grub_reboot (void) { - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - efi_call_4 (grub_efi_system_table->runtime_services->reset_system, - GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); + 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 (;;) ; } @@ -167,8 +178,8 @@ void grub_exit (void) { grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - efi_call_4 (grub_efi_system_table->boot_services->exit, - grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0); + grub_efi_system_table->boot_services->exit (grub_efi_image_handle, + GRUB_EFI_SUCCESS, 0, 0); for (;;) ; } @@ -182,8 +193,8 @@ grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, 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); + status = r->set_virtual_address_map (memory_map_size, descriptor_size, + descriptor_version, virtual_map); if (status == GRUB_EFI_SUCCESS) return GRUB_ERR_NONE; @@ -192,29 +203,21 @@ grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, } grub_err_t -grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, - void *data, grub_size_t datasize) +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_size_t len, len16; - len = grub_strlen (var); - len16 = len * GRUB_MAX_UTF16_PER_UTF8; - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); - if (!var16) + grub_utf8_to_utf16_alloc (var, &var16, NULL); + + if (var16 == NULL) return grub_errno; - len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); - var16[len16] = 0; r = grub_efi_system_table->runtime_services; - status = efi_call_5 (r->set_variable, var16, guid, - (GRUB_EFI_VARIABLE_NON_VOLATILE - | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS - | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), - datasize, data); + status = r->set_variable (var16, guid, attributes, datasize, data); grub_free (var16); if (status == GRUB_EFI_SUCCESS) return GRUB_ERR_NONE; @@ -222,55 +225,94 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); } -void * -grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - grub_size_t *datasize_out) +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; - grub_size_t len, len16; + *data_out = NULL; *datasize_out = 0; - len = grub_strlen (var); - len16 = len * GRUB_MAX_UTF16_PER_UTF8; - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); - if (!var16) - return NULL; - len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); - var16[len16] = 0; + grub_utf8_to_utf16_alloc (var, &var16, NULL); + if (var16 == NULL) + return grub_errno; r = grub_efi_system_table->runtime_services; - status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, NULL); + status = r->get_variable (var16, guid, NULL, &datasize, NULL); if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize) { grub_free (var16); - return NULL; + return status; } data = grub_malloc (datasize); if (!data) { grub_free (var16); - return NULL; + return GRUB_EFI_OUT_OF_RESOURCES; } - status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data); + status = r->get_variable (var16, guid, attributes, &datasize, data); grub_free (var16); if (status == GRUB_EFI_SUCCESS) { + *data_out = data; *datasize_out = datasize; - return data; + return status; } grub_free (data); - return NULL; + 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" @@ -278,10 +320,11 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, /* 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_modules_addr (void) +grub_efi_section_addr (const char *section_name) { grub_efi_loaded_image_t *image; - struct grub_pe32_header *header; + 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; @@ -293,7 +336,10 @@ grub_efi_modules_addr (void) return 0; header = image->image_base; - coff_header = &(header->coff_header); + 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) @@ -303,18 +349,28 @@ grub_efi_modules_addr (void) i < coff_header->num_sections; i++, section++) { - if (grub_strcmp (section->name, "mods") == 0) + if (grub_strcmp (section->name, section_name) == 0) break; } if (i == coff_header->num_sections) - return 0; + { + 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 (info->magic != GRUB_MODULE_MAGIC) - return 0; + 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; } @@ -332,7 +388,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) dp = dp0; - while (1) + while (dp) { grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); @@ -342,9 +398,15 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) { - grub_efi_uint16_t len; - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) - / sizeof (grub_efi_char16_t)); + 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; } @@ -360,7 +422,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) if (!name) return NULL; - while (1) + while (dp) { grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); @@ -376,14 +438,22 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) *p++ = '/'; - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) - / sizeof (grub_efi_char16_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); + 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_malloc (len * sizeof (*dup_name)); + dup_name = grub_calloc (len, sizeof (*dup_name)); if (!dup_name) { grub_free (name); @@ -452,7 +522,26 @@ grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp) ; p = GRUB_EFI_NEXT_DEVICE_PATH (p)) { - total_size += GRUB_EFI_DEVICE_PATH_LENGTH (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; } @@ -469,20 +558,7 @@ 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(%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x)[%x: ", - type, - (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], - vendor_data_len); + grub_printf ("/%sVendor(%pG)[%x: ", type, &vendor->vendor_guid, vendor_data_len); if (vendor->header.length > sizeof (*vendor)) { grub_uint32_t i; @@ -497,7 +573,7 @@ dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor) void grub_efi_print_device_path (grub_efi_device_path_t *dp) { - while (1) + 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); @@ -768,6 +844,13 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) 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", @@ -846,18 +929,7 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) { grub_efi_protocol_device_path_t *proto = (grub_efi_protocol_device_path_t *) dp; - 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]); + grub_printf ("/Protocol(%pG)",&proto->guid); } break; default: @@ -909,7 +981,10 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, /* Return non-zero. */ return 1; - while (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; @@ -945,5 +1020,32 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, 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 index 30100c61c..15a495a34 100644 --- a/grub-core/kern/efi/fdt.c +++ b/grub-core/kern/efi/fdt.c @@ -23,21 +23,13 @@ void * grub_efi_get_firmware_fdt (void) { - grub_efi_configuration_table_t *tables; - grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; - void *firmware_fdt = NULL; - unsigned int i; - - /* Look for FDT in UEFI config tables. */ - tables = grub_efi_system_table->configuration_table; - - for (i = 0; i < grub_efi_system_table->num_table_entries; i++) - if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0) - { - firmware_fdt = tables[i].vendor_table; - grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt); - break; - } + 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 index 3dfdf2d22..1637077e1 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -19,19 +19,85 @@ #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_modules_addr (); + grub_modbase = grub_efi_section_addr ("mods"); /* First of all, initialize the console so that GRUB can display messages. */ grub_console_init (); @@ -39,13 +105,24 @@ grub_efi_init (void) /* Initialize the memory management system. */ grub_efi_mm_init (); - efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer, - 0, 0, 0, NULL); + /* + * 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, +void (*grub_efi_net_config) (grub_efi_handle_t hnd, char **device, char **path); @@ -80,5 +157,4 @@ grub_efi_fini (void) { grub_efidisk_fini (); grub_console_fini (); - grub_efi_memory_fini (); } diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index b02fab1b1..df238b165 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -38,9 +38,8 @@ a multiplier of 4KB. */ #define MEMORY_MAP_SIZE 0x3000 -/* The minimum and maximum heap size for GRUB itself. */ -#define MIN_HEAP_SIZE 0x100000 -#define MAX_HEAP_SIZE (1600 * 0x100000) +/* 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; @@ -70,8 +69,8 @@ grub_efi_store_alloc (grub_efi_physical_address_t address, grub_efi_status_t status; b = grub_efi_system_table->boot_services; - status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, - sizeof(*alloc), (void**)&alloc); + status = b->allocate_pool (GRUB_EFI_LOADER_DATA, + sizeof(*alloc), (void**)&alloc); if (status == GRUB_EFI_SUCCESS) { @@ -96,8 +95,10 @@ grub_efi_drop_alloc (grub_efi_physical_address_t address, for (eap = NULL, ea = efi_allocated_memory; ea; eap = ea, ea = ea->next) { - if (ea->address != address || ea->pages != pages) - continue; + 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) @@ -106,7 +107,7 @@ grub_efi_drop_alloc (grub_efi_physical_address_t address, efi_allocated_memory = ea->next; /* Then free the memory backing it. */ - efi_call_1 (b->free_pool, ea); + b->free_pool (ea); /* And leave, we're done. */ break; @@ -125,22 +126,38 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, /* Limit the memory access to less than 4GB for 32-bit platforms. */ if (address > GRUB_EFI_MAX_USABLE_ADDRESS) - return 0; + { + 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 = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); + status = b->allocate_pages (alloctype, memtype, pages, &address); if (status != GRUB_EFI_SUCCESS) - return 0; + { + 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 = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); - grub_efi_free_pages (0, pages); + status = b->allocate_pages (alloctype, memtype, pages, &address); + b->free_pages (0, pages); if (status != GRUB_EFI_SUCCESS) - return 0; + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + return NULL; + } } grub_efi_store_alloc (address, pages); @@ -173,7 +190,7 @@ grub_efi_free_pages (grub_efi_physical_address_t address, grub_efi_boot_services_t *b; b = grub_efi_system_table->boot_services; - efi_call_2 (b->free_pages, address, pages); + b->free_pages (address, pages); grub_efi_drop_alloc (address, pages); } @@ -248,22 +265,24 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, &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 = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, - finish_key); + 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; @@ -278,6 +297,12 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, 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 (); @@ -328,15 +353,24 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size, if (grub_efi_is_finished) { int ret = 1; - if (*memory_map_size < finish_mmap_size) + + if (memory_map != NULL) { - grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); - ret = 0; + 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 { - grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); - ret = 1; + /* + * 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) @@ -357,7 +391,7 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size, descriptor_size = &size; b = grub_efi_system_table->boot_services; - status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key, + 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); @@ -453,29 +487,13 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, 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 +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) + grub_efi_uint64_t required_pages, + unsigned int flags) { grub_efi_memory_descriptor_t *desc; @@ -489,6 +507,10 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, 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); @@ -497,11 +519,11 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, addr = grub_efi_allocate_pages_real (start, pages, GRUB_EFI_ALLOCATE_ADDRESS, - GRUB_EFI_LOADER_CODE); + GRUB_EFI_LOADER_CODE); if (! addr) - grub_fatal ("cannot allocate conventional memory %p with %u pages", - (void *) ((grub_addr_t) start), - (unsigned) pages); + 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)); @@ -511,7 +533,11 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, } if (required_pages > 0) - grub_fatal ("too little memory"); + 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 @@ -549,23 +575,24 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map, } #endif -void -grub_efi_mm_init (void) +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_efi_uint64_t total_pages; - grub_efi_uint64_t required_pages; + grub_err_t err; int mm_status; /* Prepare a memory region to store two memory maps. */ - memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + alloc_size = 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE); + memory_map = grub_efi_allocate_any_pages (alloc_size); if (! memory_map) - grub_fatal ("cannot allocate memory"); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory for memory map"); /* Obtain descriptors for available memory. */ map_size = MEMORY_MAP_SIZE; @@ -574,23 +601,22 @@ grub_efi_mm_init (void) if (mm_status == 0) { - grub_efi_free_pages - ((grub_efi_physical_address_t) ((grub_addr_t) memory_map), - 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + 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; - memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (map_size)); + alloc_size = 2 * BYTES_TO_PAGES (map_size); + memory_map = grub_efi_allocate_any_pages (alloc_size); if (! memory_map) - grub_fatal ("cannot allocate memory"); + 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) - grub_fatal ("cannot get memory map"); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "error fetching memory map from EFI"); memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); @@ -599,22 +625,17 @@ grub_efi_mm_init (void) 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); + 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. */ @@ -630,11 +651,21 @@ grub_efi_mm_init (void) #endif /* Release the memory maps. */ - grub_efi_free_pages ((grub_addr_t) memory_map, - 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) memory_map, alloc_size); + + return GRUB_ERR_NONE; } -#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) +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) { @@ -664,3 +695,112 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) 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 new file mode 100644 index 000000000..8d3e41360 --- /dev/null +++ b/grub-core/kern/efi/sb.c @@ -0,0 +1,238 @@ +/* + * 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 index 9d7149b38..077a8500c 100644 --- a/grub-core/kern/elf.c +++ b/grub-core/kern/elf.c @@ -167,11 +167,17 @@ grub_elf_open (const char *name, enum grub_file_type type) #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" @@ -185,11 +191,17 @@ grub_elf_open (const char *name, enum grub_file_type type) #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 */ @@ -203,10 +215,16 @@ grub_elf_open (const char *name, enum grub_file_type type) #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 index 1859d1880..aabf4b9d7 100644 --- a/grub-core/kern/elfXX.c +++ b/grub-core/kern/elfXX.c @@ -205,3 +205,104 @@ grub_elfXX_check_endianess_and_bswap_ehdr (grub_elf_t elf) 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 index 166885870..8cb4608c3 100644 --- a/grub-core/kern/emu/argp_common.c +++ b/grub-core/kern/emu/argp_common.c @@ -17,8 +17,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #pragma GCC diagnostic ignored "-Wmissing-prototypes" #pragma GCC diagnostic ignored "-Wmissing-declarations" diff --git a/grub-core/kern/emu/cache_s.S b/grub-core/kern/emu/cache_s.S index 2245cddc3..6885ffd69 100644 --- a/grub-core/kern/emu/cache_s.S +++ b/grub-core/kern/emu/cache_s.S @@ -2,6 +2,11 @@ #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__) diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index e9ec680cd..0e6eebdc8 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -538,7 +538,7 @@ read_device_map (const char *dev_map) map[drive].device = grub_canonicalize_file_name (p); if (! map[drive].device) map[drive].device = xstrdup (p); - + if (!map[drive].drive) { char c; @@ -615,7 +615,7 @@ static char * grub_util_path_concat_real (size_t n, int ext, va_list ap) { size_t totlen = 0; - char **l = xmalloc ((n + ext) * sizeof (l[0])); + char **l = xcalloc (n + ext, sizeof (l[0])); char *r, *p, *pi; size_t i; int first = 1; diff --git a/grub-core/kern/emu/hostfs.c b/grub-core/kern/emu/hostfs.c index cb532105e..ccbe13f98 100644 --- a/grub-core/kern/emu/hostfs.c +++ b/grub-core/kern/emu/hostfs.c @@ -122,7 +122,7 @@ grub_hostfs_open (struct grub_file *file, const char *name) return grub_errno; } - data->f = f; + data->f = f; file->data = data; diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 425bb9603..8a70bd7d6 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include @@ -55,7 +55,7 @@ static jmp_buf main_env; /* Store the prefix specified by an argument. */ -static char *root_dev = NULL, *dir = NULL; +static char *root_dev = NULL, *dir = NULL, *tpm_dev = NULL; grub_addr_t grub_modbase = 0; @@ -107,6 +107,8 @@ static struct argp_option options[] = { 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 } }; @@ -164,6 +166,13 @@ argp_parser (int key, char *arg, struct argp_state *state) 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: { @@ -194,7 +203,7 @@ int main (int argc, char *argv[]) { struct arguments arguments = - { + { .dev_map = DEFAULT_DEVICE_MAP, .hold = 0, .mem_disk = 0, @@ -272,6 +281,9 @@ main (int argc, char *argv[]) dir = xstrdup (dir); + if (tpm_dev) + grub_util_tpm_open (tpm_dev); + /* Start GRUB! */ if (setjmp (main_env) == 0) grub_main (); @@ -279,6 +291,7 @@ main (int argc, char *argv[]) grub_fini_all (); grub_hostfs_fini (); grub_host_fini (); + grub_util_tpm_close (); grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c index 65db79baa..1db24fde7 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -39,6 +41,9 @@ #include int verbosity; +int kexecute; + +static int grub_util_tpm_fd = -1; void grub_util_warn (const char *fmt, ...) @@ -82,7 +87,19 @@ grub_util_error (const char *fmt, ...) vfprintf (stderr, fmt, ap); va_end (ap); fprintf (stderr, ".\n"); - exit (1); + 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 * @@ -123,16 +140,16 @@ xstrdup (const char *str) #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 @@ -141,6 +158,9 @@ xasprintf (const char *fmt, ...) void grub_exit (void) { +#if defined (GRUB_KERNEL) + grub_reboot (); +#endif exit (1); } #endif @@ -168,7 +188,7 @@ grub_util_get_image_size (const char *path) 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)); @@ -202,3 +222,62 @@ grub_util_load_image (const char *path, char *buf) 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 index f262e95e3..4d1046a21 100644 --- a/grub-core/kern/emu/mm.c +++ b/grub-core/kern/emu/mm.c @@ -25,6 +25,16 @@ #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) { @@ -50,7 +60,8 @@ grub_zalloc (grub_size_t size) void grub_free (void *ptr) { - free (ptr); + if (ptr) + free (ptr); } void * diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c index c40862642..764068896 100644 --- a/grub-core/kern/env.c +++ b/grub-core/kern/env.c @@ -144,6 +144,19 @@ 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) { @@ -226,12 +239,12 @@ grub_env_export (const char *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/file.c b/grub-core/kern/file.c index 58454458c..6e7efe89a 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -25,6 +25,7 @@ #include #include #include +#include void (*EXPORT_VAR (grub_grubnet_fini)) (void); @@ -66,6 +67,9 @@ grub_file_open (const char *name, enum grub_file_type type) const char *file_name; grub_file_filter_id_t filter; + /* Reset grub_errno before we start. */ + grub_errno = GRUB_ERR_NONE; + device_name = grub_file_get_device_name (name); if (grub_errno) goto fail; @@ -79,6 +83,7 @@ grub_file_open (const char *name, enum grub_file_type type) device = grub_device_open (device_name); grub_free (device_name); + device_name = NULL; if (! device) goto fail; @@ -110,6 +115,12 @@ grub_file_open (const char *name, enum grub_file_type type) if ((file->fs->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; @@ -131,6 +142,7 @@ grub_file_open (const char *name, enum grub_file_type type) return file; fail: + grub_free (device_name); if (device) grub_device_close (device); @@ -189,6 +201,9 @@ 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); @@ -210,9 +225,9 @@ grub_file_seek (grub_file_t file, grub_off_t offset) N_("attempt to seek outside of the file")); return -1; } - + old = file->offset; file->offset = offset; - + return old; } diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c index 2b85f4950..80d325868 100644 --- a/grub-core/kern/fs.c +++ b/grub-core/kern/fs.c @@ -75,6 +75,8 @@ grub_fs_probe (grub_device_t device) 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 (); @@ -128,17 +130,18 @@ grub_fs_probe (grub_device_t device) struct grub_fs_block { grub_disk_addr_t offset; - unsigned long length; + grub_disk_addr_t length; }; static grub_err_t grub_fs_blocklist_open (grub_file_t file, const char *name) { - char *p = (char *) name; + const char *p = 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 @@ -151,11 +154,12 @@ grub_fs_blocklist_open (grub_file_t file, const char *name) while (p); /* Allocate a block list. */ - blocks = grub_zalloc (sizeof (struct grub_fs_block) * (num + 1)); + blocks = grub_calloc (num + 1, sizeof (struct grub_fs_block)); 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++) { @@ -171,7 +175,11 @@ grub_fs_blocklist_open (grub_file_t file, const char *name) } p++; - blocks[i].length = grub_strtoul (p, &p, 0); + if (*p == '\0' || *p == ',') + blocks[i].length = max_sectors - blocks[i].offset; + else + blocks[i].length = grub_strtoul (p, &p, 0); + if (grub_errno != GRUB_ERR_NONE || blocks[i].length == 0 || (*p && *p != ',' && ! grub_isspace (*p))) @@ -181,7 +189,7 @@ grub_fs_blocklist_open (grub_file_t file, const char *name) goto fail; } - if (disk->total_sectors < blocks[i].offset + blocks[i].length) + if (max_sectors < blocks[i].offset + blocks[i].length) { grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors"); goto fail; @@ -207,12 +215,15 @@ 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) @@ -224,9 +235,12 @@ 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 (file->device->disk, p->offset + sector, offset, + if (grub_disk_read (disk, p->offset + sector, offset, size, buf) != GRUB_ERR_NONE) - return -1; + { + ret = -1; + break; + } ret += size; len -= size; @@ -236,6 +250,8 @@ 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; } diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c index 3314f027f..4fae8b571 100644 --- a/grub-core/kern/i386/coreboot/init.c +++ b/grub-core/kern/i386/coreboot/init.c @@ -77,7 +77,7 @@ heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, if (modend && begin < modend) begin = modend; - + if (end <= begin) return 0; diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index c8486548d..df6adbabb 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -18,7 +18,6 @@ #include #include -#include #include #include #include diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c index da499aba0..46476e27e 100644 --- a/grub-core/kern/i386/efi/init.c +++ b/grub-core/kern/i386/efi/init.c @@ -27,7 +27,6 @@ #include #include #include -#include void grub_machine_init (void) @@ -39,6 +38,11 @@ grub_machine_init (void) void grub_machine_fini (int flags) { - if (flags & GRUB_LOADER_FLAG_NORETURN) - grub_efi_fini (); + 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/i386/efi/tsc.c b/grub-core/kern/i386/efi/tsc.c index 4b93ba8e1..e41dc6526 100644 --- a/grub-core/kern/i386/efi/tsc.c +++ b/grub-core/kern/i386/efi/tsc.c @@ -33,7 +33,7 @@ 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 (); - efi_call_1 (grub_efi_system_table->boot_services->stall, 1000); + 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/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 245583bdb..62cf348e0 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -18,7 +18,6 @@ #include #include -#include #include #include diff --git a/grub-core/kern/i386/pc/acpi.c b/grub-core/kern/i386/pc/acpi.c index 297f5d05f..0a69eba7b 100644 --- a/grub-core/kern/i386/pc/acpi.c +++ b/grub-core/kern/i386/pc/acpi.c @@ -27,7 +27,7 @@ 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 *) 0x40e)) << 4); + ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4); ebda_len = * (grub_uint16_t *) ebda; if (! ebda_len) /* FIXME do we really need this check? */ goto scan_bios; @@ -55,7 +55,7 @@ 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 *) 0x40e)) << 4); + ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4); ebda_len = * (grub_uint16_t *) ebda; if (! ebda_len) /* FIXME do we really need this check? */ goto scan_bios; diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 27bc68b8a..326d491c5 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -191,7 +191,7 @@ extern grub_uint16_t grub_bios_via_workaround1, grub_bios_via_workaround2; static void grub_via_workaround_init (void) { - grub_uint32_t manufacturer[3], max_cpuid; + grub_uint32_t manufacturer[3], max_cpuid, proc_info; if (! grub_cpu_is_cpuid_supported ()) return; @@ -200,6 +200,15 @@ grub_via_workaround_init (void) 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"); diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c index c0c3c3585..53fcf45af 100644 --- a/grub-core/kern/i386/pc/mmap.c +++ b/grub-core/kern/i386/pc/mmap.c @@ -73,9 +73,9 @@ grub_get_ext_memsize (void) 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. + BX = memory above 16M in 64K parts. */ - + static inline grub_uint32_t grub_get_eisa_mmap (void) { @@ -114,7 +114,7 @@ grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, /* 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; @@ -127,7 +127,7 @@ grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, regs.eax = 0xe820; grub_bios_interrupt (0x15, ®s); - /* write length of buffer (zero if error) into ADDR */ + /* 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; @@ -143,7 +143,7 @@ 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_MEMORY_MACHINE_SCRATCH_ADDR; + = (struct grub_machine_mmap_entry *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); int e820_works = 0; while (1) diff --git a/grub-core/kern/i386/qemu/init.c b/grub-core/kern/i386/qemu/init.c index 271b6fbfa..08f81d25e 100644 --- a/grub-core/kern/i386/qemu/init.c +++ b/grub-core/kern/i386/qemu/init.c @@ -168,13 +168,13 @@ enable_cards (grub_pci_device_t dev, class = (grub_pci_read (addr) >> 16) & 0xffff; - if (class == GRUB_PCI_CLASS_SUBCLASS_VGA) + if (class == GRUB_PCI_CLASS_DISPLAY_VGA) cmd |= GRUB_PCI_COMMAND_IO_ENABLED | GRUB_PCI_COMMAND_MEM_ENABLED; - if (class == GRUB_PCI_CLASS_SUBCLASS_USB) + if (class == GRUB_PCI_CLASS_SERIAL_USB) return 0; - + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); grub_pci_write (addr, cmd); @@ -237,7 +237,7 @@ grub_pci_assign_addresses (void) + 4 * resources[i].bar + 4); grub_pci_write (addr, 0); } - } + } } grub_pci_iterate (enable_cards, NULL); } diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S index 998fdc756..265cdcb9d 100644 --- a/grub-core/kern/i386/realmode.S +++ b/grub-core/kern/i386/realmode.S @@ -77,7 +77,7 @@ protstack: * description. */ - .p2align 5 /* force 4-byte alignment */ + .p2align 5 /* force 32-byte alignment */ gdt: .word 0, 0 .byte 0, 0, 0, 0 diff --git a/grub-core/kern/i386/tsc_pmtimer.c b/grub-core/kern/i386/tsc_pmtimer.c index c9c361699..dd044590d 100644 --- a/grub-core/kern/i386/tsc_pmtimer.c +++ b/grub-core/kern/i386/tsc_pmtimer.c @@ -33,35 +33,88 @@ grub_pmtimer_wait_count_tsc (grub_port_t pmtimer, grub_uint16_t num_pm_ticks) { grub_uint32_t start; - grub_uint32_t last; - grub_uint32_t cur, end; + grub_uint64_t cur, end; grub_uint64_t start_tsc; grub_uint64_t end_tsc; - int num_iter = 0; + grub_uint32_t num_iter = 0; + int bad_reads = 0; - start = grub_inl (pmtimer) & 0xffffff; - last = start; + /* + * 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 = grub_inl (pmtimer) & 0xffffff; - if (cur < last) - cur |= 0x1000000; - num_iter++; + 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) { - end_tsc = grub_get_tsc (); + 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. - 50000000 TSCs is between 5 ms (10GHz) and 200 ms (250 MHz) - if after this time we still don't have 1 ms on pmtimer, then - pmtimer is broken. + + /* + * 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 & 0xffffff) == 0 && grub_get_tsc () - start_tsc > 5000000) { - return 0; - } + 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; + } } } @@ -74,15 +127,31 @@ grub_tsc_calibrate_from_pmtimer (void) fadt = grub_acpi_find_fadt (); if (!fadt) - return 0; + { + grub_dprintf ("pmtimer", "No FADT found; not using pmtimer.\n"); + return 0; + } pmtimer = fadt->pmtimer; if (!pmtimer) - return 0; + { + 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/ia64/dl.c b/grub-core/kern/ia64/dl.c index ebcf31629..db59300fe 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -136,9 +136,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, case R_IA64_LDXMOV: break; default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); + { + 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 index c60159573..05a0a68db 100644 --- a/grub-core/kern/ia64/dl_helper.c +++ b/grub-core/kern/ia64/dl_helper.c @@ -73,7 +73,7 @@ grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) case 0: val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2))); - val = (((((val & MASK20) + value) & MASK20) << 2) + val = (((((val & MASK20) + value) & MASK20) << 2) | (val & ~(MASK20 << 2))); grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2), grub_cpu_to_le32 (val)); @@ -161,9 +161,9 @@ static grub_uint8_t jump[0x20] = /* [MIB] ld8 r1=[r15] */ 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* mov b6=r16 */ - 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, + 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* br.few b6;; */ - 0x60, 0x00, 0x80, 0x00 + 0x60, 0x00, 0x80, 0x00 }; #else static const grub_uint8_t jump[0x20] = diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c index b5ecbd091..f8de85398 100644 --- a/grub-core/kern/ia64/efi/init.c +++ b/grub-core/kern/ia64/efi/init.c @@ -51,16 +51,16 @@ grub_machine_init (void) grub_efi_uintn_t idx; grub_efi_init (); - efi_call_5 (grub_efi_system_table->boot_services->create_event, - GRUB_EFI_EVT_TIMER, GRUB_EFI_TPL_CALLBACK, 0, 0, &event); + grub_efi_system_table->boot_services->create_event (GRUB_EFI_EVT_TIMER, + GRUB_EFI_TPL_CALLBACK, + 0, 0, &event); before = get_itc (); - efi_call_3 (grub_efi_system_table->boot_services->set_timer, event, - GRUB_EFI_TIMER_RELATIVE, 200000); - efi_call_3 (grub_efi_system_table->boot_services->wait_for_event, 1, - &event, &idx); + 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 (); - efi_call_1 (grub_efi_system_table->boot_services->close_event, event); + grub_efi_system_table->boot_services->close_event (event); divisor = (after - before + 5) / 20; if (divisor == 0) divisor = 800000; @@ -70,6 +70,11 @@ grub_machine_init (void) void grub_machine_fini (int flags) { - if (flags & GRUB_LOADER_FLAG_NORETURN) - grub_efi_fini (); + 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/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c index 20cbbd761..e74de3248 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/grub-core/kern/ieee1275/cmain.c @@ -49,7 +49,6 @@ 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]; @@ -124,6 +123,14 @@ grub_ieee1275_find_options (void) 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) @@ -189,21 +196,9 @@ grub_ieee1275_find_options (void) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM); grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF); - } - - if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom) - || ! grub_ieee1275_finddevice ("/boot-rom", &bootrom)) - { - rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0); - if (rc >= 0 && !grub_strncmp (tmp, "PPC Open Hack'Ware", - sizeof ("PPC Open Hack'Ware") - 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); - } +#if defined(__powerpc__) + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_POWER_KVM); +#endif } } diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c index 86f81a3c4..36ca2dbfc 100644 --- a/grub-core/kern/ieee1275/ieee1275.c +++ b/grub-core/kern/ieee1275/ieee1275.c @@ -306,7 +306,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,9 +398,6 @@ 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; @@ -593,6 +590,9 @@ 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; } diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index d483e35ee..a5586f85b 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c @@ -17,6 +17,8 @@ * along with GRUB. If not, see . */ +#include /* offsetof() */ + #include #include #include @@ -44,24 +46,29 @@ #ifdef __sparc__ #include #endif +#if defined(__powerpc__) || defined(__i386__) +#include +#endif -/* 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 */ +/* 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 +#else /* __powerpc__ */ #define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024) #endif -/* If possible, we will avoid claiming heap above this address, because it - seems to cause relocation problems with OSes that link at 4 MiB */ -#ifdef __i386__ -#define HEAP_MAX_ADDR (unsigned long) (64 * 1024 * 1024) -#else -#define HEAP_MAX_ADDR (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[]; @@ -70,6 +77,52 @@ extern char _end[]; 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) { @@ -149,23 +202,149 @@ grub_machine_get_bootlocation (char **device, char **path) /* Claim some available memory in the first /memory node. */ #ifdef __sparc__ -static void +static void grub_claim_heap (void) { grub_mm_init_region ((void *) (grub_modules_get_end () + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); } #else -/* Helper for grub_claim_heap. */ -static int -heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - void *data) +/* Helpers for mm on powerpc. */ + +/* ibm,kernel-dump data structures */ +struct kd_section { - unsigned long *total = data; + 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) @@ -177,17 +356,6 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, addr = 0x180000; } } - 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 @@ -200,6 +368,173 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, 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; @@ -207,26 +542,416 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, err = grub_claimmap (addr, len); if (err) return err; - grub_mm_init_region ((void *) (grub_addr_t) addr, len); + if (rcr->init_region) + grub_mm_init_region ((void *) (grub_addr_t) addr, len); + rcr->total -= len; + + rcr->addr = addr; } - *total += len; - if (*total >= HEAP_MAX_SIZE) + *(grub_uint32_t *) data = rcr->total; + + if (rcr->total == 0) return 1; return 0; } -static void +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) { - unsigned long total = 0; + 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 - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) - heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, - 1, &total); - else - grub_machine_mmap_iterate (heap_init, &total); + 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 @@ -275,7 +1000,7 @@ grub_addr_t grub_modbase; void grub_machine_init (void) { - grub_modbase = ALIGN_UP((grub_addr_t) _end + grub_modbase = ALIGN_UP((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); grub_ieee1275_init (); diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index 4d493ab76..11b2beb2f 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -404,7 +404,7 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) if (comma) { char *filepath = comma + 1; - + /* Make sure filepath has leading backslash. */ if (filepath[0] != '\\') ret = grub_xasprintf ("\\%s", filepath); diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c new file mode 100644 index 000000000..af6d493cd --- /dev/null +++ b/grub-core/kern/lockdown.c @@ -0,0 +1,85 @@ +/* + * 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 new file mode 100644 index 000000000..ff834dca4 --- /dev/null +++ b/grub-core/kern/loongarch64/cache.c @@ -0,0 +1,39 @@ +/* + * 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/include/grub/i386/rdmsr.h b/grub-core/kern/loongarch64/cache_flush.S similarity index 59% rename from include/grub/i386/rdmsr.h rename to grub-core/kern/loongarch64/cache_flush.S index c0a0c717a..a587ed58f 100644 --- a/include/grub/i386/rdmsr.h +++ b/grub-core/kern/loongarch64/cache_flush.S @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. + * 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 @@ -16,22 +16,18 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_RDMSR_H -#define GRUB_RDMSR_H 1 +#include + .file "cache_flush.S" + .text /* - * TODO: Add a general protection exception handler. - * Accessing a reserved or unimplemented MSR address results in a GP#. + * No further work to do because cache consistency is maintained by hardware on + * LoongArch. */ +FUNCTION(grub_arch_clean_dcache_range) + dbar 0 + jr $ra -static inline grub_uint64_t -grub_msr_read (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; -} - -#endif /* GRUB_RDMSR_H */ +FUNCTION(grub_arch_invalidate_icache_range) + ibar 0 + jr $ra diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c new file mode 100644 index 000000000..7f923b415 --- /dev/null +++ b/grub-core/kern/loongarch64/dl.c @@ -0,0 +1,150 @@ +/* + * 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 new file mode 100644 index 000000000..006e8500e --- /dev/null +++ b/grub-core/kern/loongarch64/dl_helper.c @@ -0,0 +1,285 @@ +/* + * 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 new file mode 100644 index 000000000..924b0e87d --- /dev/null +++ b/grub-core/kern/loongarch64/efi/init.c @@ -0,0 +1,77 @@ +/* + * 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/loongarch64/efi/startup.S b/grub-core/kern/loongarch64/efi/startup.S new file mode 100644 index 000000000..87cfb23ea --- /dev/null +++ b/grub-core/kern/loongarch64/efi/startup.S @@ -0,0 +1,34 @@ +/* + * 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 "startup.S" + .text + +FUNCTION(_start) + /* + * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in $a1/$a0. + */ + + 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) diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 9cad0c448..143a232b8 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -29,11 +30,16 @@ #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) { @@ -207,7 +213,7 @@ grub_set_prefix_and_root (void) if (device) { char *prefix_set; - + prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); if (prefix_set) { @@ -236,6 +242,39 @@ grub_load_normal_mode (void) 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) { @@ -264,15 +303,31 @@ reclaim_module_space (void) 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 (); @@ -282,11 +337,14 @@ grub_main (void) grub_register_exported_symbols (); #ifdef GRUB_LINKER_HAVE_INIT grub_arch_dl_init_linker (); -#endif +#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 (); diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index 3834a1490..2ed3ff319 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -430,7 +430,7 @@ grub_machine_get_bootlocation (char **device, char **path) } if (poff == 0 - && pend == grub_disk_get_size (parent)) + && pend == grub_disk_native_sectors (parent)) { grub_disk_close (parent); *device = dname; diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S index fa6897e14..fa331eca1 100644 --- a/grub-core/kern/mips/cache.S +++ b/grub-core/kern/mips/cache.S @@ -7,6 +7,7 @@ FUNCTION (grub_arch_sync_caches) #include "cache_flush.S" j $ra + nop FUNCTION (grub_arch_sync_dma_caches) move $t2, $a0 @@ -66,3 +67,4 @@ FUNCTION (grub_arch_sync_dma_caches) sync_op jr $ra + nop diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c index 5d7d299c7..5b02f97fc 100644 --- a/grub-core/kern/mips/dl.c +++ b/grub-core/kern/mips/dl.c @@ -164,7 +164,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, #endif /* Handle partner lo16 relocation. Lower part is - treated as signed. Hence add 0x8000 to compensate. + treated as signed. Hence add 0x8000 to compensate. */ value = (*(grub_uint16_t *) addr << 16) + sym_value + 0x8000; @@ -206,8 +206,8 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, value = raw << 2; value += sym_value; raw = (value >> 2) & 0x3ffffff; - - *(grub_uint32_t *) addr = + + *(grub_uint32_t *) addr = raw | ((*(grub_uint32_t *) addr) & 0xfc000000); } break; @@ -265,7 +265,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, return GRUB_ERR_NONE; } -void +void grub_arch_dl_init_linker (void) { grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0, 0); diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c index 7b96531b9..5bd721260 100644 --- a/grub-core/kern/mips/loongson/init.c +++ b/grub-core/kern/mips/loongson/init.c @@ -107,10 +107,10 @@ init_pci (void) *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + GRUB_PCI_REG_CACHELINE)) = 0xff; - *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + *((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 + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + GRUB_PCI_REG_ADDRESS_REG1)) = 0; grub_pci_iterate (set_card, NULL); @@ -183,7 +183,7 @@ grub_machine_init (void) 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; diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c index be88b77d2..b5477b87f 100644 --- a/grub-core/kern/mips/qemu_mips/init.c +++ b/grub-core/kern/mips/qemu_mips/init.c @@ -41,7 +41,7 @@ grub_machine_init (void) 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); @@ -87,7 +87,7 @@ grub_halt (void) while (1); } -grub_err_t +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); diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 3b633d51f..2b7922393 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include union printf_arg { @@ -33,7 +35,9 @@ union printf_arg enum { INT, LONG, LONGLONG, - UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG + UNSIGNED_INT = 3, UNSIGNED_LONG, UNSIGNED_LONGLONG, + STRING, + GUID } type; long long ll; }; @@ -112,10 +116,30 @@ 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; } @@ -158,19 +182,63 @@ 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; - const char *debug = grub_env_get ("debug"); - if (! debug) - return; - - if (grub_strword (debug, "all") || grub_strword (debug, condition)) + if (grub_debug_enabled (condition)) { - grub_printf ("%s:%d: ", file, line); + grub_printf ("%s:%d:%s: ", file, line, condition); va_start (args, fmt); grub_vprintf (fmt, args); va_end (args); @@ -340,7 +408,8 @@ grub_isspace (int c) } unsigned long -grub_strtoul (const char *str, char **end, int base) +grub_strtoul (const char * restrict str, const char ** const restrict end, + int base) { unsigned long long num; @@ -357,7 +426,8 @@ grub_strtoul (const char *str, char **end, int base) } unsigned long long -grub_strtoull (const char *str, char **end, int base) +grub_strtoull (const char * restrict str, const char ** const restrict end, + int base) { unsigned long long num = 0; int found = 0; @@ -406,6 +476,10 @@ grub_strtoull (const char *str, char **end, int base) { grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + + if (end) + *end = (char *) str; + return ~0ULL; } @@ -417,6 +491,10 @@ grub_strtoull (const char *str, char **end, int base) { grub_error (GRUB_ERR_BAD_NUMBER, N_("unrecognized number")); + + if (end) + *end = (char *) str; + return 0; } @@ -588,7 +666,7 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) static inline char * grub_lltoa (char *str, int c, unsigned long long n) { - unsigned base = (c == 'x') ? 16 : 10; + unsigned base = ((c == 'x') || (c == 'X')) ? 16 : ((c == 'o') ? 8 : 10); char *p; if ((long long) n < 0 && c == 'd') @@ -603,9 +681,15 @@ grub_lltoa (char *str, int c, unsigned long long n) do { unsigned d = (unsigned) (n & 0xf); - *p++ = (d > 9) ? d + 'a' - 10 : d + '0'; + *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 @@ -623,9 +707,26 @@ grub_lltoa (char *str, int c, unsigned long long n) return p; } -static void -parse_printf_args (const char *fmt0, struct printf_args *args, - va_list args_in) +/* + * 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; @@ -652,7 +753,12 @@ parse_printf_args (const char *fmt0, struct printf_args *args, fmt++; if (*fmt == '$') - fmt++; + { + if (fmt_check) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "positional arguments are not supported"); + fmt++; + } if (*fmt =='-') fmt++; @@ -675,24 +781,42 @@ parse_printf_args (const char *fmt0, struct printf_args *args, 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_malloc (args->count * sizeof (args->ptr[0])); + 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); @@ -706,7 +830,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, while ((c = *fmt++) != 0) { int longfmt = 0; - grub_size_t curn; + unsigned long curn; const char *p; if (c != '%') @@ -724,7 +848,10 @@ parse_printf_args (const char *fmt0, struct printf_args *args, if (*fmt == '$') { - curn = grub_strtoull (p, 0, 10) - 1; + curn = grub_strtoul (p, 0, 10); + if (curn == 0) + continue; + curn--; fmt++; } @@ -762,6 +889,8 @@ parse_printf_args (const char *fmt0, struct printf_args *args, switch (c) { case 'x': + case 'X': + case 'o': case 'u': args->ptr[curn].type = UNSIGNED_INT + longfmt; break; @@ -769,11 +898,17 @@ parse_printf_args (const char *fmt0, struct printf_args *args, args->ptr[curn].type = INT + longfmt; break; case 'p': - case 's': 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': @@ -782,6 +917,16 @@ parse_printf_args (const char *fmt0, struct printf_args *args, } } + 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) { @@ -801,6 +946,13 @@ parse_printf_args (const char *fmt0, struct printf_args *args, 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; } } @@ -813,6 +965,27 @@ write_char (char *str, grub_size_t *count, grub_size_t max_len, unsigned char 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) @@ -834,7 +1007,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, if (c != '%') { - write_char (str, &count, max_len,c); + write_char (str, &count, max_len, c); continue; } @@ -853,17 +1026,19 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, { if (fmt[0] == '0') zerofill = '0'; - format1 = grub_strtoul (fmt, (char **) &fmt, 10); + format1 = grub_strtoul (fmt, &fmt, 10); } if (*fmt == '.') fmt++; if (grub_isdigit (*fmt)) - format2 = grub_strtoul (fmt, (char **) &fmt, 10); + format2 = grub_strtoul (fmt, &fmt, 10); if (*fmt == '$') { + if (format1 == 0) + continue; curn = format1 - 1; fmt++; format1 = 0; @@ -882,7 +1057,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, if (c == '%') { - write_char (str, &count, max_len,c); + write_char (str, &count, max_len, c); n--; continue; } @@ -895,34 +1070,44 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, switch (c) { case 'p': - write_char (str, &count, max_len, '0'); - write_char (str, &count, max_len, 'x'); - c = 'x'; + 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': - { - char tmp[32]; - const char *p = tmp; - grub_size_t len; - grub_size_t fill; - - len = grub_lltoa (tmp, c, curarg) - 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); - } + case 'o': + write_number (str, &count, max_len, format1, rightfill, zerofill, c, curarg); break; case 'c': - write_char (str, &count, max_len,curarg & 0xff); + write_char (str, &count, max_len, curarg & 0xff); break; case 'C': @@ -958,10 +1143,10 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, mask = 0; } - write_char (str, &count, max_len,mask | (code >> shift)); + 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))); + write_char (str, &count, max_len, 0x80 | (0x3f & (code >> shift))); } break; @@ -982,7 +1167,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, write_char (str, &count, max_len, zerofill); for (i = 0; i < len; i++) - write_char (str, &count, max_len,*p++); + write_char (str, &count, max_len, *p++); if (rightfill) while (fill--) @@ -992,7 +1177,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, break; default: - write_char (str, &count, max_len,c); + write_char (str, &count, max_len, c); break; } } @@ -1021,7 +1206,7 @@ grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap) free_printf_args (&args); - return ret < n ? ret : n; + return ret; } int @@ -1081,12 +1266,48 @@ grub_xasprintf (const char *fmt, ...) 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. */ -static void __attribute__ ((noreturn)) +void __attribute__ ((noreturn)) grub_abort (void) { grub_printf ("\nAborted."); - + #ifndef GRUB_UTIL if (grub_term_inputs) #endif @@ -1112,6 +1333,37 @@ grub_fatal (const char *fmt, ...) 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 @@ -1141,7 +1393,7 @@ grub_real_boot_time (const char *file, n->next = 0; va_start (args, fmt); - n->msg = grub_xvasprintf (fmt, args); + n->msg = grub_xvasprintf (fmt, args); va_end (args); *boot_time_last = n; diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c index ee88ff611..027a25cd1 100644 --- a/grub-core/kern/mm.c +++ b/grub-core/kern/mm.c @@ -28,6 +28,9 @@ - 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. @@ -67,8 +70,10 @@ #include #include #include +#include #ifdef MM_DEBUG +# undef grub_calloc # undef grub_malloc # undef grub_zalloc # undef grub_realloc @@ -78,7 +83,51 @@ +/* + * 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 @@ -113,9 +162,8 @@ 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 + 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. */ @@ -126,26 +174,109 @@ grub_mm_init_region (void *addr, grub_size_t 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) - if ((grub_uint8_t *) addr + size + q->pre_size == (grub_uint8_t *) q) - { - r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN); - *r = *q; - r->pre_size += size; - - if (r->pre_size >> GRUB_MM_ALIGN_LOG2) - { - h = (grub_mm_header_t) (r + 1); - h->size = (r->pre_size >> GRUB_MM_ALIGN_LOG2); - h->magic = GRUB_MM_ALLOC_MAGIC; - r->size += h->size << GRUB_MM_ALIGN_LOG2; - r->pre_size &= (GRUB_MM_ALIGN - 1); - *p = r; - grub_free (h + 1); - } - *p = r; - return; - } + { + /* + * 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); @@ -164,6 +295,7 @@ grub_mm_init_region (void *addr, grub_size_t size) 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. */ @@ -176,13 +308,20 @@ grub_mm_init_region (void *addr, grub_size_t size) } /* 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. */ + * 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 p, q; + 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. */ @@ -190,24 +329,24 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) return 0; /* Try to search free slot for allocation in this memory region. */ - for (q = *first, p = q->next; ; q = p, p = p->next) + for (prev = *first, cur = prev->next; ; prev = cur, cur = cur->next) { grub_off_t extra; - extra = ((grub_addr_t) (p + 1) >> GRUB_MM_ALIGN_LOG2) & (align - 1); + extra = ((grub_addr_t) (cur + 1) >> GRUB_MM_ALIGN_LOG2) & (align - 1); if (extra) extra = align - extra; - if (! p) + if (! cur) 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 (cur->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("free magic is broken at %p: 0x%x", cur, cur->magic); - if (p->size >= n + extra) + if (cur->size >= n + extra) { - extra += (p->size - extra - n) & (~(align - 1)); - if (extra == 0 && p->size == n) + 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. @@ -220,9 +359,9 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) | alloc, size=n | | +---------------+ v */ - q->next = p->next; + prev->next = cur->next; } - else if (align == 1 || p->size == n + extra) + else if (align == 1 || cur->size == n + extra) { /* There might be alignment requirement, when taking it into account memory block fits in. @@ -239,23 +378,22 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) | alloc, size=n | | +---------------+ v */ - - p->size -= n; - p += p->size; + cur->size -= n; + cur += cur->size; } else if (extra == 0) { grub_mm_header_t r; - - r = p + extra + n; - r->magic = GRUB_MM_FREE_MAGIC; - r->size = p->size - extra - n; - r->next = p->next; - q->next = r; - if (q == p) + 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) { - q = r; + prev = r; r->next = r; } } @@ -282,32 +420,32 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) */ grub_mm_header_t r; - r = p + extra + n; + r = cur + extra + n; r->magic = GRUB_MM_FREE_MAGIC; - r->size = p->size - extra - n; - r->next = p; + r->size = cur->size - extra - n; + r->next = cur; - p->size = extra; - q->next = r; - p += extra; + cur->size = extra; + prev->next = r; + cur += extra; } - p->magic = GRUB_MM_ALLOC_MAGIC; - p->size = n; + 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 64K. */ + /* So do it only for chunks under 32K. */ if (n < (0x8000 >> GRUB_MM_ALIGN_LOG2) - || *first == p) - *first = q; + || *first == cur) + *first = prev; - return p + 1; + return cur + 1; } /* Search was completed without result. */ - if (p == *first) + if (cur == *first) break; } @@ -320,6 +458,7 @@ 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) @@ -328,10 +467,12 @@ grub_memalign (grub_size_t align, grub_size_t size) 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 ((size + align) > ~(grub_size_t) 0x100000) + if (grow > ~(grub_size_t) 0x100000) goto fail; align = (align >> GRUB_MM_ALIGN_LOG2); @@ -353,19 +494,56 @@ grub_memalign (grub_size_t align, grub_size_t size) 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; -#if 0 - case 1: - /* Unload unneeded modules. */ - grub_dl_unload_unneeded (); - count++; - goto again; -#endif - default: break; } @@ -375,6 +553,30 @@ grub_memalign (grub_size_t align, grub_size_t size) 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) @@ -414,54 +616,73 @@ grub_free (void *ptr) } else { - grub_mm_header_t q, s; + grub_mm_header_t cur, prev; #if 0 - q = r->first; + cur = r->first; do { grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n", - GRUB_FILE, __LINE__, q, q->size, q->magic); - q = q->next; + GRUB_FILE, __LINE__, cur, cur->size, cur->magic); + cur = cur->next; } - while (q != r->first); + while (cur != r->first); #endif - - for (s = r->first, q = s->next; q <= p || q->next >= p; s = q, q = s->next) + /* 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 (q->magic != GRUB_MM_FREE_MAGIC) - grub_fatal ("free magic is broken at %p: 0x%x", q, q->magic); + if (cur->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("free magic is broken at %p: 0x%x", cur, cur->magic); - if (q <= q->next && (q > p || q->next < p)) + /* 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 = q->next; - q->next = p; + 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; - q->next = p->next; + cur->next = p->next; p = p->next; } - r->first = q; + r->first = cur; - if (q == p + p->size) + /* Likewise if can be merged with the preceeding free block */ + if (cur == p + p->size) { - q->magic = 0; - p->size += q->size; - if (q == s) - s = p; - s->next = p; - q = s; + cur->magic = 0; + p->size += cur->size; + if (cur == prev) + prev = p; + prev->next = p; + cur = prev; } - r->first = q; + /* + * 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; } } @@ -513,6 +734,8 @@ grub_mm_dump_free (void) { 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 @@ -540,6 +763,8 @@ grub_mm_dump (unsigned lineno) { 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; @@ -561,6 +786,20 @@ grub_mm_dump (unsigned lineno) 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) { @@ -613,7 +852,7 @@ grub_debug_memalign (const char *file, int line, grub_size_t align, void *ptr; if (grub_mm_debug) - grub_printf ("%s:%d: memalign (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE + grub_printf ("%s:%d: memalign (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ", file, line, align, size); ptr = grub_memalign (align, size); if (grub_mm_debug) diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c index 78175aac2..9b7b31a51 100644 --- a/grub-core/kern/parser.c +++ b/grub-core/kern/parser.c @@ -1,7 +1,7 @@ /* 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. + * 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 @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -107,8 +108,8 @@ check_varstate (grub_parser_state_t s) } -static void -add_var (char *varname, char **bp, char **vp, +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; @@ -116,17 +117,74 @@ add_var (char *varname, char **bp, char **vp, /* Check if a variable was being read in and the end of the name was reached. */ if (!(check_varstate (state) && !check_varstate (newstate))) - return; + return GRUB_ERR_NONE; - *((*vp)++) = '\0'; - val = grub_env_get (varname); - *vp = varname; + 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; + return GRUB_ERR_NONE; /* Insert the contents of the variable in the buffer. */ - for (; *val; val++) - *((*bp)++) = *val; + 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 @@ -135,23 +193,36 @@ grub_parser_split_cmdline (const char *cmdline, 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; + grub_buffer_t buffer, varname; char *rd = (char *) cmdline; - char varname[200]; - char *vp = varname; - char *args; + 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 (!rd || !*rd) + if (rp == NULL || *rp == '\0') { + if (rd != cmdline) + { + grub_free (rd); + rd = rp = NULL; + } if (getline) - getline (&rd, 1, getline_data); + { + getline (&rd, 1, getline_data); + rp = rd; + } else break; } @@ -159,39 +230,14 @@ grub_parser_split_cmdline (const char *cmdline, if (!rd) break; - for (; *rd; rd++) + for (; *rp != '\0'; rp++) { grub_parser_state_t newstate; - char use; - newstate = grub_parser_cmdline_state (state, *rd, &use); + if (process_char (*rp, buffer, varname, state, argc, + &newstate) != GRUB_ERR_NONE) + goto fail; - /* If a variable was being processed and this character does - not describe the variable anymore, write the variable to - the buffer. */ - add_var (varname, &bp, &vp, state, newstate); - - if (check_varstate (newstate)) - { - if (use) - *(vp++) = 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. */ - if (bp != buffer && *(bp - 1)) - { - *(bp++) = '\0'; - (*argc)++; - } - } - else if (use) - *(bp++) = use; - } state = newstate; } } @@ -199,39 +245,62 @@ grub_parser_split_cmdline (const char *cmdline, /* A special case for when the last character was part of a variable. */ - add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT); + if (add_var (varname, buffer, state, GRUB_PARSER_STATE_TEXT) != GRUB_ERR_NONE) + goto fail; - if (bp != buffer && *(bp - 1)) + /* 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) { - *(bp++) = '\0'; - (*argc)++; + grub_errno = GRUB_ERR_NONE; + goto out; } - /* 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)); + *argv = grub_calloc (*argc + 1, sizeof (char *)); if (!*argv) - { - grub_free (args); - return grub_errno; - } + goto fail; /* 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++; + 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; } - return 0; + /* 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. */ diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c index e499147cb..3b128e6d2 100644 --- a/grub-core/kern/partition.c +++ b/grub-core/kern/partition.c @@ -28,6 +28,9 @@ 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 @@ -109,24 +112,35 @@ grub_partition_map_probe (const grub_partition_map_t partmap, grub_partition_t grub_partition_probe (struct grub_disk *disk, const char *str) { - grub_partition_t part = 0; + 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; - int num; + unsigned long num; const char *partname, *partname_end; partname = ptr; while (*ptr && grub_isalpha (*ptr)) ptr++; - partname_end = ptr; - num = grub_strtoul (ptr, (char **) &ptr, 0) - 1; + 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. */ @@ -205,7 +219,12 @@ part_iterate (grub_disk_t dsk, const grub_partition_t partition, void *data) FOR_PARTITION_MAPS(partmap) { grub_err_t err; - err = partmap->iterate (dsk, part_iterate, ctx); + 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) diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c index cdd61b305..7b6418eab 100644 --- a/grub-core/kern/powerpc/dl.c +++ b/grub-core/kern/powerpc/dl.c @@ -47,7 +47,7 @@ struct trampoline grub_uint32_t bctr; }; -static const struct trampoline trampoline_template = +static const struct trampoline trampoline_template = { 0x3d800000, 0x618c0000, @@ -74,7 +74,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, 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; @@ -82,7 +82,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, 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); @@ -138,7 +138,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, tptr->ori |= ((value) & 0xffff); mod->trampptr = tptr + 1; } - + if (delta << 6 >> 6 != delta) return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); diff --git a/grub-core/kern/rescue_parser.c b/grub-core/kern/rescue_parser.c index 633836699..799641a03 100644 --- a/grub-core/kern/rescue_parser.c +++ b/grub-core/kern/rescue_parser.c @@ -36,10 +36,16 @@ grub_rescue_parse_line (char *line, if (grub_parser_split_cmdline (line, getline, getline_data, &n, &args) || n < 0) - return grub_errno; + { + grub_free(args); + return grub_errno; + } if (n == 0) - return GRUB_ERR_NONE; + { + grub_free(args); + return GRUB_ERR_NONE; + } /* In case of an assignment set the environment accordingly instead of calling a function. */ diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c index dcd7d4439..a71ada8fb 100644 --- a/grub-core/kern/rescue_reader.c +++ b/grub-core/kern/rescue_reader.c @@ -78,6 +78,19 @@ grub_rescue_read_line (char **line, int cont, void __attribute__ ((noreturn)) 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) diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c index 6fb8385ef..896653bb4 100644 --- a/grub-core/kern/riscv/dl.c +++ b/grub-core/kern/riscv/dl.c @@ -188,6 +188,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, 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; @@ -330,9 +331,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, case R_RISCV_RELAX: break; default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); + { + 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); + } } } diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c index 7eb1969d0..0d7de4f54 100644 --- a/grub-core/kern/riscv/efi/init.c +++ b/grub-core/kern/riscv/efi/init.c @@ -33,16 +33,15 @@ grub_efi_get_time_ms (void) grub_uint64_t tmr; #if __riscv_xlen == 64 - asm volatile ("rdcycle %0" : "=r" (tmr)); + asm volatile ("rdtime %0" : "=r"(tmr)); #else grub_uint32_t lo, hi, tmp; - asm volatile ( - "1:\n" - "rdcycleh %0\n" - "rdcycle %1\n" - "rdcycleh %2\n" - "bne %0, %2, 1b" - : "=&r" (hi), "=&r" (lo), "=&r" (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 @@ -73,4 +72,7 @@ grub_machine_fini (int flags) return; grub_efi_fini (); + + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) + grub_efi_memory_fini (); } diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c index 739be4717..f3d960186 100644 --- a/grub-core/kern/sparc64/dl.c +++ b/grub-core/kern/sparc64/dl.c @@ -176,9 +176,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, & 0x1fff); break; default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); + { + 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); + } } } diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c index 07720ee67..14d596498 100644 --- a/grub-core/kern/term.c +++ b/grub-core/kern/term.c @@ -120,6 +120,45 @@ grub_getkey (void) } } +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) { diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c index be4816fe6..aac8f9ae1 100644 --- a/grub-core/kern/uboot/uboot.c +++ b/grub-core/kern/uboot/uboot.c @@ -133,7 +133,7 @@ grub_uboot_dev_enum (void) return num_devices; max_devices = 2; - enum_devices = grub_malloc (sizeof(struct device_info) * max_devices); + enum_devices = grub_calloc (max_devices, sizeof(struct device_info)); if (!enum_devices) return 0; diff --git a/grub-core/commands/verifiers.c b/grub-core/kern/verifiers.c similarity index 97% rename from grub-core/commands/verifiers.c rename to grub-core/kern/verifiers.c index 0dde48182..75d7994cf 100644 --- a/grub-core/commands/verifiers.c +++ b/grub-core/kern/verifiers.c @@ -196,7 +196,8 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) return ret; fail: - ver->close (context); + if (ver->close) + ver->close (context); fail_noclose: verified_free (verified); grub_free (ret); @@ -207,6 +208,9 @@ 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; @@ -217,12 +221,8 @@ grub_verify_string (char *str, enum grub_verify_string_type type) return GRUB_ERR_NONE; } -GRUB_MOD_INIT(verifiers) +void +grub_verifiers_init (void) { grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open); } - -GRUB_MOD_FINI(verifiers) -{ - grub_file_filter_unregister (GRUB_FILE_FILTER_VERIFY); -} diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c index 3a73e6e6c..e5a8bdcf4 100644 --- a/grub-core/kern/x86_64/dl.c +++ b/grub-core/kern/x86_64/dl.c @@ -106,9 +106,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, break; default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); + { + 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); + } } } diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S deleted file mode 100644 index 1337fd9fc..000000000 --- a/grub-core/kern/x86_64/efi/callwrap.S +++ /dev/null @@ -1,129 +0,0 @@ -/* callwrap.S - wrapper for x86_64 efi calls */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#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, %rsi, %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_7) - subq $88, %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 - -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/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c index f2ec04a8c..52b331558 100644 --- a/grub-core/lib/LzmaEnc.c +++ b/grub-core/lib/LzmaEnc.c @@ -1359,7 +1359,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 +1403,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) } } } - } + } } } /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ @@ -1877,13 +1877,19 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize } else { - UInt32 posSlot; + UInt32 posSlot, lenToPosState; RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); p->state = kMatchNextStates[p->state]; LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); pos -= LZMA_NUM_REPS; GetPosSlot(pos, posSlot); - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); + lenToPosState = GetLenToPosState(len); + if (lenToPosState >= kNumLenToPosStates) + { + p->result = SZ_ERROR_DATA; + return CheckErrors(p); + } + RcTree_Encode(&p->rc, p->posSlotEncoder[lenToPosState], kNumPosSlotBits, posSlot); if (posSlot >= kStartPosModelIndex) { diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c index fd7744a6f..c2bd6a452 100644 --- a/grub-core/lib/arg.c +++ b/grub-core/lib/arg.c @@ -23,6 +23,7 @@ #include #include #include +#include /* Built-in parser for default options. */ static const struct grub_arg_option help_options[] = @@ -216,7 +217,13 @@ static inline grub_err_t add_arg (char ***argl, int *num, char *s) { char **p = *argl; - *argl = grub_realloc (*argl, (++(*num) + 1) * sizeof (char *)); + 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); @@ -263,7 +270,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, for (curshort = arg + 1; *curshort; curshort++) if (!find_short (cmd->options, *curshort)) break; - + if (*curshort) { if (add_arg (&argl, &num, arg) != 0) @@ -292,6 +299,19 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, 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; } @@ -375,7 +395,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, case ARG_TYPE_INT: { - char *tail; + const char * tail; grub_strtoull (option, &tail, 0); if (tail == 0 || tail == option || *tail != '\0' || grub_errno) @@ -431,6 +451,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, 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) @@ -443,7 +464,15 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */ } - list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt); + 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; diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index ca334d5a4..396f76410 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -59,7 +59,7 @@ _gcry_burn_stack (int 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); } @@ -83,7 +83,7 @@ void _gcry_log_error (const char *fmt, ...) } } -void +void grub_cipher_register (gcry_cipher_spec_t *cipher) { cipher->next = grub_ciphers; @@ -102,14 +102,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; @@ -314,7 +314,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 +335,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; @@ -458,7 +458,7 @@ grub_password_get (char buf[], unsigned buf_size) while (1) { - key = grub_getkey (); + key = grub_getkey (); if (key == '\n' || key == '\r') break; diff --git a/grub-core/normal/datetime.c b/grub-core/lib/datetime.c similarity index 86% rename from grub-core/normal/datetime.c rename to grub-core/lib/datetime.c index 95b8c9ff5..8f0922fb0 100644 --- a/grub-core/normal/datetime.c +++ b/grub-core/lib/datetime.c @@ -19,6 +19,13 @@ #include #include +#include +#include +#ifdef GRUB_MACHINE_EMU +#include + +GRUB_MOD_LICENSE ("GPLv3+"); +#endif static const char *const grub_weekday_names[] = { @@ -60,7 +67,7 @@ grub_get_weekday_name (struct grub_datetime *datetime) void -grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime) +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}; @@ -73,11 +80,17 @@ grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime) unsigned days; /* Seconds into current day. */ unsigned secs_in_day; + /* Transform C divisions and modulos to mathematical ones */ if (nix < 0) - days_epoch = -(((unsigned) (SECPERDAY-nix-1)) / SECPERDAY); + /* + * 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 = ((unsigned) nix) / SECPERDAY; + days_epoch = grub_divmod64 (nix, SECPERDAY, NULL); + secs_in_day = nix - days_epoch * SECPERDAY; days = days_epoch + 69 * DAYSPERYEAR + 17; diff --git a/grub-core/lib/disk.c b/grub-core/lib/disk.c index b4eb064a8..123993dd4 100644 --- a/grub-core/lib/disk.c +++ b/grub-core/lib/disk.c @@ -101,7 +101,7 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, grub_disk_cache_invalidate (disk->dev->id, disk->id, sector); - if ((disk->dev->disk_write) (disk, transform_sector (disk, sector), + if ((disk->dev->disk_write) (disk, grub_disk_to_native_sector (disk, sector), 1, tmp_buf) != GRUB_ERR_NONE) { grub_free (tmp_buf); @@ -130,7 +130,7 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, << (GRUB_DISK_CACHE_BITS + GRUB_DISK_SECTOR_BITS - disk->log_sector_size)); - if ((disk->dev->disk_write) (disk, transform_sector (disk, sector), + if ((disk->dev->disk_write) (disk, grub_disk_to_native_sector (disk, sector), n, buf) != GRUB_ERR_NONE) goto finish; diff --git a/grub-core/lib/efi/datetime.c b/grub-core/lib/efi/datetime.c index 0fd1b5fbd..b03e4df5e 100644 --- a/grub-core/lib/efi/datetime.c +++ b/grub-core/lib/efi/datetime.c @@ -32,8 +32,7 @@ grub_get_datetime (struct grub_datetime *datetime) grub_efi_status_t status; struct grub_efi_time efi_time; - status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, - &efi_time, 0); + status = grub_efi_system_table->runtime_services->get_time (&efi_time, 0); if (status) return grub_error (GRUB_ERR_INVALID_COMMAND, @@ -57,8 +56,7 @@ grub_set_datetime (struct grub_datetime *datetime) grub_efi_status_t status; struct grub_efi_time efi_time; - status = efi_call_2 (grub_efi_system_table->runtime_services->get_time, - &efi_time, 0); + status = grub_efi_system_table->runtime_services->get_time (&efi_time, 0); if (status) return grub_error (GRUB_ERR_INVALID_COMMAND, @@ -71,8 +69,7 @@ grub_set_datetime (struct grub_datetime *datetime) efi_time.minute = datetime->minute; efi_time.second = datetime->second; - status = efi_call_1 (grub_efi_system_table->runtime_services->set_time, - &efi_time); + status = 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/efi/halt.c b/grub-core/lib/efi/halt.c index 5859f0498..a58a747e5 100644 --- a/grub-core/lib/efi/halt.c +++ b/grub-core/lib/efi/halt.c @@ -28,13 +28,14 @@ void grub_halt (void) { - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); #if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \ - !defined(__riscv) + !defined(__loongarch__) && !defined(__riscv) grub_acpi_halt (); #endif - efi_call_4 (grub_efi_system_table->runtime_services->reset_system, - GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL); + 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 index 319b69eeb..b4518d000 100644 --- a/grub-core/lib/efi/relocator.c +++ b/grub-core/lib/efi/relocator.c @@ -26,7 +26,7 @@ #define NEXT_MEMORY_DESCRIPTOR(desc, size) \ ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) -unsigned +unsigned grub_relocator_firmware_get_max_events (void) { grub_efi_uintn_t mmapsize = 0, descriptor_size = 0; @@ -39,7 +39,7 @@ grub_relocator_firmware_get_max_events (void) return 2 * (mmapsize / descriptor_size + 10); } -unsigned +unsigned grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) { grub_efi_uintn_t mmapsize = 0, desc_size = 0; @@ -65,7 +65,7 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) 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. + /* 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. @@ -81,7 +81,7 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) counter++; events[counter].type = REG_FIRMWARE_END; events[counter].pos = end; - counter++; + counter++; } return counter; @@ -101,8 +101,8 @@ grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size) (unsigned long long) start, (unsigned long long) size); #endif b = grub_efi_system_table->boot_services; - status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS, - GRUB_EFI_LOADER_DATA, size >> 12, &address); + status = b->allocate_pages (GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_DATA, size >> 12, &address); return (status == GRUB_EFI_SUCCESS); } @@ -115,5 +115,5 @@ grub_relocator_firmware_free_region (grub_addr_t start, grub_size_t size) return; b = grub_efi_system_table->boot_services; - efi_call_2 (b->free_pages, start, size >> 12); + b->free_pages (start, size >> 12); } diff --git a/grub-core/lib/efi/tcg2.c b/grub-core/lib/efi/tcg2.c new file mode 100644 index 000000000..841bf50bb --- /dev/null +++ b/grub-core/lib/efi/tcg2.c @@ -0,0 +1,143 @@ +/* + * 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/envblk.c b/grub-core/lib/envblk.c index 230e0e9d9..2e4e78b13 100644 --- a/grub-core/lib/envblk.c +++ b/grub-core/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. */ diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c index 0d371c563..73cfa94a2 100644 --- a/grub-core/lib/fdt.c +++ b/grub-core/lib/fdt.c @@ -335,7 +335,7 @@ int grub_fdt_next_node (const void *fdt, unsigned int currentoffset) 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) { @@ -355,7 +355,7 @@ int grub_fdt_first_node (const void *fdt, unsigned int parentoffset) 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, diff --git a/grub-core/lib/gnulib-patches/fix-null-deref.patch b/grub-core/lib/gnulib-patches/fix-null-deref.patch deleted file mode 100644 index 8fafa153a..000000000 --- a/grub-core/lib/gnulib-patches/fix-null-deref.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/lib/argp-parse.c b/lib/argp-parse.c -index 6dec57310..900adad54 100644 ---- a/lib/argp-parse.c -+++ b/lib/argp-parse.c -@@ -940,7 +940,7 @@ weak_alias (__argp_parse, argp_parse) - void * - __argp_input (const struct argp *argp, const struct argp_state *state) - { -- if (state) -+ if (state && state->pstate) - { - struct group *group; - struct parser *parser = state->pstate; diff --git a/grub-core/lib/gnulib-patches/fix-width.patch b/grub-core/lib/gnulib-patches/fix-width.patch index 0a208ad08..15f091c0d 100644 --- a/grub-core/lib/gnulib-patches/fix-width.patch +++ b/grub-core/lib/gnulib-patches/fix-width.patch @@ -143,7 +143,7 @@ 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 -@@ -51,6 +51,7 @@ +@@ -52,6 +52,7 @@ #include "argp.h" #include "argp-fmtstream.h" #include "argp-namefrob.h" @@ -151,7 +151,7 @@ index e5375a0f0..5d8f451ec 100644 #ifndef SIZE_MAX # define SIZE_MAX ((size_t) -1) -@@ -1432,7 +1433,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, +@@ -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. */ @@ -204,7 +204,7 @@ diff --git a/lib/mbswidth.h b/lib/mbswidth.h index 2b5c53c37..45a123e63 100644 --- a/lib/mbswidth.h +++ b/lib/mbswidth.h -@@ -45,6 +45,10 @@ extern "C" { +@@ -40,6 +40,10 @@ extern "C" { control characters and 1 otherwise. */ #define MBSW_REJECT_UNPRINTABLE 2 diff --git a/grub-core/lib/gnulib-patches/no-abort.patch b/grub-core/lib/gnulib-patches/no-abort.patch deleted file mode 100644 index e469c4762..000000000 --- a/grub-core/lib/gnulib-patches/no-abort.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/lib/regcomp.c b/lib/regcomp.c -index cc85f35ac..de45ebb5c 100644 ---- a/lib/regcomp.c -+++ b/lib/regcomp.c -@@ -528,9 +528,9 @@ regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf, - to this routine. If we are given anything else, or if other regex - code generates an invalid error code, then the program has a bug. - Dump core so we can fix it. */ -- abort (); -- -- msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); -+ msg = gettext ("unknown regexp error"); -+ else -+ msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); - - msg_size = strlen (msg) + 1; /* Includes the null. */ - -@@ -1136,7 +1136,7 @@ optimize_utf8 (re_dfa_t *dfa) - } - break; - default: -- abort (); -+ break; - } - - if (mb_chars || has_period) diff --git a/grub-core/lib/i386/reboot.c b/grub-core/lib/i386/reboot.c index dce0b563d..d0fd6a50e 100644 --- a/grub-core/lib/i386/reboot.c +++ b/grub-core/lib/i386/reboot.c @@ -55,7 +55,7 @@ grub_reboot (void) state.a20 = 0; grub_stop_floppy (); - + err = grub_relocator16_boot (relocator, state); while (1); diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c index 71dd4f0ab..54a1dcd8b 100644 --- a/grub-core/lib/i386/relocator.c +++ b/grub-core/lib/i386/relocator.c @@ -83,11 +83,10 @@ grub_relocator32_boot (struct grub_relocator *rel, /* 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 (rel, &ch, 0x1000, - 0x9a000 - RELOCATOR_SIZEOF (32), - RELOCATOR_SIZEOF (32), 16, - GRUB_RELOCATOR_PREFERENCE_LOW, - avoid_efi_bootservices); + 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; @@ -125,17 +124,14 @@ grub_relocator16_boot (struct grub_relocator *rel, grub_relocator_chunk_t ch; /* Put it higher than the byte it checks for A20 check. */ - err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010, - 0xa0000 - RELOCATOR_SIZEOF (16) - - GRUB_RELOCATOR16_STACK_SIZE, - RELOCATOR_SIZEOF (16) - + GRUB_RELOCATOR16_STACK_SIZE, 16, - GRUB_RELOCATOR_PREFERENCE_NONE, - 0); + 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_cs = state.cs; grub_relocator16_ip = state.ip; grub_relocator16_ds = state.ds; @@ -183,11 +179,9 @@ grub_relocator64_boot (struct grub_relocator *rel, void *relst; grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr, - max_addr - RELOCATOR_SIZEOF (64), - RELOCATOR_SIZEOF (64), 16, - GRUB_RELOCATOR_PREFERENCE_NONE, - 0); + 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; diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S index 371a2ed69..e9238119b 100644 --- a/grub-core/lib/i386/relocator16.S +++ b/grub-core/lib/i386/relocator16.S @@ -38,15 +38,21 @@ VARIABLE(grub_relocator16_start) #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 @@ -88,15 +94,15 @@ VARIABLE(grub_relocator16_start) 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) (%esi, 1) - lidt LOCAL(idt_offset) (%esi, 1) + 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)) (%esi, 1) + movw %ax, (LOCAL (segment) - LOCAL (base)) - lidt (EXT_C(grub_relocator16_idt) - LOCAL (base)) (%esi, 1) + lidt (EXT_C(grub_relocator16_idt) - LOCAL (base)) /* jump to a 16 bit segment */ ljmp $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base)) @@ -311,11 +317,17 @@ LOCAL(cs_base_byte3): .byte 0x9E, 0, 0 /* -- 16 bit real mode DS -- - * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present + * base = filled by code, limit 0x0FFFF (1 B Granularity), present * type = 16 bit data read/write, DPL = 0 */ - .word 0xFFFF, 0 - .byte 0, 0x92, 0, 0 + .word 0xFFFF +LOCAL(ds_base_bytes12): + .word 0 +LOCAL(ds_base_byte3): + .byte 0 + + .byte 0x92, 0, 0 + LOCAL(gdt_end): #ifdef __APPLE__ diff --git a/grub-core/lib/i386/relocator64.S b/grub-core/lib/i386/relocator64.S index 148f38adb..c80538e7e 100644 --- a/grub-core/lib/i386/relocator64.S +++ b/grub-core/lib/i386/relocator64.S @@ -63,7 +63,9 @@ VARIABLE(grub_relocator64_cr3) movq %rax, %cr3 #endif +#ifdef __x86_64__ .code64 +#endif /* mov imm64, %rax */ .byte 0x48 @@ -71,7 +73,14 @@ VARIABLE(grub_relocator64_cr3) 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) @@ -85,7 +94,15 @@ VARIABLE(grub_relocator64_rsp) */ 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 @@ -95,8 +112,15 @@ LOCAL(skip_efi_stack_align): 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 @@ -125,9 +149,9 @@ VARIABLE(grub_relocator64_rdx) payload and makes this implementation easier. */ cld -#ifdef __APPLE__ +#if defined (__APPLE__) || !defined (__x86_64__) .byte 0xff, 0x25 - .quad 0 + .long 0 #else jmp *LOCAL(jump_addr) (%rip) #endif diff --git a/grub-core/lib/i386/relocator_common.S b/grub-core/lib/i386/relocator_common.S index 03f427a03..1b5210dd3 100644 --- a/grub-core/lib/i386/relocator_common.S +++ b/grub-core/lib/i386/relocator_common.S @@ -29,8 +29,6 @@ #endif .macro DISABLE_PAGING -#ifdef GRUB_MACHINE_IEEE1275 -#endif movl %cr0, %eax andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax diff --git a/grub-core/lib/i386/xen/relocator.S b/grub-core/lib/i386/xen/relocator.S index 96e51b59a..dab4d8ace 100644 --- a/grub-core/lib/i386/xen/relocator.S +++ b/grub-core/lib/i386/xen/relocator.S @@ -75,10 +75,10 @@ VARIABLE(grub_relocator_xen_mfn_list) .long 0 movl 0(%eax, %ebp, 4), %ecx /* mfn */ movl %ebp, %ebx - shll $PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */ + shll $GRUB_PAGE_SHIFT, %ebx /* virtual address (1:1 mapping) */ movl %ecx, %edx - shll $PAGE_SHIFT, %ecx /* prepare pte low part */ - shrl $(32 - PAGE_SHIFT), %edx /* pte high part */ + 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 diff --git a/grub-core/lib/ieee1275/cmos.c b/grub-core/lib/ieee1275/cmos.c index 328d70a0c..1400cfb67 100644 --- a/grub-core/lib/ieee1275/cmos.c +++ b/grub-core/lib/ieee1275/cmos.c @@ -52,7 +52,7 @@ grub_cmos_find_port_iter (struct grub_ieee1275_devalias *alias) #if GRUB_CPU_SIZEOF_VOID_P == 8 if (actual == 8) { - grub_cmos_port = (volatile grub_uint8_t *) + grub_cmos_port = (volatile grub_uint8_t *) ((((grub_addr_t) addr[0]) << 32) | addr[1]); return 1; } @@ -72,6 +72,6 @@ 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 index b81fba2ed..74578f15a 100644 --- a/grub-core/lib/ieee1275/datetime.c +++ b/grub-core/lib/ieee1275/datetime.c @@ -95,7 +95,7 @@ grub_get_datetime (struct grub_datetime *datetime) datetime->year = args.year; datetime->month = args.month; - datetime->day = args.day + 1; + datetime->day = args.day; datetime->hour = args.hour; datetime->minute = args.minute; datetime->second = args.second; @@ -140,7 +140,7 @@ grub_set_datetime (struct grub_datetime *datetime) args.year = datetime->year; args.month = datetime->month; - args.day = datetime->day - 1; + args.day = datetime->day; args.hour = datetime->hour; args.minute = datetime->minute; args.second = datetime->second; diff --git a/grub-core/lib/ieee1275/relocator.c b/grub-core/lib/ieee1275/relocator.c index c6dd8facb..918392f1e 100644 --- a/grub-core/lib/ieee1275/relocator.c +++ b/grub-core/lib/ieee1275/relocator.c @@ -33,13 +33,11 @@ count (grub_uint64_t addr __attribute__ ((unused)), return 0; } -unsigned +unsigned grub_relocator_firmware_get_max_events (void) { int counter = 0; - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) - return 0; grub_machine_mmap_iterate (count, &counter); return 2 * counter; } @@ -84,7 +82,7 @@ grub_relocator_firmware_fill_events_iter (grub_uint64_t addr, return 0; } -unsigned +unsigned grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) { struct grub_relocator_firmware_fill_events_ctx ctx = { @@ -92,8 +90,6 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) .counter = 0 }; - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) - return 0; grub_machine_mmap_iterate (grub_relocator_firmware_fill_events_iter, &ctx); return ctx.counter; } diff --git a/grub-core/lib/ieee1275/tcg2.c b/grub-core/lib/ieee1275/tcg2.c new file mode 100644 index 000000000..40161c2f9 --- /dev/null +++ b/grub-core/lib/ieee1275/tcg2.c @@ -0,0 +1,157 @@ +/* + * 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 new file mode 100644 index 000000000..3178dcc97 --- /dev/null +++ b/grub-core/lib/json/jsmn.h @@ -0,0 +1,471 @@ +/* + * 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 new file mode 100644 index 000000000..1eadd1ce9 --- /dev/null +++ b/grub-core/lib/json/json.c @@ -0,0 +1,382 @@ +/* + * 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 new file mode 100644 index 000000000..626074c35 --- /dev/null +++ b/grub-core/lib/json/json.h @@ -0,0 +1,140 @@ +/* + * 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 index ef56150ac..fa0131a1e 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -92,7 +92,7 @@ static struct legacy_command legacy_commands[] = 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, + {"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" @@ -115,7 +115,7 @@ static struct legacy_command legacy_commands[] = 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, + "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."}, @@ -128,7 +128,7 @@ static struct legacy_command legacy_commands[] = " tag."}, {"displayapm", "lsapm\n", NULL, 0, 0, {}, 0, 0, "Display APM BIOS information."}, - {"displaymem", "lsmmap\n", NULL, 0, 0, {}, 0, 0, + {"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. */ @@ -213,7 +213,7 @@ static struct legacy_command legacy_commands[] = 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", + {"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}, @@ -291,7 +291,7 @@ static struct legacy_command legacy_commands[] = "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, + {"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" @@ -418,7 +418,7 @@ adjust_file (const char *in, grub_size_t len) } if (*comma != ',') return grub_legacy_escape (in, len); - part = grub_strtoull (comma + 1, (char **) &rest, 0); + part = grub_strtoull (comma + 1, &rest, 0); if (rest[0] == ',' && rest[1] >= 'a' && rest[1] <= 'z') { subpart = rest[1] - 'a'; @@ -438,7 +438,7 @@ adjust_file (const char *in, grub_size_t len) { if (*ptr == '\'' || *ptr == '\\') *outptr++ = '\\'; - + *outptr++ = *ptr; } if (subpart != -1) @@ -451,7 +451,7 @@ adjust_file (const char *in, grub_size_t len) { if (*ptr == '\'' || *ptr == '\\') *outptr++ = '\\'; - + *outptr++ = *ptr; } *outptr = 0; @@ -489,7 +489,7 @@ is_option (enum arg_type opt, const char *curarg, grub_size_t len) return (len >= 2 && curarg[0] == '-' && curarg[1] == '-'); default: return 0; - } + } } char * @@ -635,7 +635,7 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) { int hold_arg = 0; - const char *curarg = NULL; + const char *curarg = NULL; for (i = 0; i < legacy_commands[cmdnum].argc; i++) { grub_size_t curarglen; @@ -685,7 +685,7 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) ptr++; overhead += 3; } - + outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg)); if (!outptr0) return NULL; @@ -819,14 +819,14 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) case TYPE_FORCE_OPTION: case TYPE_NOAPM_OPTION: case TYPE_TYPE_OR_NOMEM_OPTION: - case TYPE_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: + case TYPE_VBE_MODE: args[i] = grub_strdup ("auto"); break; } @@ -849,7 +849,7 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) if (!invert) return NULL; grub_memcpy (invert, slash + 1, len - (slash - corig) - 1); - invert[len - (slash - args[0]) - 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; diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c index f5e946a2d..63f6fcd11 100644 --- a/grub-core/lib/libgcrypt/cipher/ac.c +++ b/grub-core/lib/libgcrypt/cipher/ac.c @@ -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_malloc (sizeof (*data_mpis_new) * data_mpis_n); + data_mpis_new = gcry_calloc (data_mpis_n, sizeof (*data_mpis_new)); if (! data_mpis_new) { err = gcry_error_from_errno (errno); @@ -572,7 +572,7 @@ _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, } /* Add MPI list. */ - arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1)); + arg_list = gcry_calloc (data_n + 1, sizeof (*arg_list)); if (! arg_list) { err = gcry_error_from_errno (errno); @@ -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_malloc (sizeof (*arg_list) * (data_length * 2)); + arg_list = gcry_calloc (data_length, sizeof (*arg_list) * 2); if (! arg_list) { err = gcry_error_from_errno (errno); @@ -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_malloc (sizeof (*arg_list) * arg_list_n); + arg_list = gcry_calloc (arg_list_n, sizeof (*arg_list)); if (! arg_list) { err = gcry_error_from_errno (errno); diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c index 2788e349f..b12e79b19 100644 --- a/grub-core/lib/libgcrypt/cipher/primegen.c +++ b/grub-core/lib/libgcrypt/cipher/primegen.c @@ -383,7 +383,7 @@ prime_generate_internal (int need_q_factor, } /* Allocate an array to track pool usage. */ - pool_in_use = gcry_malloc (n * sizeof *pool_in_use); + pool_in_use = gcry_calloc (n, sizeof *pool_in_use); if (!pool_in_use) { err = gpg_err_code_from_errno (errno); @@ -765,7 +765,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, if (nbits < 16) log_fatal ("can't generate a prime with less than %d bits\n", 16); - mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods ); + mods = gcry_xcalloc( 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); diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c index 910982141..ca087ad75 100644 --- a/grub-core/lib/libgcrypt/cipher/pubkey.c +++ b/grub-core/lib/libgcrypt/cipher/pubkey.c @@ -2941,7 +2941,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey) * array to a format string, so we have to do it this way :-(. */ /* FIXME: There is now such a format specifier, so we can change the code to be more clear. */ - arg_list = malloc (nelem * sizeof *arg_list); + arg_list = calloc (nelem, sizeof *arg_list); if (!arg_list) { rc = gpg_err_code_from_syserror (); @@ -3233,7 +3233,7 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) } strcpy (p, "))"); - arg_list = malloc (nelem * sizeof *arg_list); + arg_list = calloc (nelem, sizeof *arg_list); if (!arg_list) { rc = gpg_err_code_from_syserror (); diff --git a/grub-core/lib/libgcrypt/cipher/rijndael.c b/grub-core/lib/libgcrypt/cipher/rijndael.c index 559550b50..b3effa2db 100644 --- a/grub-core/lib/libgcrypt/cipher/rijndael.c +++ b/grub-core/lib/libgcrypt/cipher/rijndael.c @@ -181,7 +181,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) static int initialized = 0; static const char *selftest_failed=0; int rounds; - int i,j, r, t, rconpointer = 0; + unsigned int i; + int j, r, t, rconpointer = 0; int KC; union { @@ -227,7 +228,9 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) KC = 4; if (0) - ; + { + ; + } #ifdef USE_PADLOCK else if ((_gcry_get_hw_features () & HWF_PADLOCK_AES)) { diff --git a/grub-core/lib/libgcrypt/cipher/test-getrusage.c b/grub-core/lib/libgcrypt/cipher/test-getrusage.c index 479eaab8d..978cf2de9 100644 --- a/grub-core/lib/libgcrypt/cipher/test-getrusage.c +++ b/grub-core/lib/libgcrypt/cipher/test-getrusage.c @@ -27,7 +27,7 @@ main (int argc, char **argv) } printf ("ru_utime = %ld.%06ld\n", - buf.ru_utime.tv_sec, buf.ru_utime.tv_usec); + 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 ); @@ -60,7 +60,7 @@ collect_rusage_stats (struct rusage *rb) { static int idx; static struct rusage buf[100]; - + if (!rb) { int i; @@ -68,12 +68,12 @@ collect_rusage_stats (struct rusage *rb) 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_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; @@ -99,7 +99,7 @@ collect_rusage_stats (struct rusage *rb) add_randomness( &buf, sizeof buf, 1 ); memset( &buf, 0, sizeof buf ); } - + */ diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c index 4a84df64d..4ffe0eb23 100644 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c +++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c @@ -1,5 +1,5 @@ /* mpihelp-add_1.c - MPI helper functions - * Copyright (C) 1994, 1996, 1997, 1998, + * Copyright (C) 1994, 1996, 1997, 1998, * 2000, 2002 Free Software Foundation, Inc. * * This file is part of Libgcrypt. @@ -48,7 +48,7 @@ _gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, res_ptr -= j; cy = 0; - do + do { y = s2_ptr[j]; x = s1_ptr[j]; @@ -57,7 +57,7 @@ _gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 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 index f48c12cd0..8c1d943b0 100644 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c +++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c @@ -54,7 +54,7 @@ _gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, low_limb = up[i]; retval = low_limb >> sh_2; high_limb = low_limb; - while ( --i >= 0 ) + while ( --i >= 0 ) { low_limb = up[i]; wp[i] = (high_limb << sh_1) | (low_limb >> sh_2); diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c index 0e8197d88..614646c43 100644 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c +++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c @@ -48,13 +48,13 @@ _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, res_ptr -= j; cy_limb = 0; - do + 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 index 3b7549605..56979dfdb 100644 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c +++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c @@ -48,7 +48,7 @@ _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, s1_ptr -= j; cy_limb = 0; - do + do { umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb ); @@ -59,9 +59,9 @@ _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 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 index 5e84f94f3..9b8df1a69 100644 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c +++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c @@ -48,7 +48,7 @@ _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, s1_ptr -= j; cy_limb = 0; - do + do { umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb); @@ -59,7 +59,7 @@ _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 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-sub1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c index e88821bfb..25b08af1c 100644 --- a/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c +++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c @@ -48,7 +48,7 @@ _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, res_ptr -= j; cy = 0; - do + do { y = s2_ptr[j]; x = s1_ptr[j]; @@ -57,7 +57,7 @@ _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, 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/i386/syntax.h b/grub-core/lib/libgcrypt/mpi/i386/syntax.h index 39ede988f..88845f28d 100644 --- a/grub-core/lib/libgcrypt/mpi/i386/syntax.h +++ b/grub-core/lib/libgcrypt/mpi/i386/syntax.h @@ -1,6 +1,6 @@ /* syntax.h -- Definitions for x86 syntax variations. * - * Copyright (C) 1992, 1994, 1995, 1998, + * Copyright (C) 1992, 1994, 1995, 1998, * 2001, 2002 Free Software Foundation, Inc. * * This file is part of Libgcrypt. diff --git a/grub-core/lib/libgcrypt/mpi/m68k/syntax.h b/grub-core/lib/libgcrypt/mpi/m68k/syntax.h index e27de98b4..6a3fea130 100644 --- a/grub-core/lib/libgcrypt/mpi/m68k/syntax.h +++ b/grub-core/lib/libgcrypt/mpi/m68k/syntax.h @@ -2,7 +2,7 @@ * * 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 diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c index a3435ed14..6fe389165 100644 --- a/grub-core/lib/libgcrypt/mpi/mpicoder.c +++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c @@ -379,6 +379,9 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, 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 @@ -458,7 +461,7 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, if (len && len < 4) return gcry_error (GPG_ERR_TOO_SHORT); - n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); + 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; diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c index beeb661a3..74c6eafe5 100644 --- a/grub-core/lib/libgcrypt_wrap/mem.c +++ b/grub-core/lib/libgcrypt_wrap/mem.c @@ -4,6 +4,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -36,7 +37,10 @@ void * gcry_xcalloc (size_t n, size_t m) { void *ret; - ret = grub_zalloc (n * m); + 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; @@ -56,7 +60,10 @@ void * gcry_xcalloc_secure (size_t n, size_t m) { void *ret; - ret = grub_zalloc (n * m); + 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; 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 new file mode 100644 index 000000000..85bfa0732 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0001-libtasn1-disable-code-not-needed-in-grub.patch @@ -0,0 +1,320 @@ +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 new file mode 100644 index 000000000..908016df7 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0002-libtasn1-replace-strcat-with-strcpy-in-_asn1_str_cat.patch @@ -0,0 +1,33 @@ +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 new file mode 100644 index 000000000..d92ae1586 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0003-libtasn1-replace-strcat-with-_asn1_str_cat.patch @@ -0,0 +1,71 @@ +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 new file mode 100644 index 000000000..a5d5be417 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0004-libtasn1-adjust-the-header-paths-in-libtasn1.h.patch @@ -0,0 +1,39 @@ +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 new file mode 100644 index 000000000..201df10f7 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0005-libtasn1-Use-grub_divmod64-for-division.patch @@ -0,0 +1,31 @@ +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 new file mode 100644 index 000000000..f9f45ae72 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0006-libtasn1-fix-the-potential-buffer-overrun.patch @@ -0,0 +1,36 @@ +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 new file mode 100644 index 000000000..29b931368 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0007-asn1_test-include-asn1_test.h-only.patch @@ -0,0 +1,164 @@ +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 new file mode 100644 index 000000000..bd34b47f8 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0008-asn1_test-rename-the-main-functions-to-the-test-name.patch @@ -0,0 +1,129 @@ +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 new file mode 100644 index 000000000..b76942d84 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0009-asn1_test-return-either-0-or-1-to-reflect-the-result.patch @@ -0,0 +1,78 @@ +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 new file mode 100644 index 000000000..2bd8ffb48 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0010-asn1_test-remove-verbose-and-the-unnecessary-printf.patch @@ -0,0 +1,173 @@ +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 new file mode 100644 index 000000000..aadd362cd --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0011-asn1_test-print-the-error-messages-with-grub_printf.patch @@ -0,0 +1,485 @@ +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 new file mode 100644 index 000000000..ba2715751 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0012-asn1_test-use-the-grub-specific-functions-and-types.patch @@ -0,0 +1,263 @@ +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 new file mode 100644 index 000000000..a81a350c9 --- /dev/null +++ b/grub-core/lib/libtasn1-patches/0013-asn1_test-enable-the-testcase-only-when-GRUB_LONG_MA.patch @@ -0,0 +1,48 @@ +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 new file mode 100644 index 000000000..e8b3628db --- /dev/null +++ b/grub-core/lib/libtasn1/COPYING @@ -0,0 +1,16 @@ +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 new file mode 100644 index 000000000..b0305b93e --- /dev/null +++ b/grub-core/lib/libtasn1/README.md @@ -0,0 +1,98 @@ +# 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 new file mode 100644 index 000000000..ea5bc370e --- /dev/null +++ b/grub-core/lib/libtasn1/lib/coding.c @@ -0,0 +1,1425 @@ +/* + * 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 new file mode 100644 index 000000000..b9245c486 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/decoding.c @@ -0,0 +1,2501 @@ +/* + * 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 new file mode 100644 index 000000000..d4c558e10 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/element.c @@ -0,0 +1,1109 @@ +/* + * 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 new file mode 100644 index 000000000..8dd0ceba8 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/element.h @@ -0,0 +1,42 @@ +/* + * 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 new file mode 100644 index 000000000..aef5dfe6f --- /dev/null +++ b/grub-core/lib/libtasn1/lib/errors.c @@ -0,0 +1,100 @@ +/* + * 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 new file mode 100644 index 000000000..eef419554 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/gstr.c @@ -0,0 +1,74 @@ +/* + * 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 new file mode 100644 index 000000000..99be6c4af --- /dev/null +++ b/grub-core/lib/libtasn1/lib/gstr.h @@ -0,0 +1,50 @@ +/* + * 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 new file mode 100644 index 000000000..d94d51c8c --- /dev/null +++ b/grub-core/lib/libtasn1/lib/int.h @@ -0,0 +1,221 @@ +/* + * 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 new file mode 100644 index 000000000..c05bd2339 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/parser_aux.c @@ -0,0 +1,1178 @@ +/* + * 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 new file mode 100644 index 000000000..3eac1fa30 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/parser_aux.h @@ -0,0 +1,172 @@ +/* + * 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 new file mode 100644 index 000000000..512dd601f --- /dev/null +++ b/grub-core/lib/libtasn1/lib/structure.c @@ -0,0 +1,1225 @@ +/* + * 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 new file mode 100644 index 000000000..b973ce963 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/structure.h @@ -0,0 +1,46 @@ +/* + * 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 new file mode 100644 index 000000000..51cc7879f --- /dev/null +++ b/grub-core/lib/libtasn1/libtasn1.h @@ -0,0 +1,643 @@ +/* + * 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 new file mode 100644 index 000000000..e7930136c --- /dev/null +++ b/grub-core/lib/libtasn1/tests/CVE-2018-1000654-1_asn1_tab.h @@ -0,0 +1,32 @@ +#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 new file mode 100644 index 000000000..e8170f5d5 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/CVE-2018-1000654-2_asn1_tab.h @@ -0,0 +1,36 @@ +#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 new file mode 100644 index 000000000..0c22b7012 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/CVE-2018-1000654.c @@ -0,0 +1,72 @@ +/* + * 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 new file mode 100644 index 000000000..c61dea4bb --- /dev/null +++ b/grub-core/lib/libtasn1/tests/Test_overflow.c @@ -0,0 +1,168 @@ +/* + * 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 new file mode 100644 index 000000000..6cd07e069 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/Test_simple.c @@ -0,0 +1,226 @@ +/* + * 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 new file mode 100644 index 000000000..27f7215e1 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/Test_strings.c @@ -0,0 +1,156 @@ +/* + * 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 new file mode 100644 index 000000000..06a6c52a2 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/object-id-decoding.c @@ -0,0 +1,121 @@ +/* + * 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 new file mode 100644 index 000000000..1a3396986 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/object-id-encoding.c @@ -0,0 +1,133 @@ +/* + * 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 new file mode 100644 index 000000000..69eb18a62 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/octet-string.c @@ -0,0 +1,230 @@ +/* + * 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 new file mode 100644 index 000000000..a09d8b021 --- /dev/null +++ b/grub-core/lib/libtasn1/tests/reproducers.c @@ -0,0 +1,90 @@ +/* + * 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 new file mode 100644 index 000000000..fcada55a8 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/wrap.c @@ -0,0 +1,27 @@ +/* + * 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 new file mode 100644 index 000000000..2b46c41a3 --- /dev/null +++ b/grub-core/lib/loongarch64/setjmp.S @@ -0,0 +1,69 @@ +/* + * 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 index 1d0fe14fc..f9a8bdbee 100644 --- a/grub-core/lib/minilzo/lzoconf.h +++ b/grub-core/lib/minilzo/lzoconf.h @@ -2,22 +2,7 @@ This file is part of the LZO real-time data compression library. - Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer All Rights Reserved. The LZO library is free software; you can redistribute it and/or @@ -44,9 +29,9 @@ #ifndef __LZOCONF_H_INCLUDED #define __LZOCONF_H_INCLUDED 1 -#define LZO_VERSION 0x2050 -#define LZO_VERSION_STRING "2.05" -#define LZO_VERSION_DATE "Apr 23 2011" +#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) @@ -63,7 +48,7 @@ #if !defined(CHAR_BIT) || (CHAR_BIT != 8) # error "invalid CHAR_BIT" #endif -#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +#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) @@ -72,7 +57,7 @@ /* get OS and architecture defines */ #ifndef __LZODEFS_H_INCLUDED -#include "lzodefs.h" +#include #endif @@ -85,14 +70,6 @@ extern "C" { // some core defines ************************************************************************/ -#if !defined(LZO_UINT32_C) -# if (UINT_MAX < LZO_0xffffffffL) -# define LZO_UINT32_C(c) c ## UL -# else -# define LZO_UINT32_C(c) ((c) + 0U) -# endif -#endif - /* memory checkers */ #if !defined(__LZO_CHECKER) # if defined(__BOUNDS_CHECKING_ON) @@ -111,28 +88,35 @@ extern "C" { // integral and pointer types ************************************************************************/ -/* lzo_uint should match size_t */ +/* lzo_uint must match size_t */ #if !defined(LZO_UINT_MAX) -# if defined(LZO_ABI_LLP64) /* WIN64 */ -# if defined(LZO_OS_WIN64) +# 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 unsigned long long lzo_uint; - typedef long long lzo_int; + 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 defined(LZO_ABI_IP32L64) /* MIPS R5900 */ +# 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 @@ -141,63 +125,23 @@ extern "C" { # endif #endif -/* Integral types with 32 bits or more. */ -#if !defined(LZO_UINT32_MAX) -# if (UINT_MAX >= LZO_0xffffffffL) - typedef unsigned int lzo_uint32; - typedef int lzo_int32; -# define LZO_UINT32_MAX UINT_MAX -# define LZO_INT32_MAX INT_MAX -# define LZO_INT32_MIN INT_MIN -# elif (ULONG_MAX >= LZO_0xffffffffL) - typedef unsigned long lzo_uint32; - typedef long lzo_int32; -# define LZO_UINT32_MAX ULONG_MAX -# define LZO_INT32_MAX LONG_MAX -# define LZO_INT32_MIN LONG_MIN -# else -# error "lzo_uint32" -# endif -#endif - -/* Integral types with exactly 64 bits. */ -#if !defined(LZO_UINT64_MAX) -# if (LZO_UINT_MAX >= LZO_0xffffffffL) -# if ((((LZO_UINT_MAX) >> 31) >> 31) == 3) -# define lzo_uint64 lzo_uint -# define lzo_int64 lzo_int -# define LZO_UINT64_MAX LZO_UINT_MAX -# define LZO_INT64_MAX LZO_INT_MAX -# define LZO_INT64_MIN LZO_INT_MIN -# endif -# elif (ULONG_MAX >= LZO_0xffffffffL) -# if ((((ULONG_MAX) >> 31) >> 31) == 3) - typedef unsigned long lzo_uint64; - typedef long lzo_int64; -# define LZO_UINT64_MAX ULONG_MAX -# define LZO_INT64_MAX LONG_MAX -# define LZO_INT64_MIN LONG_MIN -# endif -# endif -#endif - -/* The larger type of lzo_uint and lzo_uint32. */ -#if (LZO_UINT_MAX >= LZO_UINT32_MAX) +/* 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 +# define lzo_xint lzo_uint32_t #endif -/* Memory model that allows to access memory at offsets of lzo_uint. */ -#if !defined(__LZO_MMODEL) -# if (LZO_UINT_MAX <= UINT_MAX) -# define __LZO_MMODEL /*empty*/ -# elif defined(LZO_HAVE_MM_HUGE_PTR) -# define __LZO_MMODEL_HUGE 1 -# define __LZO_MMODEL __huge -# else -# define __LZO_MMODEL /*empty*/ -# 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 */ @@ -206,21 +150,52 @@ extern "C" { #define lzo_voidp void __LZO_MMODEL * #define lzo_shortp short __LZO_MMODEL * #define lzo_ushortp unsigned short __LZO_MMODEL * -#define lzo_uint32p lzo_uint32 __LZO_MMODEL * -#define lzo_int32p lzo_int32 __LZO_MMODEL * -#if defined(LZO_UINT64_MAX) -#define lzo_uint64p lzo_uint64 __LZO_MMODEL * -#define lzo_int64p lzo_int64 __LZO_MMODEL * -#endif -#define lzo_uintp lzo_uint __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 * -/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */ -#define lzo_byte unsigned char __LZO_MMODEL -typedef int lzo_bool; +#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)) /*********************************************************************** @@ -251,13 +226,13 @@ typedef int lzo_bool; /* __cdecl calling convention for public C and assembly functions */ #if !defined(LZO_PUBLIC) -# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +# define LZO_PUBLIC(r) __LZO_EXPORT1 r __LZO_EXPORT2 __LZO_CDECL #endif #if !defined(LZO_EXTERN) -# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) +# define LZO_EXTERN(r) __LZO_EXTERN_C LZO_PUBLIC(r) #endif #if !defined(LZO_PRIVATE) -# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL +# define LZO_PRIVATE(r) static r __LZO_CDECL #endif /* function types */ @@ -315,7 +290,7 @@ struct lzo_callback_t /* a progress indicator callback function (set to 0 to disable) */ lzo_progress_func_t nprogress; - /* NOTE: the first parameter "self" of the nalloc/nfree/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; @@ -343,6 +318,9 @@ struct lzo_callback_t #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 @@ -356,7 +334,7 @@ struct lzo_callback_t * 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),(int)sizeof(lzo_uint),\ + (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); @@ -379,18 +357,22 @@ LZO_EXTERN(lzo_voidp) lzo_memset(lzo_voidp buf, int c, lzo_uint len); /* checksum functions */ -LZO_EXTERN(lzo_uint32) - lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len); -LZO_EXTERN(lzo_uint32) - lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len); -LZO_EXTERN(const lzo_uint32p) +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_bytep p; lzo_uint u; } __lzo_pu_u; -typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; -typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t; +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); @@ -399,9 +381,34 @@ LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size); /*********************************************************************** -// deprecated macros - only for backward compatibility with LZO v1.xx +// 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 @@ -443,4 +450,4 @@ LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size); #endif /* already included */ -/* vim:set ts=4 et: */ +/* vim:set ts=4 sw=4 et: */ diff --git a/grub-core/lib/minilzo/lzodefs.h b/grub-core/lib/minilzo/lzodefs.h index 0e40e332a..c3e2bcf5d 100644 --- a/grub-core/lib/minilzo/lzodefs.h +++ b/grub-core/lib/minilzo/lzodefs.h @@ -2,22 +2,7 @@ This file is part of the LZO real-time data compression library. - Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer All Rights Reserved. The LZO library is free software; you can redistribute it and/or @@ -47,12 +32,6 @@ #if defined(__CYGWIN32__) && !defined(__CYGWIN__) # define __CYGWIN__ __CYGWIN32__ #endif -#if defined(__IBMCPP__) && !defined(__IBMC__) -# define __IBMC__ __IBMCPP__ -#endif -#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) -# define __INTEL_COMPILER __ICL -#endif #if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) # define _ALL_SOURCE 1 #endif @@ -61,19 +40,57 @@ # define __LONG_MAX__ 9223372036854775807L # endif #endif -#if defined(__INTEL_COMPILER) && defined(__linux__) +#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) -#endif -#if defined(__KEIL__) && defined(__C166__) +#elif defined(__KEIL__) && defined(__C166__) # pragma warning disable = 322 -#elif 0 && defined(__C251__) -# pragma warning disable = 322 -#endif -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) -# if (_MSC_VER >= 1300) +#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 @@ -82,13 +99,29 @@ #if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) # pragma option -h #endif -#if 0 -#define LZO_0xffffL 0xfffful -#define LZO_0xffffffffL 0xfffffffful -#else -#define LZO_0xffffL 65535ul -#define LZO_0xffffffffL 4294967295ul +#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 @@ -103,6 +136,13 @@ # 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) @@ -122,10 +162,12 @@ # endif #endif #endif -#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +#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 @@ -233,14 +275,31 @@ #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) @@ -248,12 +307,16 @@ #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)-1)) - (o)) << 1) + (o)) +#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 @@ -263,9 +326,13 @@ # endif #endif #if defined(__cplusplus) -# define LZO_EXTERN_C extern "C" +# 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 extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ #endif #if !defined(__LZO_OS_OVERRIDE) #if (LZO_OS_FREESTANDING) @@ -360,18 +427,18 @@ #elif defined(__TOS__) || defined(__atarist__) # define LZO_OS_TOS 1 # define LZO_INFO_OS "tos" -#elif defined(macintosh) && !defined(__ppc__) +#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__)) +#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__)) +#elif defined(__mips__) && defined(__psp__) # define LZO_OS_CONSOLE 1 # define LZO_OS_CONSOLE_PSP 1 # define LZO_INFO_OS "console" @@ -399,9 +466,18 @@ # elif defined(__linux__) || defined(__linux) || defined(__LINUX__) # define LZO_OS_POSIX_LINUX 1 # define LZO_INFO_OS_POSIX "linux" -# elif defined(__APPLE__) || defined(__MACOS__) -# define LZO_OS_POSIX_MACOSX 1 -# define LZO_INFO_OS_POSIX "macosx" +# 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" @@ -436,18 +512,18 @@ #endif #if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) # if (UINT_MAX != LZO_0xffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# 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 "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif #if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) @@ -463,59 +539,81 @@ # 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__ * 0x100 + __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__ -#elif defined(__INTEL_COMPILER) -# define LZO_CC_INTELC 1 +# 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(_WIN32) || defined(_WIN64) -# define LZO_CC_SYNTAX_MSC 1 -# else -# define LZO_CC_SYNTAX_GNUC 1 +# 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(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) # if defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) # else -# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) # endif -# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) -# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) -# else -# define LZO_CC_CLANG_CLANG 0x010000L -# endif -# define LZO_CC_CLANG LZO_CC_CLANG_GNUC -# define LZO_INFO_CC "clang" +# 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__ * 0x100 + __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__ * 0x100) +# 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(__GNUC__) && defined(__VERSION__) -# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) -# elif defined(__GNUC_MINOR__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) -# else -# define LZO_CC_GNUC (__GNUC__ * 0x10000L) -# endif -# define LZO_INFO_CC "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" @@ -540,10 +638,23 @@ # 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" @@ -552,10 +663,14 @@ # else # define LZO_INFO_CCVER "unknown" # endif -#elif defined(__IBMC__) -# define LZO_CC_IBMC 1 +#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" @@ -572,16 +687,8 @@ # else # define LZO_INFO_CCVER "unknown" # endif -#elif defined(_MSC_VER) -# define LZO_CC_MSC 1 -# 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 -#elif defined(__MWERKS__) -# define LZO_CC_MWERKS 1 +#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) @@ -592,6 +699,15 @@ # 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" @@ -606,7 +722,7 @@ # define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) #elif defined(__SUNPRO_C) # define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_C)+0 > 0) +# if ((__SUNPRO_C-0) > 0) # define LZO_CC_SUNPROC __SUNPRO_C # define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) # else @@ -615,7 +731,7 @@ # endif #elif defined(__SUNPRO_CC) # define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_CC)+0 > 0) +# if ((__SUNPRO_CC-0) > 0) # define LZO_CC_SUNPROC __SUNPRO_CC # define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) # else @@ -641,16 +757,46 @@ #elif defined(__ZTC__) # define LZO_CC_ZORTECHC 1 # define LZO_INFO_CC "Zortech C" -# if (__ZTC__ == 0x310) +# 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 @@ -668,8 +814,10 @@ # define LZO_INFO_ARCH "generic" #elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) # define LZO_ARCH_I086 1 -# define LZO_ARCH_IA16 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" @@ -679,23 +827,12 @@ #elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) # define LZO_ARCH_AMD64 1 # define LZO_INFO_ARCH "amd64" -#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) -# define LZO_ARCH_ARM 1 -# define LZO_ARCH_ARM_THUMB 1 -# define LZO_INFO_ARCH "arm_thumb" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) -# define LZO_ARCH_ARM 1 -# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) -# define LZO_ARCH_ARM_THUMB 1 -# define LZO_INFO_ARCH "arm_thumb" -# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) -# define LZO_INFO_ARCH "arm" -# else -# define LZO_INFO_ARCH "arm" -# endif #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" @@ -768,6 +905,15 @@ #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" @@ -802,57 +948,171 @@ # 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 WIN32 define for CPU architecture" +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" #endif #if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) -# error "FIXME - missing WIN64 define for CPU architecture" +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" #endif #if (LZO_OS_OS216 || LZO_OS_WIN16) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #elif 1 && (LZO_OS_DOS16 && defined(BLX286)) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #endif -#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM) -# error "this should not happen" +#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_I086PM) && !(LZO_ARCH_I086) -# error "this should not happen" +#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 "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif #if (LZO_ARCH_I386) # if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif -#if !defined(__LZO_MM_OVERRIDE) +#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 "this should not happen" +# error "unexpected configuration - check your compiler defines" #endif #if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) # define LZO_MM_TINY 1 @@ -879,7 +1139,7 @@ #elif (LZO_CC_ZORTECHC && defined(__VCM__)) # define LZO_MM_LARGE 1 #else -# error "unknown memory model" +# 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 @@ -902,13 +1162,13 @@ #endif #if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) # if (LZO_OS_DOS16) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # elif (LZO_CC_ZORTECHC) # else -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif #if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) @@ -931,13 +1191,13 @@ extern "C" { #else # error "FIXME - implement LZO_MM_AHSHIFT" #endif -#ifdef __cplusplus +#if defined(__cplusplus) } #endif #endif #elif (LZO_ARCH_C166) #if !defined(__MODEL__) -# error "FIXME - C166 __MODEL__" +# error "FIXME - LZO_ARCH_C166 __MODEL__" #elif ((__MODEL__) == 0) # define LZO_MM_SMALL 1 #elif ((__MODEL__) == 1) @@ -951,11 +1211,11 @@ extern "C" { #elif ((__MODEL__) == 5) # define LZO_MM_XSMALL 1 #else -# error "FIXME - C166 __MODEL__" +# error "FIXME - LZO_ARCH_C166 __MODEL__" #endif #elif (LZO_ARCH_MCS251) #if !defined(__MODEL__) -# error "FIXME - MCS251 __MODEL__" +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" #elif ((__MODEL__) == 0) # define LZO_MM_SMALL 1 #elif ((__MODEL__) == 2) @@ -967,11 +1227,11 @@ extern "C" { #elif ((__MODEL__) == 5) # define LZO_MM_XSMALL 1 #else -# error "FIXME - MCS251 __MODEL__" +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" #endif #elif (LZO_ARCH_MCS51) #if !defined(__MODEL__) -# error "FIXME - MCS51 __MODEL__" +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" #elif ((__MODEL__) == 1) # define LZO_MM_SMALL 1 #elif ((__MODEL__) == 2) @@ -983,7 +1243,7 @@ extern "C" { #elif ((__MODEL__) == 5) # define LZO_MM_XSMALL 1 #else -# error "FIXME - MCS51 __MODEL__" +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" #endif #elif (LZO_ARCH_CRAY_PVP) # define LZO_MM_PVP 1 @@ -1010,567 +1270,197 @@ extern "C" { # error "unknown memory model" #endif #endif -#if defined(SIZEOF_SHORT) -# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) -#endif -#if defined(SIZEOF_INT) -# define LZO_SIZEOF_INT (SIZEOF_INT) -#endif -#if defined(SIZEOF_LONG) -# define LZO_SIZEOF_LONG (SIZEOF_LONG) -#endif -#if defined(SIZEOF_LONG_LONG) -# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) -#endif -#if defined(SIZEOF___INT16) -# define LZO_SIZEOF___INT16 (SIZEOF___INT16) -#endif -#if defined(SIZEOF___INT32) -# define LZO_SIZEOF___INT32 (SIZEOF___INT32) -#endif -#if defined(SIZEOF___INT64) -# define LZO_SIZEOF___INT64 (SIZEOF___INT64) -#endif -#if defined(SIZEOF_VOID_P) -# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) -#endif -#if defined(SIZEOF_SIZE_T) -# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) -#endif -#if defined(SIZEOF_PTRDIFF_T) -# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) -#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 -#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 -#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,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 -#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_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_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 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) || defined(__NO_LONG_LONG) -# undef LZO_SIZEOF_LONG_LONG -#endif -#if !defined(LZO_SIZEOF_VOID_P) -#if (LZO_ARCH_I086) -# define __LZO_WORDSIZE 2 -# 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 "LZO_MM" -# endif -#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) -# define __LZO_WORDSIZE 1 -# 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(__NORMAL_MODE__) -# define __LZO_WORDSIZE 4 -# define LZO_SIZEOF_VOID_P 2 -# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) -# define __LZO_WORDSIZE 4 -# define LZO_SIZEOF_VOID_P 4 -# else -# define __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_M16C) -# define __LZO_WORDSIZE 2 -# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) -# define LZO_SIZEOF_VOID_P 4 -# else -# define LZO_SIZEOF_VOID_P 2 -# endif -#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) -# define __LZO_WORDSIZE 8 -# define LZO_SIZEOF_VOID_P 4 -#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) -# define __LZO_WORDSIZE 8 -# define LZO_SIZEOF_VOID_P 8 -#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) -# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -#elif (LZO_OS_OS400 || defined(__OS400__)) -# define __LZO_WORDSIZE LZO_SIZEOF_LONG -# define LZO_SIZEOF_VOID_P 16 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -#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 -#elif (LZO_ARCH_SPU) -# if 0 -# define __LZO_WORDSIZE 16 -# endif -# define LZO_SIZEOF_VOID_P 4 -#else -# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG -#endif -#endif -#if !defined(LZO_WORDSIZE) -# if defined(__LZO_WORDSIZE) -# define LZO_WORDSIZE __LZO_WORDSIZE -# else -# define LZO_WORDSIZE LZO_SIZEOF_VOID_P -# endif -#endif -#if !defined(LZO_SIZEOF_SIZE_T) -#if (LZO_ARCH_I086 || LZO_ARCH_M16C) -# define LZO_SIZEOF_SIZE_T 2 -#else -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P -#endif -#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 "LZO_MM" -# endif -#else -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T -#endif -#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) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390) -# 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(__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_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 "this should not happen" -#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 == 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 !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 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__ * 0x100 + __UCLIBC_SUBLEVEL__) -# else -# define LZO_LIBC_UCLIBC 0x00090bL -# endif -# define LZO_INFO_LIBC "uclibc" -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) -# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 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 !defined(__lzo_gnuc_extension__) #if (LZO_CC_GNUC >= 0x020800ul) # define __lzo_gnuc_extension__ __extension__ -#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) # define __lzo_gnuc_extension__ __extension__ -#else +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#endif +#endif +#if !defined(__lzo_gnuc_extension__) # define __lzo_gnuc_extension__ /*empty*/ #endif -#endif -#if !defined(__lzo_ua_volatile) -# define __lzo_ua_volatile volatile -#endif -#if !defined(__lzo_alignof) -#if (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_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 && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_alignof(e) __alignof__(e) +#if !defined(lzo_has_builtin) +#if (LZO_CC_CLANG) && defined(__has_builtin) +# define lzo_has_builtin __has_builtin #endif #endif -#if defined(__lzo_alignof) -# define __lzo_HAVE_alignof 1 +#if !defined(lzo_has_builtin) +# define lzo_has_builtin(x) 0 #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_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_constructor __attribute__((__constructor__)) +#if !defined(lzo_has_attribute) +#if (LZO_CC_CLANG) && defined(__has_attribute) +# define lzo_has_attribute __has_attribute #endif #endif -#if defined(__lzo_constructor) -# define __lzo_HAVE_constructor 1 +#if !defined(lzo_has_attribute) +# define lzo_has_attribute(x) 0 #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_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_destructor __attribute__((__destructor__)) +#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_destructor) -# define __lzo_HAVE_destructor 1 +#if !defined(lzo_has_declspec_attribute) +# define lzo_has_declspec_attribute(x) 0 #endif -#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) -# error "this should not happen" -#endif -#if !defined(__lzo_inline) -#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) -#elif defined(__cplusplus) -# define __lzo_inline inline -#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) -# define __lzo_inline __inline -#elif (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_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 && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_inline __inline__ -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define __lzo_inline inline +#if !defined(lzo_has_feature) +#if (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_feature __has_feature #endif #endif -#if defined(__lzo_inline) -# define __lzo_HAVE_inline 1 -#else -# define __lzo_inline /*empty*/ +#if !defined(lzo_has_feature) +# define lzo_has_feature(x) 0 #endif -#if !defined(__lzo_forceinline) -#if (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) -# define __lzo_forceinline __forceinline -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (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_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#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_forceinline) -# define __lzo_HAVE_forceinline 1 -#else -# define __lzo_forceinline /*empty*/ +#if !defined(lzo_has_extension) +# define lzo_has_extension(x) 0 #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_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) -# define __lzo_noinline __declspec(noinline) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (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) +#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_noinline __declspec(noinline) +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 # endif -#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_noinline __attribute__((__noinline__)) #endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 #endif -#if defined(__lzo_noinline) -# define __lzo_HAVE_noinline 1 -#else -# define __lzo_noinline /*empty*/ +#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 (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) -# error "this should not happen" +#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_noreturn) -#if (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) -# define __lzo_noreturn __declspec(noreturn) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (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) +#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_noreturn) -# define __lzo_HAVE_noreturn 1 -#else -# define __lzo_noreturn /*empty*/ +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) #endif -#if !defined(__lzo_nothrow) -#if (LZO_CC_GNUC >= 0x030300ul) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) -# define __lzo_nothrow __declspec(nothrow) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (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) +#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_nothrow) -# define __lzo_HAVE_nothrow 1 -#else -# define __lzo_nothrow /*empty*/ +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) #endif -#if !defined(__lzo_restrict) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_CLANG || LZO_CC_LLVM) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) -# define __lzo_restrict __restrict +#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_restrict) -# define __lzo_HAVE_restrict 1 -#else -# define __lzo_restrict /*empty*/ +#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_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_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_LLVM || LZO_CC_PATHSCALE) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#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_likely) -# define __lzo_HAVE_likely 1 -#else -# define __lzo_likely(e) (e) +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) #endif -#if defined(__lzo_unlikely) -# define __lzo_HAVE_unlikely 1 -#else -# define __lzo_unlikely(e) (e) +#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)];} +# 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) @@ -1579,6 +1469,9 @@ extern "C" { # 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) @@ -1591,18 +1484,18 @@ extern "C" { # 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)];} +# 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_WATCOMC) && defined(__cplusplus) -# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l -# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) -# define LZO_UNUSED_LABEL(l) if (0) goto l +# 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 +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l # endif #endif #if !defined(LZO_DEFINE_UNINITIALIZED_VAR) @@ -1614,39 +1507,512 @@ extern "C" { # define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init # endif #endif -#if !defined(LZO_UNCONST_CAST) -# if 0 && defined(__cplusplus) -# define LZO_UNCONST_CAST(t,e) (const_cast (e)) -# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e)))))) -# else -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e))))) +#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) extern int __lzo_cta[1-!(e)]; +# 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) extern int __lzo_cta[1u-2*!(e)]; +# 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) extern int __lzo_cta[1-!(e)]; +# 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) extern int __lzo_cta[1-2*!(e)]; +# 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_t[1-!(e)];} +# 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_t[1-2*!(e)];} +# 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) @@ -1710,70 +2076,680 @@ extern "C" { # 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 && LZO_CC_GNUC) && defined(__PW32__) +# 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_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_AVOID_SHORT 1 -# define LZO_OPT_AVOID_USHORT 1 +# define LZO_WORDSIZE 8 #elif (LZO_ARCH_AMD64) -# define LZO_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 -# define LZO_OPT_UNALIGNED64 1 -#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) -#elif (LZO_ARCH_ARM) -# define LZO_OPT_AVOID_SHORT 1 -# define LZO_OPT_AVOID_USHORT 1 -#elif (LZO_ARCH_CRIS) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 -#elif (LZO_ARCH_I386) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 +# 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_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_PREFER_POSTINC 1 +# 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 +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 # if defined(__mc68020__) && !defined(__mcoldfire__) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 +# 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 +# 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) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 +# 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) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 -# if (LZO_SIZEOF_SIZE_T == 8) -# define LZO_OPT_UNALIGNED64 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_SH) -# define LZO_OPT_PREFER_POSTINC 1 -# define LZO_OPT_PREFER_PREDEC 1 +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 #endif #ifndef LZO_CFG_NO_INLINE_ASM -#if (LZO_CC_LLVM) +#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 @@ -1784,25 +2760,6 @@ extern "C" { # undef LZO_OPT_UNALIGNED32 # undef LZO_OPT_UNALIGNED64 #endif -#if (LZO_CFG_NO_INLINE_ASM) -#elif (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 -#endif -#if (LZO_ASM_SYNTAX_GNUC) -#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) -# define __LZO_ASM_CLOBBER "ax" -#elif (LZO_CC_INTELC) -# define __LZO_ASM_CLOBBER "memory" -#else -# define __LZO_ASM_CLOBBER "cc", "memory" -#endif -#endif #if defined(__LZO_INFOSTR_MM) #elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) # define __LZO_INFOSTR_MM "" @@ -1846,7 +2803,466 @@ extern "C" { #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 et: */ +/* vim:set ts=4 sw=4 et: */ diff --git a/grub-core/lib/minilzo/minilzo.c b/grub-core/lib/minilzo/minilzo.c index 25a1f68b3..8fd866450 100644 --- a/grub-core/lib/minilzo/minilzo.c +++ b/grub-core/lib/minilzo/minilzo.c @@ -2,22 +2,7 @@ This file is part of the LZO real-time data compression library. - Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer All Rights Reserved. The LZO library is free software; you can redistribute it and/or @@ -67,12 +52,6 @@ #if defined(__CYGWIN32__) && !defined(__CYGWIN__) # define __CYGWIN__ __CYGWIN32__ #endif -#if defined(__IBMCPP__) && !defined(__IBMC__) -# define __IBMC__ __IBMCPP__ -#endif -#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER) -# define __INTEL_COMPILER __ICL -#endif #if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) # define _ALL_SOURCE 1 #endif @@ -81,19 +60,57 @@ # define __LONG_MAX__ 9223372036854775807L # endif #endif -#if defined(__INTEL_COMPILER) && defined(__linux__) +#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) -#endif -#if defined(__KEIL__) && defined(__C166__) +#elif defined(__KEIL__) && defined(__C166__) # pragma warning disable = 322 -#elif 0 && defined(__C251__) -# pragma warning disable = 322 -#endif -#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) -# if (_MSC_VER >= 1300) +#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 @@ -102,13 +119,29 @@ #if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) # pragma option -h #endif -#if 0 -#define LZO_0xffffL 0xfffful -#define LZO_0xffffffffL 0xfffffffful -#else -#define LZO_0xffffL 65535ul -#define LZO_0xffffffffL 4294967295ul +#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 @@ -123,6 +156,13 @@ # 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) @@ -142,10 +182,12 @@ # endif #endif #endif -#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +#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 @@ -253,14 +295,31 @@ #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) @@ -268,12 +327,16 @@ #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)-1)) - (o)) << 1) + (o)) +#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 @@ -283,9 +346,13 @@ # endif #endif #if defined(__cplusplus) -# define LZO_EXTERN_C extern "C" +# 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 extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ #endif #if !defined(__LZO_OS_OVERRIDE) #if (LZO_OS_FREESTANDING) @@ -380,18 +447,18 @@ #elif defined(__TOS__) || defined(__atarist__) # define LZO_OS_TOS 1 # define LZO_INFO_OS "tos" -#elif defined(macintosh) && !defined(__ppc__) +#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__)) +#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__)) +#elif defined(__mips__) && defined(__psp__) # define LZO_OS_CONSOLE 1 # define LZO_OS_CONSOLE_PSP 1 # define LZO_INFO_OS "console" @@ -419,9 +486,18 @@ # elif defined(__linux__) || defined(__linux) || defined(__LINUX__) # define LZO_OS_POSIX_LINUX 1 # define LZO_INFO_OS_POSIX "linux" -# elif defined(__APPLE__) || defined(__MACOS__) -# define LZO_OS_POSIX_MACOSX 1 -# define LZO_INFO_OS_POSIX "macosx" +# 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" @@ -456,18 +532,18 @@ #endif #if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) # if (UINT_MAX != LZO_0xffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# 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 "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif #if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) @@ -483,59 +559,81 @@ # 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__ * 0x100 + __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__ -#elif defined(__INTEL_COMPILER) -# define LZO_CC_INTELC 1 +# 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(_WIN32) || defined(_WIN64) -# define LZO_CC_SYNTAX_MSC 1 -# else -# define LZO_CC_SYNTAX_GNUC 1 +# 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(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) # if defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) # else -# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) # endif -# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) -# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) -# else -# define LZO_CC_CLANG_CLANG 0x010000L -# endif -# define LZO_CC_CLANG LZO_CC_CLANG_GNUC -# define LZO_INFO_CC "clang" +# 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__ * 0x100 + __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__ * 0x100) +# 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(__GNUC__) && defined(__VERSION__) -# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) -# elif defined(__GNUC_MINOR__) -# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) -# else -# define LZO_CC_GNUC (__GNUC__ * 0x10000L) -# endif -# define LZO_INFO_CC "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" @@ -560,10 +658,23 @@ # 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" @@ -572,10 +683,14 @@ # else # define LZO_INFO_CCVER "unknown" # endif -#elif defined(__IBMC__) -# define LZO_CC_IBMC 1 +#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" @@ -592,16 +707,8 @@ # else # define LZO_INFO_CCVER "unknown" # endif -#elif defined(_MSC_VER) -# define LZO_CC_MSC 1 -# 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 -#elif defined(__MWERKS__) -# define LZO_CC_MWERKS 1 +#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) @@ -612,6 +719,15 @@ # 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" @@ -626,7 +742,7 @@ # define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) #elif defined(__SUNPRO_C) # define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_C)+0 > 0) +# if ((__SUNPRO_C-0) > 0) # define LZO_CC_SUNPROC __SUNPRO_C # define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) # else @@ -635,7 +751,7 @@ # endif #elif defined(__SUNPRO_CC) # define LZO_INFO_CC "SunPro C" -# if ((__SUNPRO_CC)+0 > 0) +# if ((__SUNPRO_CC-0) > 0) # define LZO_CC_SUNPROC __SUNPRO_CC # define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) # else @@ -661,16 +777,46 @@ #elif defined(__ZTC__) # define LZO_CC_ZORTECHC 1 # define LZO_INFO_CC "Zortech C" -# if (__ZTC__ == 0x310) +# 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 @@ -688,8 +834,10 @@ # define LZO_INFO_ARCH "generic" #elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) # define LZO_ARCH_I086 1 -# define LZO_ARCH_IA16 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" @@ -699,23 +847,12 @@ #elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) # define LZO_ARCH_AMD64 1 # define LZO_INFO_ARCH "amd64" -#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) -# define LZO_ARCH_ARM 1 -# define LZO_ARCH_ARM_THUMB 1 -# define LZO_INFO_ARCH "arm_thumb" -#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) -# define LZO_ARCH_ARM 1 -# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1) -# define LZO_ARCH_ARM_THUMB 1 -# define LZO_INFO_ARCH "arm_thumb" -# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2) -# define LZO_INFO_ARCH "arm" -# else -# define LZO_INFO_ARCH "arm" -# endif #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" @@ -788,6 +925,15 @@ #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" @@ -822,57 +968,171 @@ # 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 WIN32 define for CPU architecture" +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" #endif #if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) -# error "FIXME - missing WIN64 define for CPU architecture" +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" #endif #if (LZO_OS_OS216 || LZO_OS_WIN16) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #elif 1 && (LZO_OS_DOS16 && defined(BLX286)) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) # define LZO_ARCH_I086PM 1 -# define LZO_ARCH_IA16PM 1 #endif -#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM) -# error "this should not happen" +#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_I086PM) && !(LZO_ARCH_I086) -# error "this should not happen" +#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 "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif #if (LZO_ARCH_I386) # if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif # if (ULONG_MAX != LZO_0xffffffffL) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif -#if !defined(__LZO_MM_OVERRIDE) +#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 "this should not happen" +# error "unexpected configuration - check your compiler defines" #endif #if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) # define LZO_MM_TINY 1 @@ -899,7 +1159,7 @@ #elif (LZO_CC_ZORTECHC && defined(__VCM__)) # define LZO_MM_LARGE 1 #else -# error "unknown memory model" +# 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 @@ -922,13 +1182,13 @@ #endif #if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) # if (LZO_OS_DOS16) -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # elif (LZO_CC_ZORTECHC) # else -# error "this should not happen" +# error "unexpected configuration - check your compiler defines" # endif #endif -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif #if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) @@ -951,13 +1211,13 @@ extern "C" { #else # error "FIXME - implement LZO_MM_AHSHIFT" #endif -#ifdef __cplusplus +#if defined(__cplusplus) } #endif #endif #elif (LZO_ARCH_C166) #if !defined(__MODEL__) -# error "FIXME - C166 __MODEL__" +# error "FIXME - LZO_ARCH_C166 __MODEL__" #elif ((__MODEL__) == 0) # define LZO_MM_SMALL 1 #elif ((__MODEL__) == 1) @@ -971,11 +1231,11 @@ extern "C" { #elif ((__MODEL__) == 5) # define LZO_MM_XSMALL 1 #else -# error "FIXME - C166 __MODEL__" +# error "FIXME - LZO_ARCH_C166 __MODEL__" #endif #elif (LZO_ARCH_MCS251) #if !defined(__MODEL__) -# error "FIXME - MCS251 __MODEL__" +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" #elif ((__MODEL__) == 0) # define LZO_MM_SMALL 1 #elif ((__MODEL__) == 2) @@ -987,11 +1247,11 @@ extern "C" { #elif ((__MODEL__) == 5) # define LZO_MM_XSMALL 1 #else -# error "FIXME - MCS251 __MODEL__" +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" #endif #elif (LZO_ARCH_MCS51) #if !defined(__MODEL__) -# error "FIXME - MCS51 __MODEL__" +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" #elif ((__MODEL__) == 1) # define LZO_MM_SMALL 1 #elif ((__MODEL__) == 2) @@ -1003,7 +1263,7 @@ extern "C" { #elif ((__MODEL__) == 5) # define LZO_MM_XSMALL 1 #else -# error "FIXME - MCS51 __MODEL__" +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" #endif #elif (LZO_ARCH_CRAY_PVP) # define LZO_MM_PVP 1 @@ -1030,567 +1290,197 @@ extern "C" { # error "unknown memory model" #endif #endif -#if defined(SIZEOF_SHORT) -# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) -#endif -#if defined(SIZEOF_INT) -# define LZO_SIZEOF_INT (SIZEOF_INT) -#endif -#if defined(SIZEOF_LONG) -# define LZO_SIZEOF_LONG (SIZEOF_LONG) -#endif -#if defined(SIZEOF_LONG_LONG) -# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) -#endif -#if defined(SIZEOF___INT16) -# define LZO_SIZEOF___INT16 (SIZEOF___INT16) -#endif -#if defined(SIZEOF___INT32) -# define LZO_SIZEOF___INT32 (SIZEOF___INT32) -#endif -#if defined(SIZEOF___INT64) -# define LZO_SIZEOF___INT64 (SIZEOF___INT64) -#endif -#if defined(SIZEOF_VOID_P) -# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) -#endif -#if defined(SIZEOF_SIZE_T) -# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) -#endif -#if defined(SIZEOF_PTRDIFF_T) -# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) -#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 -#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 -#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,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 -#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_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_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 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) || defined(__NO_LONG_LONG) -# undef LZO_SIZEOF_LONG_LONG -#endif -#if !defined(LZO_SIZEOF_VOID_P) -#if (LZO_ARCH_I086) -# define __LZO_WORDSIZE 2 -# 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 "LZO_MM" -# endif -#elif (LZO_ARCH_AVR || LZO_ARCH_Z80) -# define __LZO_WORDSIZE 1 -# 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(__NORMAL_MODE__) -# define __LZO_WORDSIZE 4 -# define LZO_SIZEOF_VOID_P 2 -# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) -# define __LZO_WORDSIZE 4 -# define LZO_SIZEOF_VOID_P 4 -# else -# define __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_M16C) -# define __LZO_WORDSIZE 2 -# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) -# define LZO_SIZEOF_VOID_P 4 -# else -# define LZO_SIZEOF_VOID_P 2 -# endif -#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) -# define __LZO_WORDSIZE 8 -# define LZO_SIZEOF_VOID_P 4 -#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) -# define __LZO_WORDSIZE 8 -# define LZO_SIZEOF_VOID_P 8 -#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) -# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -#elif (LZO_OS_OS400 || defined(__OS400__)) -# define __LZO_WORDSIZE LZO_SIZEOF_LONG -# define LZO_SIZEOF_VOID_P 16 -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG -#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 -#elif (LZO_ARCH_SPU) -# if 0 -# define __LZO_WORDSIZE 16 -# endif -# define LZO_SIZEOF_VOID_P 4 -#else -# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG -#endif -#endif -#if !defined(LZO_WORDSIZE) -# if defined(__LZO_WORDSIZE) -# define LZO_WORDSIZE __LZO_WORDSIZE -# else -# define LZO_WORDSIZE LZO_SIZEOF_VOID_P -# endif -#endif -#if !defined(LZO_SIZEOF_SIZE_T) -#if (LZO_ARCH_I086 || LZO_ARCH_M16C) -# define LZO_SIZEOF_SIZE_T 2 -#else -# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P -#endif -#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 "LZO_MM" -# endif -#else -# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T -#endif -#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) -# define LZO_ABI_LITTLE_ENDIAN 1 -#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390) -# 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(__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_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 "this should not happen" -#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 == 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 !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 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__ * 0x100 + __UCLIBC_SUBLEVEL__) -# else -# define LZO_LIBC_UCLIBC 0x00090bL -# endif -# define LZO_INFO_LIBC "uclibc" -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) -# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 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 !defined(__lzo_gnuc_extension__) #if (LZO_CC_GNUC >= 0x020800ul) # define __lzo_gnuc_extension__ __extension__ -#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) # define __lzo_gnuc_extension__ __extension__ -#else +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#endif +#endif +#if !defined(__lzo_gnuc_extension__) # define __lzo_gnuc_extension__ /*empty*/ #endif -#endif -#if !defined(__lzo_ua_volatile) -# define __lzo_ua_volatile volatile -#endif -#if !defined(__lzo_alignof) -#if (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_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 && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_alignof(e) __alignof__(e) +#if !defined(lzo_has_builtin) +#if (LZO_CC_CLANG) && defined(__has_builtin) +# define lzo_has_builtin __has_builtin #endif #endif -#if defined(__lzo_alignof) -# define __lzo_HAVE_alignof 1 +#if !defined(lzo_has_builtin) +# define lzo_has_builtin(x) 0 #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_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_constructor __attribute__((__constructor__)) +#if !defined(lzo_has_attribute) +#if (LZO_CC_CLANG) && defined(__has_attribute) +# define lzo_has_attribute __has_attribute #endif #endif -#if defined(__lzo_constructor) -# define __lzo_HAVE_constructor 1 +#if !defined(lzo_has_attribute) +# define lzo_has_attribute(x) 0 #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_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define __lzo_destructor __attribute__((__destructor__)) +#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_destructor) -# define __lzo_HAVE_destructor 1 +#if !defined(lzo_has_declspec_attribute) +# define lzo_has_declspec_attribute(x) 0 #endif -#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) -# error "this should not happen" -#endif -#if !defined(__lzo_inline) -#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) -#elif defined(__cplusplus) -# define __lzo_inline inline -#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) -# define __lzo_inline __inline -#elif (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_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 && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_inline __inline__ -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define __lzo_inline inline +#if !defined(lzo_has_feature) +#if (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_feature __has_feature #endif #endif -#if defined(__lzo_inline) -# define __lzo_HAVE_inline 1 -#else -# define __lzo_inline /*empty*/ +#if !defined(lzo_has_feature) +# define lzo_has_feature(x) 0 #endif -#if !defined(__lzo_forceinline) -#if (LZO_CC_GNUC >= 0x030200ul) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) -# define __lzo_forceinline __forceinline -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) -#elif (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_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#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_forceinline) -# define __lzo_HAVE_forceinline 1 -#else -# define __lzo_forceinline /*empty*/ +#if !defined(lzo_has_extension) +# define lzo_has_extension(x) 0 #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_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC) -# define __lzo_noinline __declspec(noinline) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC) -# define __lzo_noinline __attribute__((__noinline__)) -#elif (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) +#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_noinline __declspec(noinline) +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 # endif -#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100)) -# define __lzo_noinline __attribute__((__noinline__)) #endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 #endif -#if defined(__lzo_noinline) -# define __lzo_HAVE_noinline 1 -#else -# define __lzo_noinline /*empty*/ +#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 (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) -# error "this should not happen" +#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_noreturn) -#if (LZO_CC_GNUC >= 0x020700ul) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) -# define __lzo_noreturn __declspec(noreturn) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) -# define __lzo_noreturn __attribute__((__noreturn__)) -#elif (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) +#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_noreturn) -# define __lzo_HAVE_noreturn 1 -#else -# define __lzo_noreturn /*empty*/ +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) #endif -#if !defined(__lzo_nothrow) -#if (LZO_CC_GNUC >= 0x030300ul) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus) -# define __lzo_nothrow __declspec(nothrow) -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC) -# define __lzo_nothrow __attribute__((__nothrow__)) -#elif (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) +#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_nothrow) -# define __lzo_HAVE_nothrow 1 -#else -# define __lzo_nothrow /*empty*/ +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) #endif -#if !defined(__lzo_restrict) -#if (LZO_CC_GNUC >= 0x030400ul) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_CLANG || LZO_CC_LLVM) -# define __lzo_restrict __restrict__ -#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) -# define __lzo_restrict __restrict +#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_restrict) -# define __lzo_HAVE_restrict 1 -#else -# define __lzo_restrict /*empty*/ +#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_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_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_LLVM || LZO_CC_PATHSCALE) -# define __lzo_likely(e) (__builtin_expect(!!(e),1)) -# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#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_likely) -# define __lzo_HAVE_likely 1 -#else -# define __lzo_likely(e) (e) +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) #endif -#if defined(__lzo_unlikely) -# define __lzo_HAVE_unlikely 1 -#else -# define __lzo_unlikely(e) (e) +#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)];} +# 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) @@ -1599,6 +1489,9 @@ extern "C" { # 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) @@ -1611,18 +1504,18 @@ extern "C" { # 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)];} +# 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_WATCOMC) && defined(__cplusplus) -# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l -# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) -# define LZO_UNUSED_LABEL(l) if (0) goto l +# 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 +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l # endif #endif #if !defined(LZO_DEFINE_UNINITIALIZED_VAR) @@ -1634,39 +1527,512 @@ extern "C" { # define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init # endif #endif -#if !defined(LZO_UNCONST_CAST) -# if 0 && defined(__cplusplus) -# define LZO_UNCONST_CAST(t,e) (const_cast (e)) -# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e)))))) -# else -# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e))))) +#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) extern int __lzo_cta[1-!(e)]; +# 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) extern int __lzo_cta[1u-2*!(e)]; +# 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) extern int __lzo_cta[1-!(e)]; +# 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) extern int __lzo_cta[1-2*!(e)]; +# 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_t[1-!(e)];} +# 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_t[1-2*!(e)];} +# 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) @@ -1730,70 +2096,680 @@ extern "C" { # 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 && LZO_CC_GNUC) && defined(__PW32__) +# 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_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_AVOID_SHORT 1 -# define LZO_OPT_AVOID_USHORT 1 +# define LZO_WORDSIZE 8 #elif (LZO_ARCH_AMD64) -# define LZO_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 -# define LZO_OPT_UNALIGNED64 1 -#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB) -#elif (LZO_ARCH_ARM) -# define LZO_OPT_AVOID_SHORT 1 -# define LZO_OPT_AVOID_USHORT 1 -#elif (LZO_ARCH_CRIS) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 -#elif (LZO_ARCH_I386) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 +# 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_OPT_AVOID_INT_INDEX 1 -# define LZO_OPT_AVOID_UINT_INDEX 1 -# define LZO_OPT_PREFER_POSTINC 1 +# 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 +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 # if defined(__mc68020__) && !defined(__mcoldfire__) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 +# 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 +# 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) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 +# 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) -# define LZO_OPT_UNALIGNED16 1 -# define LZO_OPT_UNALIGNED32 1 -# if (LZO_SIZEOF_SIZE_T == 8) -# define LZO_OPT_UNALIGNED64 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_SH) -# define LZO_OPT_PREFER_POSTINC 1 -# define LZO_OPT_PREFER_PREDEC 1 +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 #endif #ifndef LZO_CFG_NO_INLINE_ASM -#if (LZO_CC_LLVM) +#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 @@ -1804,25 +2780,6 @@ extern "C" { # undef LZO_OPT_UNALIGNED32 # undef LZO_OPT_UNALIGNED64 #endif -#if (LZO_CFG_NO_INLINE_ASM) -#elif (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 -#endif -#if (LZO_ASM_SYNTAX_GNUC) -#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) -# define __LZO_ASM_CLOBBER "ax" -#elif (LZO_CC_INTELC) -# define __LZO_ASM_CLOBBER "memory" -#else -# define __LZO_ASM_CLOBBER "cc", "memory" -#endif -#endif #if defined(__LZO_INFOSTR_MM) #elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) # define __LZO_INFOSTR_MM "" @@ -1866,6 +2823,465 @@ extern "C" { #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 @@ -1874,7 +3290,7 @@ extern "C" { #undef LZO_HAVE_CONFIG_H #include "minilzo.h" -#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2050) +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x20a0) # error "version mismatch in miniLZO source files" #endif @@ -1886,23 +3302,9 @@ extern "C" { #define __LZO_CONF_H 1 #if !defined(__LZO_IN_MINILZO) -#if (LZO_CFG_FREESTANDING) +#if defined(LZO_CFG_FREESTANDING) && (LZO_CFG_FREESTANDING) # define LZO_LIBC_FREESTANDING 1 # define LZO_OS_FREESTANDING 1 -# define ACC_LIBC_FREESTANDING 1 -# define ACC_OS_FREESTANDING 1 -#endif -#if (LZO_CFG_NO_UNALIGNED) -# define ACC_CFG_NO_UNALIGNED 1 -#endif -#if (LZO_ARCH_GENERIC) -# define ACC_ARCH_GENERIC 1 -#endif -#if (LZO_ABI_NEUTRAL_ENDIAN) -# define ACC_ABI_NEUTRAL_ENDIAN 1 -#endif -#if (LZO_HAVE_CONFIG_H) -# define ACC_CONFIG_NO_HEADER 1 #endif #if defined(LZO_CFG_EXTRA_CONFIG_HEADER) # include LZO_CFG_EXTRA_CONFIG_HEADER @@ -1910,23 +3312,41 @@ extern "C" { #if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) # error "include this file first" #endif -#include "lzo/lzoconf.h" +#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 (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED) +#if !defined(__LZOCONF_H_INCLUDED) || (LZO_VERSION+0 != 0x20a0) # error "version mismatch" #endif -#if (LZO_CC_BORLANDC && LZO_ARCH_I086) -# pragma option -h +#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) -# pragma warning(disable: 4514 4710 4711) +#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) @@ -1937,49 +3357,42 @@ extern "C" { #endif #endif -#if (__LZO_MMODEL_HUGE) && !(LZO_HAVE_MM_HUGE_PTR) -# error "this should not happen - check defines for __huge" +#if !defined(__LZO_NOEXPORT1) +# define __LZO_NOEXPORT1 /*empty*/ +#endif +#if !defined(__LZO_NOEXPORT2) +# define __LZO_NOEXPORT2 /*empty*/ #endif -#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING) -#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) -# define ACC_WANT_ACC_INCD_H 1 -# define ACC_WANT_ACC_INCE_H 1 -# define ACC_WANT_ACC_INCI_H 1 +#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 ACC_WANT_ACC_INCD_H 1 +# define LZO_WANT_ACC_INCD_H 1 #endif - -#if (LZO_ARCH_I086) -# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT -# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0]) -# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1]) -# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o))) +#if defined(LZO_HAVE_CONFIG_H) +# define LZO_CFG_NO_CONFIG_HEADER 1 #endif -#if !defined(lzo_uintptr_t) -# if defined(__LZO_MMODEL_HUGE) -# define lzo_uintptr_t unsigned long -# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16) -# define __LZO_UINTPTR_T_IS_POINTER 1 - typedef char* lzo_uintptr_t; -# define lzo_uintptr_t lzo_uintptr_t -# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P) -# define lzo_uintptr_t size_t -# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P) -# define lzo_uintptr_t unsigned long -# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P) -# define lzo_uintptr_t unsigned int -# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P) -# define lzo_uintptr_t unsigned long long -# else -# define lzo_uintptr_t size_t -# endif -#endif -LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) - #if 1 && !defined(LZO_CFG_FREESTANDING) #if 1 && !defined(HAVE_STRING_H) #define HAVE_STRING_H 1 @@ -2002,6 +3415,23 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) #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 @@ -2012,28 +3442,28 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) #if !(HAVE_MEMCMP) # undef memcmp # define memcmp(a,b,c) lzo_memcmp(a,b,c) -#elif !(__LZO_MMODEL_HUGE) +#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) -#elif !(__LZO_MMODEL_HUGE) +#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) -#elif !(__LZO_MMODEL_HUGE) +#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) -#elif !(__LZO_MMODEL_HUGE) +#else # undef lzo_memset # define lzo_memset(a,b,c) memset(a,b,c) #endif @@ -2058,27 +3488,29 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) # define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) #endif -#if !defined(__lzo_inline) -# define __lzo_inline /*empty*/ -#endif -#if !defined(__lzo_forceinline) -# define __lzo_forceinline /*empty*/ -#endif -#if !defined(__lzo_noinline) -# define __lzo_noinline /*empty*/ -#endif - #if (LZO_CFG_PGO) -# undef __acc_likely -# undef __acc_unlikely # undef __lzo_likely # undef __lzo_unlikely -# define __acc_likely(e) (e) -# define __acc_unlikely(e) (e) # 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 @@ -2097,84 +3529,544 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) #define LZO_SIZE(bits) (1u << (bits)) #define LZO_MASK(bits) (LZO_SIZE(bits) - 1) -#define LZO_LSIZE(bits) (1ul << (bits)) -#define LZO_LMASK(bits) (LZO_LSIZE(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)(a) * (lzo_uint32)(b))) +# 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 -#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386 || LZO_ARCH_POWERPC) -# if (LZO_SIZEOF_SHORT == 2) -# define LZO_UNALIGNED_OK_2 1 -# endif -# if (LZO_SIZEOF_INT == 4) -# define LZO_UNALIGNED_OK_4 1 -# 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 -#if 1 && (LZO_ARCH_AMD64) -# if defined(LZO_UINT64_MAX) -# define LZO_UNALIGNED_OK_8 1 -# endif #endif -#if (LZO_CFG_NO_UNALIGNED) -# undef LZO_UNALIGNED_OK_2 -# undef LZO_UNALIGNED_OK_4 -# undef LZO_UNALIGNED_OK_8 #endif -#undef UA_GET16 -#undef UA_SET16 -#undef UA_COPY16 -#undef UA_GET32 -#undef UA_SET32 -#undef UA_COPY32 -#undef UA_GET64 -#undef UA_SET64 -#undef UA_COPY64 -#if defined(LZO_UNALIGNED_OK_2) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(unsigned short) == 2) -# if 1 && defined(ACC_UA_COPY16) -# define UA_GET16 ACC_UA_GET16 -# define UA_SET16 ACC_UA_SET16 -# define UA_COPY16 ACC_UA_COPY16 -# else -# define UA_GET16(p) (* (__lzo_ua_volatile const lzo_ushortp) (__lzo_ua_volatile const lzo_voidp) (p)) -# define UA_SET16(p,v) ((* (__lzo_ua_volatile lzo_ushortp) (__lzo_ua_volatile lzo_voidp) (p)) = (unsigned short) (v)) -# define UA_COPY16(d,s) UA_SET16(d, UA_GET16(s)) -# 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_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4) -# if 1 && defined(ACC_UA_COPY32) -# define UA_GET32 ACC_UA_GET32 -# define UA_SET32 ACC_UA_SET32 -# define UA_COPY32 ACC_UA_COPY32 -# else -# define UA_GET32(p) (* (__lzo_ua_volatile const lzo_uint32p) (__lzo_ua_volatile const lzo_voidp) (p)) -# define UA_SET32(p,v) ((* (__lzo_ua_volatile lzo_uint32p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint32) (v)) -# define UA_COPY32(d,s) UA_SET32(d, UA_GET32(s)) -# 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 -#if defined(LZO_UNALIGNED_OK_8) - LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64) == 8) -# if 1 && defined(ACC_UA_COPY64) -# define UA_GET64 ACC_UA_GET64 -# define UA_SET64 ACC_UA_SET64 -# define UA_COPY64 ACC_UA_COPY64 -# else -# define UA_GET64(p) (* (__lzo_ua_volatile const lzo_uint64p) (__lzo_ua_volatile const lzo_voidp) (p)) -# define UA_SET64(p,v) ((* (__lzo_ua_volatile lzo_uint64p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint64) (v)) -# define UA_COPY64(d,s) UA_SET64(d, UA_GET64(s)) -# 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) \ @@ -2195,25 +4087,10 @@ LZO_EXTERN(const lzo_bytep) lzo_copyright(void); extern "C" { #endif -#if !defined(lzo_uintptr_t) -# if (__LZO_MMODEL_HUGE) -# define lzo_uintptr_t unsigned long -# else -# define lzo_uintptr_t acc_uintptr_t -# ifdef __ACC_INTPTR_T_IS_POINTER -# define __LZO_UINTPTR_T_IS_POINTER 1 -# endif -# endif -#endif - #if (LZO_ARCH_I086) -#define PTR(a) ((lzo_bytep) (a)) -#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0) -#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0) +#error "LZO_ARCH_I086 is unsupported" #elif (LZO_MM_PVP) -#define PTR(a) ((lzo_bytep) (a)) -#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0) -#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0) +#error "LZO_MM_PVP is unsupported" #else #define PTR(a) ((lzo_uintptr_t) (a)) #define PTR_LINEAR(a) PTR(a) @@ -2243,24 +4120,28 @@ typedef union unsigned long a_ulong; lzo_int a_lzo_int; lzo_uint a_lzo_uint; - lzo_int32 a_lzo_int32; - lzo_uint32 a_lzo_uint32; -#if defined(LZO_UINT64_MAX) - lzo_int64 a_lzo_int64; - lzo_uint64 a_lzo_uint64; + 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; - lzo_voidp a_lzo_voidp; void * a_void_p; - lzo_bytep a_lzo_bytep; - lzo_bytepp a_lzo_bytepp; - lzo_uintp a_lzo_uintp; - lzo_uint * a_lzo_uint_p; - lzo_uint32p a_lzo_uint32p; - lzo_uint32 * a_lzo_uint32_p; - unsigned char * a_uchar_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; @@ -2276,18 +4157,14 @@ lzo_full_align_t; #ifndef LZO_DICT_USE_PTR #define LZO_DICT_USE_PTR 1 -#if 0 && (LZO_ARCH_I086) -# undef LZO_DICT_USE_PTR -# define LZO_DICT_USE_PTR 0 -#endif #endif #if (LZO_DICT_USE_PTR) # define lzo_dict_t const lzo_bytep -# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +# define lzo_dict_p lzo_dict_t * #else # define lzo_dict_t lzo_uint -# define lzo_dict_p lzo_dict_t __LZO_MMODEL * +# define lzo_dict_p lzo_dict_t * #endif #endif @@ -2300,10 +4177,9 @@ __lzo_ptr_linear(const lzo_voidp ptr) lzo_uintptr_t p; #if (LZO_ARCH_I086) - p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr)); +#error "LZO_ARCH_I086 is unsupported" #elif (LZO_MM_PVP) - p = (lzo_uintptr_t) (ptr); - p = (p << 3) | (p >> 61); +#error "LZO_MM_PVP is unsupported" #else p = (lzo_uintptr_t) PTR_LINEAR(ptr); #endif @@ -2314,16 +4190,20 @@ __lzo_ptr_linear(const lzo_voidp ptr) LZO_PUBLIC(unsigned) __lzo_align_gap(const lzo_voidp ptr, lzo_uint size) { -#if defined(__LZO_UINTPTR_T_IS_POINTER) - size_t n = (size_t) ptr; - n = (((n + size - 1) / size) * size) - n; +#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(size > 0); assert((long)n >= 0); assert(n <= size); return (unsigned)n; @@ -2336,27 +4216,25 @@ __lzo_align_gap(const lzo_voidp ptr, lzo_uint size) * keep this copyright string in the executable of your product. */ -static const char __lzo_copyright[] = +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-2011 Markus Franz Xaver Johannes Oberhumer\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) { -#if (LZO_OS_DOS16 && LZO_CC_TURBOC) - return (lzo_voidp) __lzo_copyright; -#else - return (const lzo_bytep) __lzo_copyright; -#endif + return (const lzo_bytep) lzo_copyright_; } LZO_PUBLIC(unsigned) @@ -2368,41 +4246,41 @@ lzo_version(void) LZO_PUBLIC(const char *) lzo_version_string(void) { - return LZO_VERSION_STRING; + return lzo_version_string_; } LZO_PUBLIC(const char *) lzo_version_date(void) { - return LZO_VERSION_DATE; + return lzo_version_date_; } LZO_PUBLIC(const lzo_charp) _lzo_version_string(void) { - return LZO_VERSION_STRING; + return lzo_version_string_; } LZO_PUBLIC(const lzo_charp) _lzo_version_date(void) { - return LZO_VERSION_DATE; + 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); +#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) -lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len) +LZO_PUBLIC(lzo_uint32_t) +lzo_adler32(lzo_uint32_t adler, const lzo_bytep buf, lzo_uint len) { - lzo_uint32 s1 = adler & 0xffff; - lzo_uint32 s2 = (adler >> 16) & 0xffff; + lzo_uint32_t s1 = adler & 0xffff; + lzo_uint32_t s2 = (adler >> 16) & 0xffff; unsigned k; if (buf == NULL) @@ -2459,8 +4337,8 @@ lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len) 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 = (const lzo_hbyte_p) s1; - const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2; + 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; @@ -2476,8 +4354,8 @@ LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo 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_hbyte_p) dest; - const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + 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 @@ -2491,8 +4369,8 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src 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_hbyte_p) dest; - const lzo_hbyte_p p2 = (const lzo_hbyte_p) src; + 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) @@ -2514,16 +4392,17 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p sr return memmove(dest, src, len); #endif } -LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len) +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_hbyte_p) s; + 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++ = (unsigned char) c; + *p++ = c; while __lzo_likely(--len > 0); return s; #else - return memset(s, c, len); + return memset(s, cc, len); #endif } #undef LZOLIB_PUBLIC @@ -2532,105 +4411,28 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len) #if !defined(__LZO_IN_MINILZO) -#define ACC_WANT_ACC_CHK_CH 1 -#undef ACCCHK_ASSERT +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT - ACCCHK_ASSERT_IS_SIGNED_T(lzo_int) - ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) - - ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32) - ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32) - ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) - ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4) -#if defined(LZO_UINT64_MAX) - ACCCHK_ASSERT(sizeof(lzo_uint64) == 8) - ACCCHK_ASSERT_IS_SIGNED_T(lzo_int64) - ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint64) + 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 - -#if !defined(__LZO_UINTPTR_T_IS_POINTER) - ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) -#endif - ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) - - ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) - ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32)) - ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint)) - ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint)) + LZOCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) #endif -#undef ACCCHK_ASSERT +#undef LZOCHK_ASSERT -#if 0 -#define WANT_lzo_bitops_clz32 1 -#define WANT_lzo_bitops_clz64 1 -#endif -#define WANT_lzo_bitops_ctz32 1 -#define WANT_lzo_bitops_ctz64 1 - -#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) -#include -#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0 -#pragma intrinsic(_BitScanReverse) -static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v) -{ - unsigned long r; - (void) _BitScanReverse(&r, v); - return (unsigned) r; -} -#define lzo_bitops_clz32 lzo_bitops_clz32 -#endif -#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0 -#pragma intrinsic(_BitScanReverse64) -static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v) -{ - unsigned long r; - (void) _BitScanReverse64(&r, v); - return (unsigned) r; -} -#define lzo_bitops_clz64 lzo_bitops_clz64 -#endif -#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) -#pragma intrinsic(_BitScanForward) -static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v) -{ - unsigned long r; - (void) _BitScanForward(&r, v); - return (unsigned) r; -} -#define lzo_bitops_ctz32 lzo_bitops_ctz32 -#endif -#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) -#pragma intrinsic(_BitScanForward64) -static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v) -{ - unsigned long r; - (void) _BitScanForward64(&r, v); - return (unsigned) r; -} -#define lzo_bitops_ctz64 lzo_bitops_ctz64 -#endif - -#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || LZO_CC_LLVM) -#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) -#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v)) -#endif -#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) -#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v)) -#endif -#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) -#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v)) -#endif -#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) -#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v)) -#endif -#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32) -#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v)) -#endif -#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX) -#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v)) -#endif +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))) @@ -2644,73 +4446,101 @@ static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off) LZO_PUBLIC(int) _lzo_config_check(void) { - lzo_bool r = 1; - union { - lzo_xint a[2]; unsigned char b[2*LZO_MAX(8,sizeof(lzo_xint))]; -#if defined(LZO_UNALIGNED_OK_8) - lzo_uint64 c[2]; +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030100ul && LZO_CC_CLANG < 0x030300ul)) +# if 0 + volatile +# endif #endif - unsigned short x[2]; lzo_uint32 y[2]; lzo_uint z[2]; - } u; + 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 !defined(LZO_CFG_NO_CONFIG_CHECK) -#if defined(LZO_ABI_BIG_ENDIAN) +#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 defined(LZO_ABI_LITTLE_ENDIAN) +#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 -#if defined(LZO_UNALIGNED_OK_2) u.a[0] = u.a[1] = 0; - u.b[0] = 1; u.b[sizeof(unsigned short) + 1] = 2; + u.b[0] = 1; u.b[3] = 2; p = u2p(&u, 1); - r &= ((* (lzo_ushortp) p) == 0); + 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 -#if defined(LZO_UNALIGNED_OK_4) u.a[0] = u.a[1] = 0; - u.b[0] = 3; u.b[sizeof(lzo_uint32) + 1] = 4; + u.b[0] = 3; u.b[5] = 4; p = u2p(&u, 1); - r &= ((* (lzo_uint32p) p) == 0); + 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 defined(LZO_UNALIGNED_OK_8) +#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[sizeof(lzo_uint64) + 1] = 6; + u.b[0] = 5; u.b[9] = 6; p = u2p(&u, 1); - r &= ((* (lzo_uint64p) p) == 0); -#endif -#if defined(lzo_bitops_clz32) - { unsigned i; lzo_uint32 v = 1; - for (i = 0; i < 31; i++, v <<= 1) - r &= lzo_bitops_clz32(v) == 31 - i; - } -#endif -#if defined(lzo_bitops_clz64) - { unsigned i; lzo_uint64 v = 1; - for (i = 0; i < 63; i++, v <<= 1) - r &= lzo_bitops_clz64(v) == 63 - i; - } -#endif -#if defined(lzo_bitops_ctz32) - { unsigned i; lzo_uint32 v = 1; - for (i = 0; i < 31; i++, v <<= 1) - r &= lzo_bitops_ctz32(v) == i; - } -#endif -#if defined(lzo_bitops_ctz64) - { unsigned i; lzo_uint64 v = 1; - for (i = 0; i < 63; i++, v <<= 1) - r &= lzo_bitops_ctz64(v) == i; - } + 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; } @@ -2724,11 +4554,11 @@ __lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, #if defined(__LZO_IN_MINILZO) #elif (LZO_CC_MSC && ((_MSC_VER) < 700)) #else -#define ACC_WANT_ACC_CHK_CH 1 -#undef ACCCHK_ASSERT -#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT +#define LZOCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) #endif -#undef ACCCHK_ASSERT +#undef LZOCHK_ASSERT if (v == 0) return LZO_E_ERROR; @@ -2736,7 +4566,7 @@ __lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, 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)) && + (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 *)) && @@ -2779,11 +4609,11 @@ int __far __pascal LibMain ( int a, short b, short c, long d ) #if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) -#if 1 && defined(UA_GET32) +#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 unsigned short +#define lzo_dict_t lzo_uint16_t #endif #define LZO_NEED_DICT_H 1 @@ -2806,7 +4636,7 @@ int __far __pascal LibMain ( int a, short b, short c, long d ) #endif #if !defined(__LZO_IN_MINILZO) -#include "lzo/lzo1x.h" +#include #endif #ifndef LZO_EOF_CODE @@ -2998,7 +4828,7 @@ extern "C" { #if !defined(DVAL_ASSERT) #if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) -#if (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_LLVM) +#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 @@ -3088,77 +4918,7 @@ DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) #endif #if 1 && defined(DO_COMPRESS) && !defined(do_compress) -# define do_compress LZO_CPP_ECONCAT2(DO_COMPRESS,_core) -#endif - -#if defined(UA_GET64) -# define WANT_lzo_bitops_ctz64 1 -#elif defined(UA_GET32) -# define WANT_lzo_bitops_ctz32 1 -#endif - -#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) -#include -#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0 -#pragma intrinsic(_BitScanReverse) -static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v) -{ - unsigned long r; - (void) _BitScanReverse(&r, v); - return (unsigned) r; -} -#define lzo_bitops_clz32 lzo_bitops_clz32 -#endif -#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0 -#pragma intrinsic(_BitScanReverse64) -static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v) -{ - unsigned long r; - (void) _BitScanReverse64(&r, v); - return (unsigned) r; -} -#define lzo_bitops_clz64 lzo_bitops_clz64 -#endif -#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) -#pragma intrinsic(_BitScanForward) -static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v) -{ - unsigned long r; - (void) _BitScanForward(&r, v); - return (unsigned) r; -} -#define lzo_bitops_ctz32 lzo_bitops_ctz32 -#endif -#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) -#pragma intrinsic(_BitScanForward64) -static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v) -{ - unsigned long r; - (void) _BitScanForward64(&r, v); - return (unsigned) r; -} -#define lzo_bitops_ctz64 lzo_bitops_ctz64 -#endif - -#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || LZO_CC_LLVM) -#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) -#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v)) -#endif -#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) -#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v)) -#endif -#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32) -#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v)) -#endif -#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX) -#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v)) -#endif -#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32) -#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v)) -#endif -#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX) -#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v)) -#endif +# define do_compress LZO_PP_ECONCAT2(DO_COMPRESS,_core) #endif static __lzo_noinline lzo_uint @@ -3166,7 +4926,7 @@ do_compress ( const lzo_bytep in , lzo_uint in_len, lzo_bytep out, lzo_uintp out_len, lzo_uint ti, lzo_voidp wrkmem) { - register const lzo_bytep ip; + 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; @@ -3175,7 +4935,7 @@ do_compress ( const lzo_bytep in , lzo_uint in_len, op = out; ip = in; - ii = ip - ti; + ii = ip; ip += ti < 4 ? 4 - ti : 0; for (;;) @@ -3205,8 +4965,8 @@ next: goto literal; try_match: -#if defined(UA_GET32) - if (UA_GET32(m_pos) != UA_GET32(ip)) +#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 @@ -3221,49 +4981,43 @@ literal: lzo_uint m_off; lzo_uint m_len; { - lzo_uint32 dv; + lzo_uint32_t dv; lzo_uint dindex; literal: ip += 1 + ((ip - ii) >> 5); next: if __lzo_unlikely(ip >= ip_end) break; - dv = UA_GET32(ip); + 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_GET32(m_pos)) + if __lzo_unlikely(dv != UA_GET_LE32(m_pos)) goto literal; } #endif + ii -= ti; ti = 0; { - register lzo_uint t = pd(ip,ii); + lzo_uint t = pd(ip,ii); if (t != 0) { if (t <= 3) { - op[-2] |= LZO_BYTE(t); -#if defined(UA_COPY32) - UA_COPY32(op, ii); + 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 defined(UA_COPY32) || defined(UA_COPY64) +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) else if (t <= 16) { *op++ = LZO_BYTE(t - 3); -#if defined(UA_COPY64) - UA_COPY64(op, ii); - UA_COPY64(op+8, ii+8); -#else - UA_COPY32(op, ii); - UA_COPY32(op+4, ii+4); - UA_COPY32(op+8, ii+8); - UA_COPY32(op+12, ii+12); -#endif + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); op += t; } #endif @@ -3273,31 +5027,21 @@ next: *op++ = LZO_BYTE(t - 3); else { - register lzo_uint tt = t - 18; + lzo_uint tt = t - 18; *op++ = 0; while __lzo_unlikely(tt > 255) { tt -= 255; -#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) - * (volatile unsigned char *) op++ = 0; -#else - *op++ = 0; -#endif + UA_SET1(op, 0); + op++; } assert(tt > 0); *op++ = LZO_BYTE(tt); } -#if defined(UA_COPY32) || defined(UA_COPY64) +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) do { -#if defined(UA_COPY64) - UA_COPY64(op, ii); - UA_COPY64(op+8, ii+8); -#else - UA_COPY32(op, ii); - UA_COPY32(op+4, ii+4); - UA_COPY32(op+8, ii+8); - UA_COPY32(op+12, ii+12); -#endif + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); op += 16; ii += 16; t -= 16; } while (t >= 16); if (t > 0) #endif @@ -3307,19 +5051,26 @@ next: } m_len = 4; { -#if defined(UA_GET64) - lzo_uint64 v; - v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len); +#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_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len); + 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_LITTLE_ENDIAN) && defined(lzo_bitops_ctz64) - m_len += lzo_bitops_ctz64(v) / CHAR_BIT; +#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; @@ -3330,19 +5081,30 @@ next: m_len += 1; } while (ip[m_len] == m_pos[m_len]); #endif -#elif defined(UA_GET32) - lzo_uint32 v; - v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len); +#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_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len); + 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_LITTLE_ENDIAN) && defined(lzo_bitops_ctz32) - m_len += lzo_bitops_ctz32(v) / CHAR_BIT; +#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; @@ -3357,6 +5119,27 @@ next: 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]); @@ -3390,11 +5173,8 @@ m_len_done: while __lzo_unlikely(m_len > 255) { m_len -= 255; -#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) - * (volatile unsigned char *) op++ = 0; -#else - *op++ = 0; -#endif + UA_SET1(op, 0); + op++; } *op++ = LZO_BYTE(m_len); } @@ -3413,11 +5193,8 @@ m_len_done: while __lzo_unlikely(m_len > 255) { m_len -= 255; -#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) - * (volatile unsigned char *) op++ = 0; -#else - *op++ = 0; -#endif + UA_SET1(op, 0); + op++; } *op++ = LZO_BYTE(m_len); } @@ -3428,7 +5205,7 @@ m_len_done: } *out_len = pd(op, out); - return pd(in_end,ii); + return pd(in_end,ii-ti); } LZO_PUBLIC(int) @@ -3468,7 +5245,7 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, if (op == out && t <= 238) *op++ = LZO_BYTE(17 + t); else if (t <= 3) - op[-2] |= LZO_BYTE(t); + op[-2] = LZO_BYTE(op[-2] | t); else if (t <= 18) *op++ = LZO_BYTE(t - 3); else @@ -3479,17 +5256,14 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, while (tt > 255) { tt -= 255; -#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400)) - - * (volatile unsigned char *) op++ = 0; -#else - *op++ = 0; -#endif + UA_SET1(op, 0); + op++; } assert(tt > 0); *op++ = LZO_BYTE(tt); } - do *op++ = *ii++; while (--t > 0); + UA_COPYN(op, ii, t); + op += t; } *op++ = M4_MARKER | 1; @@ -3526,10 +5300,13 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, #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 @@ -3544,6 +5321,7 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, # 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 @@ -3555,12 +5333,13 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, # 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 (m_pos < out || m_pos >= op) goto lookbehind_overrun -# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +# 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) @@ -3581,15 +5360,27 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, # 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) @@ -3606,14 +5397,14 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, lzo_voidp wrkmem ) #endif { - register lzo_bytep op; - register const lzo_bytep ip; - register lzo_uint t; + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; #if defined(COPY_DICT) lzo_uint m_off; const lzo_bytep dict_end; #else - register const lzo_bytep m_pos; + const lzo_bytep m_pos; #endif const lzo_bytep const ip_end = in + in_len; @@ -3648,43 +5439,45 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, 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+1); + assert(t > 0); NEED_OP(t); NEED_IP(t+3); do *op++ = *ip++; while (--t > 0); goto first_literal_run; } - while (TEST_IP && TEST_OP) + for (;;) { + NEED_IP(3); t = *ip++; if (t >= 16) goto match; if (t == 0) { - NEED_IP(1); 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+4); -#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + 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_COPY64(op,ip); + UA_COPY8(op,ip); op += 8; ip += 8; t -= 8; } while (t >= 8); if (t >= 4) { - UA_COPY32(op,ip); + UA_COPY4(op,ip); op += 4; ip += 4; t -= 4; } if (t > 0) @@ -3692,19 +5485,19 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, *op++ = *ip++; if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } } -#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) -#if !defined(LZO_UNALIGNED_OK_4) +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) if (PTR_ALIGNED2_4(op,ip)) { #endif - UA_COPY32(op,ip); + UA_COPY4(op,ip); op += 4; ip += 4; if (--t > 0) { if (t >= 4) { do { - UA_COPY32(op,ip); + UA_COPY4(op,ip); op += 4; ip += 4; t -= 4; } while (t >= 4); if (t > 0) do *op++ = *ip++; while (--t > 0); @@ -3712,12 +5505,12 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, else do *op++ = *ip++; while (--t > 0); } -#if !defined(LZO_UNALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) } else #endif #endif -#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8) +#if !(LZO_OPT_UNALIGNED32) { *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; do *op++ = *ip++; while (--t > 0); @@ -3753,7 +5546,7 @@ first_literal_run: #endif goto match_done; - do { + for (;;) { match: if (t >= 64) { @@ -3813,14 +5606,15 @@ match: t &= 31; if (t == 0) { - NEED_IP(1); 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) @@ -3836,9 +5630,9 @@ match: m_pos = op - off; last_m_off = off; } -#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) m_pos = op - 1; - m_pos -= UA_GET16(ip) >> 2; + m_pos -= UA_GET_LE16(ip) >> 2; #else m_pos = op - 1; m_pos -= (ip[0] >> 2) + (ip[1] << 6); @@ -3857,14 +5651,15 @@ match: t &= 7; if (t == 0) { - NEED_IP(1); 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) @@ -3882,8 +5677,8 @@ match: #else #if defined(LZO1Z) m_pos -= (ip[0] << 6) + (ip[1] >> 2); -#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) - m_pos -= UA_GET16(ip) >> 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 @@ -3931,18 +5726,18 @@ match: #else TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); -#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) if (op - m_pos >= 8) { t += (3 - 1); if (t >= 8) do { - UA_COPY64(op,m_pos); + UA_COPY8(op,m_pos); op += 8; m_pos += 8; t -= 8; } while (t >= 8); if (t >= 4) { - UA_COPY32(op,m_pos); + UA_COPY4(op,m_pos); op += 4; m_pos += 4; t -= 4; } if (t > 0) @@ -3952,8 +5747,8 @@ match: } } else -#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) -#if !defined(LZO_UNALIGNED_OK_4) +#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); @@ -3961,10 +5756,10 @@ match: if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) { #endif - UA_COPY32(op,m_pos); + UA_COPY4(op,m_pos); op += 4; m_pos += 4; t -= 4 - (3 - 1); do { - UA_COPY32(op,m_pos); + 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); @@ -3989,7 +5784,7 @@ match_done: break; match_next: - assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); #if 0 do *op++ = *ip++; while (--t > 0); #else @@ -3997,16 +5792,10 @@ match_next: if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } #endif t = *ip++; - } while (TEST_IP && TEST_OP); + } } -#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) - *out_len = pd(op, out); - return LZO_E_EOF_NOT_FOUND; -#endif - eof_found: - assert(t == 1); *out_len = pd(op, out); return (ip == ip_end ? LZO_E_OK : (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); @@ -4052,10 +5841,13 @@ lookbehind_overrun: #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 @@ -4070,6 +5862,7 @@ lookbehind_overrun: # 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 @@ -4081,12 +5874,13 @@ lookbehind_overrun: # 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 (m_pos < out || m_pos >= op) goto lookbehind_overrun -# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +# 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) @@ -4107,15 +5901,27 @@ lookbehind_overrun: # 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) @@ -4132,14 +5938,14 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, lzo_voidp wrkmem ) #endif { - register lzo_bytep op; - register const lzo_bytep ip; - register lzo_uint t; + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; #if defined(COPY_DICT) lzo_uint m_off; const lzo_bytep dict_end; #else - register const lzo_bytep m_pos; + const lzo_bytep m_pos; #endif const lzo_bytep const ip_end = in + in_len; @@ -4174,43 +5980,45 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, 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+1); + assert(t > 0); NEED_OP(t); NEED_IP(t+3); do *op++ = *ip++; while (--t > 0); goto first_literal_run; } - while (TEST_IP && TEST_OP) + for (;;) { + NEED_IP(3); t = *ip++; if (t >= 16) goto match; if (t == 0) { - NEED_IP(1); 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+4); -#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) + 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_COPY64(op,ip); + UA_COPY8(op,ip); op += 8; ip += 8; t -= 8; } while (t >= 8); if (t >= 4) { - UA_COPY32(op,ip); + UA_COPY4(op,ip); op += 4; ip += 4; t -= 4; } if (t > 0) @@ -4218,19 +6026,19 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, *op++ = *ip++; if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } } -#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) -#if !defined(LZO_UNALIGNED_OK_4) +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) if (PTR_ALIGNED2_4(op,ip)) { #endif - UA_COPY32(op,ip); + UA_COPY4(op,ip); op += 4; ip += 4; if (--t > 0) { if (t >= 4) { do { - UA_COPY32(op,ip); + UA_COPY4(op,ip); op += 4; ip += 4; t -= 4; } while (t >= 4); if (t > 0) do *op++ = *ip++; while (--t > 0); @@ -4238,12 +6046,12 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, else do *op++ = *ip++; while (--t > 0); } -#if !defined(LZO_UNALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) } else #endif #endif -#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8) +#if !(LZO_OPT_UNALIGNED32) { *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; do *op++ = *ip++; while (--t > 0); @@ -4279,7 +6087,7 @@ first_literal_run: #endif goto match_done; - do { + for (;;) { match: if (t >= 64) { @@ -4339,14 +6147,15 @@ match: t &= 31; if (t == 0) { - NEED_IP(1); 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) @@ -4362,9 +6171,9 @@ match: m_pos = op - off; last_m_off = off; } -#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) m_pos = op - 1; - m_pos -= UA_GET16(ip) >> 2; + m_pos -= UA_GET_LE16(ip) >> 2; #else m_pos = op - 1; m_pos -= (ip[0] >> 2) + (ip[1] << 6); @@ -4383,14 +6192,15 @@ match: t &= 7; if (t == 0) { - NEED_IP(1); 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) @@ -4408,8 +6218,8 @@ match: #else #if defined(LZO1Z) m_pos -= (ip[0] << 6) + (ip[1] >> 2); -#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) - m_pos -= UA_GET16(ip) >> 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 @@ -4457,18 +6267,18 @@ match: #else TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); -#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4) +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) if (op - m_pos >= 8) { t += (3 - 1); if (t >= 8) do { - UA_COPY64(op,m_pos); + UA_COPY8(op,m_pos); op += 8; m_pos += 8; t -= 8; } while (t >= 8); if (t >= 4) { - UA_COPY32(op,m_pos); + UA_COPY4(op,m_pos); op += 4; m_pos += 4; t -= 4; } if (t > 0) @@ -4478,8 +6288,8 @@ match: } } else -#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) -#if !defined(LZO_UNALIGNED_OK_4) +#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); @@ -4487,10 +6297,10 @@ match: if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) { #endif - UA_COPY32(op,m_pos); + UA_COPY4(op,m_pos); op += 4; m_pos += 4; t -= 4 - (3 - 1); do { - UA_COPY32(op,m_pos); + 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); @@ -4515,7 +6325,7 @@ match_done: break; match_next: - assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1); + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); #if 0 do *op++ = *ip++; while (--t > 0); #else @@ -4523,16 +6333,10 @@ match_next: if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } #endif t = *ip++; - } while (TEST_IP && TEST_OP); + } } -#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) - *out_len = pd(op, out); - return LZO_E_EOF_NOT_FOUND; -#endif - eof_found: - assert(t == 1); *out_len = pd(op, out); return (ip == ip_end ? LZO_E_OK : (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); @@ -4559,4 +6363,3 @@ lookbehind_overrun: #endif /***** End of minilzo.c *****/ - diff --git a/grub-core/lib/minilzo/minilzo.h b/grub-core/lib/minilzo/minilzo.h index 74fefa9fe..c1c229757 100644 --- a/grub-core/lib/minilzo/minilzo.h +++ b/grub-core/lib/minilzo/minilzo.h @@ -2,22 +2,7 @@ This file is part of the LZO real-time data compression library. - Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer All Rights Reserved. The LZO library is free software; you can redistribute it and/or @@ -47,15 +32,25 @@ */ -#ifndef __MINILZO_H -#define __MINILZO_H 1 +#ifndef __MINILZO_H_INCLUDED +#define __MINILZO_H_INCLUDED 1 -#define MINILZO_VERSION 0x2050 +#define MINILZO_VERSION 0x20a0 /* 2.10 */ -#ifdef __LZOCONF_H +#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" @@ -78,7 +73,7 @@ extern "C" { */ #define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS -#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t)) #define LZO1X_MEM_DECOMPRESS (0) @@ -107,3 +102,5 @@ lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, #endif /* already included */ + +/* vim:set ts=4 sw=4 et: */ diff --git a/grub-core/lib/mips/loongson/reboot.c b/grub-core/lib/mips/loongson/reboot.c index a20e5748b..7317e5868 100644 --- a/grub-core/lib/mips/loongson/reboot.c +++ b/grub-core/lib/mips/loongson/reboot.c @@ -42,7 +42,7 @@ grub_reboot (void) break; grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_RESET, grub_cs5536_read_msr (dev, - GRUB_CS5536_MSR_DIVIL_RESET) + GRUB_CS5536_MSR_DIVIL_RESET) | 1); break; } diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c index 9d5f49cb9..773f3b769 100644 --- a/grub-core/lib/mips/relocator.c +++ b/grub-core/lib/mips/relocator.c @@ -103,7 +103,7 @@ grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, 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, + grub_memcpy (ptr, &grub_relocator_forward_start, RELOCATOR_SRC_SIZEOF (forward)); } @@ -120,10 +120,8 @@ grub_relocator32_boot (struct grub_relocator *rel, unsigned i; grub_addr_t vtarget; - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, - (0xffffffff - stateset_size) - + 1, stateset_size, - sizeof (grub_uint32_t), + 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; diff --git a/grub-core/lib/posix_wrap/c-ctype.h b/grub-core/lib/posix_wrap/c-ctype.h new file mode 100644 index 000000000..5f8fc8ce3 --- /dev/null +++ b/grub-core/lib/posix_wrap/c-ctype.h @@ -0,0 +1,114 @@ +/* + * 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 index 38b572703..67bcaac68 100644 --- a/grub-core/lib/posix_wrap/ctype.h +++ b/grub-core/lib/posix_wrap/ctype.h @@ -27,13 +27,13 @@ toupper (int c) return grub_toupper (c); } -static inline int +static inline int isspace (int c) { return grub_isspace (c); } -static inline int +static inline int isdigit (int c) { return grub_isdigit (c); @@ -63,19 +63,19 @@ isxdigit (int c) return grub_isxdigit (c); } -static inline int +static inline int isprint (int c) { return grub_isprint (c); } -static inline int +static inline int iscntrl (int c) { return !grub_isprint (c); } -static inline int +static inline int isgraph (int c) { return grub_isprint (c) && !grub_isspace (c); @@ -87,13 +87,13 @@ isalnum (int c) return grub_isalpha (c) || grub_isdigit (c); } -static inline int +static inline int ispunct (int c) { return grub_isprint (c) && !grub_isspace (c) && !isalnum (c); } -static inline int +static inline int isalpha (int c) { return grub_isalpha (c); diff --git a/grub-core/lib/posix_wrap/errno.h b/grub-core/lib/posix_wrap/errno.h index ba63b2366..5ede4fe69 100644 --- a/grub-core/lib/posix_wrap/errno.h +++ b/grub-core/lib/posix_wrap/errno.h @@ -26,4 +26,8 @@ #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/limits.h b/grub-core/lib/posix_wrap/limits.h index 7217138ff..4be7b4080 100644 --- a/grub-core/lib/posix_wrap/limits.h +++ b/grub-core/lib/posix_wrap/limits.h @@ -25,7 +25,11 @@ #define USHRT_MAX GRUB_USHRT_MAX #define UINT_MAX GRUB_UINT_MAX #define ULONG_MAX GRUB_ULONG_MAX -#define SIZE_MAX GRUB_SIZE_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 @@ -37,5 +41,6 @@ #define LONG_MAX GRUB_LONG_MAX #define CHAR_BIT 8 +#define WORD_BIT 32 #endif diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h index 3b46f47ff..14e4efdd0 100644 --- a/grub-core/lib/posix_wrap/stdlib.h +++ b/grub-core/lib/posix_wrap/stdlib.h @@ -21,8 +21,9 @@ #include #include +#include -static inline void +static inline void free (void *ptr) { grub_free (ptr); @@ -37,7 +38,12 @@ malloc (grub_size_t size) static inline void * calloc (grub_size_t size, grub_size_t nelem) { - return grub_zalloc (size * nelem); + grub_size_t sz; + + if (grub_mul (size, nelem, &sz)) + return NULL; + + return grub_zalloc (sz); } static inline void * @@ -52,4 +58,18 @@ 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 index 7ae6eee97..d3e400d50 100644 --- a/grub-core/lib/posix_wrap/string.h +++ b/grub-core/lib/posix_wrap/string.h @@ -30,13 +30,13 @@ strlen (const char *s) return grub_strlen (s); } -static inline int +static inline int strcmp (const char *s1, const char *s2) { return grub_strcmp (s1, s2); } -static inline int +static inline int strcasecmp (const char *s1, const char *s2) { return grub_strcasecmp (s1, s2); @@ -84,6 +84,27 @@ 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 diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h index 854eb0122..2f3e86549 100644 --- a/grub-core/lib/posix_wrap/sys/types.h +++ b/grub-core/lib/posix_wrap/sys/types.h @@ -23,11 +23,10 @@ #include +/* Provided by gnulib if not present. */ +#include + typedef grub_ssize_t ssize_t; -#ifndef GRUB_POSIX_BOOL_DEFINED -typedef enum { false = 0, true = 1 } bool; -#define GRUB_POSIX_BOOL_DEFINED 1 -#endif typedef grub_uint8_t uint8_t; typedef grub_uint16_t uint16_t; @@ -51,6 +50,7 @@ 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 diff --git a/grub-core/lib/posix_wrap/wctype.h b/grub-core/lib/posix_wrap/wctype.h index 3771dc5cb..cc9faf554 100644 --- a/grub-core/lib/posix_wrap/wctype.h +++ b/grub-core/lib/posix_wrap/wctype.h @@ -37,7 +37,7 @@ static inline wctype_t wctype (const char *name) { wctype_t i; - static const char names[][10] = { "", + static const char names[][10] = { "", "alnum", "cntrl", "lower", "space", "alpha", "digit", "print", "upper", "blank", diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c index bdf2b111b..15aeb0246 100644 --- a/grub-core/lib/powerpc/relocator.c +++ b/grub-core/lib/powerpc/relocator.c @@ -55,7 +55,7 @@ static void write_reg (int regn, grub_uint32_t val, void **target) { /* lis r, val >> 16 */ - *(grub_uint32_t *) *target = + *(grub_uint32_t *) *target = ((0x3c00 | (regn << 5)) << 16) | (val >> 16); *target = ((grub_uint32_t *) *target) + 1; /* ori r, r, val & 0xffff. */ @@ -99,7 +99,7 @@ grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, 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, + grub_memcpy (ptr, &grub_relocator_forward_start, RELOCATOR_SRC_SIZEOF (forward)); } @@ -115,10 +115,8 @@ grub_relocator32_boot (struct grub_relocator *rel, unsigned i; grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (rel, &ch, 0, - (0xffffffff - stateset_size) - + 1, stateset_size, - sizeof (grub_uint32_t), + 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; diff --git a/grub-core/lib/priority_queue.c b/grub-core/lib/priority_queue.c index 659be0b7f..ba59dda79 100644 --- a/grub-core/lib/priority_queue.c +++ b/grub-core/lib/priority_queue.c @@ -92,7 +92,7 @@ grub_priority_queue_new (grub_size_t elsize, { struct grub_priority_queue *ret; void *els; - els = grub_malloc (elsize * 8); + els = grub_calloc (8, elsize); if (!els) return 0; ret = (struct grub_priority_queue *) grub_malloc (sizeof (*ret)); @@ -139,7 +139,7 @@ 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; ) diff --git a/grub-core/lib/progress.c b/grub-core/lib/progress.c index 4b7cbbca6..4f4389dd5 100644 --- a/grub-core/lib/progress.c +++ b/grub-core/lib/progress.c @@ -29,10 +29,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define UPDATE_INTERVAL 800 -static void +static grub_err_t grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)), unsigned offset __attribute__ ((unused)), - unsigned length, void *data) + unsigned length, + char *buf __attribute__ ((unused)), void *data) { static int call_depth = 0; grub_uint64_t now; @@ -42,11 +43,11 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)), file->progress_offset += length; if (call_depth) - return; + return GRUB_ERR_NONE; e = grub_env_get ("enable_progress_indicator"); if (e && e[0] == '0') { - return; + return GRUB_ERR_NONE; } call_depth = 1; @@ -132,6 +133,8 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)), last_progress_update_time = now; } call_depth = 0; + + return GRUB_ERR_NONE; } GRUB_MOD_INIT(progress) diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index ee9fa7b4f..562bd2e3e 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -20,6 +20,7 @@ #include #include #include +#define xcalloc calloc #define xmalloc malloc #define grub_memset memset #define grub_memcpy memcpy @@ -101,6 +102,11 @@ 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) { @@ -158,11 +164,9 @@ 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 = xmalloc ((s + rs) * sizeof (gf_single_t)); + m = xcalloc (s + rs, sizeof (gf_single_t)); grub_memcpy (m, data, s * sizeof (gf_single_t)); - grub_memset (m + s, 0, rs * sizeof (gf_single_t)); - rs_polynomial = xmalloc ((rs + 1) * sizeof (gf_single_t)); - grub_memset (rs_polynomial, 0, (rs + 1) * 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++) @@ -266,7 +270,7 @@ rs_recover (gf_single_t *mm, grub_size_t s, grub_size_t rs) 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]) @@ -320,6 +324,10 @@ decode_block (gf_single_t *ptr, grub_size_t s, } } +#if __GNUC__ == 12 +#pragma GCC diagnostic pop +#endif + #if !defined (STANDALONE) static void encode_block (gf_single_t *ptr, grub_size_t s, @@ -339,7 +347,7 @@ encode_block (gf_single_t *ptr, grub_size_t s, for (j = 0; j < ds; j++) m[j] = ptr[SECTOR_SIZE * j + i]; rs_encode (m, ds, rr); - for (j = 0; j < rr; j++) + for (j = 0; j < rr; j++) rptr[SECTOR_SIZE * j + i] = m[j + ds]; free (m); } @@ -474,7 +482,7 @@ main (int argc, char **argv) buf = xmalloc (s + rs + SECTOR_SIZE); fread (buf, 1, s + rs, out); - fclose (out); + fclose (out); #endif #if 1 grub_memset (buf + 512 * 15, 0, 512); diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index ea3ebc719..3306a1bb7 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -108,7 +108,7 @@ grub_relocator_new (void) 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", @@ -139,7 +139,7 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb, grub_mm_header_t new_header; grub_mm_header_t hb = (grub_mm_header_t) (rb + 1); -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF +#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); @@ -163,7 +163,7 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb, { new_header = hb->next; if (new_header == hb) - new_header = (void *) (newreg_start + sizeof (*rb)); + new_header = (void *) (newreg_start + sizeof (*rb)); } { struct grub_mm_header *newregfirst = rb->first; @@ -212,7 +212,7 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, (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)) { @@ -246,7 +246,7 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, } else foll = hb->next; - + hbp->next = foll; if (rb->first == hb) { @@ -409,7 +409,7 @@ free_subchunk (const struct grub_relocator_subchunk *subchu) } break; #endif - } + } } static int @@ -439,7 +439,7 @@ malloc_in_range (struct grub_relocator *rel, if (end < start + size) return 0; - /* We have to avoid any allocations when filling scanline events. + /* We have to avoid any allocations when filling scanline events. Hence 2-stages. */ for (r = grub_mm_base; r; r = r->next) @@ -478,6 +478,8 @@ malloc_in_range (struct grub_relocator *rel, #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) { @@ -495,9 +497,9 @@ malloc_in_range (struct grub_relocator *rel, } #endif - eventt = grub_malloc (maxevents * sizeof (events[0])); + eventt = grub_calloc (maxevents, sizeof (events[0])); counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0])); - events = grub_malloc (maxevents * sizeof (events[0])); + events = grub_calloc (maxevents, sizeof (events[0])); if (!events || !eventt || !counter) { grub_dprintf ("relocator", "events or counter allocation failed %d\n", @@ -527,7 +529,7 @@ malloc_in_range (struct grub_relocator *rel, { #ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n", - (unsigned long) r - r->pre_size, + (unsigned long) r - r->pre_size, (unsigned long) (r + 1) + r->size); #endif events[N].type = FIRMWARE_BLOCK_START; @@ -596,7 +598,7 @@ malloc_in_range (struct grub_relocator *rel, p = pa->next; if (p->magic == GRUB_MM_ALLOC_MAGIC) continue; - do + do { if (p->magic != GRUB_MM_FREE_MAGIC) grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", @@ -654,12 +656,12 @@ malloc_in_range (struct grub_relocator *rel, { grub_memset (counter, 0, (1 + (1 << DIGITSORT_BITS)) * sizeof (counter[0])); for (j = 0; j < N; j++) - counter[((events[j].pos >> (DIGITSORT_BITS * i)) + 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)) + eventt[counter[((events[j].pos >> (DIGITSORT_BITS * i)) & DIGITSORT_MASK)]++] = events[j]; t = eventt; eventt = events; @@ -680,7 +682,7 @@ malloc_in_range (struct grub_relocator *rel, 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); + for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1); from_low_priv ? j++ : j--) { int isinsidebefore, isinsideafter; @@ -734,7 +736,7 @@ malloc_in_range (struct grub_relocator *rel, nstarted--; break; } - isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw) + isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw) && !nblockfw))); if (from_low_priv) { if (!isinsidebefore && isinsideafter) @@ -744,7 +746,7 @@ malloc_in_range (struct grub_relocator *rel, { target = starta; if (target < start) - target = start; + target = ALIGN_UP (start, align); if (target + size <= end && target + size <= events[j].pos) /* Found an usable address. */ goto found; @@ -761,7 +763,7 @@ malloc_in_range (struct grub_relocator *rel, { target = starta - size; if (target > end - size) - target = end - size; + target = ALIGN_DOWN (end - size, align); if (target >= start && target >= events[j].pos) goto found; } @@ -847,13 +849,13 @@ malloc_in_range (struct grub_relocator *rel, fend = ALIGN_UP (alloc_end, GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); -#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF +#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, + if (!grub_relocator_firmware_alloc_region (fstart, fend - fstart)) { if (from_low_priv) @@ -879,9 +881,11 @@ malloc_in_range (struct grub_relocator *rel, offend = GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; lo->freebytes[offstart / 8] &= ((1 << (8 - (start % 8))) - 1); - grub_memset (lo->freebytes + (offstart + 7) / 8, 0, - offend / 8 - (offstart + 7) / 8); - lo->freebytes[offend / 8] &= ~((1 << (offend % 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 @@ -889,7 +893,7 @@ malloc_in_range (struct grub_relocator *rel, nallocs++; } } - + switch (events[j].type) { case REG_BEG_START: @@ -963,7 +967,7 @@ malloc_in_range (struct grub_relocator *rel, #endif unsigned cural = 0; int oom = 0; - res->subchunks = grub_malloc (sizeof (res->subchunks[0]) * nallocs); + res->subchunks = grub_calloc (nallocs, sizeof (res->subchunks[0])); if (!res->subchunks) oom = 1; res->nsubchunks = nallocs; @@ -989,7 +993,7 @@ malloc_in_range (struct grub_relocator *rel, if (j != 0 && events[j - 1].pos != events[j].pos) { grub_addr_t alloc_start, alloc_end; - struct grub_relocator_subchunk tofree; + struct grub_relocator_subchunk tofree = {0}; struct grub_relocator_subchunk *curschu = &tofree; if (!oom) curschu = &res->subchunks[cural]; @@ -1201,7 +1205,7 @@ malloc_in_range (struct grub_relocator *rel, } static void -adjust_limits (struct grub_relocator *rel, +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) { @@ -1296,9 +1300,9 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, { if (rel->highestnonpostaddr < target + size) rel->highestnonpostaddr = target + size; - + if (rel->highestnonpostaddr < chunk->src + size) - rel->highestnonpostaddr = chunk->src + size; + rel->highestnonpostaddr = chunk->src + size; } grub_dprintf ("relocator", "relocators_size=%ld\n", @@ -1386,8 +1390,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, }; grub_addr_t min_addr2 = 0, max_addr2; - if (max_addr > ~size) - max_addr = ~size; + if (size && (max_addr > ~size)) + max_addr = ~size + 1; #ifdef GRUB_MACHINE_PCBIOS if (min_addr < 0x1000) @@ -1436,6 +1440,7 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, break; } + grub_free (ctx.chunk); return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); } while (0); @@ -1452,7 +1457,10 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); #endif if (!ctx.found) - return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); + { + grub_free (ctx.chunk); + return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); + } } while (1) { @@ -1508,7 +1516,7 @@ grub_relocator_unload (struct grub_relocator *rel) for (chunk = rel->chunks; chunk; chunk = next) { unsigned i; - for (i = 0; i < chunk->nsubchunks; i++) + for (i = 0; i < chunk->nsubchunks; i++) free_subchunk (&chunk->subchunks[i]); grub_unmap_memory (chunk->srcv, chunk->size); next = chunk->next; @@ -1543,7 +1551,7 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, *relsize = rel->relocators_size; grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv); - + { unsigned i; grub_size_t count[257]; @@ -1555,15 +1563,15 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, struct grub_relocator_chunk *chunk; for (chunk = rel->chunks; chunk; chunk = chunk->next) { - grub_dprintf ("relocator", "chunk %p->%p, 0x%lx\n", + 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_malloc (nchunks * sizeof (sorted[0])); - to = grub_malloc (nchunks * sizeof (sorted[0])); + from = grub_calloc (nchunks, sizeof (sorted[0])); + to = grub_calloc (nchunks, sizeof (sorted[0])); if (!from || !to) { grub_free (from); @@ -1599,7 +1607,7 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, for (j = 0; j < nchunks; j++) { - grub_dprintf ("relocator", "sorted chunk %p->%p, 0x%lx\n", + 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) @@ -1641,7 +1649,7 @@ grub_mm_check_real (const char *file, int line) p = pa->next; if (p->magic == GRUB_MM_ALLOC_MAGIC) continue; - do + do { if ((grub_addr_t) p < (grub_addr_t) (r + 1) || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index aa297ab0a..ffb26df79 100644 --- a/grub-core/lib/setjmp.S +++ b/grub-core/lib/setjmp.S @@ -1,3 +1,7 @@ +/* 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__) @@ -15,6 +19,8 @@ #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 diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c index 4afa99279..ae61a96dd 100644 --- a/grub-core/lib/syslinux_parse.c +++ b/grub-core/lib/syslinux_parse.c @@ -51,8 +51,8 @@ struct syslinux_menuentry char hotkey; int make_default; struct syslinux_say *say; - - enum { KERNEL_NO_KERNEL, KERNEL_LINUX, KERNEL_CHAINLOADER, + + 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; @@ -170,7 +170,7 @@ 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)); + return print (outbuf, buf, grub_strlen (buf)); } static grub_err_t @@ -233,7 +233,7 @@ kernel (const char *line, struct syslinux_menu *menu) if (end - line >= 4 && grub_strcasecmp (end - 4, ".img") == 0) menu->entries->entry_type = KERNEL_IMG; - + return GRUB_ERR_NONE; } @@ -247,7 +247,7 @@ cmd_linux (const char *line, struct syslinux_menu *menu) if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = KERNEL_LINUX; - + return GRUB_ERR_NONE; } @@ -261,7 +261,7 @@ cmd_boot (const char *line, struct syslinux_menu *menu) if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = KERNEL_CHAINLOADER; - + return GRUB_ERR_NONE; } @@ -275,7 +275,7 @@ cmd_bss (const char *line, struct syslinux_menu *menu) if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; - + return GRUB_ERR_NONE; } @@ -289,7 +289,7 @@ cmd_pxe (const char *line, struct syslinux_menu *menu) if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = KERNEL_PXE; - + return GRUB_ERR_NONE; } @@ -303,7 +303,7 @@ cmd_fdimage (const char *line, struct syslinux_menu *menu) if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = KERNEL_IMG; - + return GRUB_ERR_NONE; } @@ -317,7 +317,7 @@ cmd_comboot (const char *line, struct syslinux_menu *menu) if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = KERNEL_COM; - + return GRUB_ERR_NONE; } @@ -331,7 +331,7 @@ cmd_com32 (const char *line, struct syslinux_menu *menu) if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = KERNEL_COM32; - + return GRUB_ERR_NONE; } @@ -354,7 +354,7 @@ cmd_config (const char *line, struct syslinux_menu *menu) return grub_errno; } menu->entries->entry_type = KERNEL_CONFIG; - + return GRUB_ERR_NONE; } @@ -367,7 +367,7 @@ cmd_append (const char *line, struct syslinux_menu *menu) menu->entries->append = grub_strdup (line); if (!menu->entries->append) return grub_errno; - + return GRUB_ERR_NONE; } @@ -405,7 +405,7 @@ cmd_initrd (const char *line, struct syslinux_menu *menu) while (*line == ',') line++; } - + return GRUB_ERR_NONE; } @@ -415,7 +415,7 @@ cmd_default (const char *line, struct syslinux_menu *menu) menu->def = grub_strdup (line); if (!menu->def) return grub_errno; - + return GRUB_ERR_NONE; } @@ -423,7 +423,7 @@ static grub_err_t cmd_timeout (const char *line, struct syslinux_menu *menu) { menu->timeout = grub_strtoul (line, NULL, 0); - + return GRUB_ERR_NONE; } @@ -434,7 +434,7 @@ cmd_menudefault (const char *line __attribute__ ((unused)), if (!menu->entries) return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); - menu->entries->make_default = 1; + menu->entries->make_default = 1; return GRUB_ERR_NONE; } @@ -457,7 +457,7 @@ cmd_localboot (const char *line, if (!menu->entries->kernel_file) return grub_errno; menu->entries->entry_type = LOCALBOOT; - + return GRUB_ERR_NONE; } @@ -485,7 +485,7 @@ cmd_extlabel (const char *line, struct syslinux_menu *menu) *out++ = *in++; } *out = 0; - + return GRUB_ERR_NONE; } @@ -548,7 +548,7 @@ syslinux_parse (const char *filename, 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); @@ -737,7 +737,10 @@ syslinux_parse_real (struct syslinux_menu *menu) && grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0)) { if (helptext (ptr5, file, menu)) - return 1; + { + grub_free (buf); + return 1; + } continue; } @@ -757,11 +760,12 @@ syslinux_parse_real (struct syslinux_menu *menu) } fail: grub_file_close (file); + grub_free (buf); return err; } static grub_err_t -print_escaped (struct output_buffer *outbuf, +print_escaped (struct output_buffer *outbuf, const char *from, const char *to) { const char *ptr; @@ -1036,7 +1040,7 @@ write_entry (struct output_buffer *outbuf, case KERNEL_COM: { char *basename = NULL; - + { char *ptr; for (ptr = curentry->kernel_file; *ptr; ptr++) @@ -1062,7 +1066,7 @@ write_entry (struct output_buffer *outbuf, if (ptr[0] == 'h' && ptr[1] == 'd') { is_fd = 0; - devn = grub_strtoul (ptr + 2, &ptr, 0); + devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0); continue; } if (grub_strncasecmp (ptr, "file=", 5) == 0) @@ -1086,12 +1090,12 @@ write_entry (struct output_buffer *outbuf, if (ptr[0] == 'f' && ptr[1] == 'd') { is_fd = 1; - devn = grub_strtoul (ptr + 2, &ptr, 0); + devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0); continue; } if (grub_isdigit (ptr[0])) { - part = grub_strtoul (ptr, &ptr, 0); + part = grub_strtoul (ptr, (const char **)&ptr, 0); continue; } /* FIXME: isolinux, ntldr, cmldr, *dos, seg, hide @@ -1243,8 +1247,8 @@ write_entry (struct output_buffer *outbuf, if (grub_strcasecmp (basename, "whichsys.c32") == 0) { grub_syslinux_flavour_t flavour = GRUB_SYSLINUX_ISOLINUX; - const char *flav[] = - { + const char *flav[] = + { [GRUB_SYSLINUX_ISOLINUX] = "iso", [GRUB_SYSLINUX_PXELINUX] = "pxe", [GRUB_SYSLINUX_SYSLINUX] = "sys" @@ -1415,7 +1419,7 @@ free_menu (struct syslinux_menu *menu) grub_free (initrd->file); grub_free (initrd); } - + grub_free (entry->comments); grub_free (entry->kernel_file); grub_free (entry->label); @@ -1503,7 +1507,7 @@ config_file (struct output_buffer *outbuf, print_string ("\n"); } for (curentry = lentry; curentry; curentry = curentry->prev) - { + { print_string ("menuentry "); err = print_escaped (outbuf, curentry->extlabel ? : curentry->label, NULL); diff --git a/grub-core/lib/tss2/buffer.c b/grub-core/lib/tss2/buffer.c new file mode 100644 index 000000000..16d59a8f5 --- /dev/null +++ b/grub-core/lib/tss2/buffer.c @@ -0,0 +1,147 @@ +/* + * 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 new file mode 100644 index 000000000..3d26373dd --- /dev/null +++ b/grub-core/lib/tss2/tcg2.h @@ -0,0 +1,35 @@ +/* + * 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 new file mode 100644 index 000000000..cab930d2b --- /dev/null +++ b/grub-core/lib/tss2/tcg2_emu.c @@ -0,0 +1,49 @@ +/* + * 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 new file mode 100644 index 000000000..6d25db1ab --- /dev/null +++ b/grub-core/lib/tss2/tpm2_cmd.c @@ -0,0 +1,1248 @@ +/* + * 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 new file mode 100644 index 000000000..90b42efec --- /dev/null +++ b/grub-core/lib/tss2/tpm2_cmd.h @@ -0,0 +1,189 @@ +/* + * 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 new file mode 100644 index 000000000..48251e9b4 --- /dev/null +++ b/grub-core/lib/tss2/tss2.c @@ -0,0 +1,21 @@ +/* + * 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 new file mode 100644 index 000000000..fb9db1aed --- /dev/null +++ b/grub-core/lib/tss2/tss2_buffer.h @@ -0,0 +1,64 @@ +/* + * 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 new file mode 100644 index 000000000..816e5b37f --- /dev/null +++ b/grub-core/lib/tss2/tss2_mu.c @@ -0,0 +1,1213 @@ +/* + * 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 new file mode 100644 index 000000000..6440de57c --- /dev/null +++ b/grub-core/lib/tss2/tss2_mu.h @@ -0,0 +1,409 @@ +/* + * 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 new file mode 100644 index 000000000..2eefba87c --- /dev/null +++ b/grub-core/lib/tss2/tss2_structs.h @@ -0,0 +1,833 @@ +/* + * 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 new file mode 100644 index 000000000..bddde7191 --- /dev/null +++ b/grub-core/lib/tss2/tss2_types.h @@ -0,0 +1,410 @@ +/* + * 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/x86_64/efi/relocator.c b/grub-core/lib/x86_64/efi/relocator.c index 3caef7a40..7d200a125 100644 --- a/grub-core/lib/x86_64/efi/relocator.c +++ b/grub-core/lib/x86_64/efi/relocator.c @@ -50,10 +50,9 @@ grub_relocator64_efi_boot (struct grub_relocator *rel, * 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 (rel, &ch, 0, - 0x100000000 - RELOCATOR_SIZEOF (64_efi), - RELOCATOR_SIZEOF (64_efi), 16, - GRUB_RELOCATOR_PREFERENCE_NONE, 1); + 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; diff --git a/grub-core/lib/x86_64/relocator_asm.S b/grub-core/lib/x86_64/relocator_asm.S index 2ab6d8cb7..12728d8e1 100644 --- a/grub-core/lib/x86_64/relocator_asm.S +++ b/grub-core/lib/x86_64/relocator_asm.S @@ -22,25 +22,25 @@ .p2align 2 VARIABLE(grub_relocator_backward_start) - /* mov imm32, %rax */ + /* mov imm64, %rax */ .byte 0x48 .byte 0xb8 VARIABLE(grub_relocator_backward_dest) - .long 0, 0 + .quad 0 movq %rax, %rdi /* mov imm64, %rax */ .byte 0x48 .byte 0xb8 VARIABLE(grub_relocator_backward_src) - .long 0, 0 + .quad 0 movq %rax, %rsi /* mov imm64, %rcx */ .byte 0x48 .byte 0xb9 VARIABLE(grub_relocator_backward_chunk_size) - .long 0, 0 + .quad 0 add %rcx, %rsi add %rcx, %rdi @@ -62,21 +62,21 @@ VARIABLE(grub_relocator_forward_start) .byte 0x48 .byte 0xb8 VARIABLE(grub_relocator_forward_dest) - .long 0, 0 + .quad 0 movq %rax, %rdi /* mov imm64, %rax */ .byte 0x48 .byte 0xb8 VARIABLE(grub_relocator_forward_src) - .long 0, 0 + .quad 0 movq %rax, %rsi /* mov imm64, %rcx */ .byte 0x48 .byte 0xb9 VARIABLE(grub_relocator_forward_chunk_size) - .long 0, 0 + .quad 0 /* Forward copy. */ cld diff --git a/grub-core/lib/x86_64/xen/relocator.S b/grub-core/lib/x86_64/xen/relocator.S index f5364ed0f..852cd40aa 100644 --- a/grub-core/lib/x86_64/xen/relocator.S +++ b/grub-core/lib/x86_64/xen/relocator.S @@ -60,9 +60,9 @@ LOCAL(cont): jz 3f 2: movq %r12, %rdi - shlq $PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */ + shlq $GRUB_PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */ movq (%rbx, %r12, 8), %rsi /* mfn */ - shlq $PAGE_SHIFT, %rsi + 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 */ diff --git a/grub-core/lib/xzembed/xz.h b/grub-core/lib/xzembed/xz.h index f7b32d800..d1417039a 100644 --- a/grub-core/lib/xzembed/xz.h +++ b/grub-core/lib/xzembed/xz.h @@ -29,10 +29,7 @@ #include #include #include - -#ifndef GRUB_POSIX_BOOL_DEFINED -typedef enum { false = 0, true = 1 } bool; -#endif +#include /** * enum xz_ret - Return codes diff --git a/grub-core/lib/xzembed/xz_dec_bcj.c b/grub-core/lib/xzembed/xz_dec_bcj.c index bf6b5862e..aef4638d4 100644 --- a/grub-core/lib/xzembed/xz_dec_bcj.c +++ b/grub-core/lib/xzembed/xz_dec_bcj.c @@ -353,7 +353,7 @@ static noinline_for_stack size_t bcj_sparc( * avoid pointers to static data (at least on x86). */ static void bcj_apply(struct xz_dec_bcj *s, - uint8_t *buf, size_t *pos, size_t size) + uint8_t *buf __attribute__((unused)), size_t *pos, size_t size __attribute__((unused))) { size_t filtered; diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index a29751e14..832d8af9a 100644 --- a/grub-core/lib/xzembed/xz_dec_stream.c +++ b/grub-core/lib/xzembed/xz_dec_stream.c @@ -381,7 +381,7 @@ static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b, { #ifndef GRUB_EMBED_DECOMPRESSOR const gcry_md_spec_t *hash = crc32 ? s->crc32 : s->hash; - void *hash_context = crc32 ? s->crc32_context + void *hash_context = crc32 ? s->crc32_context : s->hash_context; if(!s->have_hash_value && hash && sizeof (s->hash_value) >= hash->mdlen) @@ -512,7 +512,7 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) 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) @@ -521,7 +521,7 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) 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) { diff --git a/grub-core/lib/zstd/fse_decompress.c b/grub-core/lib/zstd/fse_decompress.c index 72bbead5b..2227b84bc 100644 --- a/grub-core/lib/zstd/fse_decompress.c +++ b/grub-core/lib/zstd/fse_decompress.c @@ -82,7 +82,7 @@ FSE_DTable* FSE_createDTable (unsigned tableLog) { if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; - return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); + return (FSE_DTable*)calloc( FSE_DTABLE_SIZE_U32(tableLog), sizeof (U32) ); } void FSE_freeDTable (FSE_DTable* dt) diff --git a/grub-core/lib/zstd/zstd_decompress.c b/grub-core/lib/zstd/zstd_decompress.c index 711b5b6d7..e4b5670c2 100644 --- a/grub-core/lib/zstd/zstd_decompress.c +++ b/grub-core/lib/zstd/zstd_decompress.c @@ -1325,7 +1325,7 @@ typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) { - seq_t seq; + 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; diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c index 51684914c..19ddedbc2 100644 --- a/grub-core/loader/arm/linux.c +++ b/grub-core/loader/arm/linux.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -78,7 +79,7 @@ linux_prepare_atag (void *target_atag) /* some place for cmdline, initrd and terminator. */ tmp_size = get_atag_size (atag_orig) + 20 + (arg_size) / 4; - tmp_atag = grub_malloc (tmp_size * sizeof (grub_uint32_t)); + tmp_atag = grub_calloc (tmp_size, sizeof (grub_uint32_t)); if (!tmp_atag) return grub_errno; @@ -304,7 +305,7 @@ linux_boot (void) static grub_err_t linux_load (const char *filename, grub_file_t file) { - struct linux_arm_kernel_header *lh; + struct linux_arch_kernel_header *lh; int size; size = grub_file_size (file); @@ -422,7 +423,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_dprintf ("loader", "Loading initrd to 0x%08x\n", (grub_addr_t) initrd_start); - if (grub_initrd_load (&initrd_ctx, argv, (void *) initrd_start)) + if (grub_initrd_load (&initrd_ctx, (void *) initrd_start)) goto fail; initrd_end = initrd_start + size; @@ -452,7 +453,7 @@ load_dtb (grub_file_t dtb, int size) 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. */ @@ -493,9 +494,9 @@ GRUB_MOD_INIT (linux) 0, N_("Load Linux.")); cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0, N_("Load initrd.")); - cmd_devicetree = grub_register_command ("devicetree", grub_cmd_devicetree, - /* TRANSLATORS: DTB stands for device tree blob. */ - 0, N_("Load DTB file.")); + 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 (); diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c index 22cc25ecc..26e1472c9 100644 --- a/grub-core/loader/arm64/xen_boot.c +++ b/grub-core/loader/arm64/xen_boot.c @@ -27,11 +27,9 @@ #include #include #include -#include #include #include #include -#include /* required by struct xen_hypervisor_header */ #include #include @@ -65,18 +63,6 @@ enum module_type }; typedef enum module_type module_type_t; -struct xen_hypervisor_header -{ - struct linux_arm64_kernel_header efi_head; - - /* This is always PE\0\0. */ - grub_uint8_t signature[GRUB_PE32_SIGNATURE_SIZE]; - /* The COFF file header. */ - struct grub_pe32_coff_header coff_header; - /* The Optional header. */ - struct grub_pe64_optional_header optional_header; -}; - struct xen_boot_binary { struct xen_boot_binary *next; @@ -452,7 +438,7 @@ static grub_err_t grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { - struct xen_hypervisor_header sh; + struct linux_arch_kernel_header lh; grub_file_t file = NULL; grub_dl_ref (my_mod); @@ -467,10 +453,7 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)), if (!file) goto fail; - if (grub_file_read (file, &sh, sizeof (sh)) != (long) sizeof (sh)) - goto fail; - if (grub_arch_efi_linux_check_image - ((struct linux_arch_kernel_header *) &sh) != GRUB_ERR_NONE) + if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE) goto fail; grub_file_seek (file, 0); @@ -484,7 +467,8 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)), return grub_errno; xen_hypervisor->is_hypervisor = 1; - xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment; + 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) diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c index 74888c463..a0b61a240 100644 --- a/grub-core/loader/efi/appleloader.c +++ b/grub-core/loader/efi/appleloader.c @@ -40,7 +40,7 @@ grub_appleloader_unload (void) grub_efi_boot_services_t *b; b = grub_efi_system_table->boot_services; - efi_call_1 (b->unload_image, image_handle); + b->unload_image (image_handle); grub_free (cmdline); cmdline = 0; @@ -55,7 +55,7 @@ grub_appleloader_boot (void) grub_efi_boot_services_t *b; b = grub_efi_system_table->boot_services; - efi_call_3 (b->start_image, image_handle, 0, 0); + b->start_image (image_handle, 0, 0); grub_appleloader_unload (); @@ -126,7 +126,7 @@ static struct piwg_full_device_path devpath_6 = MAKE_PIWG_PATH (0xffcc4000, static struct piwg_full_device_path devpath_7 = MAKE_PIWG_PATH (0xff981000, 0xffc8ffff); -/* mid-2012 MBP retina (MacBookPro10,1) */ +/* mid-2012 MBP retina (MacBookPro10,1) */ static struct piwg_full_device_path devpath_8 = MAKE_PIWG_PATH (0xff990000, 0xffb2ffff); @@ -165,8 +165,8 @@ grub_cmd_appleloader (grub_command_t cmd __attribute__ ((unused)), b = grub_efi_system_table->boot_services; for (pdev = devs ; pdev->devpath ; pdev++) - if (efi_call_6 (b->load_image, 0, grub_efi_image_handle, pdev->devpath, - NULL, 0, &image_handle) == GRUB_EFI_SUCCESS) + if (b->load_image (0, grub_efi_image_handle, pdev->devpath, + NULL, 0, &image_handle) == GRUB_EFI_SUCCESS) break; if (! pdev->devpath) diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index cd92ea3f2..869307bf3 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -44,40 +45,35 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; -static grub_efi_physical_address_t address; -static grub_efi_uintn_t pages; -static grub_efi_device_path_t *file_path; -static grub_efi_handle_t image_handle; -static grub_efi_char16_t *cmdline; - static grub_err_t -grub_chainloader_unload (void) +grub_chainloader_unload (void *context) { + grub_efi_handle_t image_handle = (grub_efi_handle_t) context; + grub_efi_loaded_image_t *loaded_image; grub_efi_boot_services_t *b; - b = grub_efi_system_table->boot_services; - efi_call_1 (b->unload_image, image_handle); - efi_call_2 (b->free_pages, address, pages); + loaded_image = grub_efi_get_loaded_image (image_handle); + if (loaded_image != NULL) + grub_free (loaded_image->load_options); - grub_free (file_path); - grub_free (cmdline); - cmdline = 0; - file_path = 0; + b = grub_efi_system_table->boot_services; + b->unload_image (image_handle); grub_dl_unref (my_mod); return GRUB_ERR_NONE; } static grub_err_t -grub_chainloader_boot (void) +grub_chainloader_boot (void *context) { + grub_efi_handle_t image_handle = (grub_efi_handle_t) context; grub_efi_boot_services_t *b; grub_efi_status_t status; grub_efi_uintn_t exit_data_size; grub_efi_char16_t *exit_data = NULL; b = grub_efi_system_table->boot_services; - status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); + status = b->start_image (image_handle, &exit_data_size, &exit_data); if (status != GRUB_EFI_SUCCESS) { if (exit_data) @@ -90,7 +86,7 @@ grub_chainloader_boot (void) *grub_utf16_to_utf8 ((grub_uint8_t *) buf, exit_data, exit_data_size) = 0; - grub_error (GRUB_ERR_BAD_OS, buf); + grub_error (GRUB_ERR_BAD_OS, "%s", buf); grub_free (buf); } } @@ -99,14 +95,14 @@ grub_chainloader_boot (void) } if (exit_data) - efi_call_1 (b->free_pool, exit_data); + b->free_pool (exit_data); grub_loader_unset (); return grub_errno; } -static void +static grub_err_t copy_file_path (grub_efi_file_path_device_path_t *fp, const char *str, grub_efi_uint16_t len) { @@ -116,9 +112,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; - path_name = grub_malloc (len * GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); + path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); if (!path_name) - return; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer"); size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8, (const grub_uint8_t *) str, len, 0); @@ -131,6 +127,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, fp->path_name[size++] = '\0'; fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp); grub_free (path_name); + return GRUB_ERR_NONE; } static grub_efi_device_path_t * @@ -139,7 +136,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) char *dir_start; char *dir_end; grub_size_t size; - grub_efi_device_path_t *d; + grub_efi_device_path_t *d, *file_path; dir_start = grub_strchr (filename, ')'); if (! dir_start) @@ -156,9 +153,18 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) size = 0; d = dp; - while (1) + while (d) { - size += GRUB_EFI_DEVICE_PATH_LENGTH (d); + grub_size_t len = GRUB_EFI_DEVICE_PATH_LENGTH (d); + + if (len < 4) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + "malformed EFI Device Path node has length=%" PRIuGRUB_SIZE, len); + return NULL; + } + + size += len; if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d))) break; d = GRUB_EFI_NEXT_DEVICE_PATH (d); @@ -179,14 +185,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) /* Fill the file path for the directory. */ d = (grub_efi_device_path_t *) ((char *) file_path + ((char *) d - (char *) dp)); - grub_efi_print_device_path (d); - copy_file_path ((grub_efi_file_path_device_path_t *) d, - dir_start, dir_end - dir_start); + if (copy_file_path ((grub_efi_file_path_device_path_t *) d, + dir_start, dir_end - dir_start) != GRUB_ERR_NONE) + { + fail: + grub_free (file_path); + return 0; + } /* Fill the file path for the file. */ d = GRUB_EFI_NEXT_DEVICE_PATH (d); - copy_file_path ((grub_efi_file_path_device_path_t *) d, - dir_end + 1, grub_strlen (dir_end + 1)); + if (copy_file_path ((grub_efi_file_path_device_path_t *) d, + dir_end + 1, grub_strlen (dir_end + 1)) != GRUB_ERR_NONE) + goto fail; /* Fill the end of device path nodes. */ d = GRUB_EFI_NEXT_DEVICE_PATH (d); @@ -206,11 +217,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), grub_efi_status_t status; grub_efi_boot_services_t *b; grub_device_t dev = 0; - grub_efi_device_path_t *dp = 0; + grub_efi_device_path_t *dp = NULL, *file_path = NULL; grub_efi_loaded_image_t *loaded_image; char *filename; void *boot_image = 0; grub_efi_handle_t dev_handle = 0; + grub_efi_physical_address_t address = 0; + grub_efi_uintn_t pages = 0; + grub_efi_char16_t *cmdline = NULL; + grub_efi_handle_t image_handle = NULL; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); @@ -218,11 +233,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), grub_dl_ref (my_mod); - /* Initialize some global variables. */ - address = 0; - image_handle = 0; - file_path = 0; - b = grub_efi_system_table->boot_services; file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE); @@ -231,10 +241,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), /* Get the root device's device path. */ dev = grub_device_open (0); - if (! dev) - goto fail; - - if (dev->disk) + if (dev == NULL) + ; + else if (dev->disk) dev_handle = grub_efidisk_get_device_handle (dev->disk); else if (dev->net && dev->net->server) { @@ -257,19 +266,13 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), if (dev_handle) dp = grub_efi_get_device_path (dev_handle); - if (! dp) + if (dp != NULL) { - grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device"); - goto fail; + file_path = make_file_path (dp, filename); + if (file_path == NULL) + goto fail; } - file_path = make_file_path (dp, filename); - if (! file_path) - goto fail; - - grub_printf ("file path: "); - grub_efi_print_device_path (file_path); - size = grub_file_size (file); if (!size) { @@ -277,9 +280,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), filename); goto fail; } - pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12); + pages = (grub_efi_uintn_t) GRUB_EFI_BYTES_TO_PAGES (size); - status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, + status = b->allocate_pages (GRUB_EFI_ALLOCATE_ANY_PAGES, GRUB_EFI_LOADER_CODE, pages, &address); if (status != GRUB_EFI_SUCCESS) @@ -336,9 +339,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), } #endif - status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, - boot_image, size, - &image_handle); + status = b->load_image (0, grub_efi_image_handle, file_path, + boot_image, size, + &image_handle); if (status != GRUB_EFI_SUCCESS) { if (status == GRUB_EFI_OUT_OF_RESOURCES) @@ -360,6 +363,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), } loaded_image->device_handle = dev_handle; + /* Build load options with arguments from chainloader command line. */ if (argc > 1) { int i, len; @@ -392,7 +396,11 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), grub_file_close (file); grub_device_close (dev); - grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); + /* We're finished with the source image buffer and file path now. */ + b->free_pages (address, pages); + grub_free (file_path); + + grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0); return 0; fail: @@ -403,10 +411,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), if (file) grub_file_close (file); + grub_free (cmdline); grub_free (file_path); if (address) - efi_call_2 (b->free_pages, address, pages); + b->free_pages (address, pages); + + if (image_handle != NULL) + b->unload_image (image_handle); grub_dl_unref (my_mod); diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c index ee9c5592c..e510b3491 100644 --- a/grub-core/loader/efi/fdt.c +++ b/grub-core/loader/efi/fdt.c @@ -1,6 +1,7 @@ /* * 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 @@ -18,13 +19,16 @@ #include #include +#include #include #include #include +#include #include #include #include #include +#include static void *loaded_fdt; static void *fdt; @@ -35,6 +39,13 @@ static void *fdt; 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) { @@ -60,7 +71,10 @@ grub_fdt_load (grub_size_t additional_size) size += additional_size; grub_dprintf ("linux", "allocating %d bytes for fdt\n", size); - fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (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; @@ -82,16 +96,19 @@ grub_err_t grub_fdt_install (void) { grub_efi_boot_services_t *b; - grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID; + 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); + 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 ? fdt : loaded_fdt); return GRUB_ERR_NONE; } @@ -160,16 +177,52 @@ out: 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 ("devicetree", grub_cmd_devicetree, 0, - N_("Load DTB file.")); + 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/arm64/linux.c b/grub-core/loader/efi/linux.c similarity index 53% rename from grub-core/loader/arm64/linux.c rename to grub-core/loader/efi/linux.c index ef3e9f944..78ea07ca8 100644 --- a/grub-core/loader/arm64/linux.c +++ b/grub-core/loader/efi/linux.c @@ -25,11 +25,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -48,11 +48,52 @@ 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_check_image (struct linux_arch_kernel_header * lh) +grub_arch_efi_linux_load_image_header (grub_file_t file, + struct linux_arch_kernel_header * lh) { - if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE) - return grub_error(GRUB_ERR_BAD_OS, "invalid magic number"); + 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, @@ -61,9 +102,40 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) 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) { @@ -71,21 +143,21 @@ finalize_params_linux (void) void *fdt; - 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; - /* 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); @@ -108,6 +180,7 @@ 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) @@ -143,12 +216,17 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) grub_dprintf ("linux", "linux command line: '%s'\n", args); - /* Convert command line to UCS-2 */ + /* 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; + } loaded_image->load_options_size = len = (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); loaded_image->load_options = - grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); + grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (len)); if (!loaded_image->load_options) return grub_errno; @@ -160,9 +238,12 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) status = b->start_image (image_handle, 0, NULL); /* When successful, not reached */ - b->unload_image (image_handle); + 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 (loaded_image->load_options_size)); + GRUB_EFI_BYTES_TO_PAGES (len)); + loaded_image->load_options = NULL; +unload: + b->unload_image (image_handle); return grub_errno; } @@ -170,16 +251,20 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) 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)); + 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) @@ -190,10 +275,25 @@ grub_linux_unload (void) 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, @@ -229,14 +329,52 @@ allocate_initrd_mem (int 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[]) { - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - int initrd_size, initrd_pages; - void *initrd_mem = NULL; + 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) { @@ -244,6 +382,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 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, @@ -254,6 +397,32 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 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"); @@ -266,18 +435,20 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), goto fail; } - if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) - 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); - if (initrd_mem && !initrd_start) - grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); return grub_errno; } @@ -292,6 +463,22 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 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")); @@ -304,11 +491,25 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), kernel_size = grub_file_size (file); - if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) - return grub_errno; - - if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) + 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_loader_unset(); diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c new file mode 100644 index 000000000..638c55bf8 --- /dev/null +++ b/grub-core/loader/emu/linux.c @@ -0,0 +1,182 @@ +/* + * 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 index 3730ed382..4b7c436d4 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #ifdef GRUB_MACHINE_PCBIOS #include @@ -134,7 +135,7 @@ static const struct grub_arg_option openbsd_opts[] = {"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, + {"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. @@ -167,7 +168,7 @@ static const struct grub_arg_option netbsd_opts[] = {"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, + {"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. @@ -230,7 +231,7 @@ grub_bsd_add_meta_ptr (grub_uint32_t type, void **ptr, grub_uint32_t len) newtag->next = NULL; *ptr = newtag->data; - if (kernel_type == KERNEL_TYPE_FREEBSD + if (kernel_type == KERNEL_TYPE_FREEBSD && type == (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_SMAP)) { struct bsd_tag *p; @@ -262,7 +263,7 @@ grub_err_t grub_bsd_add_meta (grub_uint32_t type, const void *data, grub_uint32_t len) { grub_err_t err; - void *ptr; + void *ptr = NULL; err = grub_bsd_add_meta_ptr (type, &ptr, len); if (err) @@ -434,7 +435,7 @@ grub_freebsd_add_meta_module (const char *filename, const char *type, { 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_ADDR, &addr64, sizeof (addr64)) || grub_bsd_add_meta (FREEBSD_MODINFO_SIZE, &size64, sizeof (size64))) return grub_errno; } @@ -632,7 +633,7 @@ grub_freebsd_boot (void) 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 @@ -677,7 +678,7 @@ grub_freebsd_boot (void) { grub_uint8_t *p_tag = p; struct bsd_tag *tag; - + for (tag = tags; tag; tag = tag->next) { struct freebsd_tag_header *head @@ -727,7 +728,7 @@ grub_freebsd_boot (void) if (is_64bit) { - struct grub_relocator64_state state; + struct grub_relocator64_state state = {0}; grub_uint8_t *pagetable; grub_uint32_t *stack; grub_addr_t stack_target; @@ -766,7 +767,7 @@ grub_freebsd_boot (void) } else { - struct grub_relocator32_state state; + struct grub_relocator32_state state = {0}; grub_uint32_t *stack; grub_addr_t stack_target; @@ -841,7 +842,7 @@ grub_openbsd_boot (void) 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; @@ -928,7 +929,7 @@ grub_netbsd_setup_video (void) struct grub_video_mode_info mode_info; void *framebuffer; const char *modevar; - struct grub_netbsd_btinfo_framebuf params; + struct grub_netbsd_btinfo_framebuf params = {0}; grub_err_t err; grub_video_driver_id_t driv_id; @@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void) 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++; - mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * 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; @@ -1334,6 +1340,7 @@ 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; @@ -1364,8 +1371,11 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) if (grub_errno) return grub_errno; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, - kern_start, kern_end - kern_start); + + 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; @@ -1425,8 +1435,10 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start, - kern_end - kern_start); + 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); @@ -1494,7 +1506,7 @@ grub_bsd_load (int argc, char *argv[]) fail: if (grub_errno != GRUB_ERR_NONE) - grub_dl_unref (my_mod); + grub_dl_unref (my_mod); return grub_errno; } @@ -1531,9 +1543,7 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) grub_file_t file; int len = is_64bit ? 8 : 4; - err = grub_freebsd_add_meta_module (argv[0], is_64bit - ? FREEBSD_MODTYPE_KERNEL64 - : FREEBSD_MODTYPE_KERNEL, + err = grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_KERNEL, argc - 1, argv + 1, kern_start, kern_end - kern_start); @@ -1599,7 +1609,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) kernel_type = KERNEL_TYPE_OPENBSD; bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags); - if (ctxt->state[OPENBSD_ROOT_ARG].set) + 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; @@ -1615,8 +1625,8 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown disk type name"); - unit = grub_strtoul (arg, (char **) &arg, 10); - if (! (arg && *arg >= 'a' && *arg <= 'z')) + 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"); @@ -1633,7 +1643,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) if (ctxt->state[OPENBSD_SERIAL_ARG].set) { struct grub_openbsd_bootarg_console serial; - char *ptr; + const char *ptr; unsigned port = 0; unsigned speed = 9600; @@ -1652,7 +1662,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) "only com0-com3 are supported"); if (*ptr == ',') { - ptr++; + ptr++; speed = grub_strtoul (ptr, &ptr, 0); if (grub_errno) return grub_errno; @@ -1662,7 +1672,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) 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; } @@ -1735,7 +1745,7 @@ grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) if (ctxt->state[NETBSD_SERIAL_ARG].set) { struct grub_netbsd_btinfo_serial serial; - char *ptr; + const char *ptr; grub_memset (&serial, 0, sizeof (serial)); grub_strcpy (serial.devname, "com"); @@ -1749,7 +1759,7 @@ grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) if (grub_memcmp (ptr, "com", sizeof ("com") - 1) == 0) { ptr += sizeof ("com") - 1; - serial.addr + serial.addr = grub_ns8250_hw_get_port (grub_strtoul (ptr, &ptr, 0)); } else @@ -1919,7 +1929,7 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)), { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, + err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, file->size); if (err) goto fail; @@ -1970,7 +1980,7 @@ grub_netbsd_module_load (char *filename, grub_uint32_t type) { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, + err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, file->size); if (err) goto fail; @@ -2104,7 +2114,8 @@ grub_cmd_openbsd_ramdisk (grub_command_t cmd __attribute__ ((unused)), { grub_file_close (file); return grub_error (GRUB_ERR_BAD_OS, "your kOpenBSD supports ramdisk only" - " up to %u bytes, however you supplied a %u bytes one", + " up to %" PRIuGRUB_SIZE " bytes, however you supplied" + " a %" PRIuGRUB_SIZE " bytes one", openbsd_ramdisk.max_size, size); } diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c index af6741d15..d3de8a29b 100644 --- a/grub-core/loader/i386/bsdXX.c +++ b/grub-core/loader/i386/bsdXX.c @@ -24,9 +24,12 @@ load (grub_file_t file, const char *filename, void *where, grub_off_t off, grub_ } static inline grub_err_t -read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr) +read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, Elf_Shdr **shdr) { - if (grub_file_seek (file, 0) == (grub_off_t) -1) + 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)) @@ -48,15 +51,19 @@ read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr) if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS)) return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); - *shdr = grub_malloc ((grub_uint32_t) e->e_shnum * e->e_shentsize); + 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, (grub_uint32_t) e->e_shnum * e->e_shentsize) - != (grub_ssize_t) ((grub_uint32_t) e->e_shnum * e->e_shentsize)) + if (grub_file_read (file, *shdr, shnum * e->e_shentsize) + != ((grub_ssize_t) shnum * e->e_shentsize)) { if (grub_errno) return grub_errno; @@ -77,45 +84,51 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator, char *argv[], grub_addr_t *kern_end) { Elf_Ehdr e; - Elf_Shdr *s; - char *shdr = 0; + Elf_Shdr *s, *shdr = NULL; + Elf_Shnum shnum; grub_addr_t curload, module; grub_err_t err; - grub_size_t chunk_size = 0; void *chunk_src; - curload = module = ALIGN_PAGE (*kern_end); + module = ALIGN_PAGE (*kern_end); err = read_headers (file, argv[0], &e, &shdr); - if (err) + if (err != GRUB_ERR_NONE) goto out; - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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) - chunk_size = ALIGN_UP (chunk_size + *kern_end, s->sh_addralign) - - *kern_end; + curload = ALIGN_UP (curload, s->sh_addralign); - chunk_size += s->sh_size; + curload += s->sh_size; } + *kern_end = ALIGN_PAGE (curload); + { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_addr (relocator, &ch, - module, chunk_size); - if (err) + module, curload - module); + if (err != GRUB_ERR_NONE) goto out; chunk_src = get_virtual_current_address (ch); } - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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; @@ -132,13 +145,13 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator, { default: case SHT_PROGBITS: - err = load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, + err = load (file, argv[0], (grub_uint8_t *) chunk_src + curload - module, s->sh_offset, s->sh_size); - if (err) + if (err != GRUB_ERR_NONE) goto out; break; case SHT_NOBITS: - grub_memset ((grub_uint8_t *) chunk_src + curload - *kern_end, 0, + grub_memset ((grub_uint8_t *) chunk_src + curload - module, 0, s->sh_size); break; } @@ -150,14 +163,14 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (struct grub_relocator *relocator, err = grub_freebsd_add_meta_module (argv[0], FREEBSD_MODTYPE_ELF_MODULE_OBJ, argc - 1, argv + 1, module, curload - module); - if (! err) - err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA + if (err == GRUB_ERR_NONE) + err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ELFHDR, &e, sizeof (e)); - if (! err) + if (err == GRUB_ERR_NONE) err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_SHDR, - shdr, e.e_shnum * e.e_shentsize); + shdr, shnum * e.e_shentsize); out: grub_free (shdr); @@ -172,8 +185,9 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, grub_addr_t *kern_end) { Elf_Ehdr e; - Elf_Shdr *s; - char *shdr = 0; + 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; @@ -182,12 +196,19 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, curload = module = ALIGN_PAGE (*kern_end); err = read_headers (file, argv[0], &e, &shdr); - if (err) + if (err != GRUB_ERR_NONE) goto out; - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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; @@ -200,23 +221,22 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, if (chunk_size < sizeof (e)) chunk_size = sizeof (e); - chunk_size += (grub_uint32_t) e.e_phnum * e.e_phentsize; - chunk_size += (grub_uint32_t) e.e_shnum * e.e_shentsize; + 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) + if (err != GRUB_ERR_NONE) goto out; chunk_src = get_virtual_current_address (ch); } - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) ((char *) shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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; @@ -236,7 +256,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, (grub_uint8_t *) chunk_src + module + s->sh_addr - *kern_end, s->sh_offset, s->sh_size); - if (err) + if (err != GRUB_ERR_NONE) goto out; break; case SHT_NOBITS: @@ -253,14 +273,14 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, curload = module + sizeof (e); load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_shoff, - (grub_uint32_t) e.e_shnum * e.e_shentsize); + (grub_size_t) shnum * e.e_shentsize); e.e_shoff = curload - module; - curload += (grub_uint32_t) e.e_shnum * e.e_shentsize; + curload += (grub_addr_t) shnum * e.e_shentsize; load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_phoff, - (grub_uint32_t) e.e_phnum * e.e_phentsize); + (grub_size_t) phnum * e.e_phentsize); e.e_phoff = curload - module; - curload += (grub_uint32_t) e.e_phnum * e.e_phentsize; + curload += (grub_addr_t) phnum * e.e_phentsize; *kern_end = curload; @@ -269,7 +289,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator, curload - module); out: grub_free (shdr); - if (err) + if (err != GRUB_ERR_NONE) return err; return SUFFIX (grub_freebsd_load_elf_meta) (relocator, file, argv[0], kern_end); } @@ -284,8 +304,8 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator, { grub_err_t err; Elf_Ehdr e; - Elf_Shdr *s; - char *shdr = 0; + Elf_Shdr *s, *shdr = NULL; + Elf_Shnum shnum; unsigned symoff, stroff, symsize, strsize; grub_freebsd_addr_t symstart, symend, symentsize, dynamic; Elf_Sym *sym; @@ -297,22 +317,24 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator, grub_size_t chunk_size; err = read_headers (file, filename, &e, &shdr); - if (err) + 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) + if (err != GRUB_ERR_NONE) goto out; - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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 *) ((char *) shdr - + e.e_shnum * e.e_shentsize)) + 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; @@ -320,7 +342,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator, symoff = s->sh_offset; symsize = s->sh_size; symentsize = s->sh_entsize; - s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link); + s = (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shentsize * s->sh_link); stroff = s->sh_offset; strsize = s->sh_size; @@ -333,7 +355,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator, grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_addr (relocator, &ch, symtarget, chunk_size); - if (err) + if (err != GRUB_ERR_NONE) goto out; sym_chunk = get_virtual_current_address (ch); } @@ -396,14 +418,14 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator, err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_DYNAMIC, &dynamic, sizeof (dynamic)); - if (err) + if (err != GRUB_ERR_NONE) goto out; } err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_SSYM, &symstart, sizeof (symstart)); - if (err) + if (err != GRUB_ERR_NONE) goto out; err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA | @@ -411,7 +433,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (struct grub_relocator *relocator, sizeof (symend)); out: grub_free (shdr); - if (err) + if (err != GRUB_ERR_NONE) return err; *kern_end = ALIGN_PAGE (symend); @@ -426,8 +448,8 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, { grub_err_t err; Elf_Ehdr e; - Elf_Shdr *s, *symsh, *strsh; - char *shdr = NULL; + Elf_Shdr *s, *symsh, *strsh, *shdr = NULL; + Elf_Shnum shnum; unsigned symsize, strsize; void *sym_chunk; grub_uint8_t *curload; @@ -437,39 +459,44 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, grub_addr_t symtarget; err = read_headers (file, filename, &e, &shdr); - if (err) + if (err != GRUB_ERR_NONE) { grub_free (shdr); return grub_errno; } - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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 *) ((char *) shdr - + e.e_shnum * e.e_shentsize)) + 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 *) (shdr + e.e_shentsize * s->sh_link); + 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) + (grub_uint32_t) e.e_shnum * e.e_shentsize; + + 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) + if (err != GRUB_ERR_NONE) goto out; sym_chunk = get_virtual_current_address (ch); } @@ -479,7 +506,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, symtab.esyms = symtarget + chunk_size; curload = sym_chunk; - + e2 = (Elf_Ehdr *) curload; grub_memcpy (curload, &e, sizeof (e)); e2->e_phoff = 0; @@ -490,18 +517,17 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, curload += sizeof (e); - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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) + (grub_uint32_t) e.e_shnum * e.e_shentsize; + 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) + (grub_uint32_t) e.e_shnum * e.e_shentsize; + + sizeof (e) + shnum * e.e_shentsize; else s2->sh_offset = 0; s2->sh_addr = s2->sh_offset; @@ -539,12 +565,12 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator, goto out; } - err = grub_bsd_add_meta (NETBSD_BTINFO_SYMTAB, + err = grub_bsd_add_meta (NETBSD_BTINFO_SYMTAB, &symtab, sizeof (symtab)); out: grub_free (shdr); - if (err) + if (err != GRUB_ERR_NONE) return err; *kern_end = ALIGN_PAGE (symtarget + chunk_size); @@ -564,22 +590,28 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, { grub_err_t err; Elf_Ehdr e; - Elf_Shdr *s; - char *shdr = NULL; - + Elf_Shdr *s, *shdr = NULL; + Elf_Shnum shnum; + err = read_headers (file, filename, &e, &shdr); - if (err) + if (err != GRUB_ERR_NONE) { grub_free (shdr); return err; } - for (s = (Elf_Shdr *) shdr; s < (Elf_Shdr *) (shdr - + e.e_shnum * e.e_shentsize); - s = (Elf_Shdr *) ((char *) s + e.e_shentsize)) + 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 *) ((char *) shdr + e.e_shnum * e.e_shentsize)) + if (s >= (Elf_Shdr *) ((grub_uint8_t *) shdr + shnum * e.e_shentsize)) { grub_free (shdr); return GRUB_ERR_NONE; @@ -588,8 +620,8 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, symsize = s->sh_size; symentsize = s->sh_entsize; symoff = s->sh_offset; - - s = (Elf_Shdr *) (shdr + e.e_shentsize * s->sh_link); + + s = (Elf_Shdr *) ((grub_uint8_t *) shdr + e.e_shentsize * s->sh_link); stroff = s->sh_offset; strsize = s->sh_size; grub_free (shdr); diff --git a/grub-core/loader/i386/coreboot/chainloader.c b/grub-core/loader/i386/coreboot/chainloader.c index 0a19ebb9c..4a5179806 100644 --- a/grub-core/loader/i386/coreboot/chainloader.c +++ b/grub-core/loader/i386/coreboot/chainloader.c @@ -461,7 +461,7 @@ grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), "payload is too short"); return grub_errno; } - + switch (head) { case ELFMAG0 | (ELFMAG1 << 8) | (ELFMAG2 << 16) | (ELFMAG3 << 24): diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index d0501e229..12731feb2 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -36,6 +36,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -45,6 +46,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #ifdef GRUB_MACHINE_EFI #include +#include #define HAS_VGA_TEXT 0 #define DEFAULT_VIDEO_MODE "auto" #define ACCEPTS_PURE_TEXT 0 @@ -122,7 +124,7 @@ find_mmap_size (void) grub_mmap_iterate (count_hook, &count); - mmap_size = count * sizeof (struct grub_e820_mmap); + mmap_size = count * sizeof (struct grub_boot_e820_entry); /* Increase the size a bit for safety, because GRUB allocates more on later. */ @@ -180,9 +182,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, for (; err && *align + 1 > min_align; (*align)--) { grub_errno = GRUB_ERR_NONE; - err = grub_relocator_alloc_chunk_align (relocator, &ch, - 0x1000000, - 0xffffffff & ~prot_size, + err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000000, + UP_TO_TOP32 (prot_size), prot_size, 1 << *align, GRUB_RELOCATOR_PREFERENCE_LOW, 1); @@ -211,20 +212,20 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, } static grub_err_t -grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, +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_map[n - 1].addr + e820_map[n - 1].size == start) && - (e820_map[n - 1].type == type)) - e820_map[n - 1].size += size; + 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_map[n].addr = start; - e820_map[n].size = size; - e820_map[n].type = type; + e820_entry[n].addr = start; + e820_entry[n].size = size; + e820_entry[n].type = type; (*e820_num)++; } return GRUB_ERR_NONE; @@ -252,43 +253,43 @@ grub_linux_setup_video (struct linux_kernel_params *params) return 1; } - params->lfb_width = mode_info.width; - params->lfb_height = mode_info.height; - params->lfb_depth = mode_info.bpp; - params->lfb_line_len = mode_info.pitch; + params->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->lfb_base = (grub_size_t) framebuffer; + params->screen_info.lfb_base = (grub_size_t) framebuffer; #if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) - params->ext_lfb_base = (grub_size_t) (((grub_uint64_t)(grub_size_t) framebuffer) >> 32); - params->capabilities |= VIDEO_CAPABILITY_64BIT_BASE; + 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->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536); + params->screen_info.lfb_size = ALIGN_UP (params->screen_info.lfb_linelength * params->screen_info.lfb_height, 65536); - params->red_mask_size = mode_info.red_mask_size; - params->red_field_pos = mode_info.red_field_pos; - params->green_mask_size = mode_info.green_mask_size; - params->green_field_pos = mode_info.green_field_pos; - params->blue_mask_size = mode_info.blue_mask_size; - params->blue_field_pos = mode_info.blue_field_pos; - params->reserved_mask_size = mode_info.reserved_mask_size; - params->reserved_field_pos = mode_info.reserved_field_pos; + 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->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_SIMPLE; else { switch (driver_id) { case GRUB_VIDEO_DRIVER_VBE: - params->lfb_size >>= 16; - params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + 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->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; + params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_EFIFB; break; /* FIXME: check if better id is available. */ @@ -306,7 +307,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) case GRUB_VIDEO_DRIVER_SDL: case GRUB_VIDEO_DRIVER_NONE: case GRUB_VIDEO_ADAPTER_CAPTURE: - params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + params->screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_SIMPLE; break; } } @@ -331,9 +332,9 @@ grub_linux_setup_video (struct linux_kernel_params *params) /* 6 is default after mode reset. */ width = 6; - params->red_mask_size = params->green_mask_size - = params->blue_mask_size = width; - params->reserved_mask_size = 0; + params->screen_info.red_size = params->screen_info.green_size + = params->screen_info.blue_size = width; + params->screen_info.rsvd_size = 0; } #endif @@ -390,7 +391,7 @@ grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, { struct grub_linux_boot_ctx *ctx = data; - if (grub_e820_add_region (ctx->params->e820_map, &ctx->e820_num, + if (grub_e820_add_region (ctx->params->e820_table, &ctx->e820_num, addr, size, type)) return 1; @@ -422,10 +423,10 @@ grub_linux_boot (void) "bootpath", bootpath, grub_strlen (bootpath) + 1, &len); - linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE; - linux_params.ofw_num_items = 1; - linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn; - linux_params.ofw_idt = 0; + 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 @@ -470,19 +471,19 @@ grub_linux_boot (void) if (grub_linux_setup_video (&linux_params)) { #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) - linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; - linux_params.video_mode = 0x3; + linux_params.screen_info.orig_video_isVGA = GRUB_VIDEO_LINUX_TYPE_TEXT; + linux_params.screen_info.orig_video_mode = 0x3; #else - linux_params.have_vga = 0; - linux_params.video_mode = 0; - linux_params.video_width = 0; - linux_params.video_height = 0; + 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.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT) + if (linux_params.screen_info.orig_video_isVGA == GRUB_VIDEO_LINUX_TYPE_TEXT) #endif { grub_term_output_t term; @@ -493,19 +494,19 @@ grub_linux_boot (void) || grub_strcmp (term->name, "ofconsole") == 0) { struct grub_term_coordinate pos = grub_term_getxy (term); - linux_params.video_cursor_x = pos.x; - linux_params.video_cursor_y = pos.y; - linux_params.video_width = grub_term_width (term); - linux_params.video_height = grub_term_height (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.video_cursor_x = 0; - linux_params.video_cursor_y = 0; - linux_params.video_width = 80; - linux_params.video_height = 25; + 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; } } @@ -516,8 +517,8 @@ grub_linux_boot (void) 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.setup_sects << GRUB_DISK_SECTOR_BITS)) - cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects + 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); @@ -547,9 +548,13 @@ grub_linux_boot (void) { 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, - (ctx.real_size + efi_mmap_size)); + ctx.real_mode_target, sz); if (err) return err; real_mode_mem = get_virtual_current_address (ch); @@ -562,66 +567,81 @@ grub_linux_boot (void) ctx.params = real_mode_mem; *ctx.params = linux_params; - ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset; + 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->code32_start); + (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->mmap_size = ctx.e820_num; + 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 + 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->version) >= 0x0208) + if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0208) { - ctx.params->v0208.efi_mem_desc_size = efi_desc_size; - ctx.params->v0208.efi_mem_desc_version = efi_desc_version; - ctx.params->v0208.efi_mmap = efi_mmap_target; - ctx.params->v0208.efi_mmap_size = efi_mmap_size; + 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->v0208.efi_mmap_hi = (efi_mmap_target >> 32); + ctx.params->efi_info.v0208.efi_memmap_hi = (efi_mmap_target >> 32); #endif } - else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206) + else if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0206) { - ctx.params->v0206.efi_mem_desc_size = efi_desc_size; - ctx.params->v0206.efi_mem_desc_version = efi_desc_version; - ctx.params->v0206.efi_mmap = efi_mmap_target; - ctx.params->v0206.efi_mmap_size = efi_mmap_size; + 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->version) >= 0x0204) + else if (grub_le_to_cpu16 (ctx.params->hdr.version) >= 0x0204) { - ctx.params->v0204.efi_mem_desc_size = efi_desc_size; - ctx.params->v0204.efi_mem_desc_version = efi_desc_version; - ctx.params->v0204.efi_mmap = efi_mmap_target; - ctx.params->v0204.efi_mmap_size = efi_mmap_size; + 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->code32_start; + state.eip = ctx.params->hdr.code32_start; return grub_relocator32_boot (relocator, state, 0); } @@ -728,14 +748,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), for (align = 0; align < 32; align++) if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align)) break; - relocatable = grub_le_to_cpu32 (lh.relocatable); + relocatable = lh.relocatable; } else { align = 0; relocatable = 0; } - + if (grub_le_to_cpu16 (lh.version) >= 0x020a) { min_align = lh.min_alignment; @@ -743,14 +763,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), prot_init_space = page_align (prot_size); if (relocatable) preferred_address = grub_le_to_cpu64 (lh.pref_address); - else - preferred_address = GRUB_LINUX_BZIMAGE_ADDR; } else { min_align = align; prot_size = prot_file_size; - preferred_address = GRUB_LINUX_BZIMAGE_ADDR; /* Usually, the compression ratio is about 50%. */ prot_init_space = page_align (prot_size) * 3; } @@ -761,17 +778,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; grub_memset (&linux_params, 0, sizeof (linux_params)); - grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); - - linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; - linux_params.kernel_alignment = (1 << align); - linux_params.ps_mouse = linux_params.padding10 = 0; /* * The Linux 32-bit boot protocol defines the setup header end * to be at 0x202 + the byte value at 0x201. */ - len = 0x202 + *((char *) &linux_params.jump + 1); + 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) { @@ -779,10 +791,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 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 (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len) + 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"), @@ -790,58 +805,62 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; + 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.cl_magic = GRUB_LINUX_CL_MAGIC; - linux_params.cl_offset = 0x1000; + linux_params.screen_info.cl_magic = GRUB_LINUX_CL_MAGIC; + linux_params.screen_info.cl_offset = 0x1000; - linux_params.ramdisk_image = 0; - linux_params.ramdisk_size = 0; + linux_params.hdr.ramdisk_image = 0; + linux_params.hdr.ramdisk_size = 0; - linux_params.heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; - linux_params.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; + 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.ext_mem = ((32 * 0x100000) >> 10); - linux_params.alt_mem = ((32 * 0x100000) >> 10); + linux_params.screen_info.ext_mem_k = ((32 * 0x100000) >> 10); + linux_params.alt_mem_k = ((32 * 0x100000) >> 10); /* Ignored by Linux. */ - linux_params.video_page = 0; + linux_params.screen_info.orig_video_page = 0; /* Only used when `video_mode == 0x7', otherwise ignored. */ - linux_params.video_ega_bx = 0; + linux_params.screen_info.orig_video_ega_bx = 0; - linux_params.font_size = 16; /* XXX */ + linux_params.screen_info.orig_video_points = 16; /* XXX */ #ifdef GRUB_MACHINE_EFI #ifdef __x86_64__ - if (grub_le_to_cpu16 (linux_params.version) < 0x0208 && - ((grub_addr_t) grub_efi_system_table >> 32) != 0) - return grub_error(GRUB_ERR_BAD_OS, - "kernel does not support 64-bit addressing"); + 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.version) >= 0x0208) + if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0208) { - linux_params.v0208.efi_signature = GRUB_LINUX_EFI_SIGNATURE; - linux_params.v0208.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; + 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.v0208.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32); + 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.version) >= 0x0206) + else if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0206) { - linux_params.v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE; - linux_params.v0206.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; + 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.version) >= 0x0204) + else if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0204) { - linux_params.v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204; - linux_params.v0204.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; + 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 @@ -943,7 +962,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), #endif /* GRUB_MACHINE_PCBIOS */ if (grub_memcmp (argv[i], "mem=", 4) == 0) { - char *val = argv[i] + 4; + const char *val = argv[i] + 4; linux_mem_size = grub_strtoul (val, &val, 0); @@ -980,7 +999,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0) { - linux_params.loadflags |= GRUB_LINUX_FLAG_QUIET; + linux_params.hdr.loadflags |= GRUB_LINUX_FLAG_QUIET; } /* Create kernel command line. */ @@ -1055,9 +1074,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), aligned_size = ALIGN_UP (size, 4096); /* Get the highest address available for the initrd. */ - if (grub_le_to_cpu16 (linux_params.version) >= 0x0203) + if (grub_le_to_cpu16 (linux_params.hdr.version) >= 0x0203) { - addr_max = grub_cpu_to_le32 (linux_params.initrd_addr_max); + 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 @@ -1079,9 +1098,22 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 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"); @@ -1096,20 +1128,20 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), GRUB_RELOCATOR_PREFERENCE_HIGH, 1); if (err) - return err; + goto fail; initrd_mem = get_virtual_current_address (ch); initrd_mem_target = get_physical_target_address (ch); } - if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + if (grub_initrd_load (&initrd_ctx, initrd_mem)) goto fail; - grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n", - (unsigned) addr, (unsigned) size); + grub_dprintf ("linux", "Initrd (%p) at 0x%" PRIxGRUB_ADDR ", size=0x%" PRIxGRUB_SIZE "\n", + initrd_mem, initrd_mem_target, size); - linux_params.ramdisk_image = initrd_mem_target; - linux_params.ramdisk_size = size; - linux_params.root_dev = 0x0100; /* XXX */ + 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); @@ -1117,6 +1149,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } +#ifndef GRUB_MACHINE_EFI static grub_command_t cmd_linux, cmd_initrd; GRUB_MOD_INIT(linux) @@ -1133,3 +1166,10 @@ 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 index ad3cc292f..bdaf67ad0 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -69,7 +69,6 @@ static grub_err_t load_kernel (grub_file_t file, const char *filename, char *buffer, struct multiboot_header *header) { - grub_err_t err; mbi_load_data_t mld; mld.file = file; @@ -81,12 +80,15 @@ load_kernel (grub_file_t file, const char *filename, if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE) { - err = grub_multiboot_load_elf (&mld); + 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) { @@ -97,13 +99,14 @@ load_kernel (grub_file_t file, const char *filename, 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, + err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch, header->load_addr, code_size); if (err) @@ -200,7 +203,7 @@ grub_multiboot_load (grub_file_t file, const char *filename) switch (header->mode_type) { case 1: - err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, + err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, GRUB_MULTIBOOT_CONSOLE_EGA_TEXT | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, 0, 0, 0, 0); @@ -213,14 +216,14 @@ grub_multiboot_load (grub_file_t file, const char *filename) header->depth, 0); break; default: - err = grub_error (GRUB_ERR_BAD_OS, + 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, + err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, 0, 0, 0, 0); return err; @@ -238,7 +241,7 @@ grub_multiboot_get_mbi_size (void) ret = sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd - + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + + 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) @@ -293,12 +296,12 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, struct grub_vbe_mode_info_block *mode_info; #if GRUB_MACHINE_HAS_VBE grub_vbe_status_t status; - void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - + 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); @@ -307,7 +310,7 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, mbi->vbe_control_info = 0; #endif -#if GRUB_MACHINE_HAS_VBE +#if GRUB_MACHINE_HAS_VBE status = grub_vbe_bios_get_mode (scratch); vbe_mode = *(grub_uint32_t *) scratch; if (status != GRUB_VBE_STATUS_OK) @@ -329,7 +332,7 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, } else { -#if GRUB_MACHINE_HAS_VBE +#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"); @@ -340,19 +343,19 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, ptrorig += sizeof (struct grub_vbe_mode_info_block); ptrdest += sizeof (struct grub_vbe_mode_info_block); -#if GRUB_MACHINE_HAS_VBE +#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_pitch = 2 * mode_info->x_resolution; mbi->framebuffer_width = mode_info->x_resolution; mbi->framebuffer_height = mode_info->y_resolution; @@ -406,7 +409,7 @@ retrieve_video_parameters (struct multiboot_info *mbi, 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; @@ -457,7 +460,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) unsigned i; struct module *cur; grub_size_t mmap_size; - grub_uint8_t *ptrorig; + grub_uint8_t *ptrorig; grub_addr_t ptrdest; grub_err_t err; @@ -466,10 +469,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target) bufsize = grub_multiboot_get_mbi_size (); - err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, - 0x10000, 0xa0000 - bufsize, - bufsize, 4, - GRUB_RELOCATOR_PREFERENCE_NONE, 0); + 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); @@ -542,7 +544,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) mbi->mods_count = 0; } - mmap_size = grub_multiboot_get_mmap_count () + 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; @@ -751,7 +753,7 @@ grub_multiboot_set_bootdev (void) if (dev) grub_device_close (dev); - bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16) + 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 index 976fea73a..a38389999 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -57,7 +57,7 @@ typedef enum static grub_err_t grub_chainloader_boot (void) { - struct grub_relocator16_state state = { + struct grub_relocator16_state state = { .edx = boot_drive, .esi = boot_part_addr, .ds = 0, @@ -118,7 +118,7 @@ grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl) || (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; @@ -243,7 +243,7 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) if (dev) grub_device_close (dev); - + /* Ignore errors. Perhaps it's not fatal. */ grub_errno = GRUB_ERR_NONE; diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c index aac6c9715..f2242dc51 100644 --- a/grub-core/loader/i386/pc/freedos.c +++ b/grub-core/loader/i386/pc/freedos.c @@ -62,7 +62,7 @@ static grub_uint32_t ebx = 0xffffffff; static grub_err_t grub_freedos_boot (void) { - struct grub_relocator16_state state = { + struct grub_relocator16_state state = { .cs = GRUB_FREEDOS_SEGMENT, .ip = 0, @@ -161,7 +161,7 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), 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; diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index 47ea2945e..4adeee9ae 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -35,6 +35,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -54,7 +55,7 @@ static grub_err_t grub_linux16_boot (void) { grub_uint16_t segment; - struct grub_relocator16_state state; + struct grub_relocator16_state state = {0}; segment = grub_linux_real_target >> 4; state.gs = state.fs = state.es = state.ds = state.ss = segment; @@ -66,7 +67,7 @@ grub_linux16_boot (void) grub_video_set_mode ("text", 0, 0); grub_stop_floppy (); - + return grub_relocator16_boot (relocator, state); } @@ -218,16 +219,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; real_size = setup_sects << GRUB_DISK_SECTOR_BITS; - grub_linux16_prot_size = grub_file_size (file) - - real_size - GRUB_DISK_SECTOR_SIZE; + 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%x > 0x%x), use bzImage instead", - (char *) GRUB_LINUX_ZIMAGE_ADDR + grub_linux16_prot_size, - (grub_size_t) 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; } @@ -259,7 +265,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } else if (grub_memcmp (argv[i], "mem=", 4) == 0) { - char *val = argv[i] + 4; + const char *val = argv[i] + 4; linux_mem_size = grub_strtoul (val, &val, 0); @@ -448,17 +454,15 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (relocator, &ch, - addr_min, addr_max - size, - size, 0x1000, - GRUB_RELOCATOR_PREFERENCE_HIGH, 0); + err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, addr_min, addr_max, size, + 0x1000, GRUB_RELOCATOR_PREFERENCE_HIGH, 0); if (err) return err; initrd_chunk = get_virtual_current_address (ch); initrd_addr = get_physical_target_address (ch); } - if (grub_initrd_load (&initrd_ctx, argv, initrd_chunk)) + if (grub_initrd_load (&initrd_ctx, initrd_chunk)) goto fail; lh->ramdisk_image = initrd_addr; diff --git a/grub-core/loader/i386/pc/ntldr.c b/grub-core/loader/i386/pc/ntldr.c index f0d74145b..2b1dec62a 100644 --- a/grub-core/loader/i386/pc/ntldr.c +++ b/grub-core/loader/i386/pc/ntldr.c @@ -45,7 +45,7 @@ static grub_uint32_t edx = 0xffffffff; static grub_err_t grub_ntldr_boot (void) { - struct grub_relocator16_state state = { + struct grub_relocator16_state state = { .cs = GRUB_NTLDR_SEGMENT, .ip = 0, .ds = 0, @@ -133,7 +133,7 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)), 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; diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c index 37550155d..960e866f4 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -56,7 +56,7 @@ static const struct grub_arg_option options[] = 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_("Override guessed mapping of Plan9 devices."), N_("GRUBDEVICE=PLAN9DEVICE"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} @@ -78,7 +78,7 @@ struct grub_plan9_header static grub_err_t grub_plan9_boot (void) { - struct grub_relocator32_state state = { + struct grub_relocator32_state state = { .eax = 0, .eip = eip, .ebx = 0, @@ -122,7 +122,7 @@ static const char prefixes[5][10] = { #include -static inline grub_err_t +static inline grub_err_t grub_extend_alloc (grub_size_t sz, grub_size_t *allocated, char **ptr) { void *n; @@ -302,7 +302,7 @@ fill_disk (const char *name, void *data) 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"); @@ -331,7 +331,7 @@ fill_disk (const char *name, void *data) 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 diff --git a/grub-core/loader/i386/pc/pxechainloader.c b/grub-core/loader/i386/pc/pxechainloader.c index acb061169..df4f7c60b 100644 --- a/grub-core/loader/i386/pc/pxechainloader.c +++ b/grub-core/loader/i386/pc/pxechainloader.c @@ -46,7 +46,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_err_t grub_pxechain_boot (void) { - struct grub_relocator16_state state = { + struct grub_relocator16_state state = { .cs = 0, .ip = 0x7c00, .ds = 0, @@ -138,7 +138,7 @@ grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)), 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; diff --git a/grub-core/loader/i386/pc/truecrypt.c b/grub-core/loader/i386/pc/truecrypt.c index cbeeec7be..bae1ad031 100644 --- a/grub-core/loader/i386/pc/truecrypt.c +++ b/grub-core/loader/i386/pc/truecrypt.c @@ -48,7 +48,7 @@ static grub_err_t grub_truecrypt_boot (void) { grub_uint16_t segment = destaddr >> 4; - struct grub_relocator16_state state = { + struct grub_relocator16_state state = { .cs = segment, .ds = segment, .es = segment, @@ -194,7 +194,7 @@ grub_cmd_truecrypt (grub_command_t cmd __attribute__ ((unused)), 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); diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c index 8f662c8ac..dcdf005df 100644 --- a/grub-core/loader/i386/xen.c +++ b/grub-core/loader/i386/xen.c @@ -41,6 +41,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -91,8 +92,7 @@ static struct xen_loader_state xen_state; static grub_dl_t my_mod; -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define MAX_MODULES (PAGE_SIZE / sizeof (struct xen_multiboot_mod_list)) +#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) @@ -102,7 +102,7 @@ static grub_dl_t my_mod; static grub_uint64_t page2offset (grub_uint64_t page) { - return page << PAGE_SHIFT; + return page << GRUB_PAGE_SHIFT; } static grub_err_t @@ -141,7 +141,7 @@ get_pgtable_size (grub_uint64_t from, grub_uint64_t to, grub_uint64_t pfn) continue; } - bits = PAGE_SHIFT + (i + 1) * LOG_POINTERS_PER_PAGE; + 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; @@ -228,7 +228,7 @@ generate_page_table (grub_xen_mfn_t *mfn_list) 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 * PAGE_SIZE); + xen_state.mappings[m1].area.n_pt_pages * GRUB_PAGE_SIZE); for (l = NUMBER_OF_LEVELS - 1; l >= 0; l--) { @@ -246,11 +246,11 @@ generate_page_table (grub_xen_mfn_t *mfn_list) if (lvl->virt_start >= end || lvl->virt_end <= start) continue; p_s = (grub_max (start, lvl->virt_start) - start) >> - (PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); + (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); p_e = (grub_min (end, lvl->virt_end) - start) >> - (PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); + (GRUB_PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE); pfn = ((grub_max (start, lvl->virt_start) - lvl->virt_start) >> - (PAGE_SHIFT + l * LOG_POINTERS_PER_PAGE)) + lvl->pfn_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); @@ -323,21 +323,21 @@ grub_xen_p2m_alloc (void) map = xen_state.mappings + xen_state.n_mappings; p2msize = ALIGN_UP (sizeof (grub_xen_mfn_t) * - grub_xen_start_page_addr->nr_pages, PAGE_SIZE); + 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) >> PAGE_SHIFT); + (xen_state.max_addr + p2msize) >> GRUB_PAGE_SHIFT); if (err) return err; - map->area.pfn_start = xen_state.max_addr >> PAGE_SHIFT; + 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 >> PAGE_SHIFT; + xen_state.next_start.nr_p2m_frames = p2malloc >> GRUB_PAGE_SHIFT; } else { @@ -379,9 +379,9 @@ grub_xen_special_alloc (void) 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), PAGE_SIZE); - xen_state.console_pfn = xen_state.max_addr >> PAGE_SHIFT; - xen_state.max_addr += 2 * PAGE_SIZE; + 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, @@ -412,7 +412,7 @@ grub_xen_pt_alloc (void) xen_state.next_start.pt_base = xen_state.max_addr + xen_state.xen_inf.virt_base; - nr_info_pages = xen_state.max_addr >> PAGE_SHIFT; + nr_info_pages = xen_state.max_addr >> GRUB_PAGE_SHIFT; nr_need_pages = nr_info_pages; while (1) @@ -430,9 +430,9 @@ grub_xen_pt_alloc (void) /* 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, PAGE_SIZE, nr_need_pages); + err = get_pgtable_size (0, GRUB_PAGE_SIZE, nr_need_pages); else - err = get_pgtable_size (try_virt_end, try_virt_end + PAGE_SIZE, + err = get_pgtable_size (try_virt_end, try_virt_end + GRUB_PAGE_SIZE, nr_need_pages); if (err) return err; @@ -460,7 +460,7 @@ grub_xen_pt_alloc (void) 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 >> PAGE_SHIFT; + 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)); @@ -514,7 +514,7 @@ grub_xen_boot (void) if (err) return err; - nr_pages = xen_state.max_addr >> PAGE_SHIFT; + 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, @@ -537,7 +537,7 @@ grub_xen_boot (void) return grub_relocator_xen_boot (xen_state.relocator, xen_state.state, nr_pages, xen_state.xen_inf.virt_base < - PAGE_SIZE ? page2offset (nr_pages) : 0, + GRUB_PAGE_SIZE ? page2offset (nr_pages) : 0, xen_state.pgtbl_end - 1, page2offset (xen_state.pgtbl_end - 1) + xen_state.xen_inf.virt_base); @@ -636,6 +636,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), 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")); @@ -675,7 +676,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), goto fail; } - if (xen_state.xen_inf.virt_base & (PAGE_SIZE - 1)) + if (xen_state.xen_inf.virt_base & (GRUB_PAGE_SIZE - 1)) { grub_error (GRUB_ERR_BAD_OS, "unaligned virt_base"); goto fail; @@ -698,13 +699,19 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), 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 + PAGE_SIZE); + xen_state.xen_inf.virt_base + GRUB_PAGE_SIZE); } - xen_state.max_addr = ALIGN_UP (kern_end, PAGE_SIZE); + xen_state.max_addr = ALIGN_UP (kern_end, GRUB_PAGE_SIZE); - err = grub_relocator_alloc_chunk_addr (xen_state.relocator, &ch, kern_start, - kern_end - kern_start); + + 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); @@ -722,7 +729,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), if (xen_state.xen_inf.has_hypercall_page) { unsigned i; - for (i = 0; i < PAGE_SIZE / HYPERCALL_INTERFACE_SIZE; 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 - @@ -801,8 +808,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (err) goto fail; - if (grub_initrd_load (&initrd_ctx, argv, - get_virtual_current_address (ch))) + if (grub_initrd_load (&initrd_ctx, get_virtual_current_address (ch))) goto fail; } @@ -811,7 +817,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 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 >> PAGE_SHIFT; + xen_state.next_start.mod_start = xen_state.max_addr >> GRUB_PAGE_SHIFT; } else xen_state.next_start.mod_start = @@ -821,7 +827,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), (unsigned) (xen_state.max_addr + xen_state.xen_inf.virt_base), (unsigned) size); - xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, PAGE_SIZE); + xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, GRUB_PAGE_SIZE); fail: grub_initrd_close (&initrd_ctx); @@ -875,7 +881,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), { xen_state.xen_inf.unmapped_initrd = 0; xen_state.n_modules = 0; - xen_state.max_addr = ALIGN_UP (xen_state.max_addr, PAGE_SIZE); + 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; @@ -895,7 +901,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), MAX_MODULES * sizeof (xen_state.module_info_page[0]); } - xen_state.max_addr = ALIGN_UP (xen_state.max_addr, PAGE_SIZE); + 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)); @@ -918,7 +924,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), 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, PAGE_SIZE); + xen_state.max_addr = ALIGN_UP (xen_state.max_addr + cmdline_len, GRUB_PAGE_SIZE); if (size) { @@ -945,7 +951,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), 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, PAGE_SIZE); + xen_state.max_addr = ALIGN_UP (xen_state.max_addr + size, GRUB_PAGE_SIZE); fail: diff --git a/grub-core/loader/i386/xen_fileXX.c b/grub-core/loader/i386/xen_fileXX.c index 6329ec010..27afcaacb 100644 --- a/grub-core/loader/i386/xen_fileXX.c +++ b/grub-core/loader/i386/xen_fileXX.c @@ -25,7 +25,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi, grub_off_t off, grub_size_t sz) { char *buf; - char *ptr; + const char *ptr; int has_paddr = 0; grub_errno = GRUB_ERR_NONE; diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index e64ed08f5..b91e2f840 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -48,7 +48,7 @@ grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack; /* Aliases set for some tables. */ struct tbl_alias { - grub_efi_guid_t guid; + grub_guid_t guid; const char *name; }; @@ -262,20 +262,19 @@ grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev, if (!prop) return grub_errno; - prop->name = utf8; - prop->name16 = utf16; - prop->name16len = utf16len; - - prop->length = datalen; - prop->data = grub_malloc (prop->length); + prop->data = grub_malloc (datalen); if (!prop->data) { - grub_free (prop->name); - grub_free (prop->name16); grub_free (prop); return grub_errno; } - grub_memcpy (prop->data, data, prop->length); + grub_memcpy (prop->data, data, datalen); + + prop->name = utf8; + prop->name16 = utf16; + prop->name16len = utf16len; + prop->length = datalen; + grub_list_push (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop)); return GRUB_ERR_NONE; @@ -295,7 +294,7 @@ grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *d return grub_errno; len = grub_strlen (name); - utf16 = grub_malloc (sizeof (grub_uint16_t) * len); + utf16 = grub_calloc (len, sizeof (grub_uint16_t)); if (!utf16) { grub_free (utf8); @@ -331,7 +330,7 @@ grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor * grub_uint16_t *utf16; grub_err_t err; - utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen); + utf16 = grub_calloc (namelen, sizeof (grub_uint16_t)); if (!utf16) return grub_errno; grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen); @@ -516,14 +515,15 @@ grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)), devhead = buf; buf = devhead + 1; - dpstart = buf; + dp = dpstart = buf; - do + while (GRUB_EFI_DEVICE_PATH_VALID (dp) && buf < bufend) { - dp = buf; buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp); + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + break; + dp = buf; } - while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend); dev = grub_xnu_devprop_add_device (dpstart, (char *) buf - (char *) dpstart); @@ -694,7 +694,7 @@ grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out) { void *ptr; struct grub_xnu_devtree_key *curkey; - grub_efi_packed_guid_t guid; + grub_packed_guid_t guid; char guidbuf[64]; /* Retrieve current key. */ @@ -726,13 +726,8 @@ grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out) #endif /* The name of key for new table. */ - grub_snprintf (guidbuf, sizeof (guidbuf), "%08x-%04x-%04x-%02x%02x-", - guid.data1, guid.data2, guid.data3, guid.data4[0], - guid.data4[1]); - for (j = 2; j < 8; j++) - grub_snprintf (guidbuf + grub_strlen (guidbuf), - sizeof (guidbuf) - grub_strlen (guidbuf), - "%02x", guid.data4[j]); + grub_snprintf (guidbuf, sizeof (guidbuf), "%pG", &guid); + /* For some reason GUID has to be in uppercase. */ for (j = 0; guidbuf[j] ; j++) if (guidbuf[j] >= 'a' && guidbuf[j] <= 'f') @@ -805,14 +800,14 @@ grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out) grub_err_t grub_xnu_boot_resume (void) { - struct grub_relocator32_state state; + struct grub_relocator32_state state = {0}; state.esp = grub_xnu_stack; state.ebp = grub_xnu_stack; state.eip = grub_xnu_entry_point; state.eax = grub_xnu_arg1; - return grub_relocator32_boot (grub_xnu_relocator, state, 0); + return grub_relocator32_boot (grub_xnu_relocator, state, 0); } /* Setup video for xnu. */ @@ -912,7 +907,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params_common *params) params->lfb_line_len = mode_info.pitch; params->lfb_base = (grub_addr_t) framebuffer; - params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH + params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO; return GRUB_ERR_NONE; @@ -960,7 +955,7 @@ grub_xnu_boot (void) grub_addr_t devtree_target; grub_size_t devtreelen; int i; - struct grub_relocator32_state state; + struct grub_relocator32_state state = {0}; grub_uint64_t fsbfreq = 100000000; int v2 = (grub_xnu_darwin_version >= 11); grub_uint32_t efi_system_table = 0; @@ -1069,7 +1064,7 @@ grub_xnu_boot (void) if (v2) bootparams->v2.efi_system_table = (grub_addr_t) grub_autoefi_system_table; else - bootparams->v1.efi_system_table = (grub_addr_t) grub_autoefi_system_table; + bootparams->v1.efi_system_table = (grub_addr_t) grub_autoefi_system_table; firstruntimepage = (((grub_addr_t) grub_xnu_heap_target_start + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1) diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c index 7987fd1ba..99cb244d8 100644 --- a/grub-core/loader/ia64/efi/linux.c +++ b/grub-core/loader/ia64/efi/linux.c @@ -106,7 +106,7 @@ query_fpswa (void) grub_efi_boot_services_t *bs; grub_efi_status_t status; grub_efi_uintn_t size; - static const grub_efi_guid_t fpswa_protocol = + static const grub_guid_t fpswa_protocol = { 0xc41b6531, 0x97b9, 0x11d3, {0x9a, 0x29, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} }; @@ -114,7 +114,7 @@ query_fpswa (void) 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, @@ -131,7 +131,7 @@ query_fpswa (void) grub_printf ("%s\n", _("FPSWA protocol wasn't able to find the interface")); return; - } + } } static void @@ -188,7 +188,7 @@ allocate_pages (grub_uint64_t align, grub_uint64_t size_pages, } 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; @@ -240,7 +240,7 @@ 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) @@ -250,7 +250,7 @@ set_boot_param_console (void) "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; @@ -300,7 +300,7 @@ grub_linux_boot (void) /* 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; } @@ -383,6 +383,7 @@ grub_load_elf64 (grub_file_t file, void *buffer, const char *filename) { 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)) @@ -411,7 +412,7 @@ grub_load_elf64 (grub_file_t file, void *buffer, const char *filename) "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; @@ -424,7 +425,7 @@ grub_load_elf64 (grub_file_t file, void *buffer, const char *filename) filename); return grub_errno; } - + if (phdr->p_filesz < phdr->p_memsz) grub_memset ((char *)(phdr->p_paddr + reloc_offset + phdr->p_filesz), @@ -453,7 +454,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_dl_ref (my_mod); grub_loader_unset (); - + if (argc == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); @@ -507,7 +508,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 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; @@ -539,7 +540,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 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")); @@ -559,11 +560,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), 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, argv, initrd_mem)) + if (grub_initrd_load (&initrd_ctx, initrd_mem)) goto fail; fail: grub_initrd_close (&initrd_ctx); @@ -589,7 +590,7 @@ 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.")); diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c index 471b214d6..56bc1be58 100644 --- a/grub-core/loader/linux.c +++ b/grub-core/loader/linux.c @@ -4,6 +4,7 @@ #include #include #include +#include struct newc_head { @@ -63,6 +64,8 @@ make_header (grub_uint8_t *ptr, 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); @@ -98,13 +101,14 @@ free_dir (struct dir *root) grub_free (root); } -static grub_size_t +static grub_err_t insert_dir (const char *name, struct dir **root, - grub_uint8_t *ptr) + grub_uint8_t *ptr, grub_size_t *size) { struct dir *cur, **head = root; const char *cb, *ce = name; - grub_size_t size = 0; + *size = 0; + while (1) { for (cb = ce; *cb == '/'; cb++); @@ -113,7 +117,7 @@ insert_dir (const char *name, struct dir **root, break; for (cur = *root; cur; cur = cur->next) - if (grub_memcmp (cur->name, cb, ce - cb) + if (grub_memcmp (cur->name, cb, ce - cb) == 0 && cur->name[ce - cb] == 0) break; if (!cur) @@ -126,18 +130,36 @@ insert_dir (const char *name, struct dir **root, n->name = grub_strndup (cb, ce - cb); if (ptr) { - grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce); - ptr = make_header (ptr, name, ce - name, + /* + * 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; } - size += ALIGN_UP ((ce - (char *) name) - + sizeof (struct newc_head), 4); *head = n; cur = n; } root = &cur->next; } - return size; + return GRUB_ERR_NONE; } grub_err_t @@ -151,8 +173,7 @@ grub_initrd_init (int argc, char *argv[], initrd_ctx->nfiles = 0; initrd_ctx->components = 0; - initrd_ctx->components = grub_zalloc (argc - * sizeof (initrd_ctx->components[0])); + initrd_ctx->components = grub_calloc (argc, sizeof (initrd_ctx->components[0])); if (!initrd_ctx->components) return grub_errno; @@ -173,26 +194,33 @@ grub_initrd_init (int argc, char *argv[], 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) + 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; } - initrd_ctx->size - += ALIGN_UP (sizeof (struct newc_head) - + grub_strlen (initrd_ctx->components[i].newc_name), - 4); - initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, - &root, 0); + 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) { - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) - + sizeof ("TRAILER!!!") - 1, 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; newc = 0; @@ -208,19 +236,29 @@ grub_initrd_init (int argc, char *argv[], initrd_ctx->nfiles++; initrd_ctx->components[i].size = grub_file_size (initrd_ctx->components[i].file); - initrd_ctx->size += initrd_ctx->components[i].size; + 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); - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) - + sizeof ("TRAILER!!!") - 1, 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 @@ -246,7 +284,7 @@ grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx) grub_err_t grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, - char *argv[], void *target) + void *target) { grub_uint8_t *ptr = target; int i; @@ -261,17 +299,25 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, if (initrd_ctx->components[i].newc_name) { - ptr += insert_dir (initrd_ctx->components[i].newc_name, - &root, ptr); + 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), + 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!!!") - 1, + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), 0, 0); free_dir (root); root = 0; @@ -284,7 +330,7 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, { if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - argv[i]); + initrd_ctx->components[i].file->name); grub_initrd_close (initrd_ctx); return grub_errno; } @@ -294,7 +340,7 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, { grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); ptr += ALIGN_UP_OVERHEAD (cursize, 4); - ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0); + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), 0, 0); } free_dir (root); root = 0; diff --git a/grub-core/loader/lzss.c b/grub-core/loader/lzss.c index 532d8e4a3..2c3e4507f 100644 --- a/grub-core/loader/lzss.c +++ b/grub-core/loader/lzss.c @@ -31,7 +31,7 @@ grub_decompress_lzss (grub_uint8_t *dst, grub_uint8_t *dstend, 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 ( ; ; ) { diff --git a/grub-core/loader/macho.c b/grub-core/loader/macho.c index 085f9c689..05710c48e 100644 --- a/grub-core/loader/macho.c +++ b/grub-core/loader/macho.c @@ -97,7 +97,7 @@ grub_macho_file (grub_file_t file, const char *filename, int is_64bit) if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header)) == (grub_off_t) -1) goto fail; - archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs); + archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch)); if (!archs) goto fail; if (grub_file_read (macho->file, archs, diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 7b723bf18..7264ba2b6 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -100,7 +100,7 @@ grub_linux_boot (void) str = (char *) (magic + 1); grub_strcpy (str, params); } -#endif +#endif #ifndef GRUB_MACHINE_MIPS_QEMU_MIPS state.gpr[4] = linux_argc; @@ -261,11 +261,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_argc++; #endif /* Main arguments. */ - size = (linux_argc) * sizeof (grub_uint32_t); + size = (linux_argc) * sizeof (grub_uint32_t); /* Initrd address and size. */ - size += 2 * sizeof (grub_uint32_t); + size += 2 * sizeof (grub_uint32_t); /* NULL terminator. */ - size += sizeof (grub_uint32_t); + size += sizeof (grub_uint32_t); /* First argument is always "a0". */ size += ALIGN_UP (sizeof ("a0"), 4); @@ -442,12 +442,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (relocator, &ch, - (target_addr & 0x1fffffff) - + linux_size + 0x10000, - (0x10000000 - size), - size, 0x10000, - GRUB_RELOCATOR_PREFERENCE_NONE, 0); + err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, (target_addr & 0x1fffffff) + + linux_size + 0x10000, 0x10000000, size, + 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE, 0); if (err) goto fail; @@ -455,7 +452,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), initrd_dest = get_physical_target_address (ch) | 0x80000000; } - if (grub_initrd_load (&initrd_ctx, argv, initrd_src)) + if (grub_initrd_load (&initrd_ctx, initrd_src)) goto fail; #ifdef GRUB_MACHINE_MIPS_QEMU_MIPS diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index 4a98d7082..36b27a906 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -238,7 +238,7 @@ GRUB_MULTIBOOT (set_console) (int console_type, int accepted_consoles, int console_req) { console_required = console_req; - if (!(accepted_consoles + if (!(accepted_consoles & (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER | (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0)))) { @@ -403,7 +403,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, - lowest_addr, (0xffffffff - size) + 1, + lowest_addr, UP_TO_TOP32 (size), size, MULTIBOOT_MOD_ALIGN, GRUB_RELOCATOR_PREFERENCE_NONE, 1); if (err) @@ -420,13 +420,6 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), target = 0; } - err = GRUB_MULTIBOOT (add_module) (target, size, argc - 1, argv + 1); - if (err) - { - grub_file_close (file); - return err; - } - if (size && grub_file_read (file, module, size) != size) { grub_file_close (file); @@ -437,7 +430,8 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), } grub_file_close (file); - return GRUB_ERR_NONE; + + return GRUB_MULTIBOOT (add_module) (target, size, argc - 1, argv + 1); } static grub_command_t cmd_multiboot, cmd_module; diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c index 70cd1db51..1edad0594 100644 --- a/grub-core/loader/multiboot_elfxx.c +++ b/grub-core/loader/multiboot_elfxx.c @@ -17,19 +17,29 @@ */ #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 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 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 @@ -57,8 +67,11 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) char *phdr_base; grub_err_t err; grub_relocator_chunk_t ch; - grub_uint32_t load_offset = 0, load_size; - int i; + 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 @@ -75,8 +88,21 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) 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? */ - if (ehdr->e_phoff + (grub_uint32_t) ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH) + 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; @@ -85,7 +111,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) mld->link_base_addr = ~0; /* Calculate lowest and highest load address. */ - for (i = 0; i < ehdr->e_phnum; i++) + 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); @@ -109,12 +135,12 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) 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 (GRUB_MULTIBOOT (relocator), &ch, - mld->min_addr, mld->max_addr - load_size, - load_size, mld->align ? mld->align : 1, - mld->preference, mld->avoid_efi_boot_services); + 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) + if (err != GRUB_ERR_NONE) { grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); return err; @@ -131,7 +157,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) mld->link_base_addr, mld->load_base_addr); /* Load every loadable segment in memory. */ - for (i = 0; i < ehdr->e_phnum; i++) + for (i = 0; i < phnum; i++) { if (phdr(i)->p_type == PT_LOAD) { @@ -146,10 +172,11 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) } else { + load_size = phdr(i)->p_memsz; err = grub_relocator_alloc_chunk_addr (GRUB_MULTIBOOT (relocator), &ch, - phdr(i)->p_paddr, phdr(i)->p_memsz); + phdr(i)->p_paddr, load_size); - if (err) + if (err != GRUB_ERR_NONE) { grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); return err; @@ -175,12 +202,18 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) } if (phdr(i)->p_filesz < phdr(i)->p_memsz) - grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0, - phdr(i)->p_memsz - phdr(i)->p_filesz); + { + /* 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 < ehdr->e_phnum; i++) + 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) { @@ -202,41 +235,41 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) break; } - if (i == ehdr->e_phnum) + 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 (ehdr->e_shnum) + if (shnum) { grub_uint8_t *shdr, *shdrptr; - shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize); + 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) - { - grub_free (shdr); - return grub_errno; - } - if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize) - != (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize) + 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); - return grub_errno; + goto fail; } - - for (shdrptr = shdr, i = 0; i < ehdr->e_shnum; + + for (shdrptr = shdr, i = 0; i < shnum; shdrptr += ehdr->e_shentsize, i++) { Elf_Shdr *sh = (Elf_Shdr *) shdrptr; @@ -244,32 +277,36 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) grub_addr_t target; if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet"); + { + 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, - (0xffffffff - sh->sh_size) + 1, + UP_TO_TOP32 (sh->sh_size), sh->sh_size, sh->sh_addralign, GRUB_RELOCATOR_PREFERENCE_NONE, mld->avoid_efi_boot_services); - if (err) + if (err != GRUB_ERR_NONE) { grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i); - return err; + 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) - return grub_errno; + goto fail; if (grub_file_read (mld->file, src, sh->sh_size) != (grub_ssize_t) sh->sh_size) @@ -277,12 +314,16 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), mld->filename); - return grub_errno; + goto fail; } sh->sh_addr = target; } - GRUB_MULTIBOOT (add_elfsyms) (ehdr->e_shnum, ehdr->e_shentsize, - ehdr->e_shstrndx, shdr); + GRUB_MULTIBOOT (add_elfsyms) (shnum, ehdr->e_shentsize, + shstrndx, shdr); + return GRUB_ERR_NONE; + + fail: + grub_free (shdr); } #undef phdr @@ -296,3 +337,8 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) #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 index 53da78615..00a48413c 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -48,6 +48,12 @@ #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; @@ -190,7 +196,7 @@ grub_multiboot2_load (grub_file_t file, const char *filename) } break; } - + case MULTIBOOT_HEADER_TAG_ADDRESS: addr_tag = (struct multiboot_header_tag_address *) tag; break; @@ -268,7 +274,7 @@ grub_multiboot2_load (grub_file_t file, const char *filename) 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) @@ -295,10 +301,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename) return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); } - err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, - mld.min_addr, mld.max_addr - code_size, - code_size, mld.align ? mld.align : 1, - mld.preference, keep_bs); + 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, @@ -486,7 +492,7 @@ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) tag->type = MULTIBOOT_TAG_TYPE_MMAP; tag->size = sizeof (struct multiboot_tag_mmap) - + sizeof (struct multiboot_mmap_entry) * grub_multiboot2_get_mmap_count (); + + sizeof (struct multiboot_mmap_entry) * grub_multiboot2_get_mmap_count (); tag->entry_size = sizeof (struct multiboot_mmap_entry); tag->entry_version = 0; @@ -498,18 +504,18 @@ static void fill_vbe_tag (struct multiboot_tag_vbe *tag) { grub_vbe_status_t status; - void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + 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) @@ -532,7 +538,7 @@ fill_vbe_tag (struct multiboot_tag_vbe *tag) 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); @@ -571,7 +577,7 @@ retrieve_video_parameters (grub_properly_aligned_t **ptrorig) #if defined (GRUB_MACHINE_PCBIOS) { grub_vbe_status_t status; - void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + 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) @@ -610,13 +616,13 @@ retrieve_video_parameters (grub_properly_aligned_t **ptrorig) tag->common.size = 0; tag->common.framebuffer_addr = 0xb8000; - - tag->common.framebuffer_pitch = 2 * vbe_mode_info.x_resolution; + + 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; @@ -658,7 +664,7 @@ retrieve_video_parameters (grub_properly_aligned_t **ptrorig) tag->common.framebuffer_bpp = mode_info.bpp; tag->common.reserved = 0; - + if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) { unsigned i; @@ -708,7 +714,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0); err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, - 0, 0xffffffff - bufsize, + MBI_MIN_ADDR, UP_TO_TOP32 (bufsize), bufsize, MULTIBOOT_TAG_ALIGN, GRUB_RELOCATOR_PREFERENCE_NONE, 1); if (err) @@ -742,7 +748,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) { 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; + 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); @@ -751,7 +757,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) { 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); + 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); @@ -765,7 +771,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) struct multiboot_tag_apm *tag = (struct multiboot_tag_apm *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_APM; - tag->size = sizeof (struct multiboot_tag_apm); + tag->size = sizeof (struct multiboot_tag_apm); tag->cseg = info.cseg; tag->offset = info.offset; @@ -858,7 +864,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) struct multiboot_tag_bootdev *tag = (struct multiboot_tag_bootdev *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_BOOTDEV; - tag->size = sizeof (struct multiboot_tag_bootdev); + tag->size = sizeof (struct multiboot_tag_bootdev); tag->biosdev = biosdev; tag->slice = slice; @@ -1070,7 +1076,11 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, err = grub_create_loader_cmdline (argc, argv, newmod->cmdline, newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE); if (err) - return err; + { + grub_free (newmod->cmdline); + grub_free (newmod); + return err; + } if (modules_last) modules_last->next = newmod; diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c index 818b2a86d..4864e5fb0 100644 --- a/grub-core/loader/powerpc/ieee1275/linux.c +++ b/grub-core/loader/powerpc/ieee1275/linux.c @@ -30,6 +30,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -111,25 +112,27 @@ grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size, .found_addr = (grub_addr_t) -1 }; - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) - { - grub_uint64_t addr = target; - if (addr < GRUB_IEEE1275_STATIC_HEAP_START - + GRUB_IEEE1275_STATIC_HEAP_LEN) - addr = GRUB_IEEE1275_STATIC_HEAP_START - + GRUB_IEEE1275_STATIC_HEAP_LEN; - addr = ALIGN_UP (addr, align); - if (grub_claimmap (addr, size) == GRUB_ERR_NONE) - return addr; - return (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) { @@ -241,10 +244,18 @@ grub_linux_load64 (grub_elf_t elf, const char *filename) offset = entry - base_addr; /* Linux's incorrectly contains a virtual address. */ - /* 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 (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"); @@ -353,17 +364,29 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), size = grub_get_initrd_size (&initrd_ctx); - first_addr = linux_addr + linux_size; - /* Attempt to claim at a series of addresses until successful in - the same way that grub_rescue_cmd_linux does. */ - addr = grub_linux_claimmap_iterate (first_addr, size, 0x100000); + 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) - goto fail; + { + 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, argv, (void *) addr)) + if (grub_initrd_load (&initrd_ctx, (void *) addr)) goto fail; initrd_addr = addr; diff --git a/grub-core/loader/riscv/linux.c b/grub-core/loader/riscv/linux.c deleted file mode 100644 index d17c488e1..000000000 --- a/grub-core/loader/riscv/linux.c +++ /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 . - */ - -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_err_t -grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("Linux not supported yet")); - - return grub_errno; -} - -static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char *argv[] __attribute__ ((unused))) -{ - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("Linux not supported yet")); - - 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.")); -} - -GRUB_MOD_FINI (linux) -{ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_initrd); -} diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c index bb47ee0cc..ac2206f3c 100644 --- a/grub-core/loader/sparc64/ieee1275/linux.c +++ b/grub-core/loader/sparc64/ieee1275/linux.c @@ -413,7 +413,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n", addr, paddr, size); - if (grub_initrd_load (&initrd_ctx, argv, (void *) addr)) + if (grub_initrd_load (&initrd_ctx, (void *) addr)) goto fail; initrd_addr = addr; diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index 7f74d1d6f..80831386e 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -34,6 +34,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -59,15 +60,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target) { grub_err_t err; grub_relocator_chunk_t ch; - - err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, - grub_xnu_heap_target_start - + grub_xnu_heap_size, size); + grub_addr_t tgt; + + if (grub_add (grub_xnu_heap_target_start, grub_xnu_heap_size, &tgt)) + return GRUB_ERR_OUT_OF_RANGE; + + err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch, tgt, size); if (err) return err; *src = get_virtual_current_address (ch); - *target = grub_xnu_heap_target_start + grub_xnu_heap_size; + *target = tgt; grub_xnu_heap_size += size; grub_dprintf ("xnu", "val=%p\n", *src); return GRUB_ERR_NONE; @@ -224,26 +227,33 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size) if (! memorymap) return grub_errno; - driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey)); + driverkey = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*driverkey)); if (! driverkey) return grub_errno; driverkey->name = grub_strdup ("DeviceTree"); if (! driverkey->name) - return grub_errno; + { + err = grub_errno; + goto fail; + } + driverkey->datasize = sizeof (*extdesc); driverkey->next = memorymap->first_child; memorymap->first_child = driverkey; driverkey->data = extdesc = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc)); if (! driverkey->data) - return grub_errno; + { + err = grub_errno; + goto fail; + } /* Allocate the space based on the size with dummy value. */ *size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/"); err = grub_xnu_heap_malloc (ALIGN_UP (*size + 1, GRUB_XNU_PAGESIZE), &src, target); if (err) - return err; + goto fail; /* Put real data in the dummy. */ extdesc->addr = *target; @@ -252,6 +262,15 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size) /* Write the tree to heap. */ grub_xnu_writetree_toheap_real (src, grub_xnu_devtree_root, "/"); return GRUB_ERR_NONE; + + fail: + memorymap->first_child = NULL; + + grub_free (driverkey->data); + grub_free (driverkey->name); + grub_free (driverkey); + + return err; } /* Find a key or value in parent key. */ @@ -651,6 +670,9 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile, char *name, *nameend; int namelen; + if (infoplistname == NULL) + return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing p-list filename")); + name = get_name_ptr (infoplistname); nameend = grub_strchr (name, '/'); @@ -682,10 +704,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile, else macho = 0; - if (infoplistname) - infoplist = grub_file_open (infoplistname, GRUB_FILE_TYPE_XNU_INFO_PLIST); - else - infoplist = 0; + infoplist = grub_file_open (infoplistname, GRUB_FILE_TYPE_XNU_INFO_PLIST); grub_errno = GRUB_ERR_NONE; if (infoplist) { @@ -800,7 +819,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC) { narchs = grub_be_to_cpu32 (head.nfat_arch); - archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs); + archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch)); if (! archs) { grub_file_close (file); @@ -1239,6 +1258,7 @@ grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired, grub_device_close (dev); } grub_free (device_name); + grub_free (ctx.newdirname); return GRUB_ERR_NONE; } @@ -1380,22 +1400,22 @@ grub_xnu_fill_devicetree (void) nextdot = curdot + grub_strlen (curdot) + 1; name = grub_realloc (name, nextdot - curdot + 1); - + if (!name) return grub_errno; - + unescape (name, curdot, nextdot, &len); name[len] = 0; curvalue = grub_xnu_create_value (curkey, name); + grub_free (name); if (!curvalue) return grub_errno; - grub_free (name); - + data = grub_malloc (grub_strlen (var->value) + 1); if (!data) return grub_errno; - + unescape (data, var->value, var->value + grub_strlen (var->value), &len); curvalue->datasize = len; @@ -1482,20 +1502,23 @@ GRUB_MOD_INIT(xnu) N_("Load XNU image.")); cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, 0, N_("Load 64-bit XNU image.")); - cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0, - N_("Load XNU extension package.")); - cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0, - N_("Load XNU extension.")); - cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir, - /* TRANSLATORS: OSBundleRequired is a - variable name in xnu extensions - manifests. It behaves mostly like - GNU/Linux runlevels. - */ - N_("DIRECTORY [OSBundleRequired]"), - /* TRANSLATORS: There are many extensions - in extension directory. */ - N_("Load XNU extension directory.")); + cmd_mkext = grub_register_command_lockdown ("xnu_mkext", grub_cmd_xnu_mkext, 0, + N_("Load XNU extension package.")); + cmd_kext = grub_register_command_lockdown ("xnu_kext", grub_cmd_xnu_kext, 0, + N_("Load XNU extension.")); + cmd_kextdir = grub_register_command_lockdown ("xnu_kextdir", grub_cmd_xnu_kextdir, + /* + * TRANSLATORS: OSBundleRequired is + * a variable name in xnu extensions + * manifests. It behaves mostly like + * GNU/Linux runlevels. + */ + N_("DIRECTORY [OSBundleRequired]"), + /* + * TRANSLATORS: There are many extensions + * in extension directory. + */ + N_("Load XNU extension directory.")); cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0, /* TRANSLATORS: ramdisk here isn't identifier. It can be translated. */ N_("Load XNU ramdisk. " diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c index 8089804d4..d648ef0cd 100644 --- a/grub-core/loader/xnu_resume.c +++ b/grub-core/loader/xnu_resume.c @@ -129,7 +129,7 @@ grub_xnu_resume (char *imagename) { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0, - (0xffffffff - hibhead.image_size) + 1, + UP_TO_TOP32 (hibhead.image_size), hibhead.image_size, GRUB_XNU_PAGESIZE, GRUB_RELOCATOR_PREFERENCE_NONE, 0); diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index bd495a184..2f0ec4d03 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -203,14 +203,14 @@ grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type) b = grub_efi_system_table->boot_services; address = start & (~0xfffULL); pages = (end - address + 0xfff) >> 12; - status = efi_call_2 (b->free_pages, address, pages); + status = b->free_pages (address, pages); if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND) { grub_free (curover); return 0; } - status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS, - make_efi_memtype (type), pages, &address); + status = b->allocate_pages (GRUB_EFI_ALLOCATE_ADDRESS, + make_efi_memtype (type), pages, &address); if (status != GRUB_EFI_SUCCESS) { grub_free (curover); @@ -239,7 +239,7 @@ grub_mmap_unregister (int handle) { if (curover->handle == handle) { - efi_call_2 (b->free_pages, curover->address, curover->pages); + b->free_pages (curover->address, curover->pages); if (prevover != 0) prevover->next = curover->next; else @@ -281,8 +281,8 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), #endif pages = (size + 0xfff) >> 12; - status = efi_call_4 (b->allocate_pages, atype, - make_efi_memtype (type), pages, &address); + status = b->allocate_pages (atype, + make_efi_memtype (type), pages, &address); if (status != GRUB_EFI_SUCCESS) { grub_free (curover); @@ -294,8 +294,8 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), /* Uggh, the address 0 was allocated... This is too annoying, so reallocate another one. */ address = 0xffffffff; - status = efi_call_4 (b->allocate_pages, atype, - make_efi_memtype (type), pages, &address); + status = b->allocate_pages (atype, + make_efi_memtype (type), pages, &address); grub_efi_free_pages (0, pages); if (status != GRUB_EFI_SUCCESS) return 0; diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c index 6ab4f6730..b9c5b0a00 100644 --- a/grub-core/mmap/i386/pc/mmap.c +++ b/grub-core/mmap/i386/pc/mmap.c @@ -80,13 +80,13 @@ preboot (int noreturn __attribute__ ((unused))) = min (grub_mmap_get_post64 (), 0xfc000000ULL) >> 16; /* Correct BDA. */ - *((grub_uint16_t *) 0x413) = grub_mmap_get_lower () >> 10; + *((grub_uint16_t *) grub_absolute_pointer (0x413)) = grub_mmap_get_lower () >> 10; /* Save old interrupt handlers. */ - grub_machine_mmaphook_int12offset = *((grub_uint16_t *) 0x48); - grub_machine_mmaphook_int12segment = *((grub_uint16_t *) 0x4a); - grub_machine_mmaphook_int15offset = *((grub_uint16_t *) 0x54); - grub_machine_mmaphook_int15segment = *((grub_uint16_t *) 0x56); + grub_machine_mmaphook_int12offset = *((grub_uint16_t *) grub_absolute_pointer (0x48)); + grub_machine_mmaphook_int12segment = *((grub_uint16_t *) grub_absolute_pointer (0x4a)); + grub_machine_mmaphook_int15offset = *((grub_uint16_t *) grub_absolute_pointer (0x54)); + grub_machine_mmaphook_int15segment = *((grub_uint16_t *) grub_absolute_pointer (0x56)); grub_dprintf ("mmap", "hooktarget = %p\n", hooktarget); @@ -94,11 +94,11 @@ preboot (int noreturn __attribute__ ((unused))) grub_memcpy (hooktarget, &grub_machine_mmaphook_start, &grub_machine_mmaphook_end - &grub_machine_mmaphook_start); - *((grub_uint16_t *) 0x4a) = ((grub_addr_t) hooktarget) >> 4; - *((grub_uint16_t *) 0x56) = ((grub_addr_t) hooktarget) >> 4; - *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12 + *((grub_uint16_t *) grub_absolute_pointer (0x4a)) = ((grub_addr_t) hooktarget) >> 4; + *((grub_uint16_t *) grub_absolute_pointer (0x56)) = ((grub_addr_t) hooktarget) >> 4; + *((grub_uint16_t *) grub_absolute_pointer (0x48)) = &grub_machine_mmaphook_int12 - &grub_machine_mmaphook_start; - *((grub_uint16_t *) 0x54) = &grub_machine_mmaphook_int15 + *((grub_uint16_t *) grub_absolute_pointer (0x54)) = &grub_machine_mmaphook_int15 - &grub_machine_mmaphook_start; return GRUB_ERR_NONE; @@ -108,10 +108,10 @@ static grub_err_t preboot_rest (void) { /* Restore old interrupt handlers. */ - *((grub_uint16_t *) 0x48) = grub_machine_mmaphook_int12offset; - *((grub_uint16_t *) 0x4a) = grub_machine_mmaphook_int12segment; - *((grub_uint16_t *) 0x54) = grub_machine_mmaphook_int15offset; - *((grub_uint16_t *) 0x56) = grub_machine_mmaphook_int15segment; + *((grub_uint16_t *) grub_absolute_pointer (0x48)) = grub_machine_mmaphook_int12offset; + *((grub_uint16_t *) grub_absolute_pointer (0x4a)) = grub_machine_mmaphook_int12segment; + *((grub_uint16_t *) grub_absolute_pointer (0x54)) = grub_machine_mmaphook_int15offset; + *((grub_uint16_t *) grub_absolute_pointer (0x56)) = grub_machine_mmaphook_int15segment; return GRUB_ERR_NONE; } diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c index 6a31cbae3..c8c8312c5 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -143,9 +144,9 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) /* Initialize variables. */ ctx.scanline_events = (struct grub_mmap_scan *) - grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num); + grub_calloc (mmap_num, sizeof (struct grub_mmap_scan) * 2); - present = grub_zalloc (sizeof (present[0]) * current_priority); + present = grub_calloc (current_priority, sizeof (present[0])); if (! ctx.scanline_events || !present) { @@ -269,6 +270,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) hook_data)) { grub_free (ctx.scanline_events); + grub_free (present); return GRUB_ERR_NONE; } @@ -281,6 +283,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) } grub_free (ctx.scanline_events); + grub_free (present); return GRUB_ERR_NONE; } @@ -423,7 +426,7 @@ static grub_err_t grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - char * str; + const char *str; struct badram_entry entry; if (argc != 1) @@ -465,7 +468,7 @@ static grub_uint64_t parsemem (const char *str) { grub_uint64_t ret; - char *ptr; + const char *ptr; ret = grub_strtoul (str, &ptr, 0); @@ -534,12 +537,12 @@ static grub_command_t cmd, cmd_cut; GRUB_MOD_INIT(mmap) { - cmd = grub_register_command ("badram", grub_cmd_badram, - N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), - N_("Declare memory regions as faulty (badram).")); - cmd_cut = grub_register_command ("cutmem", grub_cmd_cutmem, - N_("FROM[K|M|G] TO[K|M|G]"), - N_("Remove any memory regions in specified range.")); + 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.")); } diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 54306e3b1..1d367436c 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -128,6 +128,8 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, 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; diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index 04cfbb045..2f45a3cc2 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -24,6 +24,7 @@ #include #include #include +#include struct grub_dhcp_discover_options { @@ -95,6 +96,14 @@ enum /* 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) @@ -152,6 +161,9 @@ again: 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) { @@ -233,6 +245,7 @@ grub_net_configure_by_dhcp_ack (const char *name, addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bp->your_ip; + addr.option = 0; if (device) *device = 0; @@ -405,7 +418,40 @@ grub_net_configure_by_dhcp_ack (const char *name, 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) { @@ -424,7 +470,7 @@ 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_int32_t t = 0; + grub_int64_t t = 0; struct grub_net_buff *nb; struct udphdr *udph; grub_net_network_level_address_t target; @@ -538,7 +584,9 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6); - grub_netbuff_push (nb, sizeof (*udph)); + 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); @@ -631,14 +679,6 @@ grub_net_process_dhcp (struct grub_net_buff *nb, } } -static char -hexdigit (grub_uint8_t val) -{ - if (val < 10) - return val + '0'; - return val + 'a' - 10; -} - static grub_err_t grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) @@ -647,6 +687,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), 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, @@ -688,7 +729,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), if (grub_strcmp (args[3], "string") == 0) { grub_err_t err = GRUB_ERR_NONE; - char *val = grub_malloc (taglength + 1); + 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); @@ -721,7 +767,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), if (grub_strcmp (args[3], "hex") == 0) { grub_err_t err = GRUB_ERR_NONE; - char *val = grub_malloc (2 * taglength + 1); + 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; @@ -766,7 +817,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), if (ncards == 0) return grub_error (GRUB_ERR_NET_NO_CARD, N_("no network card found")); - ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); + ifaces = grub_calloc (ncards, sizeof (ifaces[0])); if (!ifaces) return grub_errno; @@ -789,7 +840,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), return grub_errno; } ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV; - grub_memcpy (&ifaces[j].hwaddress, &card->default_address, + grub_memcpy (&ifaces[j].hwaddress, &card->default_address, sizeof (ifaces[j].hwaddress)); ifaces[j].dhcp_tmo = ifaces[j].dhcp_tmo_left = 1; j++; diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c index 5d9afe093..f20cd6f83 100644 --- a/grub-core/net/dns.c +++ b/grub-core/net/dns.c @@ -22,6 +22,7 @@ #include #include #include +#include struct dns_cache_element { @@ -51,9 +52,15 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s) { int na = dns_servers_alloc * 2; struct grub_net_network_level_address *ns; + grub_size_t sz; + if (na < 8) na = 8; - ns = grub_realloc (dns_servers, na * sizeof (ns[0])); + + 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; @@ -139,11 +146,18 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, 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. */ @@ -165,13 +179,16 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, ptr = head + (((ptr[0] & 0x3f) << 8) | ptr[1]); continue; } - if (readable_ptr && grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0) + if (readable_ptr != NULL && (*ptr > readable_len || grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0)) return 0; - if (grub_memchr (ptr + 1, 0, *ptr) + if (grub_memchr (ptr + 1, 0, *ptr) || grub_memchr (ptr + 1, '.', *ptr)) return 0; if (readable_ptr) - readable_ptr += *ptr; + { + readable_ptr += *ptr; + readable_len -= *ptr; + } if (readable_ptr && *readable_ptr != '.' && *readable_ptr != 0) return 0; bytes_processed += *ptr + 1; @@ -185,7 +202,10 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, if (optr) *optr++ = '.'; if (readable_ptr && *readable_ptr) - readable_ptr++; + { + readable_ptr++; + readable_len--; + } ptr += *ptr + 1; } return 0; @@ -204,10 +224,17 @@ get_name (const grub_uint8_t *name_at, const grub_uint8_t *head, { int length; char *ret; + int len; if (!check_name_real (name_at, head, tail, NULL, &length, NULL)) return NULL; - ret = grub_malloc (length + 1); + + 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)) @@ -225,7 +252,7 @@ enum DNS_CLASS_AAAA = 28 }; -static grub_err_t +static grub_err_t recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), struct grub_net_buff *nb, void *data_) @@ -241,43 +268,27 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), /* 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->addresses) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } + if (*data->naddresses) + goto out; head = (struct dns_header *) nb->data; ptr = (grub_uint8_t *) (head + 1); if (ptr >= nb->tail) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - + goto out; + if (head->id != data->id) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } + goto out; if (!(head->flags & FLAGS_RESPONSE) || (head->flags & FLAGS_OPCODE)) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } + goto out; if (head->ra_z_r_code & ERRCODE_MASK) { data->dns_err = 1; - grub_netbuff_free (nb); - return GRUB_ERR_NONE; + goto out; } for (i = 0; i < grub_be_to_cpu16 (head->qdcount); i++) { if (ptr >= nb->tail) - { - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } + goto out; while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0)) ptr += *ptr + 1; if (ptr < nb->tail && (*ptr & 0xc0)) @@ -285,13 +296,12 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), ptr++; ptr += 4; } - *data->addresses = grub_malloc (sizeof ((*data->addresses)[0]) - * grub_be_to_cpu16 (head->ancount)); + *data->addresses = grub_calloc (grub_be_to_cpu16 (head->ancount), + sizeof ((*data->addresses)[0])); if (!*data->addresses) { grub_errno = GRUB_ERR_NONE; - grub_netbuff_free (nb); - return GRUB_ERR_NONE; + goto out; } reparse_ptr = ptr; reparse: @@ -302,11 +312,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), grub_uint32_t ttl = 0; grub_uint16_t length; if (ptr >= nb->tail) - { - if (!*data->naddresses) - grub_free (*data->addresses); - return GRUB_ERR_NONE; - } + goto out; ignored = !check_name (ptr, nb->data, nb->tail, data->name); while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0)) ptr += *ptr + 1; @@ -314,12 +320,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), ptr++; ptr++; if (ptr + 10 >= nb->tail) - { - if (!*data->naddresses) - grub_free (*data->addresses); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } + goto out; if (*ptr++ != 0) ignored = 1; class = *ptr++; @@ -335,12 +336,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), length = *ptr++ << 8; length |= *ptr++; if (ptr + length > nb->tail) - { - if (!*data->naddresses) - grub_free (*data->addresses); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } + goto out; if (!ignored) { if (ttl_all > ttl) @@ -354,6 +350,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), = 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; @@ -364,6 +361,9 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), = 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; @@ -380,15 +380,14 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), if (!data->name) { data->dns_err = 1; - grub_errno = 0; - return GRUB_ERR_NONE; + 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; - grub_free (redirect_save); - return GRUB_ERR_NONE; + goto out; } goto reparse; } @@ -406,8 +405,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), dns_cache[h].addresses = 0; dns_cache[h].name = grub_strdup (data->oname); dns_cache[h].naddresses = *data->naddresses; - dns_cache[h].addresses = grub_malloc (*data->naddresses - * sizeof (dns_cache[h].addresses[0])); + 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) { @@ -420,8 +419,12 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), *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; } @@ -467,8 +470,8 @@ grub_net_dns_lookup (const char *name, && grub_get_time_ms () < dns_cache[h].limit_time) { grub_dprintf ("dns", "retrieved from cache\n"); - *addresses = grub_malloc (dns_cache[h].naddresses - * sizeof ((*addresses)[0])); + *addresses = grub_calloc (dns_cache[h].naddresses, + sizeof ((*addresses)[0])); if (!*addresses) return grub_errno; *naddresses = dns_cache[h].naddresses; @@ -479,7 +482,7 @@ grub_net_dns_lookup (const char *name, } } - sockets = grub_malloc (sizeof (sockets[0]) * n_servers); + sockets = grub_calloc (n_servers, sizeof (sockets[0])); if (!sockets) return grub_errno; @@ -608,7 +611,7 @@ grub_net_dns_lookup (const char *name, grub_netbuff_free (nb); for (j = 0; j < send_servers; j++) grub_net_udp_close (sockets[j]); - + grub_free (sockets); if (*data.naddresses) @@ -616,7 +619,7 @@ grub_net_dns_lookup (const char *name, if (data.dns_err) return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found")); - + if (err) { grub_errno = err; @@ -660,9 +663,11 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), grub_net_addr_to_str (&addresses[i], buf); grub_printf ("%s\n", buf); } - grub_free (addresses); if (naddresses) - return GRUB_ERR_NONE; + { + grub_free (addresses); + return GRUB_ERR_NONE; + } return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found")); } @@ -743,11 +748,14 @@ grub_cmd_del_dns (struct grub_command *cmd __attribute__ ((unused)), if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - err = grub_net_resolve_address (args[1], &server); + + err = grub_net_resolve_address (args[0], &server); if (err) return err; - return grub_net_add_dns_server (&server); + grub_net_remove_dns_server (&server); + + return GRUB_ERR_NONE; } static grub_command_t cmd, cmd_add, cmd_del, cmd_list; diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 5388f952b..58fe381ab 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -27,8 +27,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* GUID. */ -static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; -static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_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, @@ -39,11 +39,14 @@ send_card_buffer (struct grub_net_card *dev, 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 = efi_call_3 (net->get_status, net, 0, &txbuf); + st = net->get_status (net, 0, &txbuf); if (st != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); @@ -71,8 +74,8 @@ send_card_buffer (struct grub_net_card *dev, grub_memcpy (dev->txbuf, pack->data, dev->last_pkt_size); - st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size, - dev->txbuf, NULL, NULL, NULL); + 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")); @@ -85,7 +88,7 @@ send_card_buffer (struct grub_net_card *dev, Perhaps a timeout in the FW has discarded the recycle buffer. */ txbuf = NULL; - st = efi_call_3 (net->get_status, net, 0, &txbuf); + st = net->get_status (net, 0, &txbuf); dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf); return GRUB_ERR_NONE; @@ -101,6 +104,9 @@ get_card_packet (struct grub_net_card *dev) struct grub_net_buff *nb; int i; + if (net == NULL) + return NULL; + for (i = 0; i < 2; i++) { if (!dev->rcvbuf) @@ -108,8 +114,8 @@ get_card_packet (struct grub_net_card *dev) if (!dev->rcvbuf) return NULL; - st = efi_call_7 (net->receive, net, NULL, &bufsize, - dev->rcvbuf, NULL, NULL, 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 @@ -148,15 +154,21 @@ open_card (struct grub_net_card *dev) { grub_efi_simple_network_t *net; - /* Try to reopen SNP exlusively to close any active MNP protocol instance - that may compete for packet polling + 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) + if (net != NULL) { if (net->mode->state == GRUB_EFI_NETWORK_STOPPED - && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) + && net->start (net) != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net start failed", dev->name); @@ -165,7 +177,7 @@ open_card (struct grub_net_card *dev) dev->name); if (net->mode->state == GRUB_EFI_NETWORK_STARTED - && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS) + && net->initialize (net, 0, 0) != GRUB_EFI_SUCCESS) return grub_error (GRUB_ERR_NET_NO_CARD, "%s: net initialize failed", dev->name); @@ -189,27 +201,24 @@ open_card (struct grub_net_card *dev) filters |= (net->mode->receive_filter_mask & GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS); - efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL); + net->receive_filters (net, filters, 0, 0, 0, NULL); } - efi_call_4 (grub_efi_system_table->boot_services->close_protocol, - dev->efi_net, &net_io_guid, - grub_efi_image_handle, dev->efi_handle); dev->efi_net = net; + } else { + return grub_error (GRUB_ERR_NET_NO_CARD, "%s: can't open protocol", + dev->name); } - /* If it failed we just try to run as best as we can */ return GRUB_ERR_NONE; } static void close_card (struct grub_net_card *dev) { - efi_call_1 (dev->efi_net->shutdown, dev->efi_net); - efi_call_1 (dev->efi_net->stop, dev->efi_net); - efi_call_4 (grub_efi_system_table->boot_services->close_protocol, - dev->efi_net, &net_io_guid, - grub_efi_image_handle, dev->efi_handle); + 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 = @@ -267,7 +276,8 @@ grub_efinet_findcards (void) || 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_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, @@ -277,14 +287,14 @@ grub_efinet_findcards (void) continue; if (net->mode->state == GRUB_EFI_NETWORK_STOPPED - && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) + && net->start (net) != GRUB_EFI_SUCCESS) continue; if (net->mode->state == GRUB_EFI_NETWORK_STOPPED) continue; if (net->mode->state == GRUB_EFI_NETWORK_STARTED - && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS) + && net->initialize (net, 0, 0) != GRUB_EFI_SUCCESS) continue; card = grub_zalloc (sizeof (struct grub_net_card)); @@ -311,7 +321,15 @@ grub_efinet_findcards (void) card->name = grub_xasprintf ("efinet%d", i++); card->driver = &efidriver; - card->flags = 0; + /* + * 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, @@ -330,6 +348,10 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, { 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) @@ -368,6 +390,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, 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) @@ -378,11 +409,35 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, if (! pxe) continue; pxe_mode = pxe->mode; - 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); + + 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; } } @@ -397,7 +452,7 @@ GRUB_MOD_FINI(efinet) { struct grub_net_card *card, *next; - FOR_NET_CARDS_SAFE (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 index b19492086..5f311d40f 100644 --- a/grub-core/net/drivers/emu/emunet.c +++ b/grub-core/net/drivers/emu/emunet.c @@ -25,21 +25,21 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_err_t +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 = +static struct grub_net_card_driver emudriver = { .name = "emu", .send = send_card_buffer, .recv = get_card_packet }; -static struct grub_net_card emucard = +static struct grub_net_card emucard = { .name = "emu0", .driver = &emudriver, @@ -51,7 +51,7 @@ static struct grub_net_card emucard = .flags = 0 }; -static grub_err_t +static grub_err_t send_card_buffer (struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index 3f4152d03..db17186ee 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -174,7 +174,7 @@ grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused))) grub_uint8_t *ptr, *end; struct grub_net_buff *buf; - isr = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + isr = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); if (!in_progress) { @@ -248,7 +248,7 @@ grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused))) return buf; } -static grub_err_t +static grub_err_t grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)), struct grub_net_buff *pack) { @@ -256,11 +256,11 @@ grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)), struct grub_pxe_undi_tbd *tbd; char *buf; - trans = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + trans = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); grub_memset (trans, 0, sizeof (*trans)); - tbd = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128); + tbd = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128); grub_memset (tbd, 0, sizeof (*tbd)); - buf = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256); + 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); @@ -287,7 +287,7 @@ static grub_err_t grub_pxe_open (struct grub_net_card *dev __attribute__ ((unused))) { struct grub_pxe_undi_open *ou; - ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + 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); @@ -295,7 +295,7 @@ grub_pxe_open (struct grub_net_card *dev __attribute__ ((unused))) 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 = { @@ -382,7 +382,7 @@ GRUB_MOD_INIT(pxe) if (! pxenv) return; - ui = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + 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); diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index ac4e62a95..e5be362a9 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -22,6 +22,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -82,15 +83,11 @@ get_card_packet (struct grub_net_card *dev) grub_ssize_t actual; int rc; struct grub_ofnetcard_data *data = dev->data; - grub_uint64_t start_time; struct grub_net_buff *nb; - start_time = grub_get_time_ms (); - do - rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual); - while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200)); + rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual); - if (actual <= 0) + if (actual <= 0 || rc < 0) return NULL; nb = grub_netbuff_alloc (actual + 2); @@ -220,8 +217,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, flags); inter->vlantag = vlantag; grub_net_add_ipv4_local (inter, - __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4))); - + __builtin_clz (~grub_be_to_cpu32 (subnet_mask.ipv4))); } if (gateway_addr.ipv4 != 0) @@ -321,12 +317,6 @@ grub_ieee1275_alloc_mem (grub_size_t len) } args; - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) - { - grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("interpret is not supported")); - return NULL; - } - INIT_IEEE1275_COMMON (&args.common, "interpret", 2, 2); args.len = len; args.method = (grub_ieee1275_cell_t) "alloc-mem"; @@ -354,12 +344,6 @@ grub_ieee1275_free_mem (void *addr, grub_size_t len) } args; - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) - { - grub_error (GRUB_ERR_UNKNOWN_COMMAND, N_("interpret is not supported")); - return grub_errno; - } - INIT_IEEE1275_COMMON (&args.common, "interpret", 3, 1); args.addr = (grub_ieee1275_cell_t)addr; args.len = len; @@ -404,6 +388,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias) grub_uint8_t *pprop; char *shortname; char need_suffix = 1; + grub_size_t sz; if (grub_strcmp (alias->type, "network") != 0) return 0; @@ -461,9 +446,26 @@ search_net_devices (struct grub_ieee1275_devalias *alias) } if (need_suffix) - ofdata->path = grub_malloc (grub_strlen (alias->path) + sizeof (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 - ofdata->path = grub_malloc (grub_strlen (alias->path) + 1); + { + 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 (); @@ -558,7 +560,7 @@ GRUB_MOD_FINI(ofnet) { struct grub_net_card *card, *next; - FOR_NET_CARDS_SAFE (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 index 056052e40..b9d5a0cd4 100644 --- a/grub-core/net/drivers/uboot/ubootnet.c +++ b/grub-core/net/drivers/uboot/ubootnet.c @@ -155,7 +155,7 @@ GRUB_MOD_FINI (ubootnet) { struct grub_net_card *card, *next; - FOR_NET_CARDS_SAFE (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 index 4d7ceed6f..707bbb12c 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -45,7 +45,7 @@ struct llchdr struct snaphdr { - grub_uint8_t oui[3]; + grub_uint8_t oui[3]; grub_uint16_t type; } GRUB_PACKED; @@ -58,7 +58,7 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, struct etherhdr *eth; grub_err_t err; grub_uint8_t etherhdr_size; - grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER; + 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); @@ -93,8 +93,9 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, (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, (char *) &(inf->vlantag), 2); + grub_memcpy ((char *) nb->data + etherhdr_size - 4, &vlan, 2); } return inf->card->driver->send (inf->card, nb); @@ -118,9 +119,9 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, /* 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) == VLANTAG_IDENTIFIER) + if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER)) { - vlantag = grub_get_unaligned16 (nb->data + etherhdr_size); + 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, diff --git a/grub-core/net/http.c b/grub-core/net/http.c index 5aa4ad3be..f389bf03d 100644 --- a/grub-core/net/http.c +++ b/grub-core/net/http.c @@ -29,11 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); -enum - { - HTTP_PORT = 80 - }; - +#define HTTP_PORT ((grub_uint16_t) 80) typedef struct http_data { @@ -68,7 +64,15 @@ 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) { @@ -107,7 +111,7 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) return GRUB_ERR_NONE; } ptr += sizeof ("HTTP/1.1 ") - 1; - code = grub_strtoul (ptr, &ptr, 10); + code = grub_strtoul (ptr, (const char **)&ptr, 10); if (grub_errno) return grub_errno; switch (code) @@ -134,7 +138,7 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) == 0 && !data->size_recv) { ptr += sizeof ("Content-Length: ") - 1; - file->size = grub_strtoull (ptr, &ptr, 10); + file->size = grub_strtoull (ptr, (const char **)&ptr, 10); data->size_recv = 1; return GRUB_ERR_NONE; } @@ -145,7 +149,7 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) return GRUB_ERR_NONE; } - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } static void @@ -190,9 +194,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), int have_line = 1; char *t; ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data); - if (ptr) - ptr++; - else + if (ptr == NULL) { have_line = 0; ptr = (char *) nb->tail; @@ -205,7 +207,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), 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); @@ -261,7 +263,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), { grub_netbuff_free (nb); return GRUB_ERR_NONE; - } + } err = grub_netbuff_pull (nb, ptr - (char *) nb->data); if (err) { @@ -312,12 +314,14 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) 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 (file->device->net->server) + + grub_strlen (server) + sizeof (":XXXXXXXXXX") + sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") - 1 + sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX" @@ -356,7 +360,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) sizeof (" HTTP/1.1\r\nHost: ") - 1); ptr = nb->tail; - err = grub_netbuff_put (nb, grub_strlen (file->device->net->server)); + err = grub_netbuff_put (nb, grub_strlen (server)); if (err) { grub_netbuff_free (nb); @@ -365,8 +369,14 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) 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, + err = grub_netbuff_put (nb, sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") - 1); if (err) @@ -390,9 +400,11 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) grub_netbuff_put (nb, 2); grub_memcpy (ptr, "\r\n", 2); - data->sock = grub_net_tcp_open (file->device->net->server, - HTTP_PORT, http_receive, - http_err, http_err, + 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) { @@ -409,7 +421,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) return err; } - for (i = 0; !data->headers_recv && i < 100; i++) + for (i = 0; data->sock && !data->headers_recv && i < 100; i++) { grub_net_tcp_retransmit (); grub_net_poll_cards (300, &data->headers_recv); @@ -417,7 +429,8 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) if (!data->headers_recv) { - grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); + if (data->sock) + grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); if (data->err) { char *str = data->errmsg; @@ -542,7 +555,7 @@ http_packets_pulled (struct grub_file *file) return 0; } -static struct grub_net_app_protocol grub_http_protocol = +static struct grub_net_app_protocol grub_http_protocol = { .name = "http", .open = http_open, diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c index 2cbd95dce..9a8c45112 100644 --- a/grub-core/net/icmp6.c +++ b/grub-core/net/icmp6.c @@ -225,7 +225,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, if (ohdr->len == 0 || ptr + 8 * ohdr->len > nb->tail) { grub_netbuff_free (nb); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } if (ohdr->type == OPTION_SOURCE_LINK_LAYER_ADDRESS && ohdr->len == 1) @@ -329,7 +329,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, if (ohdr->len == 0 || ptr + 8 * ohdr->len > nb->tail) { grub_netbuff_free (nb); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } if (ohdr->type == OPTION_TARGET_LINK_LAYER_ADDRESS && ohdr->len == 1) @@ -378,7 +378,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, if (ohdr->len == 0 || ptr + 8 * ohdr->len > nb->tail) { grub_netbuff_free (nb); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } if (ohdr->type == OPTION_SOURCE_LINK_LAYER_ADDRESS && ohdr->len == 1) @@ -448,7 +448,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, grub_errno = GRUB_ERR_NONE; continue; } - inf = grub_net_add_addr (name, + inf = grub_net_add_addr (name, card, &addr, &slaac->address, 0); if (!route_inf) @@ -477,7 +477,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, /* May not have gotten slaac info, find a global address on this card. */ - if (route_inf == NULL) + if (route_inf == NULL && orig_inf != NULL) { FOR_NET_NETWORK_LEVEL_INTERFACES (inf) { @@ -523,7 +523,7 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, 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; @@ -555,7 +555,7 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, ohdr = (struct option_header *) nb->data; ohdr->type = OPTION_SOURCE_LINK_LAYER_ADDRESS; ohdr->len = 1; - err = grub_netbuff_push (nb, sizeof (*sol)); + err = grub_netbuff_push (nb, sizeof (*sol)); if (err) goto fail; diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c index ea5edf8f1..3c3d0be0e 100644 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@ -25,6 +25,7 @@ #include #include #include +#include #include struct iphdr { @@ -157,7 +158,7 @@ send_fragmented (struct grub_net_network_level_interface * inf, 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 + iph->frags = grub_cpu_to_be16 (off | (((grub_ssize_t) len == nb->tail - nb->data) ? 0 : MORE_FRAGMENTS)); iph->ttl = 0xff; @@ -254,7 +255,7 @@ handle_dgram (struct grub_net_buff *nb, if (expected != chk) { grub_dprintf ("net", "Invalid UDP checksum. " - "Expected %x, got %x\n", + "Expected %x, got %x\n", grub_be_to_cpu16 (expected), grub_be_to_cpu16 (chk)); grub_netbuff_free (nb); @@ -271,7 +272,7 @@ handle_dgram (struct grub_net_buff *nb, } 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 @@ -314,7 +315,7 @@ handle_dgram (struct grub_net_buff *nb, && 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]) + && 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) @@ -325,7 +326,7 @@ handle_dgram (struct grub_net_buff *nb, break; } } - + if (!inf && !(dest->type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 && dest->ipv6[0] == grub_be_to_cpu64_compile_time (0xff02ULL << 48) @@ -439,7 +440,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, } if (actual_size < expected_size) { - grub_dprintf ("net", "Cut IP packet actual: %" PRIuGRUB_SIZE + grub_dprintf ("net", "Cut IP packet actual: %" PRIuGRUB_SIZE ", expected %" PRIuGRUB_SIZE "\n", actual_size, expected_size); grub_netbuff_free (nb); @@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, { rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) + (nb->tail - nb->data)); - rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t)); + + 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) { @@ -701,7 +709,7 @@ grub_net_recv_ip6_packets (struct grub_net_buff *nb, } if (actual_size < expected_size) { - grub_dprintf ("net", "Cut IP packet actual: %" PRIuGRUB_SIZE + grub_dprintf ("net", "Cut IP packet actual: %" PRIuGRUB_SIZE ", expected %" PRIuGRUB_SIZE "\n", actual_size, expected_size); grub_netbuff_free (nb); diff --git a/grub-core/net/net.c b/grub-core/net/net.c index d5d726a31..6ea33d1cd 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -32,6 +32,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -60,7 +61,7 @@ link_layer_find_entry (const grub_net_network_level_address_t *proto, return NULL; for (i = 0; i < LINK_LAYER_CACHE_SIZE; i++) { - if (card->link_layer_table[i].avail == 1 + 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]; @@ -86,8 +87,13 @@ grub_net_link_layer_add_address (struct grub_net_card *card, /* Add sender to cache table. */ if (card->link_layer_table == NULL) - card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE - * sizeof (card->link_layer_table[0])); + { + 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)); @@ -175,7 +181,7 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, *hw_addr = entry->ll_address; return GRUB_ERR_NONE; } - return grub_error (GRUB_ERR_TIMEOUT, + return grub_error (GRUB_ERR_TIMEOUT, N_("timeout: could not resolve hardware address")); } @@ -201,6 +207,7 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card, { 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) @@ -210,9 +217,21 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card, if (!slaac) return NULL; - slaac->name = grub_malloc (grub_strlen (card->name) - + GRUB_NET_MAX_STR_HWADDR_LEN - + sizeof (":slaac")); + 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) { @@ -232,7 +251,7 @@ 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, +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, @@ -258,7 +277,7 @@ grub_net_add_addr_real (char *name, } struct grub_net_network_level_interface * -grub_net_add_addr (const char *name, +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, @@ -266,7 +285,7 @@ grub_net_add_addr (const char *name, { 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); @@ -283,10 +302,12 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card, 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) { @@ -296,9 +317,14 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card, return inf; } - name = grub_malloc (grub_strlen (card->name) - + GRUB_NET_MAX_STR_HWADDR_LEN - + sizeof (":link")); + 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; @@ -333,8 +359,8 @@ grub_cmd_ipv6_autoconf (struct grub_command *cmd __attribute__ ((unused)), ncards++; } - ifaces = grub_zalloc (ncards * sizeof (ifaces[0])); - slaacs = grub_zalloc (ncards * sizeof (slaacs[0])); + ifaces = grub_calloc (ncards, sizeof (ifaces[0])); + slaacs = grub_calloc (ncards, sizeof (slaacs[0])); if (!ifaces || !slaacs) { grub_free (ifaces); @@ -406,7 +432,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest) for (i = 0; i < 4; i++) { unsigned long t; - t = grub_strtoul (ptr, (char **) &ptr, 0); + t = grub_strtoul (ptr, &ptr, 0); if (grub_errno) { grub_errno = GRUB_ERR_NONE; @@ -437,6 +463,13 @@ 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; @@ -453,7 +486,7 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) ptr++; continue; } - t = grub_strtoul (ptr, (char **) &ptr, 16); + t = grub_strtoul (ptr, &ptr, 16); if (grub_errno) { grub_errno = GRUB_ERR_NONE; @@ -475,6 +508,8 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) 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; @@ -508,7 +543,7 @@ match_net (const grub_net_network_level_netaddress_t *net, mask[0] = 0xffffffffffffffffULL << (64 - net->ipv6.masksize); mask[1] = 0; } - else + else { mask[0] = 0xffffffffffffffffULL; mask[1] = 0xffffffffffffffffULL << (128 - net->ipv6.masksize); @@ -563,7 +598,7 @@ grub_net_resolve_net_address (const char *name, addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; if (*rest == '/') { - addr->ipv4.masksize = grub_strtoul (rest + 1, (char **) &rest, 0); + addr->ipv4.masksize = grub_strtoul (rest + 1, &rest, 0); if (!grub_errno && *rest == 0) return GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE; @@ -579,7 +614,7 @@ grub_net_resolve_net_address (const char *name, addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; if (*rest == '/') { - addr->ipv6.masksize = grub_strtoul (rest + 1, (char **) &rest, 0); + addr->ipv6.masksize = grub_strtoul (rest + 1, &rest, 0); if (!grub_errno && *rest == 0) return GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE; @@ -707,7 +742,7 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)), grub_free (inter->name); grub_free (inter); - return GRUB_ERR_NONE; + return GRUB_ERR_NONE; } void @@ -728,14 +763,14 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) { grub_snprintf (ptr, 6, "%" PRIxGRUB_UINT64_T ":", (n >> (48 - 16 * i)) & 0xffff); - ptr += grub_strlen (ptr); + 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); + ptr += grub_strlen (ptr); } grub_snprintf (ptr, 5, "%" PRIxGRUB_UINT64_T, n & 0xffff); return; @@ -776,6 +811,20 @@ grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) 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) @@ -923,7 +972,7 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa return; for (ptr = name; *ptr; ptr++) if (*ptr == ':') - *ptr = '_'; + *ptr = '_'; grub_env_set (name, buf); grub_register_variable_hook (name, 0, hwaddr_set_env); grub_env_export (name); @@ -940,7 +989,7 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa return; for (ptr = name; *ptr; ptr++) if (*ptr == ':') - *ptr = '_'; + *ptr = '_'; grub_env_set (name, buf); grub_register_variable_hook (name, 0, addr_set_env); grub_env_export (name); @@ -955,6 +1004,38 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa 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, @@ -1015,12 +1096,12 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)), 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")); + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); err = grub_net_resolve_address (args[2], &addr); if (err) @@ -1050,7 +1131,7 @@ grub_cmd_delroute (struct grub_command *cmd __attribute__ ((unused)), 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) @@ -1131,7 +1212,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), 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; @@ -1157,6 +1238,42 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)), } } +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) { @@ -1211,10 +1328,10 @@ grub_cmd_listroutes (struct grub_command *cmd __attribute__ ((unused)), if (route->is_gateway) { grub_printf ("gw "); - print_address (&route->gw); + print_address (&route->gw); } else - grub_printf ("%s", route->interface->name); + grub_printf ("%s", route->interface->name); grub_printf ("\n"); } return GRUB_ERR_NONE; @@ -1245,9 +1362,12 @@ grub_cmd_listaddrs (struct grub_command *cmd __attribute__ ((unused)), { 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_printf ("%s %s %s\n", inf->name, bufh, 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; } @@ -1260,8 +1380,10 @@ 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) { @@ -1297,7 +1419,76 @@ grub_net_open_real (const char *name) 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++) { @@ -1308,14 +1499,13 @@ grub_net_open_real (const char *name) { grub_net_t ret = grub_zalloc (sizeof (*ret)); if (!ret) - return NULL; - ret->protocol = proto; - ret->server = grub_strdup (server); - if (!ret->server) { - grub_free (ret); + grub_free (host); return NULL; } + ret->protocol = proto; + ret->port = port; + ret->server = host; ret->fs = &grub_net_fs; return ret; } @@ -1390,6 +1580,7 @@ grub_net_open_real (const char *name) grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), name); + grub_free (host); return NULL; } @@ -1462,7 +1653,8 @@ grub_net_fs_close (grub_file_t file) grub_netbuff_free (file->device->net->packs.first->nb); grub_net_remove_packet (file->device->net->packs.first); } - file->device->net->protocol->close (file); + if (!file->device->net->broken) + file->device->net->protocol->close (file); grub_free (file->device->net->name); return GRUB_ERR_NONE; } @@ -1488,7 +1680,7 @@ receive_packets (struct grub_net_card *card, int *stop_condition) 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. */ + and just mark them as used and not used. */ struct grub_net_buff *nb; if (received > 10 && stop_condition && *stop_condition) @@ -1525,6 +1717,7 @@ grub_env_set_net_property (const char *intername, const char *suffix, { char *varname, *varvalue; char *ptr; + grub_size_t sz; varname = grub_xasprintf ("net_%s_%s", intername, suffix); if (!varname) @@ -1532,7 +1725,12 @@ grub_env_set_net_property (const char *intername, const char *suffix, for (ptr = varname; *ptr; ptr++) if (*ptr == ':') *ptr = '_'; - varvalue = grub_malloc (len + 1); + 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); @@ -1575,7 +1773,8 @@ grub_net_poll_cards_idle_real (void) || ctime >= card->last_poll + card->idle_poll_delay_ms) receive_packets (card, 0); } - grub_net_tcp_retransmit (); + if (grub_net_cards != NULL) + grub_net_tcp_retransmit (); } /* Read from the packets list*/ @@ -1601,7 +1800,7 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) total += amount; file->device->net->offset += amount; if (grub_file_progress_hook) - grub_file_progress_hook (0, 0, amount, file); + grub_file_progress_hook (0, 0, amount, NULL, file); if (buf) { grub_memcpy (ptr, nb->data, amount); @@ -1649,7 +1848,7 @@ have_ahead (struct grub_file *file) return ret; } -static grub_err_t +static grub_err_t grub_net_seek_real (struct grub_file *file, grub_off_t offset) { if (offset == file->device->net->offset) @@ -1684,7 +1883,10 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) file->device->net->stall = 0; err = file->device->net->protocol->open (file, file->device->net->name); if (err) - return err; + { + file->device->net->broken = 1; + return err; + } grub_net_fs_read_real (file, NULL, offset); return grub_errno; } @@ -1693,6 +1895,9 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) 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; @@ -1719,8 +1924,8 @@ static grub_err_t grub_net_fini_hw (int noreturn __attribute__ ((unused))) { struct grub_net_card *card; - FOR_NET_CARDS (card) - if (card->opened) + 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); @@ -1735,10 +1940,143 @@ 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_lsroutes, cmd_lscards; +static grub_command_t cmd_setvlan, cmd_lsroutes, cmd_lscards; static grub_command_t cmd_lsaddr, cmd_slaac; GRUB_MOD_INIT(net) @@ -1776,6 +2114,9 @@ GRUB_MOD_INIT(net) 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, @@ -1796,6 +2137,8 @@ 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 (); @@ -1811,5 +2154,5 @@ GRUB_MOD_FINI(net) grub_net_open = NULL; grub_net_fini_hw (0); grub_loader_unregister_preboot_hook (fini_hnd); - grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; + grub_net_poll_cards_idle = NULL; } diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index dbeeefe47..8da327bfd 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -54,7 +54,7 @@ grub_err_t grub_netbuff_pull (struct grub_net_buff *nb, grub_size_t len) { nb->data += len; - if (nb->data > nb->end) + 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; @@ -79,10 +79,23 @@ grub_netbuff_alloc (grub_size_t len) 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 diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c index e8ad34b84..93dee0caa 100644 --- a/grub-core/net/tcp.c +++ b/grub-core/net/tcp.c @@ -362,8 +362,13 @@ void grub_net_tcp_retransmit (void) { grub_net_tcp_socket_t sock; - grub_uint64_t ctime = grub_get_time_ms (); - grub_uint64_t limit_time = ctime - TCP_RETRANSMISSION_TIMEOUT; + 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) { @@ -376,7 +381,7 @@ grub_net_tcp_retransmit (void) if (unack->last_try > limit_time) continue; - + if (unack->try_count > TCP_RETRANSMISSION_COUNT) { error (sock); @@ -581,7 +586,7 @@ grub_net_tcp_open (char *server, grub_error (GRUB_ERR_BUG, "not an IP address"); return NULL; } - + err = grub_net_route_address (addr, &gateway, &inf); if (err) return NULL; @@ -592,7 +597,7 @@ grub_net_tcp_open (char *server, socket = grub_zalloc (sizeof (*socket)); if (socket == NULL) - return NULL; + return NULL; socket->out_port = out_port; socket->inf = inf; @@ -657,7 +662,7 @@ grub_net_tcp_open (char *server, { int j; nb->data = nbd; - err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), + err = grub_net_send_ip_packet (socket->inf, &(socket->out_nla), &(socket->ll_target_addr), nb, GRUB_NET_IP_TCP); if (err) @@ -667,7 +672,7 @@ grub_net_tcp_open (char *server, grub_netbuff_free (nb); return NULL; } - for (j = 0; (j < TCP_SYN_RETRANSMISSION_TIMEOUT / 50 + for (j = 0; (j < TCP_SYN_RETRANSMISSION_TIMEOUT / 50 && !socket->established); j++) grub_net_poll_cards (50, &socket->established); if (socket->established) @@ -956,7 +961,7 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb, 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) @@ -971,7 +976,7 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb, 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; diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 7d90bf66e..336b78691 100644 --- a/grub-core/net/tftp.c +++ b/grub-core/net/tftp.c @@ -25,7 +25,6 @@ #include #include #include -#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -106,31 +105,8 @@ typedef struct tftp_data int have_oack; struct grub_error_saved save_err; grub_net_udp_socket_t sock; - grub_priority_queue_t pq; } *tftp_data_t; -static int -cmp_block (grub_uint16_t a, grub_uint16_t b) -{ - grub_int16_t i = (grub_int16_t) (a - b); - if (i > 0) - return +1; - if (i < 0) - return -1; - return 0; -} - -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 tftphdr *a = (struct tftphdr *) a_->data; - struct tftphdr *b = (struct tftphdr *) b_->data; - /* We want the first elements to be on top. */ - return -cmp_block (grub_be_to_cpu16 (a->u.data.block), grub_be_to_cpu16 (b->u.data.block)); -} - static grub_err_t ack (tftp_data_t data, grub_uint64_t block) { @@ -181,7 +157,7 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), { case TFTP_OACK: data->block_size = TFTP_DEFAULTSIZE_PACKET; - data->have_oack = 1; + 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) @@ -207,79 +183,77 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), return GRUB_ERR_NONE; } - err = grub_priority_queue_push (data->pq, &nb); - if (err) - return err; + /* + * 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; - { - struct grub_net_buff **nb_top_p, *nb_top; - while (1) - { - nb_top_p = grub_priority_queue_top (data->pq); - if (!nb_top_p) - return GRUB_ERR_NONE; - nb_top = *nb_top_p; - tftph = (struct tftphdr *) nb_top->data; - if (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) >= 0) - break; - ack (data, grub_be_to_cpu16 (tftph->u.data.block)); - grub_netbuff_free (nb_top); - grub_priority_queue_pop (data->pq); - } - while (cmp_block (grub_be_to_cpu16 (tftph->u.data.block), data->block + 1) == 0) - { - unsigned size; - - grub_priority_queue_pop (data->pq); - - if (file->device->net->packs.count < 50) + if (file->device->net->packs.count < 50) + { err = ack (data, data->block + 1); - else - { - file->device->net->stall = 1; - err = 0; - } - if (err) - return err; + if (err) + return err; + } + else + file->device->net->stall = 1; - err = grub_netbuff_pull (nb_top, sizeof (tftph->opcode) + - sizeof (tftph->u.data.block)); - if (err) - return err; - size = nb_top->tail - nb_top->data; + 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_top, size - data->block_size); - if (err) - return err; - } - /* If there is data, puts packet in socket list. */ - if ((nb_top->tail - nb_top->data) > 0) - grub_net_put_packet (&file->device->net->packs, nb_top); - else - grub_netbuff_free (nb_top); - } - } + 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_netbuff_free (nb); - grub_error (GRUB_ERR_IO, (char *) tftph->u.err.errmsg); + 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); @@ -287,17 +261,26 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), } } +/* + * Create a normalized copy of the filename. Compress any string of consecutive + * forward slashes to a single forward slash. + */ static void -destroy_pq (tftp_data_t data) +grub_normalize_filename (char *normalized, const char *filename, int c) { - struct grub_net_buff **nb_p; - while ((nb_p = grub_priority_queue_top (data->pq))) - { - grub_netbuff_free (*nb_p); - grub_priority_queue_pop (data->pq); - } + char *dest = normalized; + const char *src = filename; - grub_priority_queue_destroy (data->pq); + while (*src != '\0' && c > 0) + { + if (src[0] == '/' && src[1] == '/') + src++; + else { + c--; + *dest++ = *src++; + } + } + *dest = '\0'; } static grub_err_t @@ -306,7 +289,7 @@ tftp_open (struct grub_file *file, const char *filename) struct tftphdr *tftph; char *rrq; int i; - int rrqlen; + int rrqlen, rrqsize; int hdrlen; grub_uint8_t open_data[1500]; struct grub_net_buff nb; @@ -314,6 +297,7 @@ tftp_open (struct grub_file *file, const char *filename) 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) @@ -333,32 +317,45 @@ tftp_open (struct grub_file *file, const char *filename) tftph = (struct tftphdr *) nb.data; - rrq = (char *) tftph->u.rrq; - rrqlen = 0; - tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_RRQ); - grub_strcpy (rrq, filename); - rrqlen += grub_strlen (filename) + 1; - rrq += grub_strlen (filename) + 1; + + 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"); - rrqlen += grub_strlen ("octet") + 1; rrq += grub_strlen ("octet") + 1; grub_strcpy (rrq, "blksize"); - rrqlen += grub_strlen ("blksize") + 1; rrq += grub_strlen ("blksize") + 1; grub_strcpy (rrq, "1024"); - rrqlen += grub_strlen ("1024") + 1; rrq += grub_strlen ("1024") + 1; grub_strcpy (rrq, "tsize"); - rrqlen += grub_strlen ("tsize") + 1; rrq += grub_strlen ("tsize") + 1; grub_strcpy (rrq, "0"); - rrqlen += grub_strlen ("0") + 1; rrq += grub_strlen ("0") + 1; hdrlen = sizeof (tftph->opcode) + rrqlen; @@ -372,27 +369,21 @@ tftp_open (struct grub_file *file, const char *filename) file->not_easily_seekable = 1; file->data = data; - data->pq = grub_priority_queue_new (sizeof (struct grub_net_buff *), cmp); - if (!data->pq) - { - grub_free (data); - return grub_errno; - } - err = grub_net_resolve_address (file->device->net->server, &addr); if (err) { - destroy_pq (data); + 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, - TFTP_SERVER_PORT, tftp_receive, + port ? port : TFTP_SERVER_PORT, tftp_receive, file); if (!data->sock) { - destroy_pq (data); grub_free (data); return grub_errno; } @@ -406,7 +397,6 @@ tftp_open (struct grub_file *file, const char *filename) if (err) { grub_net_udp_close (data->sock); - destroy_pq (data); grub_free (data); return err; } @@ -423,8 +413,8 @@ tftp_open (struct grub_file *file, const char *filename) if (grub_errno) { grub_net_udp_close (data->sock); - destroy_pq (data); grub_free (data); + file->data = NULL; return grub_errno; } @@ -466,8 +456,8 @@ tftp_close (struct grub_file *file) grub_print_error (); grub_net_udp_close (data->sock); } - destroy_pq (data); grub_free (data); + file->data = NULL; return GRUB_ERR_NONE; } @@ -485,7 +475,7 @@ tftp_packets_pulled (struct grub_file *file) return ack (data, data->block); } -static struct grub_net_app_protocol grub_tftp_protocol = +static struct grub_net_app_protocol grub_tftp_protocol = { .name = "tftp", .open = tftp_open, diff --git a/grub-core/net/udp.c b/grub-core/net/udp.c index df7fb95e7..91e2a017a 100644 --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@ -79,7 +79,7 @@ grub_net_udp_open (grub_net_network_level_address_t addr, grub_error (GRUB_ERR_BUG, "not an IP address"); return NULL; } - + err = grub_net_route_address (addr, &gateway, &inf); if (err) return NULL; @@ -90,7 +90,7 @@ grub_net_udp_open (grub_net_network_level_address_t addr, socket = grub_zalloc (sizeof (*socket)); if (socket == NULL) - return NULL; + return NULL; socket->out_port = out_port; socket->inf = inf; diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c index 6be678c0d..71b361bc0 100644 --- a/grub-core/normal/auth.c +++ b/grub-core/normal/auth.c @@ -25,6 +25,10 @@ #include #include +#ifdef GRUB_MACHINE_EFI +#include +#endif + struct grub_auth_user { struct grub_auth_user *next; @@ -162,7 +166,7 @@ grub_username_get (char buf[], unsigned buf_size) while (1) { - key = grub_getkey (); + key = grub_getkey (); if (key == '\n' || key == '\r') break; @@ -200,6 +204,32 @@ grub_username_get (char buf[], unsigned buf_size) return (key != GRUB_TERM_ESC); } +grub_err_t +grub_auth_check_cli_access (void) +{ + if (grub_is_cli_need_auth () == true) + { +#ifdef GRUB_MACHINE_EFI + static bool authenticated = false; + + if (authenticated == false) + { + grub_err_t ret; + + ret = grub_cryptodisk_challenge_password (); + if (ret == GRUB_ERR_NONE) + authenticated = true; + return ret; + } + return GRUB_ERR_NONE; +#else + return GRUB_ACCESS_DENIED; +#endif + } + + return GRUB_ERR_NONE; +} + grub_err_t grub_auth_check_authentication (const char *userlist) { @@ -209,6 +239,9 @@ grub_auth_check_authentication (const char *userlist) char entered[GRUB_AUTH_MAX_PASSLEN]; struct grub_auth_user *user; + if (grub_is_cli_disabled ()) + return GRUB_ACCESS_DENIED; + grub_memset (login, 0, sizeof (login)); if (is_authenticated (userlist)) diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c index b0ab47d73..4f6647116 100644 --- a/grub-core/normal/charset.c +++ b/grub-core/normal/charset.c @@ -17,7 +17,7 @@ */ /* - Current problems with Unicode rendering: + 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) @@ -48,6 +48,7 @@ #include #include #include +#include #if HAVE_FONT_SOURCE #include "widthspec.h" @@ -141,7 +142,7 @@ grub_get_num_of_utf8_bytes (const grub_uint32_t *src, grub_size_t size) while (remaining--) { grub_uint32_t code = *ptr++; - + if (code <= 0x007F) cnt++; else if (code <= 0x07FF) @@ -203,8 +204,8 @@ grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg, { grub_size_t msg_len = grub_strlen (msg); - *unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); - + *unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); + if (!*unicode_msg) return -1; @@ -394,6 +395,8 @@ 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 @@ -407,11 +410,11 @@ 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 + 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 + if (b == GRUB_UNICODE_COMB_ARABIC_SHADDA && a <= GRUB_UNICODE_COMB_ARABIC_KASRA && a >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) return 1; @@ -440,7 +443,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, for (ptr = in; ptr < in + inlen; ptr++) { - /* Variation selectors >= 17 are outside of BMP and SMP. + /* 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 @@ -457,17 +460,21 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, 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) @@ -477,10 +484,14 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, n = out->combining_inline; else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline)) { - n = grub_realloc (out->combining_ptr, - sizeof (n[0]) * (out->ncomb + 1)); + 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; } @@ -488,7 +499,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, } else { - n = grub_malloc (sizeof (n[0]) * (out->ncomb + 1)); + n = grub_calloc (out->ncomb + 1, sizeof (n[0])); if (!n) { grub_errno = GRUB_ERR_NONE; @@ -592,7 +603,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, 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; @@ -618,9 +629,9 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, last_space_width = line_width; } - if (((grub_ssize_t) maxwidth > 0 + 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; @@ -654,7 +665,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, } { - unsigned j; + unsigned j; /* FIXME: can be optimized. */ for (j = max_level; j > min_odd_level - 1; j--) { @@ -671,7 +682,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, } } } - + { unsigned i; for (i = line_start; i < kk; i++) @@ -683,10 +694,10 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, { int left, right; left = visual[i].attributes - & (GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED + & (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 | 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; @@ -751,7 +762,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, || join_type == GRUB_JOIN_TYPE_CAUSING) right_join = 1; } - } + } grub_memcpy (outptr, &visual[line_start], (kk - line_start) * sizeof (visual[0])); @@ -842,7 +853,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, } \ } - visual = grub_malloc (sizeof (visual[0]) * logical_len); + visual = grub_calloc (logical_len, sizeof (visual[0])); if (!visual) return -1; @@ -857,7 +868,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, base_level = 1; else base_level = 0; - + cur_level = base_level; cur_override = OVERRIDE_NEUTRAL; { @@ -888,7 +899,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, { visual[visual_len - 1].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED_EXPLICIT; - visual[visual_len - 1].attributes + visual[visual_len - 1].attributes &= ~GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED; } zwj_propagate_to_previous = 0; @@ -901,7 +912,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, if (*lptr >= GRUB_UNICODE_TAG_START && *lptr <= GRUB_UNICODE_TAG_END) continue; - p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr, + 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); @@ -938,7 +949,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, |= GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED_EXPLICIT | GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED; } - + if (join_state == NOJOIN) { visual[visual_len].attributes @@ -952,7 +963,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, visual[visual_len].bidi_level = cur_level; if (cur_override != OVERRIDE_NEUTRAL) - visual[visual_len].bidi_type = + visual[visual_len].bidi_type = (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L : GRUB_BIDI_TYPE_R; else @@ -1003,7 +1014,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, break; case GRUB_BIDI_TYPE_ES: if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end + && i + 1 < run_end && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN) visual[i].bidi_type = GRUB_BIDI_TYPE_EN; else @@ -1031,19 +1042,19 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++) visual[i].bidi_type = GRUB_BIDI_TYPE_ON; i--; - break; + break; } break; case GRUB_BIDI_TYPE_CS: if (last_type == GRUB_BIDI_TYPE_EN - && i + 1 < run_end + && 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 + && 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))) @@ -1165,8 +1176,8 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, { const grub_uint32_t *line_start = logical, *ptr; struct grub_unicode_glyph *visual_ptr; - *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0]) - * (logical_len + 2)); + *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++) @@ -1257,7 +1268,7 @@ grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr) } const grub_uint32_t * -grub_unicode_get_comb_start (const grub_uint32_t *str, +grub_unicode_get_comb_start (const grub_uint32_t *str, const grub_uint32_t *cur) { const grub_uint32_t *ptr; @@ -1270,7 +1281,7 @@ grub_unicode_get_comb_start (const grub_uint32_t *str, 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) @@ -1281,7 +1292,7 @@ grub_unicode_get_comb_start (const grub_uint32_t *str, } const grub_uint32_t * -grub_unicode_get_comb_end (const grub_uint32_t *end, +grub_unicode_get_comb_end (const grub_uint32_t *end, const grub_uint32_t *cur) { const grub_uint32_t *ptr; @@ -1294,7 +1305,7 @@ grub_unicode_get_comb_end (const grub_uint32_t *end, 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) diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index c037d5050..9c6d9ade9 100644 --- a/grub-core/normal/cmdline.c +++ b/grub-core/normal/cmdline.c @@ -28,6 +28,7 @@ #include #include #include +#include static grub_uint32_t *kill_buf; @@ -41,7 +42,7 @@ grub_err_t grub_set_history (int newsize) { grub_uint32_t **old_hist_lines = hist_lines; - hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize); + hist_lines = grub_calloc (newsize, sizeof (grub_uint32_t *)); /* Copy the old lines into the new buffer. */ if (old_hist_lines) @@ -114,7 +115,7 @@ static void grub_history_set (int pos, grub_uint32_t *s, grub_size_t len) { grub_free (hist_lines[pos]); - hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t)); + hist_lines[pos] = grub_calloc (len + 1, sizeof (grub_uint32_t)); if (!hist_lines[pos]) { grub_print_error (); @@ -166,7 +167,7 @@ print_completion (const char *item, grub_completion_type_t type, int count) if (count == 0) { /* If this is the first time, print a label. */ - + grub_puts (""); switch (type) { @@ -218,6 +219,8 @@ cl_set_pos (struct cmdline_term *cl_term, grub_size_t lpos) cl_term->pos.x = (cl_term->prompt_len + lpos) % cl_term->width; cl_term->pos.y = cl_term->ystart + (cl_term->prompt_len + lpos) / cl_term->width; + if (cl_term->pos.y >= cl_term->height) + cl_term->pos.y = cl_term->height - 1; grub_term_gotoxy (cl_term->term, cl_term->pos); } @@ -247,7 +250,10 @@ cl_print (struct cmdline_term *cl_term, grub_uint32_t c, { cl_term->pos.x = 0; if (cl_term->pos.y >= (unsigned) (cl_term->height - 1)) - cl_term->ystart--; + { + if (cl_term->ystart > 0) + cl_term->ystart--; + } else cl_term->pos.y++; grub_putcode ('\n', cl_term->term); @@ -307,12 +313,21 @@ cl_insert (struct cmdline_term *cl_terms, unsigned nterms, if (len + (*llen) >= (*max_len)) { grub_uint32_t *nbuf; - (*max_len) *= 2; - nbuf = grub_realloc ((*buf), sizeof (grub_uint32_t) * (*max_len)); + grub_size_t sz; + + if (grub_mul (*max_len, 2, max_len) || + grub_mul (*max_len, sizeof (grub_uint32_t), &sz)) + { + grub_errno = GRUB_ERR_OUT_OF_RANGE; + goto fail; + } + + nbuf = grub_realloc ((*buf), sz); if (nbuf) (*buf) = nbuf; else { + fail: grub_print_error (); grub_errno = GRUB_ERR_NONE; (*max_len) /= 2; @@ -349,7 +364,7 @@ grub_cmdline_get (const char *prompt_translated) char *ret; unsigned nterms; - buf = grub_malloc (max_len * sizeof (grub_uint32_t)); + buf = grub_calloc (max_len, sizeof (grub_uint32_t)); if (!buf) return 0; @@ -377,7 +392,7 @@ grub_cmdline_get (const char *prompt_translated) FOR_ACTIVE_TERM_OUTPUTS(cur) nterms++; - cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms); + cl_terms = grub_calloc (nterms, sizeof (cl_terms[0])); if (!cl_terms) { grub_free (buf); @@ -385,7 +400,7 @@ grub_cmdline_get (const char *prompt_translated) } cl_term_cur = cl_terms; - unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); + unicode_msg = grub_calloc (msg_len, sizeof (grub_uint32_t)); if (!unicode_msg) { grub_free (buf); @@ -495,7 +510,7 @@ grub_cmdline_get (const char *prompt_translated) grub_uint32_t *insert; insertlen = grub_strlen (insertu8); - insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t)); + insert = grub_calloc (insertlen + 1, sizeof (grub_uint32_t)); if (!insert) { grub_free (insertu8); @@ -602,7 +617,7 @@ grub_cmdline_get (const char *prompt_translated) grub_free (kill_buf); - kill_buf = grub_malloc ((n + 1) * sizeof(grub_uint32_t)); + kill_buf = grub_calloc (n + 1, sizeof (grub_uint32_t)); if (grub_errno) { grub_print_error (); diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c index 596102848..18cadfa85 100644 --- a/grub-core/normal/completion.c +++ b/grub-core/normal/completion.c @@ -284,7 +284,8 @@ complete_file (void) /* Cut away the filename part. */ dirfile = grub_strrchr (dir, '/'); - dirfile[1] = '\0'; + if (dirfile) + dirfile[1] = '\0'; /* Iterate the directory. */ (fs->fs_dir) (dev, dir, iterate_dir, NULL); @@ -400,8 +401,8 @@ char * grub_normal_do_completion (char *buf, int *restore, void (*hook) (const char *, grub_completion_type_t, int)) { - int argc; - char **argv; + int argc = 0; + char **argv = NULL; /* Initialize variables. */ match = 0; @@ -516,10 +517,8 @@ grub_normal_do_completion (char *buf, int *restore, fail: if (argc != 0) - { - grub_free (argv[0]); - grub_free (argv); - } + grub_free (argv[0]); + grub_free (argv); grub_free (match); grub_errno = GRUB_ERR_NONE; diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c index ee53d4a68..ba185e915 100644 --- a/grub-core/normal/context.c +++ b/grub-core/normal/context.c @@ -168,11 +168,11 @@ grub_env_extractor_close (int source) { grub_menu_t menu2; menu2 = grub_env_get_menu (); - + last = &menu2->entry_list; while (*last) last = &(*last)->next; - + *last = menu->entry_list; menu2->size += menu->size; } diff --git a/grub-core/normal/crypto.c b/grub-core/normal/crypto.c index d01e6f271..09b98dd86 100644 --- a/grub-core/normal/crypto.c +++ b/grub-core/normal/crypto.c @@ -33,7 +33,7 @@ struct load_spec static struct load_spec *crypto_specs = NULL; -static void +static void grub_crypto_autoload (const char *name) { struct load_spec *cur; @@ -57,7 +57,7 @@ grub_crypto_autoload (const char *name) depth--; } -static void +static void grub_crypto_spec_free (void) { struct load_spec *cur, *next; @@ -85,7 +85,7 @@ read_crypto_list (const char *prefix) grub_errno = GRUB_ERR_NONE; return; } - + filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/crypto.lst", prefix); if (!filename) @@ -109,12 +109,12 @@ read_crypto_list (const char *prefix) { char *p, *name; struct load_spec *cur; - + buf = grub_file_getline (file); - + if (! buf) break; - + name = buf; while (grub_isspace (name[0])) name++; @@ -122,7 +122,7 @@ read_crypto_list (const char *prefix) p = grub_strchr (name, ':'); if (! p) continue; - + *p = '\0'; p++; while (*p == ' ' || *p == '\t') @@ -134,7 +134,7 @@ read_crypto_list (const char *prefix) grub_errno = GRUB_ERR_NONE; continue; } - + cur->name = grub_strdup (name); if (! cur->name) { @@ -142,7 +142,7 @@ read_crypto_list (const char *prefix) grub_free (cur); continue; } - + cur->modname = grub_strdup (p); if (! cur->modname) { @@ -154,7 +154,7 @@ read_crypto_list (const char *prefix) cur->next = crypto_specs; crypto_specs = cur; } - + grub_file_close (file); grub_errno = GRUB_ERR_NONE; diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 1b03dfd57..96abfda2f 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -205,17 +206,17 @@ grub_normal_init_page (struct grub_term_output *term, 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; @@ -323,10 +324,27 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), prefix = grub_env_get ("prefix"); if (prefix) - { - config = grub_xasprintf ("%s/grub.cfg", prefix); - if (! config) - goto quit; + { + 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); @@ -362,7 +380,8 @@ grub_normal_reader_init (int nested) 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. %s"), + "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; @@ -381,7 +400,7 @@ grub_normal_reader_init (int nested) grub_putcode ('\n', term); } grub_free (msg_formatted); - + return 0; } @@ -413,7 +432,7 @@ grub_normal_read_line_real (char **line, int cont, int nested) return grub_errno; } } - + } static grub_err_t @@ -434,9 +453,13 @@ grub_cmdline_run (int nested, int force_auth) } 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; } @@ -488,7 +511,8 @@ 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_nativedisk_cmd", "feature_timeout_style", + "feature_search_cryptodisk_only" }; GRUB_MOD_INIT(normal) @@ -563,7 +587,9 @@ GRUB_MOD_FINI(normal) grub_xputs = grub_xputs_saved; grub_set_history (0); - grub_register_variable_hook ("pager", 0, 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.c b/grub-core/normal/menu.c index d5e0c79a7..b946c834d 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -32,6 +32,7 @@ #include #include #include +#include /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ @@ -170,8 +171,7 @@ grub_menu_set_timeout (int timeout) static int get_and_remove_first_entry_number (const char *name) { - const char *val; - char *tail; + const char *val, *tail; int entry; val = grub_env_get (name); @@ -574,13 +574,15 @@ print_countdown (struct grub_term_coordinate *pos, int n) entry to be executed is a result of an automatic default selection because of the timeout. */ static int -run_menu (grub_menu_t menu, int nested, int *auto_boot) +run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot) { grub_uint64_t saved_time; int default_entry, current_entry; int timeout; enum timeout_style timeout_style; + *notify_boot = 1; + default_entry = get_entry_number (menu, "default"); /* If DEFAULT_ENTRY is not within the menu entries, fall back to @@ -624,7 +626,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (entry >= 0) break; } - if (key == GRUB_TERM_ESC) + if (grub_key_is_interrupt (key)) { timeout = -1; break; @@ -655,6 +657,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (timeout == 0) { *auto_boot = 1; + *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN; return default_entry; } @@ -749,9 +752,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) case GRUB_TERM_CTRL | 'c': case GRUB_TERM_KEY_NPAGE: - if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) - current_entry += GRUB_MENU_PAGE_SIZE; - else + if (grub_add (current_entry, GRUB_MENU_PAGE_SIZE, ¤t_entry) || current_entry >= menu->size) current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; @@ -786,6 +787,10 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } goto refresh; + case GRUB_TERM_CTRL | 'l': + menu_fini (); + goto refresh; + default: { int entry; @@ -808,12 +813,16 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) /* Callback invoked immediately before a menu entry is executed. */ static void -notify_booting (grub_menu_entry_t entry, - void *userdata __attribute__((unused))) +notify_booting (grub_menu_entry_t entry, void *userdata) { - grub_printf (" "); - grub_printf_ (N_("Booting `%s'"), entry->title); - grub_printf ("\n\n"); + int *notify_boot = userdata; + + if (*notify_boot) + { + grub_printf (" "); + grub_printf_ (N_("Booting `%s'"), entry->title); + grub_printf ("\n\n"); + } } /* Callback invoked when a default menu entry executed because of a timeout @@ -861,8 +870,9 @@ show_menu (grub_menu_t menu, int nested, int autobooted) int boot_entry; grub_menu_entry_t e; int auto_boot; + int notify_boot; - boot_entry = run_menu (menu, nested, &auto_boot); + boot_entry = run_menu (menu, nested, &auto_boot, ¬ify_boot); if (boot_entry < 0) break; @@ -870,13 +880,14 @@ show_menu (grub_menu_t menu, int nested, int autobooted) if (! e) continue; /* Menu is empty. */ - grub_cls (); - if (auto_boot) grub_menu_execute_with_fallback (menu, e, autobooted, - &execution_callback, 0); + &execution_callback, ¬ify_boot); else - grub_menu_execute_entry (e, 0); + { + grub_cls (); + grub_menu_execute_entry (e, 0); + } if (autobooted) break; } diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index cdf3590a3..8b0d17e3f 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -27,6 +27,7 @@ #include #include #include +#include enum update_mode { @@ -95,8 +96,8 @@ init_line (struct screen *screen, struct line *linep) { linep->len = 0; linep->max_len = 80; - linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0])); - linep->pos = grub_zalloc (screen->nterms * sizeof (linep->pos[0])); + linep->buf = grub_calloc (linep->max_len + 1, sizeof (linep->buf[0])); + linep->pos = grub_calloc (screen->nterms, sizeof (linep->pos[0])); if (! linep->buf || !linep->pos) { grub_free (linep->buf); @@ -113,10 +114,18 @@ ensure_space (struct line *linep, int extra) { if (linep->max_len < linep->len + extra) { - linep->max_len = 2 * (linep->len + extra); - linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0])); + grub_size_t sz0, sz1; + + if (grub_add (linep->len, extra, &sz0) || + grub_mul (sz0, 2, &sz0) || + grub_add (sz0, 1, &sz1) || + grub_mul (sz1, sizeof (linep->buf[0]), &sz1)) + return 0; + + linep->buf = grub_realloc (linep->buf, sz1); if (! linep->buf) return 0; + linep->max_len = sz0; } return 1; @@ -287,7 +296,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, pos = linep->pos + (term_screen - screen->terms); if (!*pos) - *pos = grub_zalloc ((linep->len + 1) * sizeof (**pos)); + *pos = grub_calloc (linep->len + 1, sizeof (**pos)); if (i == region_start || linep == screen->lines + screen->line || (i > region_start && mode == ALL_LINES)) @@ -324,7 +333,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, while (y < term_screen->geo.num_entries); /* Draw up and down arrows. */ - + if (term_screen->geo.num_entries == 1) { if (up || down) @@ -352,12 +361,12 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, for (i = 0; i < screen->line; i++) y += get_logical_num_lines (screen->lines + i, term_screen); if (cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0]) - grub_term_gotoxy (term_screen->term, + grub_term_gotoxy (term_screen->term, (struct grub_term_coordinate) { cpos->x + term_screen->geo.first_entry_x, cpos->y + y + term_screen->geo.first_entry_y }); else - grub_term_gotoxy (term_screen->term, + grub_term_gotoxy (term_screen->term, (struct grub_term_coordinate) { term_screen->geo.first_entry_x, y + term_screen->geo.first_entry_y }); @@ -471,7 +480,7 @@ insert_string (struct screen *screen, const char *s, int update) /* Insert the string. */ current_linep = screen->lines + screen->line; - unicode_msg = grub_malloc ((p - s) * sizeof (grub_uint32_t)); + unicode_msg = grub_calloc (p - s, sizeof (grub_uint32_t)); if (!unicode_msg) return 0; @@ -650,14 +659,14 @@ backward_char (struct screen *screen, int update) linep = screen->lines + screen->line; screen->column--; - screen->column = grub_unicode_get_comb_start (linep->buf, + screen->column = grub_unicode_get_comb_start (linep->buf, linep->buf + screen->column) - linep->buf; grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column, screen->lines[screen->line].len - screen->column, &glyph); - screen->column = grub_unicode_get_comb_start (linep->buf, + screen->column = grub_unicode_get_comb_start (linep->buf, linep->buf + screen->column) - linep->buf; @@ -1019,12 +1028,12 @@ complete (struct screen *screen, int continuous, int update) return 1; insert = grub_normal_do_completion (u8, &restore, store_completion); - + if (completion_buffer.buf) { buflen = grub_strlen (completion_buffer.buf); - ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1)); - + ucs4 = grub_calloc (buflen + 1, sizeof (grub_uint32_t)); + if (!ucs4) { grub_print_error (); @@ -1246,9 +1255,13 @@ grub_menu_entry_run (grub_menu_entry_t entry) err = grub_auth_check_authentication (NULL); + 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; } @@ -1268,7 +1281,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) for (i = 0; i < (unsigned) screen->num_lines; i++) { grub_free (screen->lines[i].pos); - screen->lines[i].pos = grub_zalloc (screen->nterms * sizeof (screen->lines[i].pos[0])); + screen->lines[i].pos = grub_calloc (screen->nterms, sizeof (screen->lines[i].pos[0])); if (! screen->lines[i].pos) { grub_print_error (); @@ -1278,7 +1291,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) } } - screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0])); + screen->terms = grub_calloc (screen->nterms, sizeof (screen->terms[0])); if (!screen->terms) { grub_print_error (); diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c index e22bb91f6..9c383e64a 100644 --- a/grub-core/normal/menu_text.c +++ b/grub-core/normal/menu_text.c @@ -35,8 +35,8 @@ struct menu_viewer_data { int first, offset; struct grub_term_screen_geometry geo; - enum { - TIMEOUT_UNKNOWN, + enum { + TIMEOUT_UNKNOWN, TIMEOUT_NORMAL, TIMEOUT_TERSE, TIMEOUT_TERSE_NO_MARGIN @@ -78,14 +78,14 @@ grub_print_message_indented_real (const char *msg, int margin_left, grub_size_t msg_len = grub_strlen (msg) + 2; int ret = 0; - unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t)); - + 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; @@ -178,22 +178,25 @@ command-line or ESC to discard edits and return to the GRUB menu."), grub_free (msg_translated); - if (nested) + if (!grub_is_cli_disabled ()) { - 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); + 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); + } } - 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; } @@ -211,7 +214,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, title = entry ? entry->title : ""; title_len = grub_strlen (title); - unicode_title = grub_malloc (title_len * sizeof (*unicode_title)); + unicode_title = grub_calloc (title_len, sizeof (*unicode_title)); if (! unicode_title) /* XXX How to show this error? */ return; @@ -233,7 +236,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, ? GRUB_TERM_COLOR_HIGHLIGHT : GRUB_TERM_COLOR_NORMAL); - grub_term_gotoxy (data->term, (struct grub_term_coordinate) { + grub_term_gotoxy (data->term, (struct grub_term_coordinate) { data->geo.first_entry_x, y }); for (i = 0; i < len; i++) @@ -253,7 +256,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, grub_term_setcolorstate (data->term, GRUB_TERM_COLOR_NORMAL); grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { + (struct grub_term_coordinate) { grub_term_cursor_x (&data->geo), y }); grub_term_normal_color = old_color_normal; @@ -270,7 +273,7 @@ print_entries (grub_menu_t menu, const struct menu_viewer_data *data) int i; grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { + (struct grub_term_coordinate) { data->geo.first_entry_x + data->geo.entry_width + data->geo.border + 1, data->geo.first_entry_y }); @@ -472,7 +475,7 @@ menu_text_print_timeout (int timeout, void *dataptr) grub_free (msg_translated); grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { + (struct grub_term_coordinate) { grub_term_cursor_x (&data->geo), data->geo.first_entry_y + data->offset }); grub_term_refresh (data->term); @@ -537,7 +540,7 @@ menu_text_clear_timeout (void *dataptr) if (data->geo.num_entries <= 5 && !data->geo.border) { grub_term_gotoxy (data->term, - (struct grub_term_coordinate) { + (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 @@ -555,8 +558,8 @@ menu_text_clear_timeout (void *dataptr) grub_term_refresh (data->term); } -grub_err_t -grub_menu_try_text (struct grub_term_output *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; diff --git a/grub-core/normal/misc.c b/grub-core/normal/misc.c index 435cd9234..66f988042 100644 --- a/grub-core/normal/misc.c +++ b/grub-core/normal/misc.c @@ -39,7 +39,7 @@ static const char *grub_human_sizes[3][6] = /* 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"), }, + { N_("B/s"), N_("KiB/s"), N_("MiB/s"), N_("GiB/s"), N_("TiB/s"), N_("PiB/s"), }, }; const char * @@ -136,7 +136,7 @@ grub_normal_print_device_info (const char *name) } if (fs->fs_mtime) { - grub_int32_t tm; + grub_int64_t tm; struct grub_datetime datetime; (fs->fs_mtime) (dev, &tm); if (grub_errno == GRUB_ERR_NONE) @@ -176,14 +176,14 @@ grub_normal_print_device_info (const char *name) (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_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) + 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_get_size (dev->disk) >> 1), + (unsigned long long) (grub_disk_native_sectors (dev->disk) >> 1), /* TRANSLATORS: Replace dot with appropriate decimal separator for your language. */ - (grub_disk_get_size (dev->disk) & 1) ? _(".5") : ""); + (grub_disk_native_sectors (dev->disk) & 1) ? _(".5") : ""); } if (dev) diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index a1e5c5a0d..c073eb489 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -99,7 +99,7 @@ print_more (void) grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); grub_free (unicode_str); - + key = grub_getkey (); /* Remove the message. */ @@ -184,28 +184,28 @@ map_code (grub_uint32_t in, struct grub_term_output *term) { 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 '?'; } @@ -260,11 +260,11 @@ 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_malloc (cnt * sizeof (ret[0])); + ret = grub_calloc (cnt, sizeof (ret[0])); if (!ret) return NULL; @@ -291,7 +291,7 @@ grub_term_restore_pos (struct grub_term_coordinate *pos) } } -static void +static void grub_terminal_autoload_free (void) { struct grub_term_autoload *cur, *next; @@ -322,7 +322,7 @@ read_terminal_list (const char *prefix) grub_errno = GRUB_ERR_NONE; return; } - + filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/terminal.lst", prefix); if (!filename) @@ -347,9 +347,9 @@ read_terminal_list (const char *prefix) char *p, *name; struct grub_term_autoload *cur; struct grub_term_autoload **target = NULL; - + buf = grub_file_getline (file); - + if (! buf) break; @@ -369,9 +369,9 @@ read_terminal_list (const char *prefix) } if (!target) continue; - + name = p + 1; - + p = grub_strchr (name, ':'); if (! p) continue; @@ -387,7 +387,7 @@ read_terminal_list (const char *prefix) grub_errno = GRUB_ERR_NONE; continue; } - + cur->name = grub_strdup (name); if (! cur->name) { @@ -395,7 +395,7 @@ read_terminal_list (const char *prefix) grub_free (cur); continue; } - + cur->modname = grub_strdup (p); if (! cur->modname) { @@ -407,7 +407,7 @@ read_terminal_list (const char *prefix) cur->next = *target; *target = cur; } - + grub_file_close (file); grub_errno = GRUB_ERR_NONE; @@ -451,7 +451,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term, } if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) - == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL + == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL || (term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { @@ -461,7 +461,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term, { grub_uint8_t u8[20], *ptr; grub_uint32_t code; - + if (i == -1) { code = c->base; @@ -534,7 +534,7 @@ get_maxwidth (struct grub_term_output *term, .ncomb = 0, }; return (grub_term_width (term) - - grub_term_getcharwidth (term, &space_glyph) + - grub_term_getcharwidth (term, &space_glyph) * (margin_left + margin_right) - 1); } @@ -643,7 +643,7 @@ print_ucs4_terminal (const grub_uint32_t * str, if (line_width > max_width && last_space > line_start) ptr = last_space; - else if (line_width > max_width + else if (line_width > max_width && line_start == str && line_width - lastspacewidth < max_width - 5) { ptr = str; @@ -659,7 +659,7 @@ print_ucs4_terminal (const grub_uint32_t * str, for (ptr2 = line_start; ptr2 < ptr; ptr2++) { /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL && grub_unicode_get_comb_type (*ptr2) != GRUB_UNICODE_COMB_NONE) @@ -677,7 +677,7 @@ print_ucs4_terminal (const grub_uint32_t * str, if (state != &local_state && ++state->num_lines >= (grub_ssize_t) grub_term_height (term) - 2) { - state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') + 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; @@ -735,7 +735,7 @@ print_ucs4_terminal (const grub_uint32_t * str, for (ptr2 = line_start; ptr2 < last_position; ptr2++) { /* Skip combining characters on non-UTF8 terminals. */ - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL && grub_unicode_get_comb_type (*ptr2) != GRUB_UNICODE_COMB_NONE) @@ -888,7 +888,7 @@ print_ucs4_real (const grub_uint32_t * str, state = find_term_state (term); xy = term->getxy (term); - + if (xy.x < margin_left) { if (!contchar) @@ -899,9 +899,9 @@ print_ucs4_real (const grub_uint32_t * str, } } - if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS - || (term->flags & GRUB_TERM_CODE_TYPE_MASK) + || (term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) { grub_ssize_t visual_len; @@ -913,10 +913,10 @@ print_ucs4_real (const grub_uint32_t * str, visual_len = grub_bidi_logical_to_visual (str, last_position - str, &visual, getcharwidth, term, - get_maxwidth (term, + get_maxwidth (term, margin_left, margin_right), - dry_run ? 0 : get_startwidth (term, + dry_run ? 0 : get_startwidth (term, margin_left), contchar, pos, !!contchar); if (visual_len < 0) @@ -935,7 +935,7 @@ print_ucs4_real (const grub_uint32_t * str, if (vptr->base == '\n') max_lines--; - visual_len_show = vptr - visual_show; + visual_len_show = vptr - visual_show; } else visual_len_show = visual + visual_len - visual_show; @@ -1013,8 +1013,8 @@ grub_xnputs (const char *str, grub_size_t msg_len) grub_error_push (); - unicode_str = grub_malloc (msg_len * sizeof (grub_uint32_t)); - + unicode_str = grub_calloc (msg_len, sizeof (grub_uint32_t)); + grub_error_pop (); if (!unicode_str) @@ -1085,7 +1085,7 @@ grub_cls (void) { struct grub_term_output *term; - FOR_ACTIVE_TERM_OUTPUTS(term) + FOR_ACTIVE_TERM_OUTPUTS(term) { if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) { diff --git a/grub-core/osdep/apple/hostdisk.c b/grub-core/osdep/apple/hostdisk.c index 8d9b4b402..638e8ba86 100644 --- a/grub-core/osdep/apple/hostdisk.c +++ b/grub-core/osdep/apple/hostdisk.c @@ -58,9 +58,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec if (sector_size & (sector_size - 1) || !sector_size) return -1; - for (log_sector_size = 0; - (1 << log_sector_size) < sector_size; - log_sector_size++); + log_sector_size = grub_log2ull (sector_size); if (log_secsize) *log_secsize = log_sector_size; diff --git a/grub-core/osdep/aros/config.c b/grub-core/osdep/aros/config.c index c82d0ea8e..55f5728ef 100644 --- a/grub-core/osdep/aros/config.c +++ b/grub-core/osdep/aros/config.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/aros/getroot.c b/grub-core/osdep/aros/getroot.c index a27df9eb9..aff6dc53e 100644 --- a/grub-core/osdep/aros/getroot.c +++ b/grub-core/osdep/aros/getroot.c @@ -193,7 +193,7 @@ grub_guess_root_devices (const char *path) 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] = '/'; diff --git a/grub-core/osdep/aros/hostdisk.c b/grub-core/osdep/aros/hostdisk.c index 2be654ca3..08723bd45 100644 --- a/grub-core/osdep/aros/hostdisk.c +++ b/grub-core/osdep/aros/hostdisk.c @@ -116,9 +116,7 @@ grub_util_get_fd_size_volume (grub_util_fd_t fd __attribute__ ((unused)), if (sector_size & (sector_size - 1) || !sector_size) return -1; - for (log_sector_size = 0; - (1 << log_sector_size) < sector_size; - log_sector_size++); + log_sector_size = grub_log2ull (sector_size); if (log_secsize) *log_secsize = log_sector_size; @@ -194,7 +192,7 @@ grub_util_fd_open (const char *dev, int flg) p1 = dev + strlen (dev); else { - unit = grub_strtoul (p1 + 1, (char **) &p2, 16); + unit = grub_strtoul (p1 + 1, &p2, 16); if (p2 && *p2 == '/') flags = grub_strtoul (p2 + 1, 0, 16); } @@ -572,7 +570,7 @@ 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 (), diff --git a/grub-core/osdep/basic/compress.c b/grub-core/osdep/basic/compress.c index 9794640e8..dbca2906d 100644 --- a/grub-core/osdep/basic/compress.c +++ b/grub-core/osdep/basic/compress.c @@ -2,19 +2,19 @@ #include #include -int +int grub_install_compress_gzip (const char *src, const char *dest) { grub_util_error (_("no compression is available for your platform")); } -int +int grub_install_compress_xz (const char *src, const char *dest) { grub_util_error (_("no compression is available for your platform")); } -int +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 index 6362e5cfb..dbfd316d6 100644 --- a/grub-core/osdep/basic/emunet.c +++ b/grub-core/osdep/basic/emunet.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/basic/init.c b/grub-core/osdep/basic/init.c index c54c710db..b104c7e16 100644 --- a/grub-core/osdep/basic/init.c +++ b/grub-core/osdep/basic/init.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/basic/platform.c b/grub-core/osdep/basic/platform.c index a7dafd85a..68813de9a 100644 --- a/grub-core/osdep/basic/platform.c +++ b/grub-core/osdep/basic/platform.c @@ -26,7 +26,7 @@ grub_install_get_default_arm_platform (void) const char * grub_install_get_default_x86_platform (void) -{ +{ return "i386-pc"; } diff --git a/grub-core/osdep/bsd/getroot.c b/grub-core/osdep/bsd/getroot.c index dbc6a2f2a..8793d1e30 100644 --- a/grub-core/osdep/bsd/getroot.c +++ b/grub-core/osdep/bsd/getroot.c @@ -193,7 +193,7 @@ grub_util_find_partition_start_os (const char *dev) 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, diff --git a/grub-core/osdep/bsd/hostdisk.c b/grub-core/osdep/bsd/hostdisk.c index 5912d14bf..1a7ea97b4 100644 --- a/grub-core/osdep/bsd/hostdisk.c +++ b/grub-core/osdep/bsd/hostdisk.c @@ -56,6 +56,10 @@ # 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 @@ -92,7 +96,7 @@ grub_util_fd_open (const char *os_dev, int flags) ret = open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); if (ret >= 0) - configure_device_driver (fd); + configure_device_driver (ret); return ret; } @@ -105,7 +109,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec unsigned sector_size, log_sector_size; #if defined(__NetBSD__) - grub_hostdisk_configure_device_driver (fd); + configure_device_driver (fd); #endif if (ioctl (fd, DIOCGDINFO, &label) == -1) @@ -114,9 +118,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec sector_size = label.d_secsize; if (sector_size & (sector_size - 1) || !sector_size) return -1; - for (log_sector_size = 0; - (1 << log_sector_size) < sector_size; - log_sector_size++); + log_sector_size = grub_log2ull (sector_size); if (log_secsize) *log_secsize = log_sector_size; diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c index a13a39c96..5fb21aff9 100644 --- a/grub-core/osdep/devmapper/getroot.c +++ b/grub-core/osdep/devmapper/getroot.c @@ -40,12 +40,7 @@ #include #endif -#if defined(MAJOR_IN_MKDEV) -#include -#elif defined(MAJOR_IN_SYSMACROS) -#include -#endif - +#include #include #include @@ -56,6 +51,8 @@ #include #include +#include + static int grub_util_open_dm (const char *os_dev, struct dm_tree **tree, struct dm_tree_node **node) @@ -143,7 +140,8 @@ grub_util_get_dm_abstraction (const char *os_dev) grub_free (uuid); return GRUB_DEV_ABSTRACTION_LVM; } - if (strncmp (uuid, "CRYPT-LUKS1-", 12) == 0) + 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; @@ -184,11 +182,12 @@ grub_util_pull_devmapper (const char *os_dev) grub_util_pull_device (subdev); } } - if (uuid && strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0 + 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); - dm_tree_free (tree); if (grdev) { grub_err_t err; @@ -196,7 +195,111 @@ grub_util_pull_devmapper (const char *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 @@ -258,11 +361,11 @@ grub_util_get_devmapper_grub_dev (const char *os_dev) { char *dash; - dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-'); + dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS*-") - 1, '-'); if (dash) *dash = 0; grub_dev = grub_xasprintf ("cryptouuid/%s", - uuid + sizeof ("CRYPT-LUKS1-") - 1); + uuid + sizeof ("CRYPT-LUKS*-") - 1); grub_free (uuid); return grub_dev; } diff --git a/grub-core/osdep/devmapper/hostdisk.c b/grub-core/osdep/devmapper/hostdisk.c index a697bcb4d..f98ecc53c 100644 --- a/grub-core/osdep/devmapper/hostdisk.c +++ b/grub-core/osdep/devmapper/hostdisk.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -24,12 +25,6 @@ #include #include -#if defined(MAJOR_IN_MKDEV) -#include -#elif defined(MAJOR_IN_SYSMACROS) -#include -#endif - #ifdef HAVE_DEVICE_MAPPER # include @@ -113,7 +108,7 @@ grub_util_get_dm_node_linear_info (dev_t dev, void *next = NULL; uint64_t length, start; char *target, *params; - char *ptr; + const char *ptr; int major = 0, minor = 0; int first = 1; grub_disk_addr_t partstart = 0; @@ -127,7 +122,7 @@ grub_util_get_dm_node_linear_info (dev_t dev, dmt = dm_task_create(DM_DEVICE_TABLE); if (!dmt) break; - + if (! (dm_task_set_major_minor (dmt, major, minor, 0))) { dm_task_destroy (dmt); diff --git a/grub-core/osdep/freebsd/getroot.c b/grub-core/osdep/freebsd/getroot.c index b1e824495..2ff6bfa36 100644 --- a/grub-core/osdep/freebsd/getroot.c +++ b/grub-core/osdep/freebsd/getroot.c @@ -85,7 +85,7 @@ grub_util_get_geom_abstraction (const char *dev) { 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) @@ -167,7 +167,7 @@ grub_util_pull_device_os (const char *os_dev, { 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) @@ -261,7 +261,7 @@ grub_util_get_grub_dev_os (const char *os_dev) { 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) @@ -289,7 +289,7 @@ grub_util_get_grub_dev_os (const char *os_dev) } break; - default: + default: break; } @@ -325,7 +325,7 @@ grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **n 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) diff --git a/grub-core/osdep/freebsd/hostdisk.c b/grub-core/osdep/freebsd/hostdisk.c index 6145d0735..8bfe7d488 100644 --- a/grub-core/osdep/freebsd/hostdisk.c +++ b/grub-core/osdep/freebsd/hostdisk.c @@ -61,9 +61,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec return -1; if (sector_size & (sector_size - 1) || !sector_size) return -1; - for (log_sector_size = 0; - (1 << log_sector_size) < sector_size; - log_sector_size++); + log_sector_size = grub_log2ull (sector_size); if (log_secsize) *log_secsize = log_sector_size; diff --git a/grub-core/osdep/generic/blocklist.c b/grub-core/osdep/generic/blocklist.c index ea2a511b6..9ff8e44c6 100644 --- a/grub-core/osdep/generic/blocklist.c +++ b/grub-core/osdep/generic/blocklist.c @@ -30,6 +30,26 @@ #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, @@ -43,6 +63,10 @@ grub_install_get_blocklist (grub_device_t root_dev, 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); @@ -59,7 +83,7 @@ grub_install_get_blocklist (grub_device_t root_dev, grub_disk_cache_invalidate_all (); - file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | FILE_TYPE_NO_DECOMPRESS); + 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) @@ -116,12 +140,12 @@ grub_install_get_blocklist (grub_device_t root_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 | FILE_TYPE_NO_DECOMPRESS); + 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; - file->read_hook_data = hook_data; + 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")); diff --git a/grub-core/osdep/haiku/getroot.c b/grub-core/osdep/haiku/getroot.c index 4e123c090..2539a58c2 100644 --- a/grub-core/osdep/haiku/getroot.c +++ b/grub-core/osdep/haiku/getroot.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include #include @@ -66,7 +66,7 @@ grub_util_find_partition_start_os (const char *dev) if (ioctl (fd, B_GET_GEOMETRY, &geo, sizeof (geo)) < 0) return 0; ret /= geo.bytes_per_sector ? : 512; - close (fd); + close (fd); return ret; } diff --git a/grub-core/osdep/haiku/hostdisk.c b/grub-core/osdep/haiku/hostdisk.c index 562353956..62d4d5b4c 100644 --- a/grub-core/osdep/haiku/hostdisk.c +++ b/grub-core/osdep/haiku/hostdisk.c @@ -52,7 +52,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, { device_geometry part; unsigned lg; - if (ioctl (fd, B_GET_GEOMETRY, &part, sizeof (part)) < 0) + 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) diff --git a/grub-core/osdep/hurd/getroot.c b/grub-core/osdep/hurd/getroot.c index c66b206fa..b849700e6 100644 --- a/grub-core/osdep/hurd/getroot.c +++ b/grub-core/osdep/hurd/getroot.c @@ -58,7 +58,7 @@ grub_util_find_hurd_root_device (const char *path) file_t file; error_t err; char *argz = NULL, *name = NULL, *ret; - size_t argz_len = 0; + mach_msg_type_number_t argz_len = 0; int i; file = file_name_lookup (path, 0, 0); @@ -109,14 +109,36 @@ grub_util_find_hurd_root_device (const char *path) 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; - size_t size = sizeof ("/dev/") - 1 + strlen (dev_name) + 1; - char *next; - ret = malloc (size); - next = stpncpy (ret, "/dev/", size); - stpncpy (next, dev_name, size - (next - ret)); + + 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); diff --git a/grub-core/osdep/hurd/hostdisk.c b/grub-core/osdep/hurd/hostdisk.c index c47b5a5ea..17463950b 100644 --- a/grub-core/osdep/hurd/hostdisk.c +++ b/grub-core/osdep/hurd/hostdisk.c @@ -87,6 +87,23 @@ grub_util_hurd_get_disk_info (const char *dev, grub_uint32_t *secsize, grub_disk *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) @@ -130,9 +147,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec if (sector_size & (sector_size - 1) || !sector_size) return -1; - for (log_sector_size = 0; - (1 << log_sector_size) < sector_size; - log_sector_size++); + log_sector_size = grub_log2ull (sector_size); if (log_secsize) *log_secsize = log_sector_size; diff --git a/grub-core/osdep/linux/blocklist.c b/grub-core/osdep/linux/blocklist.c index c77d6085c..2efee2c2a 100644 --- a/grub-core/osdep/linux/blocklist.c +++ b/grub-core/osdep/linux/blocklist.c @@ -95,7 +95,7 @@ grub_install_get_blocklist (grub_device_t root_dev, 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; diff --git a/grub-core/osdep/linux/emunet.c b/grub-core/osdep/linux/emunet.c index 19b188f09..d5a641735 100644 --- a/grub-core/osdep/linux/emunet.c +++ b/grub-core/osdep/linux/emunet.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c index 90d92d3ad..527d4f0c5 100644 --- a/grub-core/osdep/linux/getroot.c +++ b/grub-core/osdep/linux/getroot.c @@ -35,12 +35,7 @@ #include #endif -#if defined(MAJOR_IN_MKDEV) -#include -#elif defined(MAJOR_IN_SYSMACROS) -#include -#endif - +#include #include #include /* ioctl */ #include @@ -49,6 +44,7 @@ #include #include +#include #include #include #include @@ -139,6 +135,7 @@ 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; @@ -168,24 +165,24 @@ grub_util_raid_getmembers (const char *name, int bootable) if (ret != 0) grub_util_error (_("ioctl GET_ARRAY_INFO error: %s"), strerror (errno)); - devicelist = xmalloc ((info.nr_disks + 1) * sizeof (char *)); + devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); - for (i = 0, j = 0; j < info.nr_disks; i++) + 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)); - else - devicelist[j] = NULL; - j++; + devicelist[j++] = grub_find_device (NULL, makedev (disk.major, disk.minor)); } devicelist[j] = NULL; @@ -241,7 +238,7 @@ grub_find_root_devices_from_btrfs (const char *dir) return NULL; } - ret = xmalloc ((fsi.num_devices + 1) * sizeof (ret[0])); + ret = xcalloc (fsi.num_devices + 1, sizeof (ret[0])); for (i = 1; i <= fsi.max_id && j < fsi.num_devices; i++) { @@ -273,12 +270,12 @@ get_btrfs_fs_prefix (const char *mount_path) 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; @@ -396,7 +393,7 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) if (relroot) *relroot = NULL; - entries = xmalloc (entry_max * sizeof (*entries)); + entries = xcalloc (entry_max, sizeof (*entries)); again: fp = grub_util_fopen ("/proc/self/mountinfo", "r"); @@ -487,6 +484,9 @@ again: } } + if (!entry_len) + goto out; + /* Now scan visible mounts for the ones we're interested in. */ for (i = entry_len - 1; i >= 0; i--) { @@ -615,7 +615,7 @@ get_mdadm_uuid (const char *os_dev) 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); @@ -703,7 +703,7 @@ grub_util_is_imsm (const char *os_dev) sizeof ("MD_METADATA=imsm") - 1) == 0) { is_imsm = 1; - grub_util_info ("%s is imsm", dev); + grub_util_info ("%s is imsm", dev); break; } } @@ -921,6 +921,19 @@ grub_util_part_to_disk (const char *os_dev, struct stat *st, 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') { diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c index 8b92f8528..7e24ae62c 100644 --- a/grub-core/osdep/linux/hostdisk.c +++ b/grub-core/osdep/linux/hostdisk.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -82,9 +83,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec if (sector_size & (sector_size - 1) || !sector_size) return -1; - for (log_sector_size = 0; - (1 << log_sector_size) < sector_size; - log_sector_size++); + log_sector_size = grub_log2ull (sector_size); if (log_secsize) *log_secsize = log_sector_size; @@ -98,54 +97,13 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec static char * sysfs_partition_path (const char *dev, const char *entry) { - const char *argv[7]; - int fd; - pid_t pid; - FILE *udevadm; - char *buf = NULL; - size_t len = 0; - char *path = NULL; + struct stat st; - argv[0] = "udevadm"; - argv[1] = "info"; - argv[2] = "--query"; - argv[3] = "path"; - argv[4] = "--name"; - argv[5] = dev; - argv[6] = NULL; + 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); - pid = grub_util_exec_pipe (argv, &fd); - - if (!pid) - return NULL; - - /* Parent. Read udevadm's output. */ - udevadm = fdopen (fd, "r"); - if (!udevadm) - { - grub_util_warn (_("Unable to open stream from %s: %s"), - "udevadm", strerror (errno)); - close (fd); - goto out; - } - - if (getline (&buf, &len, udevadm) > 0) - { - char *newline; - - newline = strchr (buf, '\n'); - if (newline) - *newline = '\0'; - path = xasprintf ("/sys%s/%s", buf, entry); - } - -out: - if (udevadm) - fclose (udevadm); - waitpid (pid, NULL, 0); - free (buf); - - return path; + return NULL; } static int @@ -240,7 +198,8 @@ have_devfs (void) #pragma GCC diagnostic ignored "-Wformat-nonliteral" static int -grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector) +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; @@ -305,7 +264,7 @@ grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector) 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_util_find_partition_start_os (real_dev); + 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; @@ -366,6 +325,9 @@ grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int f #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. */ @@ -383,7 +345,7 @@ grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int f && strncmp (dev, "/dev/", 5) == 0) { if (sector >= part_start) - is_partition = grub_hostdisk_linux_find_partition (dev, part_start); + is_partition = grub_hostdisk_linux_find_partition (disk, dev, part_start); else *max = part_start - sector; } diff --git a/grub-core/osdep/sun/hostdisk.c b/grub-core/osdep/sun/hostdisk.c index dab96dcff..a6d4c733e 100644 --- a/grub-core/osdep/sun/hostdisk.c +++ b/grub-core/osdep/sun/hostdisk.c @@ -57,9 +57,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec if (sector_size & (sector_size - 1) || !sector_size) return -1; - for (log_sector_size = 0; - (1 << log_sector_size) < sector_size; - log_sector_size++); + log_sector_size = grub_log2ull (sector_size); if (log_secsize) *log_secsize = log_sector_size; diff --git a/grub-core/osdep/unix/compress.c b/grub-core/osdep/unix/compress.c index dee56207f..a6e40086b 100644 --- a/grub-core/osdep/unix/compress.c +++ b/grub-core/osdep/unix/compress.c @@ -19,21 +19,21 @@ #include #include -int +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 +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 +int grub_install_compress_lzop (const char *src, const char *dest) { return grub_util_exec_redirect ((const char * []) { "lzop", "-9", "-c", diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c index 65effa9f3..0b1f7618d 100644 --- a/grub-core/osdep/unix/config.c +++ b/grub-core/osdep/unix/config.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include @@ -89,7 +89,7 @@ grub_util_load_config (struct grub_util_config *cfg) argv[0] = "sh"; argv[1] = "-c"; - script = xmalloc (4 * strlen (cfgfile) + 300); + script = xcalloc (4, strlen (cfgfile) + 300); ptr = script; memcpy (ptr, ". '", 3); diff --git a/grub-core/osdep/unix/cputime.c b/grub-core/osdep/unix/cputime.c index cff359a3b..d43e625f2 100644 --- a/grub-core/osdep/unix/cputime.c +++ b/grub-core/osdep/unix/cputime.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include @@ -17,6 +17,6 @@ grub_util_get_cpu_time_ms (void) sc_clk_tck = 1000; } - times (&tm); + 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 index 562b101a2..99b189bc1 100644 --- a/grub-core/osdep/unix/dl.c +++ b/grub-core/osdep/unix/dl.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/unix/emuconsole.c b/grub-core/osdep/unix/emuconsole.c index 7308798ef..cac159424 100644 --- a/grub-core/osdep/unix/emuconsole.c +++ b/grub-core/osdep/unix/emuconsole.c @@ -17,8 +17,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/unix/exec.c b/grub-core/osdep/unix/exec.c index db3259f65..c44ff3360 100644 --- a/grub-core/osdep/unix/exec.c +++ b/grub-core/osdep/unix/exec.c @@ -88,7 +88,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, { int fd; /* Child. */ - + /* Close fd's. */ #ifdef GRUB_UTIL grub_util_devmapper_cleanup (); @@ -188,7 +188,7 @@ grub_util_exec_pipe (const char *const *argv, int *fd) close (pipe_fd[1]); execvp ((char *) argv[0], (char **) argv); - exit (127); + _exit (127); } else { @@ -234,7 +234,7 @@ grub_util_exec_pipe_stderr (const char *const *argv, int *fd) close (pipe_fd[1]); execvp ((char *) argv[0], (char **) argv); - exit (127); + _exit (127); } else { diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c index 46d7116c6..c7aa202ab 100644 --- a/grub-core/osdep/unix/getroot.c +++ b/grub-core/osdep/unix/getroot.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include @@ -51,14 +51,9 @@ #endif /* ! FLOPPY_MAJOR */ #endif -#include -#if defined(MAJOR_IN_MKDEV) -#include -#elif defined(MAJOR_IN_SYSMACROS) -#include -#endif +#include -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +#ifdef USE_LIBZFS # include # include #endif @@ -163,7 +158,7 @@ grub_util_find_root_devices_from_poolname (char *poolname) size_t ndevices = 0; size_t devices_allocated = 0; -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +#ifdef USE_LIBZFS zpool_handle_t *zpool; libzfs_handle_t *libzfs; nvlist_t *config, *vdev_tree; @@ -179,20 +174,20 @@ grub_util_find_root_devices_from_poolname (char *poolname) zpool = zpool_open (libzfs, poolname); config = zpool_get_config (zpool, NULL); - if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0) + 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) + 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", + 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) + if (NVLIST(lookup_string) (children[i], "path", &device) != 0) error (1, errno, "nvlist_lookup_string (\"path\")"); struct stat st; @@ -234,14 +229,15 @@ grub_util_find_root_devices_from_poolname (char *poolname) char name[PATH_MAX + 1], state[257], readlen[257], writelen[257]; char cksum[257], notes[257]; unsigned int dummy; - const char *argv[4]; + const char *argv[5]; pid_t pid; int fd; argv[0] = "zpool"; argv[1] = "status"; - argv[2] = poolname; - argv[3] = NULL; + argv[2] = "-P"; + argv[3] = poolname; + argv[4] = NULL; pid = grub_util_exec_pipe (argv, &fd); if (!pid) @@ -262,7 +258,7 @@ grub_util_find_root_devices_from_poolname (char *poolname) 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) @@ -310,7 +306,7 @@ grub_util_find_root_devices_from_poolname (char *poolname) } break; } - + free (line); } @@ -454,7 +450,7 @@ grub_find_device (const char *dir, dev_t dev) cwd = xgetcwd (); res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3); - sprintf (res, + sprintf (res, #if defined(__NetBSD__) || defined(__OpenBSD__) /* Convert this block device to its character (raw) device. */ "%s/r%s", @@ -544,7 +540,6 @@ grub_guess_root_devices (const char *dir_in) for (cur = os_dev; *cur; cur++) free (*cur); free (os_dev); - os_dev = 0; } if (stat (dir, &st) < 0) diff --git a/grub-core/osdep/unix/hostdisk.c b/grub-core/osdep/unix/hostdisk.c index 91150969b..3a00d7451 100644 --- a/grub-core/osdep/unix/hostdisk.c +++ b/grub-core/osdep/unix/hostdisk.c @@ -164,6 +164,9 @@ grub_util_fd_open (const char *os_dev, int flags) #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); } diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c index 55b8f4016..de712211c 100644 --- a/grub-core/osdep/unix/platform.c +++ b/grub-core/osdep/unix/platform.c @@ -164,13 +164,13 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, ret = grub_util_exec ((const char * []){ "efibootmgr", "-q", "-c", "-d", efidir_disk, "-p", efidir_part_str, "-w", - "-L", efi_distributor, "-l", + "-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", + "-L", efi_distributor, "-l", efifile_path, NULL }); free (efidir_part_str); return ret; @@ -235,7 +235,7 @@ 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", + 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 index f719950fd..f8430481e 100644 --- a/grub-core/osdep/unix/relpath.c +++ b/grub-core/osdep/unix/relpath.c @@ -128,7 +128,7 @@ grub_make_system_path_relative_to_its_root (const char *path) free (buf); buf3 = xstrdup (buf2 + offset); buf2[offset] = 0; - + free (buf2); /* Remove trailing slashes, return empty string if root directory. */ diff --git a/grub-core/osdep/windows/config.c b/grub-core/osdep/windows/config.c index 928ab1a49..2bb8a2fd8 100644 --- a/grub-core/osdep/windows/config.c +++ b/grub-core/osdep/windows/config.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/windows/cputime.c b/grub-core/osdep/windows/cputime.c index 3568aa2d3..5d06d79dd 100644 --- a/grub-core/osdep/windows/cputime.c +++ b/grub-core/osdep/windows/cputime.c @@ -1,5 +1,5 @@ -#include #include +#include #include #include diff --git a/grub-core/osdep/windows/dl.c b/grub-core/osdep/windows/dl.c index eec6a24ad..8eab7057e 100644 --- a/grub-core/osdep/windows/dl.c +++ b/grub-core/osdep/windows/dl.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/windows/emuconsole.c b/grub-core/osdep/windows/emuconsole.c index 4fb3693cc..17a44de46 100644 --- a/grub-core/osdep/windows/emuconsole.c +++ b/grub-core/osdep/windows/emuconsole.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include diff --git a/grub-core/osdep/windows/getroot.c b/grub-core/osdep/windows/getroot.c index 661d95461..73c912664 100644 --- a/grub-core/osdep/windows/getroot.c +++ b/grub-core/osdep/windows/getroot.c @@ -59,7 +59,7 @@ grub_get_mount_point (const TCHAR *path) for (ptr = path; *ptr; ptr++); allocsize = (ptr - path + 10) * 2; - out = xmalloc (allocsize * sizeof (out[0])); + out = xcalloc (allocsize, sizeof (out[0])); /* When pointing to EFI system partition GetVolumePathName fails for ESP root and returns abberant information for everything @@ -119,16 +119,16 @@ grub_guess_root_devices (const char *dir) { free (dirwindows); grub_util_info ("can't get volume path name: %d", (int) GetLastError ()); - return 0; + return 0; } if (!mntpointwindows[0]) { free (dirwindows); free (mntpointwindows); - return 0; + return 0; } - + for (ptr = mntpointwindows; *ptr; ptr++); if (*(ptr - 1) != '\\') { @@ -255,7 +255,7 @@ grub_util_part_to_disk (const char *os_dev, free (name); return ret; } - + CloseHandle (hd); *is_part = 1; @@ -323,7 +323,7 @@ grub_util_find_partition_start_os (const char *os_dev) free (name); return 0; } - + CloseHandle (hd); free (name); return exts.Extents[0].StartingOffset.QuadPart / 512; diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c index 355100789..aaa6e2f8e 100644 --- a/grub-core/osdep/windows/hostdisk.c +++ b/grub-core/osdep/windows/hostdisk.c @@ -111,7 +111,7 @@ grub_util_get_windows_path_real (const char *path) while (1) { - fpa = xmalloc (alloc * sizeof (fpa[0])); + fpa = xcalloc (alloc, sizeof (fpa[0])); len = GetFullPathName (tpath, alloc, fpa, NULL); if (len >= alloc) @@ -185,9 +185,7 @@ grub_util_get_fd_size (grub_util_fd_t hd, const char *name_in, size = g.Cylinders.QuadPart; size *= g.TracksPerCylinder * g.SectorsPerTrack * g.BytesPerSector; - for (log_sector_size = 0; - (1 << log_sector_size) < g.BytesPerSector; - log_sector_size++); + log_sector_size = grub_log2ull (g.BytesPerSector); } else { @@ -351,7 +349,7 @@ grub_canonicalize_file_name (const char *path) return NULL; ret = grub_util_tchar_to_utf8 (windows_path); free (windows_path); - + return ret; } @@ -359,7 +357,7 @@ 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); @@ -399,7 +397,7 @@ grub_util_fd_opendir (const char *name) for (l = 0; name_windows[l]; l++); for (l--; l >= 0 && (name_windows[l] == '\\' || name_windows[l] == '/'); l--); l++; - pattern = xmalloc ((l + 3) * sizeof (pattern[0])); + pattern = xcalloc (l + 3, sizeof (pattern[0])); memcpy (pattern, name_windows, l * sizeof (pattern[0])); pattern[l] = '\\'; pattern[l + 1] = '*'; @@ -522,7 +520,7 @@ get_temp_name (void) *ptr++ = '0' + r; else *ptr++ = 'a' + (r - 10); - } + } *ptr = '\0'; return grub_util_tchar_to_utf8 (rt); @@ -606,7 +604,7 @@ grub_util_get_mtime (const char *path) us_ul.LowPart = attr.ftLastWriteTime.dwLowDateTime; us_ul.HighPart = attr.ftLastWriteTime.dwHighDateTime; - return (us_ul.QuadPart / 10000000) + return (us_ul.QuadPart / 10000000) - 86400ULL * 365 * (1970 - 1601) - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); } diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c index e8ffd62c6..b67c73c59 100644 --- a/grub-core/osdep/windows/init.c +++ b/grub-core/osdep/windows/init.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include #include +#include #include #include #include @@ -161,10 +161,10 @@ grub_util_host_init (int *argc __attribute__ ((unused)), LPWSTR *targv; targv = CommandLineToArgvW (tcmdline, argc); - *argv = xmalloc ((*argc + 1) * sizeof (argv[0])); + *argv = xcalloc (*argc + 1, sizeof (argv[0])); for (i = 0; i < *argc; i++) - (*argv)[i] = grub_util_tchar_to_utf8 (targv[i]); + (*argv)[i] = grub_util_tchar_to_utf8 (targv[i]); (*argv)[i] = NULL; #else #error "Unsupported TCHAR size" diff --git a/grub-core/osdep/windows/password.c b/grub-core/osdep/windows/password.c index 1d3af0c2c..a98c7f9ad 100644 --- a/grub-core/osdep/windows/password.c +++ b/grub-core/osdep/windows/password.c @@ -29,12 +29,12 @@ int grub_password_get (char buf[], unsigned buf_size) { - HANDLE hStdin = GetStdHandle (STD_INPUT_HANDLE); + HANDLE hStdin = GetStdHandle (STD_INPUT_HANDLE); DWORD mode = 0; char *ptr; grub_refresh (); - + GetConsoleMode (hStdin, &mode); SetConsoleMode (hStdin, mode & (~ENABLE_ECHO_INPUT)); diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c index 7eb53fe01..af04c1a1e 100644 --- a/grub-core/osdep/windows/platform.c +++ b/grub-core/osdep/windows/platform.c @@ -104,14 +104,14 @@ get_platform (void) { platform = PLAT_BIOS; return; - } + } platform = PLAT_EFI; return; } const char * grub_install_get_default_x86_platform (void) -{ +{ SYSTEM_INFO si; get_platform (); @@ -225,8 +225,8 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, grub_util_error ("%s", _("no EFI routines are available when running in BIOS mode")); distrib8_len = grub_strlen (efi_distributor); - distributor16 = xmalloc ((distrib8_len + 1) * GRUB_MAX_UTF16_PER_UTF8 - * sizeof (grub_uint16_t)); + 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); @@ -371,7 +371,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, 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_get_size (efidir_grub_dev->disk) + 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; @@ -379,10 +379,20 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, 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]; diff --git a/grub-core/osdep/windows/relpath.c b/grub-core/osdep/windows/relpath.c index cb0861744..478e8ef14 100644 --- a/grub-core/osdep/windows/relpath.c +++ b/grub-core/osdep/windows/relpath.c @@ -72,7 +72,7 @@ grub_make_system_path_relative_to_its_root (const char *path) if (dirwindows[0] && dirwindows[1] == ':') offset = 2; } - ret = xmalloc (sizeof (ret[0]) * (flen - offset + 2)); + ret = xcalloc (flen - offset + 2, sizeof (ret[0])); if (dirwindows[offset] != '\\' && dirwindows[offset] != '/' && dirwindows[offset]) diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c index 1d785906b..4e93faf1c 100644 --- a/grub-core/partmap/bsdlabel.c +++ b/grub-core/partmap/bsdlabel.c @@ -132,14 +132,14 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, &grub_bsdlabel_partition_map, hook, hook_data); - if (disk->partition + 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, + return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, &grub_bsdlabel_partition_map, hook, hook_data); } diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c index 95c96186c..b25ae0d3b 100644 --- a/grub-core/partmap/dvh.c +++ b/grub-core/partmap/dvh.c @@ -33,7 +33,7 @@ struct grub_dvh_partition_descriptor { grub_uint32_t length; grub_uint32_t start; - grub_uint32_t type; + grub_uint32_t type; } GRUB_PACKED; struct grub_dvh_block @@ -86,7 +86,7 @@ dvh_partition_map_iterate (grub_disk_t disk, 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++) diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c index 103f6796f..426f616ae 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -25,6 +25,9 @@ #include #include #include +#ifdef GRUB_UTIL +#include +#endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -33,10 +36,10 @@ static grub_uint8_t grub_gpt_magic[8] = 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 }; -static const grub_gpt_part_guid_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; +static const grub_guid_t grub_gpt_partition_type_empty = GRUB_GPT_PARTITION_TYPE_EMPTY; #ifdef GRUB_UTIL -static const grub_gpt_part_guid_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; +static const grub_guid_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; #endif /* 512 << 7 = 65536 byte sectors. */ @@ -169,7 +172,8 @@ 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) + grub_disk_addr_t **sectors, + int warn_short) { struct gpt_partition_map_embed_ctx ctx = { .start = 0, @@ -191,6 +195,9 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, 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;" @@ -199,7 +206,7 @@ gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, *nsectors = ctx.len; if (*nsectors > max_nsectors) *nsectors = max_nsectors; - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); if (!*sectors) return grub_errno; for (i = 0; i < *nsectors; i++) @@ -222,6 +229,9 @@ static struct grub_partition_map grub_gpt_partition_map = 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); } diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 7b8e45076..c85bb74be 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -55,7 +55,7 @@ const char message_warn[][200] = { " avoiding it. " "This software may cause boot or other problems in " "future. Please ask its authors not to store data " - "in the boot track") + "in the boot track") }; @@ -236,7 +236,8 @@ 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) + grub_disk_addr_t **sectors, + int warn_short) { grub_disk_addr_t end = ~0ULL; struct grub_msdos_partition_mbr mbr; @@ -311,7 +312,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, if (grub_msdos_partition_is_extended (e->type)) { - offset = ext_offset + offset = ext_offset + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); if (! ext_offset) @@ -337,7 +338,7 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, avail_nsectors = *nsectors; if (*nsectors > max_nsectors) *nsectors = max_nsectors; - *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + *sectors = grub_calloc (*nsectors, sizeof (**sectors)); if (!*sectors) return grub_errno; for (i = 0; i < *nsectors; i++) @@ -390,6 +391,9 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, 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 " diff --git a/grub-core/partmap/sun.c b/grub-core/partmap/sun.c index aac30a320..12bf5ba29 100644 --- a/grub-core/partmap/sun.c +++ b/grub-core/partmap/sun.c @@ -108,7 +108,7 @@ sun_partition_map_iterate (grub_disk_t disk, if (! grub_sun_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 < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++) diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c index 73a430c14..fe9552e21 100644 --- a/grub-core/partmap/sunpc.c +++ b/grub-core/partmap/sunpc.c @@ -91,11 +91,11 @@ sun_pc_partition_map_iterate (grub_disk_t disk, 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, + return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun_pc partition table"); } diff --git a/grub-core/parttool/msdospart.c b/grub-core/parttool/msdospart.c index dcbf74e3b..3a7699e45 100644 --- a/grub-core/parttool/msdospart.c +++ b/grub-core/parttool/msdospart.c @@ -61,7 +61,7 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev, return grub_errno; } - if (args[0].set && args[0].bool) + if (args[0].set && args[0].b) { for (i = 0; i < 4; i++) mbr.entries[i].flag = 0x0; @@ -116,7 +116,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev, if (args[1].set) { - if (args[1].bool) + if (args[1].b) type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG; else type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG; @@ -127,8 +127,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev, { dev->disk->partition = part; return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("the partition type 0x%x isn't " - "valid")); + N_("the partition type 0x%x isn't valid"), type); } mbr.entries[index].type = type; diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c index 217ec5d1e..5751fdd57 100644 --- a/grub-core/script/argv.c +++ b/grub-core/script/argv.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Return nearest power of two that is >= v. */ static unsigned @@ -81,11 +82,16 @@ 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; - p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *))); + 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; @@ -105,13 +111,19 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s, { 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; - p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char))); + 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; diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index ee299fd0e..da99dfa05 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -33,10 +33,18 @@ 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 @@ -122,7 +130,7 @@ replace_scope (struct grub_script_scope *new_scope) grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]) { - char *p = 0; + const char *p = NULL; unsigned long count; if (argc == 0) @@ -154,7 +162,7 @@ grub_err_t grub_script_shift (grub_command_t cmd __attribute__((unused)), int argc, char *argv[]) { - char *p = 0; + const char *p = NULL; unsigned long n = 0; if (! scope) @@ -215,7 +223,7 @@ grub_err_t grub_script_return (grub_command_t cmd __attribute__((unused)), int argc, char *argv[]) { - char *p; + const char *p = NULL; unsigned long n; if (! scope || argc > 1) @@ -485,7 +493,7 @@ gettext_putvar (const char *str, grub_size_t len, return 0; /* Enough for any number. */ - if (len == 1 && str[0] == '#') + if (len == 1 && str[0] == '#' && scope != NULL) { grub_snprintf (*ptr, 30, "%u", scope->argv.argc); *ptr += grub_strlen (*ptr); @@ -553,7 +561,7 @@ gettext_append (struct grub_script_argv *result, const char *orig_str) for (iptr = orig_str; *iptr; iptr++) if (*iptr == '$') dollar_cnt++; - ctx.allowed_strings = grub_malloc (sizeof (ctx.allowed_strings[0]) * 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; @@ -624,6 +632,9 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, 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)) @@ -749,6 +760,9 @@ cleanup: } } + if (result.args == NULL || result.argc == 0) + goto fail; + if (! result.args[result.argc - 1]) result.argc--; @@ -785,7 +799,7 @@ cleanup: grub_free (expansions[j]); } grub_free (expansions); - + if (failed) { grub_script_argv_free (&unexpanded); @@ -813,7 +827,13 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd) 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); @@ -838,7 +858,9 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args) old_scope = scope; scope = &new_scope; + func->executing++; ret = grub_script_execute (func->func); + func->executing--; function_return = 0; active_loops = loops; @@ -892,7 +914,10 @@ grub_script_execute_sourcecode (const char *source) break; } - ret = grub_script_execute (parsed_script); + /* 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); } @@ -938,7 +963,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) struct grub_script_argv argv = { 0, 0, 0 }; /* Lookup the command. */ - if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0]) + if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args || ! argv.args[0]) return grub_errno; for (i = 0; i < argv.argc; i++) diff --git a/grub-core/script/function.c b/grub-core/script/function.c index d36655e51..3aad04bf9 100644 --- a/grub-core/script/function.c +++ b/grub-core/script/function.c @@ -34,6 +34,7 @@ grub_script_function_create (struct grub_script_arg *functionname_arg, func = (grub_script_function_t) grub_malloc (sizeof (*func)); if (! func) return 0; + func->executing = 0; func->name = grub_strdup (functionname_arg->str); if (! func->name) @@ -60,10 +61,19 @@ grub_script_function_create (struct grub_script_arg *functionname_arg, grub_script_function_t q; q = *p; - grub_script_free (q->func); - q->func = cmd; grub_free (func); - func = q; + if (q->executing > 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("attempt to redefine a function being executed")); + func = NULL; + } + else + { + grub_script_free (q->func); + q->func = cmd; + func = q; + } } else { diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c index c6bd3172f..b6812b66c 100644 --- a/grub-core/script/lexer.c +++ b/grub-core/script/lexer.c @@ -24,6 +24,7 @@ #include #include #include +#include #define yytext_ptr char * #include "grub_script.tab.h" @@ -110,10 +111,14 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str) old = lexer->recording; if (lexer->recordlen < len) lexer->recordlen = len; - lexer->recordlen *= 2; + + 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; @@ -130,7 +135,7 @@ int grub_script_lexer_yywrap (struct grub_parser_param *parserstate, const char *input) { - grub_size_t len = 0; + grub_size_t len = 0, sz; char *p = 0; char *line = 0; YY_BUFFER_STATE buffer; @@ -168,12 +173,22 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate, } else if (len && line[len - 1] != '\n') { - p = grub_realloc (line, len + 2); + 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; } @@ -288,7 +303,7 @@ grub_script_yylex (union YYSTYPE *value, 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 @@ -331,10 +346,10 @@ grub_script_yylex (union YYSTYPE *value, } void -grub_script_yyerror (struct grub_parser_param *state, char const *err) +grub_script_yyerror (struct grub_parser_param *state, const char *err) { if (err) - grub_error (GRUB_ERR_INVALID_COMMAND, err); + grub_error (GRUB_ERR_INVALID_COMMAND, "%s", err); grub_print_error (); state->err++; diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y index 4f0ab8319..4a18ab7ba 100644 --- a/grub-core/script/parser.y +++ b/grub-core/script/parser.y @@ -279,7 +279,7 @@ function: "function" "name" $$ = state->scripts; state->scripts = 0; } - delimiters0 "{" commands1 delimiters1 "}" + newlines0 "{" commands1 delimiters1 "}" { struct grub_script *script; state->func_mem = grub_script_mem_record_stop (state, @@ -289,7 +289,8 @@ function: "function" "name" grub_script_mem_free (state->func_mem); else { script->children = state->scripts; - grub_script_function_create ($2, script); + if (!grub_script_function_create ($2, script)) + grub_script_free (script); } state->scripts = $3; diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 7b44c37b7..b7203c823 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -37,11 +37,11 @@ /* * As we don't have access to yyscanner, we cannot do much except to - * print the fatal error. + * print the fatal error and exit. */ #define YY_FATAL_ERROR(msg) \ do { \ - grub_printf (_("fatal error: %s\n"), _(msg)); \ + grub_fatal (_("fatal error: %s\n"), _(msg));\ } while (0) #define COPY(str, hint) \ diff --git a/grub-core/term/arc/console.c b/grub-core/term/arc/console.c index c944ffc2d..5591cb0e2 100644 --- a/grub-core/term/arc/console.c +++ b/grub-core/term/arc/console.c @@ -122,7 +122,7 @@ check_is_serial (void) return is_serial = 0; return is_serial = grub_arc_is_device_serial (consout, 0); } - + static void set_console_dimensions (void) { diff --git a/grub-core/term/arc/serial.c b/grub-core/term/arc/serial.c index 87d1ce821..487aa1b30 100644 --- a/grub-core/term/arc/serial.c +++ b/grub-core/term/arc/serial.c @@ -100,12 +100,16 @@ struct grub_serial_driver grub_arcserial_driver = .put = serial_hw_put }; -const char * +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; @@ -120,7 +124,7 @@ grub_arcserial_add_port (const char *path) grub_serial_register (port); - return port->name; + return port; } static int diff --git a/grub-core/term/arm/cros.c b/grub-core/term/arm/cros.c index 1ff9f8ccf..a17e49c32 100644 --- a/grub-core/term/arm/cros.c +++ b/grub-core/term/arm/cros.c @@ -30,7 +30,7 @@ #include #include -struct grub_ps2_state ps2_state; +static struct grub_ps2_state ps2_state; struct grub_cros_ec_keyscan old_scan; diff --git a/grub-core/term/arm/pl050.c b/grub-core/term/arm/pl050.c index e4cda3056..b082243b0 100644 --- a/grub-core/term/arm/pl050.c +++ b/grub-core/term/arm/pl050.c @@ -29,7 +29,7 @@ static volatile grub_uint32_t *pl050_regs; -struct grub_ps2_state ps2_state; +static struct grub_ps2_state ps2_state; static void keyboard_controller_wait_until_ready (void) diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index f0a986eb1..f8a129eb7 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -40,9 +40,19 @@ 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))); + + while (!KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) + { + grub_millisleep (1); + + /* Timeout. */ + if (!i--) + break; + } } static grub_uint8_t @@ -234,7 +244,7 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) return GRUB_TERM_NO_KEY; if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - return -1; + return GRUB_TERM_NO_KEY; at_key = grub_inb (KEYBOARD_REG_DATA); old_led = ps2_state.led_status; diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index 4840cc59d..258b52737 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -24,6 +24,24 @@ #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) { @@ -66,14 +84,93 @@ map_char (grub_uint32_t c) } static void -grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), +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_efi_is_finished) + if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE) return; o = grub_efi_system_table->con_out; @@ -91,10 +188,10 @@ grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), /* Should this test be cached? */ if ((c->base > 0x7f || c->ncomb) - && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS) + && o->test_string (o, str) != GRUB_EFI_SUCCESS) return; - efi_call_2 (o->output_string, o, str); + o->output_string (o, str); } const unsigned efi_codes[] = @@ -144,7 +241,7 @@ grub_console_getkey_con (struct grub_term_input *term __attribute__ ((unused))) grub_efi_status_t status; i = grub_efi_system_table->con_in; - status = efi_call_2 (i->read_key_stroke, i, &key); + status = i->read_key_stroke (i, &key); if (status != GRUB_EFI_SUCCESS) return GRUB_TERM_NO_KEY; @@ -152,27 +249,57 @@ grub_console_getkey_con (struct grub_term_input *term __attribute__ ((unused))) 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_console_getkey_ex (struct grub_term_input *term) { grub_efi_key_data_t key_data; - grub_efi_status_t status; grub_efi_uint32_t kss; + grub_err_t err; int key = -1; - grub_efi_simple_text_input_ex_interface_t *text_input = term->data; - - status = efi_call_2 (text_input->read_key_stroke, text_input, &key_data); - - if (status != GRUB_EFI_SUCCESS) + 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; - key = grub_efi_translate_key(key_data.key); - - if (key == GRUB_TERM_NO_KEY) - return GRUB_TERM_NO_KEY; - if (kss & GRUB_EFI_SHIFT_STATE_VALID) { if ((kss & GRUB_EFI_LEFT_SHIFT_PRESSED @@ -189,10 +316,43 @@ grub_console_getkey_ex(struct grub_term_input *term) 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) { - grub_efi_guid_t text_input_ex_guid = + static grub_guid_t text_input_ex_guid = GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; if (grub_efi_is_finished) @@ -223,14 +383,15 @@ grub_console_getkey (struct grub_term_input *term) } static struct grub_term_coordinate -grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) +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_efi_is_finished || efi_call_4 (o->query_mode, o, o->mode->mode, - &columns, &rows) != GRUB_EFI_SUCCESS) + 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; @@ -245,7 +406,7 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) { grub_efi_simple_text_output_interface_t *o; - if (grub_efi_is_finished) + 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; @@ -253,16 +414,16 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) } static void -grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), +grub_console_gotoxy (struct grub_term_output *term, struct grub_term_coordinate pos) { grub_efi_simple_text_output_interface_t *o; - if (grub_efi_is_finished) + if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE) return; o = grub_efi_system_table->con_out; - efi_call_3 (o->set_cursor_position, o, pos.x, pos.y); + o->set_cursor_position (o, pos.x, pos.y); } static void @@ -271,70 +432,25 @@ 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_efi_is_finished) + if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE) return; o = grub_efi_system_table->con_out; orig_attr = o->mode->attribute; - efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK); - efi_call_1 (o->clear_screen, o); - efi_call_2 (o->set_attributes, o, orig_attr); -} - -static void -grub_console_setcolorstate (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) - return; - - o = grub_efi_system_table->con_out; - - switch (state) { - case GRUB_TERM_COLOR_STANDARD: - efi_call_2 (o->set_attributes, o, GRUB_TERM_DEFAULT_STANDARD_COLOR - & 0x7f); - break; - case GRUB_TERM_COLOR_NORMAL: - efi_call_2 (o->set_attributes, o, grub_term_normal_color & 0x7f); - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - efi_call_2 (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) - return; - - o = grub_efi_system_table->con_out; - efi_call_2 (o->enable_cursor, o, on); -} - -static grub_err_t -grub_efi_console_output_init (struct grub_term_output *term) -{ - grub_efi_set_text_mode (1); - grub_console_setcursor (term, 1); - return 0; + 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; } @@ -342,13 +458,13 @@ 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", - .init = grub_efi_console_output_init, .fini = grub_efi_console_output_fini, .putchar = grub_console_putchar, .getwh = grub_console_getwh, @@ -364,14 +480,6 @@ static struct grub_term_output grub_console_term_output = void grub_console_init (void) { - /* FIXME: it is necessary to consider the case where no console control - is present but the default is already in text mode. */ - if (! grub_efi_set_text_mode (1)) - { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode"); - return; - } - grub_term_register_output ("console", &grub_console_term_output); grub_term_register_input ("console", &grub_console_term_input); } diff --git a/grub-core/term/efi/serial.c b/grub-core/term/efi/serial.c index 4c94723c5..5dfd2d86c 100644 --- a/grub-core/term/efi/serial.c +++ b/grub-core/term/efi/serial.c @@ -31,7 +31,7 @@ #include /* GUID. */ -static grub_efi_guid_t serial_io_guid = GRUB_EFI_SERIAL_IO_GUID; +static grub_guid_t serial_io_guid = GRUB_EFI_SERIAL_IO_GUID; static void do_real_config (struct grub_serial_port *port) @@ -51,16 +51,16 @@ do_real_config (struct grub_serial_port *port) if (port->configured) return; - status = efi_call_7 (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]); + 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 = efi_call_2 (port->interface->set_control_bits, port->interface, - port->config.rtscts ? 0x4002 : 0x2); + status = port->interface->set_control_bits (port->interface, + port->config.rtscts ? 0x4002 : 0x2); port->configured = 1; } @@ -76,7 +76,7 @@ serial_hw_fetch (struct grub_serial_port *port) if (port->broken) return -1; - status = efi_call_3 (port->interface->read, port->interface, &bufsize, &c); + status = port->interface->read (port->interface, &bufsize, &c); if (status != GRUB_EFI_SUCCESS || bufsize == 0) return -1; @@ -95,7 +95,7 @@ serial_hw_put (struct grub_serial_port *port, const int c) if (port->broken) return; - efi_call_3 (port->interface->write, port->interface, &bufsize, &c0); + port->interface->write (port->interface, &bufsize, &c0); } /* Initialize a serial device. PORT is the port number for a serial device. diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index af7c090a3..3c468f459 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -232,6 +232,15 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width; virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height; + /* + * There must be a minimum number of rows and columns for the screen to + * make sense. Arbitrarily pick half of 80x24. If either dimensions is 0 + * we would allocate 0 bytes for the text_buffer. + */ + if (virtual_screen.columns < 40 || virtual_screen.rows < 12) + return grub_error (GRUB_ERR_BAD_FONT, + "font: glyphs too large to fit on screen"); + /* Allocate memory for text buffer. */ virtual_screen.text_buffer = (struct grub_colored_char *) grub_malloc (virtual_screen.columns @@ -297,10 +306,10 @@ grub_gfxterm_set_window (struct grub_video_render_target *target, render_target = target; /* Create virtual screen. */ - if (grub_virtual_screen_setup (border_width, border_width, - width - 2 * border_width, - height - 2 * border_width, - font) + if (grub_virtual_screen_setup (border_width, border_width, + width - 2 * border_width, + height - 2 * border_width, + font) != GRUB_ERR_NONE) { return grub_errno; @@ -430,9 +439,9 @@ redraw_screen_rect (unsigned int x, unsigned int y, grub_video_set_active_render_target (render_target); /* Save viewport and set it to our window. */ - grub_video_get_viewport ((unsigned *) &saved_view.x, - (unsigned *) &saved_view.y, - (unsigned *) &saved_view.width, + grub_video_get_viewport ((unsigned *) &saved_view.x, + (unsigned *) &saved_view.y, + (unsigned *) &saved_view.width, (unsigned *) &saved_view.height); grub_video_set_viewport (window.x, window.y, window.width, window.height); @@ -670,7 +679,7 @@ draw_cursor (int show) unsigned int height; unsigned int ascent; grub_video_color_t color; - + write_char (); if (!show) @@ -693,12 +702,12 @@ draw_cursor (int show) * virtual_screen.normal_char_height + ascent); height = 2; - + /* Render cursor to text layer. */ grub_video_set_active_render_target (text_layer); grub_video_fill_rect (color, x, y, width, height); grub_video_set_active_render_target (render_target); - + /* Mark cursor to be redrawn. */ dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y, @@ -742,9 +751,9 @@ real_scroll (void) while (i--) { /* Save viewport and set it to our window. */ - grub_video_get_viewport ((unsigned *) &saved_view.x, - (unsigned *) &saved_view.y, - (unsigned *) &saved_view.width, + grub_video_get_viewport ((unsigned *) &saved_view.x, + (unsigned *) &saved_view.y, + (unsigned *) &saved_view.width, (unsigned *) &saved_view.height); grub_video_set_viewport (window.x, window.y, window.width, @@ -809,7 +818,7 @@ scroll_up (void) /* Clear first line in text buffer. */ for (i = 0; i < virtual_screen.columns; i++) grub_unicode_destroy_glyph (&virtual_screen.text_buffer[i].code); - + /* Scroll text buffer with one line to up. */ grub_memmove (virtual_screen.text_buffer, virtual_screen.text_buffer + virtual_screen.columns, @@ -895,7 +904,7 @@ grub_gfxterm_putchar (struct grub_term_output *term, { unsigned i; - for (i = 1; i < char_width && p + i < + for (i = 1; i < char_width && p + i < virtual_screen.text_buffer + virtual_screen.columns * virtual_screen.rows; i++) { diff --git a/grub-core/term/gfxterm_background.c b/grub-core/term/gfxterm_background.c index 8da71a8c8..a0e2d5118 100644 --- a/grub-core/term/gfxterm_background.c +++ b/grub-core/term/gfxterm_background.c @@ -43,7 +43,7 @@ enum 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 + /* 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 @@ -100,7 +100,7 @@ grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, { struct grub_video_bitmap *scaled_bitmap; grub_video_bitmap_create_scaled (&scaled_bitmap, - width, + width, height, grub_gfxterm_background.bitmap, GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c index f6142a2de..9403390f1 100644 --- a/grub-core/term/i386/pc/console.c +++ b/grub-core/term/i386/pc/console.c @@ -32,7 +32,7 @@ int10_9 (grub_uint8_t ch, grub_uint16_t n) regs.eax = ch | 0x0900; regs.ebx = grub_console_cur_color & 0xff; regs.ecx = n; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x10, ®s); } @@ -54,7 +54,7 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) regs.eax = 0x0300; regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x10, ®s); return (struct grub_term_coordinate) { @@ -78,7 +78,7 @@ grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), regs.ebx = 0; regs.eax = 0x0200; regs.edx = (pos.y << 8) | pos.x; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x10, ®s); } @@ -101,14 +101,14 @@ grub_console_putchar_real (grub_uint8_t c) { regs.eax = c | 0x0e00; regs.ebx = 0x0001; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + 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); @@ -158,7 +158,7 @@ grub_console_cls (struct grub_term_output *term) * %ch = cursor starting scanline * %cl = cursor ending scanline */ -static void +static void grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), int on) { @@ -170,7 +170,7 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), { regs.eax = 0x0300; regs.ebx = 0; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + 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)) @@ -179,7 +179,7 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), /* set %cx to the designated cursor shape */ regs.ecx = on ? console_cursor_shape : 0x2000; regs.eax = 0x0100; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x10, ®s); } @@ -238,12 +238,11 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL); } -static const struct grub_machine_bios_data_area *bios_data_area = - (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; - 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; } diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c index 88fecc5ea..b88fa9d2e 100644 --- a/grub-core/term/i386/pc/vga_text.c +++ b/grub-core/term/i386/pc/vga_text.c @@ -45,15 +45,15 @@ GRUB_MOD_LICENSE ("GPLv3+"); static struct grub_term_coordinate grub_curr_pos; #ifdef __mips__ -#define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb00b8000) +#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 *) 0xb0000) +#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 *) 0xb8000) +#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 @@ -63,7 +63,8 @@ static grub_uint8_t cur_color = 0x7; static void screen_write_char (int x, int y, short c) { - VGA_TEXT_SCREEN[y * COLS + x] = grub_cpu_to_le16 (c); + if (x < COLS && y < ROWS && x >= 0 && y >= 0) + VGA_TEXT_SCREEN[y * COLS + x] = grub_cpu_to_le16 (c); } static short diff --git a/grub-core/term/ieee1275/console.c b/grub-core/term/ieee1275/console.c index 7e797a7d4..7231e1824 100644 --- a/grub-core/term/ieee1275/console.c +++ b/grub-core/term/ieee1275/console.c @@ -88,7 +88,7 @@ grub_console_dimensions (void) val, sizeof (val) - 1, 0)) { grub_ieee1275_ihandle_t stdout_options; - val[sizeof (val) - 1] = 0; + val[sizeof (val) - 1] = 0; if (! grub_ieee1275_finddevice (val, &stdout_options) && ! grub_ieee1275_get_property (stdout_options, "device_type", @@ -171,6 +171,7 @@ 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 @@ -184,16 +185,12 @@ grub_console_init_output (struct grub_term_output *term) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdout"); /* Initialize colors. */ - if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS)) - { - unsigned col; - for (col = 0; col < ARRAY_SIZE (colors); col++) - grub_ieee1275_set_color (stdout_ihandle, col, colors[col].red, - colors[col].green, colors[col].blue); + 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); - } + /* Set the right fg and bg colors. */ + grub_terminfo_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); grub_console_dimensions (); @@ -251,9 +248,7 @@ grub_console_init_lately (void) { const char *type; - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) - type = "dumb"; - else if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN)) + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN)) type = "ieee1275-nocursor"; else type = "ieee1275"; diff --git a/grub-core/term/ieee1275/escc.c b/grub-core/term/ieee1275/escc.c index e605ff25e..6ffffbd13 100644 --- a/grub-core/term/ieee1275/escc.c +++ b/grub-core/term/ieee1275/escc.c @@ -90,7 +90,7 @@ do_real_config (struct grub_serial_port *port) break; case GRUB_SERIAL_STOP_BITS_2: parity_stop_spec |= 0xc; - break; + break; } *port->escc_desc->escc_ctrl = 4; diff --git a/grub-core/term/ieee1275/serial.c b/grub-core/term/ieee1275/serial.c index 9e71ca4b8..ac2a8f827 100644 --- a/grub-core/term/ieee1275/serial.c +++ b/grub-core/term/ieee1275/serial.c @@ -25,8 +25,6 @@ #include #include -#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0) - struct ofserial_hash_ent { char *devpath; @@ -44,7 +42,7 @@ do_real_config (struct grub_serial_port *port) if (grub_ieee1275_open (port->elem->devpath, &port->handle) || port->handle == (grub_ieee1275_ihandle_t) -1) - port->handle = IEEE1275_IHANDLE_INVALID; + port->handle = GRUB_IEEE1275_IHANDLE_INVALID; port->configured = 1; } @@ -58,7 +56,7 @@ serial_hw_fetch (struct grub_serial_port *port) do_real_config (port); - if (port->handle == IEEE1275_IHANDLE_INVALID) + if (port->handle == GRUB_IEEE1275_IHANDLE_INVALID) return -1; grub_ieee1275_read (port->handle, &c, 1, &actual); @@ -76,7 +74,7 @@ serial_hw_put (struct grub_serial_port *port, const int c) do_real_config (port); - if (port->handle == IEEE1275_IHANDLE_INVALID) + if (port->handle == GRUB_IEEE1275_IHANDLE_INVALID) return; grub_ieee1275_write (port->handle, &c0, 1, &actual); @@ -217,7 +215,7 @@ dev_iterate (struct grub_ieee1275_devalias *alias) return 0; } -static const char * +static struct grub_serial_port * add_port (struct ofserial_hash_ent *ent) { struct grub_serial_port *port; @@ -227,6 +225,10 @@ add_port (struct ofserial_hash_ent *ent) if (!ent->shortest) return NULL; + FOR_SERIAL_PORTS (port) + if (port->elem == ent) + return port; + port = grub_zalloc (sizeof (*port)); if (!port) return NULL; @@ -245,10 +247,10 @@ add_port (struct ofserial_hash_ent *ent) grub_serial_register (port); - return port->name; + return port; } -const char * +struct grub_serial_port * grub_ofserial_add_port (const char *path) { struct ofserial_hash_ent *ent; @@ -276,7 +278,7 @@ grub_ofserial_init (void) 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; diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c new file mode 100644 index 000000000..428b2d59a --- /dev/null +++ b/grub-core/term/ns8250-spcr.c @@ -0,0 +1,96 @@ +/* + * 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 index 39809d042..23e8e0904 100644 --- a/grub-core/term/ns8250.c +++ b/grub-core/term/ns8250.c @@ -28,7 +28,6 @@ #ifdef GRUB_MACHINE_PCBIOS #include -static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; #define GRUB_SERIAL_PORT_NUM 4 #else #include @@ -38,12 +37,67 @@ static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS; static int dead_ports = 0; -#ifdef GRUB_MACHINE_MIPS_LOONGSON -#define DEFAULT_BASE_CLOCK (2 * 115200) -#else -#define DEFAULT_BASE_CLOCK 115200 -#endif +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 @@ -54,7 +108,14 @@ serial_get_divisor (const struct grub_serial_port *port __attribute__ ((unused)) grub_uint32_t divisor; grub_uint32_t actual_speed, error; - base_clock = config->base_clock ? (config->base_clock >> 4) : DEFAULT_BASE_CLOCK; + /* 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) @@ -94,43 +155,42 @@ do_real_config (struct grub_serial_port *port) divisor = serial_get_divisor (port, &port->config); /* Turn off the interrupt. */ - grub_outb (0, port->port + UART_IER); + ns8250_reg_write (port, 0, UART_IER); /* Set DLAB. */ - grub_outb (UART_DLAB, port->port + UART_LCR); + ns8250_reg_write (port, UART_DLAB, UART_LCR); - /* Set the baud rate. */ - grub_outb (divisor & 0xFF, port->port + UART_DLL); - grub_outb (divisor >> 8, port->port + UART_DLH); + 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]); - grub_outb (status, port->port + UART_LCR); + ns8250_reg_write (port, status, UART_LCR); if (port->config.rtscts) { /* Enable the FIFO. */ - grub_outb (UART_ENABLE_FIFO_TRIGGER1, port->port + UART_FCR); + ns8250_reg_write (port, UART_ENABLE_FIFO_TRIGGER1, UART_FCR); /* Turn on DTR and RTS. */ - grub_outb (UART_ENABLE_DTRRTS, port->port + UART_MCR); + ns8250_reg_write (port, UART_ENABLE_DTRRTS, UART_MCR); } else { /* Enable the FIFO. */ - grub_outb (UART_ENABLE_FIFO_TRIGGER14, port->port + UART_FCR); + ns8250_reg_write (port, UART_ENABLE_FIFO_TRIGGER14, UART_FCR); /* Turn on DTR, RTS, and OUT2. */ - grub_outb (UART_ENABLE_DTRRTS | UART_ENABLE_OUT2, port->port + UART_MCR); + ns8250_reg_write (port, UART_ENABLE_DTRRTS | UART_ENABLE_OUT2, UART_MCR); } /* Drain the input buffer. */ endtime = grub_get_time_ms () + 1000; - while (grub_inb (port->port + UART_LSR) & UART_DATA_READY) + while (ns8250_reg_read (port, UART_LSR) & UART_DATA_READY) { - grub_inb (port->port + UART_RX); + ns8250_reg_read (port, UART_RX); if (grub_get_time_ms () > endtime) { port->broken = 1; @@ -146,8 +206,8 @@ static int serial_hw_fetch (struct grub_serial_port *port) { do_real_config (port); - if (grub_inb (port->port + UART_LSR) & UART_DATA_READY) - return grub_inb (port->port + UART_RX); + if (ns8250_reg_read (port, UART_LSR) & UART_DATA_READY) + return ns8250_reg_read (port, UART_RX); return -1; } @@ -167,7 +227,7 @@ serial_hw_put (struct grub_serial_port *port, const int c) else endtime = grub_get_time_ms () + 200; /* Wait until the transmitter holding register is empty. */ - while ((grub_inb (port->port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0) + while ((ns8250_reg_read (port, UART_LSR) & UART_EMPTY_TRANSMITTER) == 0) { if (grub_get_time_ms () > endtime) { @@ -180,7 +240,7 @@ serial_hw_put (struct grub_serial_port *port, const int c) if (port->broken) port->broken--; - grub_outb (c, port->port + UART_TX); + ns8250_reg_write (port, c, UART_TX); } /* Initialize a serial device. PORT is the port number for a serial device. @@ -237,6 +297,9 @@ 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]) @@ -260,6 +323,7 @@ grub_ns8250_init (void) 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 (); @@ -272,6 +336,9 @@ grub_ns8250_init (void) 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]; @@ -279,17 +346,29 @@ grub_ns8250_hw_get_port (const unsigned int unit) return 0; } -char * -grub_serial_ns8250_add_port (grub_port_t port) +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; - return com_names[i]; + /* 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); @@ -301,18 +380,67 @@ grub_serial_ns8250_add_port (grub_port_t port) return NULL; p = grub_malloc (sizeof (*p)); - if (!p) + if (p == NULL) return NULL; p->name = grub_xasprintf ("port%lx", (unsigned long) port); - if (!p->name) + if (p->name == NULL) { grub_free (p); return NULL; } p->driver = &grub_ns8250_driver; - grub_serial_config_defaults (p); + p->use_mmio = false; p->port = port; - grub_serial_register (p); + if (config != NULL) + grub_serial_port_configure (p, config); + else + grub_serial_config_defaults (p); + grub_serial_register (p); - return p->name; + 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 new file mode 100644 index 000000000..4b7a4a862 --- /dev/null +++ b/grub-core/term/pci/serial.c @@ -0,0 +1,91 @@ +/* + * 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 index 7ae4e9f2f..c7a09a821 100644 --- a/grub-core/term/ps2.c +++ b/grub-core/term/ps2.c @@ -28,50 +28,50 @@ 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, + /* 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, @@ -98,22 +98,22 @@ static const grub_uint8_t set1_mapping[128] = static const struct { grub_uint8_t from, to; -} set1_e0_mapping[] = +} set1_e0_mapping[] = { {0x1c, GRUB_KEYBOARD_KEY_NUMENTER}, {0x1d, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, - {0x35, GRUB_KEYBOARD_KEY_NUMSLASH }, + {0x35, GRUB_KEYBOARD_KEY_NUMSLASH }, {0x38, GRUB_KEYBOARD_KEY_RIGHT_ALT}, - {0x47, GRUB_KEYBOARD_KEY_HOME}, + {0x47, GRUB_KEYBOARD_KEY_HOME}, {0x48, GRUB_KEYBOARD_KEY_UP}, - {0x49, GRUB_KEYBOARD_KEY_PPAGE}, + {0x49, GRUB_KEYBOARD_KEY_PPAGE}, {0x4b, GRUB_KEYBOARD_KEY_LEFT}, {0x4d, GRUB_KEYBOARD_KEY_RIGHT}, - {0x4f, GRUB_KEYBOARD_KEY_END}, + {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}, + {0x53, GRUB_KEYBOARD_KEY_DELETE}, }; static const grub_uint8_t set2_mapping[256] = @@ -182,14 +182,14 @@ static const grub_uint8_t set2_mapping[256] = /* 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, + /* 0x80 */ 0, 0, /* 0x82 */ 0, GRUB_KEYBOARD_KEY_F7, }; static const struct { grub_uint8_t from, to; -} set2_e0_mapping[] = +} set2_e0_mapping[] = { {0x11, GRUB_KEYBOARD_KEY_RIGHT_ALT}, {0x14, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, @@ -266,7 +266,7 @@ fetch_key (struct grub_ps2_state *ps2_state, grub_uint8_t at_key, int *is_break) ret = set2_e0_mapping[i].to; break; } - } + } break; default: return -1; diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index db80b3ba0..8260dcb7a 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -37,8 +37,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); -#define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports)) - enum { OPTION_UNIT, @@ -65,7 +63,7 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -static struct grub_serial_port *grub_serial_ports; +struct grub_serial_port *grub_serial_ports; struct grub_serial_output_state { @@ -79,7 +77,7 @@ struct grub_serial_input_state struct grub_serial_port *port; }; -static void +static void serial_put (grub_term_output_t term, const int c) { struct grub_serial_output_state *data = term->data; @@ -147,39 +145,95 @@ 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) - break; + return port; #if (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) - if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0 + if (grub_strncmp (name, "port", sizeof ("port") - 1) == 0 && grub_isxdigit (name [sizeof ("port") - 1])) { - name = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1], - 0, 16)); - if (!name) - return NULL; - - FOR_SERIAL_PORTS (port) - if (grub_strcmp (port->name, name) == 0) - break; + 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 (!port && grub_memcmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) == 0) + if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) == 0) { - name = grub_ofserial_add_port (&name[sizeof ("ieee1275/") - 1]); - if (!name) - return NULL; - - FOR_SERIAL_PORTS (port) - if (grub_strcmp (port->name, name) == 0) - break; + port = grub_ofserial_add_port (&name[sizeof ("ieee1275/") - 1]); + if (port != NULL) + return port; } #endif - return port; + return NULL; } static grub_err_t @@ -201,8 +255,15 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) if (state[OPTION_PORT].set) { - grub_snprintf (pname, sizeof (pname), "port%lx", - grub_strtoul (state[1].arg, 0, 0)); + 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; } @@ -210,11 +271,11 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) name = args[0]; if (!name) - name = "com0"; + name = "auto"; port = grub_serial_find (name); if (!port) - return grub_error (GRUB_ERR_BAD_ARGUMENT, + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("serial port `%s' isn't found"), name); @@ -269,7 +330,7 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) if (state[OPTION_BASE_CLOCK].set) { - char *ptr; + const char *ptr; config.base_clock = grub_strtoull (state[OPTION_BASE_CLOCK].arg, &ptr, 0); if (grub_errno) return grub_errno; @@ -400,7 +461,7 @@ 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) @@ -448,6 +509,9 @@ GRUB_MOD_INIT(serial) #ifdef GRUB_MACHINE_ARC grub_arcserial_init (); #endif +#if defined(__i386__) || defined(__x86_64__) + grub_pciserial_init (); +#endif } GRUB_MOD_FINI(serial) diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index d317efa36..4e534c683 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -286,7 +286,7 @@ grub_terminfo_setcolorstate (struct grub_term_output *term, int fg; int bg; /* Map from VGA to terminal colors. */ - const int colormap[8] + const int colormap[8] = { 0, /* Black. */ 4, /* Blue. */ 2, /* Green. */ @@ -398,7 +398,7 @@ grub_terminfo_getwh (struct grub_term_output *term) } static void -grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, +grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, int max_len, int (*readkey) (struct grub_term_input *term)) { int c; @@ -414,6 +414,9 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, if (c == -1) \ return; \ \ + if (*len >= max_len) \ + return; \ + \ keys[*len] = c; \ (*len)++; \ } @@ -476,10 +479,10 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, [23] = GRUB_TERM_KEY_F11, [24] = GRUB_TERM_KEY_F12, }; - char fx_key[] = + char fx_key[] = { 'P', 'Q', 'w', 'x', 't', 'u', 'q', 'r', 'p', 'M', 'A', 'B', 'H', 'F' }; - unsigned fx_code[] = + 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, @@ -509,7 +512,7 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, } CONTINUE_READ; - + for (i = 0; i < ARRAY_SIZE (three_code_table); i++) if (three_code_table[i].key == c) { @@ -559,7 +562,7 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, keys[0] = fx_code[num - 1]; *len = 1; return; - } + } case '1' ... '9': { @@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi) return ret; } - grub_terminfo_readkey (termi, data->input_buf, - &data->npending, data->readkey); + 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 @@ -659,7 +662,7 @@ grub_terminfo_output_init (struct grub_term_output *term) static grub_err_t print_terminfo (void) { - const char *encoding_names[(GRUB_TERM_CODE_TYPE_MASK + const char *encoding_names[(GRUB_TERM_CODE_TYPE_MASK >> GRUB_TERM_CODE_TYPE_SHIFT) + 1] = { /* VGA and glyph descriptor types are just for completeness, @@ -737,7 +740,7 @@ grub_cmd_terminfo (grub_extcmd_context_t ctxt, int argc, char **args) if (state[OPTION_GEOMETRY].set) { - char *ptr = state[OPTION_GEOMETRY].arg; + const char *ptr = state[OPTION_GEOMETRY].arg; w = grub_strtoul (ptr, &ptr, 0); if (grub_errno) return grub_errno; @@ -782,8 +785,8 @@ 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"), + N_("[[-a|-u|-v] [-g WxH] [TERM] [TYPE]]"), + N_("Set terminfo type of TERM to TYPE.\n"), options); } diff --git a/grub-core/term/uboot/console.c b/grub-core/term/uboot/console.c index dfdbe9909..ff5a0d48f 100644 --- a/grub-core/term/uboot/console.c +++ b/grub-core/term/uboot/console.c @@ -110,7 +110,7 @@ grub_console_init_early (void) * grub_console_init_lately(): * Initializes terminfo formatting by registering terminal type. * Called after heap has been configured. - * + * */ void grub_console_init_lately (void) diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c index e67b8f785..7322d8dff 100644 --- a/grub-core/term/usb_keyboard.c +++ b/grub-core/term/usb_keyboard.c @@ -162,7 +162,7 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) if (curnum == ARRAY_SIZE (grub_usb_keyboards)) return 0; - if (usbdev->descdev.class != 0 + if (usbdev->descdev.class != 0 || usbdev->descdev.subclass != 0 || usbdev->descdev.protocol != 0) return 0; @@ -199,7 +199,7 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) /* 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); @@ -291,7 +291,7 @@ parse_keycode (struct grub_usb_keyboard_data *termdata) for ( ; index < termdata->max_index; index++) { keycode = termdata->current_report[index]; - + if (keycode == KEY_NO_KEY || keycode == KEY_ERR_BUFFER || keycode == KEY_ERR_POST @@ -316,7 +316,7 @@ parse_keycode (struct grub_usb_keyboard_data *termdata) /* 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; @@ -367,7 +367,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) keycode = parse_keycode (termdata); if (keycode != GRUB_TERM_NO_KEY) return keycode; - + /* Poll interrupt pipe. */ err = grub_usb_check_transfer (termdata->transfer, &actual); @@ -387,7 +387,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) grub_memcpy (termdata->last_report, termdata->current_report, sizeof (termdata->report)); - + grub_memcpy (termdata->current_report, termdata->report, sizeof (termdata->report)); @@ -424,7 +424,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) termdata->index = 2; /* New data received. */ termdata->max_index = actual; - + return parse_keycode (termdata); } @@ -457,7 +457,7 @@ GRUB_MOD_FINI(usb_keyboard) if (!data) continue; - + if (data->transfer) grub_usb_cancel_transfer (data->transfer); diff --git a/grub-core/tests/asn1/asn1_test.c b/grub-core/tests/asn1/asn1_test.c new file mode 100644 index 000000000..69606b004 --- /dev/null +++ b/grub-core/tests/asn1/asn1_test.c @@ -0,0 +1,50 @@ +/* + * 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 new file mode 100644 index 000000000..8e83d70f5 --- /dev/null +++ b/grub-core/tests/asn1/asn1_test.h @@ -0,0 +1,45 @@ +/* + * 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/cmdline_cat_test.c b/grub-core/tests/cmdline_cat_test.c index baea7688a..4748d1bb0 100644 --- a/grub-core/tests/cmdline_cat_test.c +++ b/grub-core/tests/cmdline_cat_test.c @@ -60,7 +60,7 @@ get_test_txt (grub_size_t *sz) return grub_strdup (testfile); } -struct grub_procfs_entry test_txt = +struct grub_procfs_entry test_txt = { .name = "test.txt", .get_contents = get_test_txt @@ -91,14 +91,14 @@ cmdline_cat_test (void) } 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', ' ', + grub_terminal_input_fake_sequence ((int []) + { 'c', 'a', 't', ' ', '(', 'p', 'r', 'o', 'c', ')', '/', 't', 'e', 's', 't', '.', 't', 'x', 't', '\n', diff --git a/grub-core/tests/fake_input.c b/grub-core/tests/fake_input.c index 2d6085298..b5eb516be 100644 --- a/grub-core/tests/fake_input.c +++ b/grub-core/tests/fake_input.c @@ -49,7 +49,7 @@ grub_terminal_input_fake_sequence (int *seq_in, int nseq_in) saved = grub_term_inputs; if (seq) grub_free (seq); - seq = grub_malloc (nseq_in * sizeof (seq[0])); + seq = grub_calloc (nseq_in, sizeof (seq[0])); if (!seq) return; diff --git a/grub-core/tests/gfxterm_menu.c b/grub-core/tests/gfxterm_menu.c index 12836fb96..ea4352703 100644 --- a/grub-core/tests/gfxterm_menu.c +++ b/grub-core/tests/gfxterm_menu.c @@ -63,7 +63,7 @@ get_test_cfg (grub_size_t *sz) return grub_strdup (testfile); } -struct grub_procfs_entry test_cfg = +struct grub_procfs_entry test_cfg = { .name = "test.cfg", .get_contents = get_test_cfg @@ -73,7 +73,7 @@ struct { const char *name; const char *var; - const char *val; + const char *val; } tests[] = { { "gfxterm_menu", NULL, NULL }, @@ -121,7 +121,7 @@ gfxterm_menu (void) } 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++) { diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c index 96781fb39..38e981f2c 100644 --- a/grub-core/tests/lib/functional_test.c +++ b/grub-core/tests/lib/functional_test.c @@ -79,6 +79,7 @@ grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)), 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; diff --git a/grub-core/tests/shift_test.c b/grub-core/tests/shift_test.c index 4120f520a..3d0110a06 100644 --- a/grub-core/tests/shift_test.c +++ b/grub-core/tests/shift_test.c @@ -99,7 +99,7 @@ arithmetic_right_shift64 (grub_uint64_t v, int s) if (get_bit64 (v, 63)) for (i -= s; i < 64; i++) r = set_bit64 (r, i); - + return r; } diff --git a/grub-core/tests/signature_test.c b/grub-core/tests/signature_test.c index aa49393a4..07a913a62 100644 --- a/grub-core/tests/signature_test.c +++ b/grub-core/tests/signature_test.c @@ -40,7 +40,7 @@ get_hi_dsa_sig (grub_size_t *sz) return ret; } -static struct grub_procfs_entry hi_dsa_sig_entry = +static struct grub_procfs_entry hi_dsa_sig_entry = { .name = "hi_dsa.sig", .get_contents = get_hi_dsa_sig @@ -57,7 +57,7 @@ get_hi_dsa_pub (grub_size_t *sz) return ret; } -static struct grub_procfs_entry hi_dsa_pub_entry = +static struct grub_procfs_entry hi_dsa_pub_entry = { .name = "hi_dsa.pub", .get_contents = get_hi_dsa_pub @@ -74,7 +74,7 @@ get_hi_rsa_sig (grub_size_t *sz) return ret; } -static struct grub_procfs_entry hi_rsa_sig_entry = +static struct grub_procfs_entry hi_rsa_sig_entry = { .name = "hi_rsa.sig", .get_contents = get_hi_rsa_sig @@ -91,7 +91,7 @@ get_hi_rsa_pub (grub_size_t *sz) return ret; } -static struct grub_procfs_entry hi_rsa_pub_entry = +static struct grub_procfs_entry hi_rsa_pub_entry = { .name = "hi_rsa.pub", .get_contents = get_hi_rsa_pub @@ -104,7 +104,7 @@ get_hi (grub_size_t *sz) return grub_strdup ("hi\n"); } -struct grub_procfs_entry hi = +struct grub_procfs_entry hi = { .name = "hi", .get_contents = get_hi @@ -117,7 +117,7 @@ get_hj (grub_size_t *sz) return grub_strdup ("hj\n"); } -struct grub_procfs_entry hj = +struct grub_procfs_entry hj = { .name = "hj", .get_contents = get_hj diff --git a/grub-core/tests/sleep_test.c b/grub-core/tests/sleep_test.c index 3d11c717c..ffb268114 100644 --- a/grub-core/tests/sleep_test.c +++ b/grub-core/tests/sleep_test.c @@ -32,7 +32,7 @@ static void sleep_test (void) { struct grub_datetime st, en; - grub_int32_t stu = 0, enu = 0; + 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); @@ -45,8 +45,7 @@ sleep_test (void) if (enu - stu >= 15 && enu - stu <= 17) is_delayok = 1; #endif - grub_test_assert (is_delayok, "Interval out of range: %d", enu-stu); - + 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 index 7da615ff3..5488ab26b 100644 --- a/grub-core/tests/strtoull_test.c +++ b/grub-core/tests/strtoull_test.c @@ -25,7 +25,7 @@ static void strtoull_testcase (const char *input, int base, unsigned long long expected, int num_digits, grub_err_t error) { - char *output; + const char *output; unsigned long long value; grub_errno = 0; value = grub_strtoull(input, &output, base); diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c index 74d5b65e5..39053e0eb 100644 --- a/grub-core/tests/video_checksum.c +++ b/grub-core/tests/video_checksum.c @@ -336,7 +336,7 @@ grub_video_capture_write_bmp (const char *fname, { case 4: { - grub_uint8_t *buffer = xmalloc (mode_info->width * 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); @@ -367,7 +367,7 @@ grub_video_capture_write_bmp (const char *fname, } case 3: { - grub_uint8_t *buffer = xmalloc (mode_info->width * 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); @@ -407,7 +407,7 @@ grub_video_capture_write_bmp (const char *fname, } case 2: { - grub_uint8_t *buffer = xmalloc (mode_info->width * 3); + 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); @@ -499,9 +499,9 @@ write_time (void) cur = grub_util_get_cpu_time_ms (); grub_snprintf (buf, sizeof (buf), "%s_%dx%dx%s:%d: %" PRIuGRUB_UINT64_T " ms\n", - basename, + basename, capt_mode_info.width, - capt_mode_info.height, + capt_mode_info.height, grub_video_checksum_get_modename (), ctr, cur - prev); prev = cur; @@ -605,9 +605,9 @@ checksum (void) if (!checksums || ctr >= nchk) { grub_test_assert (0, "Unexpected checksum %s_%dx%dx%s:%d: 0x%x", - basename, + basename, capt_mode_info.width, - capt_mode_info.height, + capt_mode_info.height, grub_video_checksum_get_modename (), ctr, crc); } else if (crc != checksums[ctr]) @@ -628,7 +628,7 @@ checksum (void) } #endif #ifdef GRUB_MACHINE_EMU - char *name = grub_xasprintf ("%s_%dx%dx%s_%d.bmp", basename, + char *name = grub_xasprintf ("%s_%dx%dx%s_%d.bmp", basename, capt_mode_info.width, capt_mode_info.height, grub_video_checksum_get_modename (), @@ -785,7 +785,7 @@ grub_test_use_gfxterm (void) } if (gfxterm->init (gfxterm)) - { + { grub_test_assert (0, "terminal `%s' failed: %s", "gfxterm", grub_errmsg); return 1; } diff --git a/grub-core/video/bitmap.c b/grub-core/video/bitmap.c index b2e031566..6256e209a 100644 --- a/grub-core/video/bitmap.c +++ b/grub-core/video/bitmap.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -58,7 +59,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, enum grub_video_blit_format blit_format) { struct grub_video_mode_info *mode_info; - unsigned int size; + grub_size_t size; if (!bitmap) return grub_error (GRUB_ERR_BUG, "invalid argument"); @@ -137,19 +138,25 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, mode_info->pitch = width * mode_info->bytes_per_pixel; - /* Calculate size needed for the data. */ - size = (width * mode_info->bytes_per_pixel) * height; + /* Calculate size needed for the data. */ + if (grub_mul (width, mode_info->bytes_per_pixel, &size) || + grub_mul (size, height, &size)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + goto fail; + } (*bitmap)->data = grub_zalloc (size); if (! (*bitmap)->data) - { - grub_free (*bitmap); - *bitmap = 0; - - return grub_errno; - } + goto fail; return GRUB_ERR_NONE; + + fail: + grub_free (*bitmap); + *bitmap = NULL; + + return grub_errno; } /* Frees all resources allocated by bitmap. */ diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c index 3bcfa53a9..edc651697 100644 --- a/grub-core/video/bochs.c +++ b/grub-core/video/bochs.c @@ -212,7 +212,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) 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) @@ -249,11 +249,11 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, } if (width > BOCHS_MAX_WIDTH) - return grub_error (GRUB_ERR_IO, "width must be at most", + 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", + return grub_error (GRUB_ERR_IO, "height must be at most %d", BOCHS_MAX_HEIGHT); if (width & (BOCHS_WIDTH_ALIGN - 1)) @@ -274,7 +274,7 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, " supported by bochs video"); if (depth == 4) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "4-bpp isn't cupported"); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "4-bpp isn't supported"); bytes_per_pixel = (depth + 7) / 8; if (depth == 4) diff --git a/grub-core/video/capture.c b/grub-core/video/capture.c index 4f83c7441..c653d89f9 100644 --- a/grub-core/video/capture.c +++ b/grub-core/video/capture.c @@ -89,10 +89,10 @@ grub_video_capture_start (const struct grub_video_mode_info *mode_info, framebuffer.mode_info = *mode_info; framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - framebuffer.ptr = grub_malloc (framebuffer.mode_info.height * framebuffer.mode_info.pitch); + 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); diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c index e2149e8ce..f5542ccdc 100644 --- a/grub-core/video/cirrus.c +++ b/grub-core/video/cirrus.c @@ -354,11 +354,11 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, 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) diff --git a/grub-core/video/coreboot/cbfb.c b/grub-core/video/coreboot/cbfb.c index 9af81fa5b..986003c51 100644 --- a/grub-core/video/coreboot/cbfb.c +++ b/grub-core/video/coreboot/cbfb.c @@ -106,7 +106,7 @@ grub_video_cbfb_setup (unsigned int width, unsigned int height, grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); - + return err; } diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c index 7f9d1c2df..9452f5e58 100644 --- a/grub-core/video/efi_gop.c +++ b/grub-core/video/efi_gop.c @@ -32,10 +32,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_efi_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID; -static grub_efi_guid_t active_edid_guid = GRUB_EFI_EDID_ACTIVE_GUID; -static grub_efi_guid_t discovered_edid_guid = GRUB_EFI_EDID_DISCOVERED_GUID; -static grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; +static grub_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID; +static grub_guid_t active_edid_guid = GRUB_EFI_EDID_ACTIVE_GUID; +static grub_guid_t discovered_edid_guid = GRUB_EFI_EDID_DISCOVERED_GUID; +static grub_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; static struct grub_efi_gop *gop; static unsigned old_mode; static int restore_needed; @@ -71,7 +71,10 @@ check_protocol (void) handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &graphics_output_guid, NULL, &num_handles); if (!handles || num_handles == 0) - return 0; + { + grub_dprintf ("video", "GOP: no handles\n"); + return 0; + } for (i = 0; i < num_handles; i++) { @@ -81,6 +84,7 @@ check_protocol (void) grub_video_gop_iterate (check_protocol_hook, &have_usable_mode); if (have_usable_mode) { + grub_dprintf ("video", "GOP: found usable mode\n"); grub_free (handles); return 1; } @@ -89,6 +93,8 @@ check_protocol (void) gop = 0; gop_handle = 0; + grub_dprintf ("video", "GOP: no usable mode\n"); + return 0; } @@ -104,7 +110,7 @@ grub_video_gop_fini (void) { if (restore_needed) { - efi_call_2 (gop->set_mode, gop, old_mode); + gop->set_mode (gop, old_mode); restore_needed = 0; } grub_free (framebuffer.offscreen); @@ -121,6 +127,7 @@ grub_video_gop_get_bpp (struct grub_efi_gop_mode_info *in) { case GRUB_EFI_GOT_BGRA8: case GRUB_EFI_GOT_RGBA8: + case GRUB_EFI_GOT_BLT_ONLY: return 32; case GRUB_EFI_GOT_BITMASK: @@ -187,6 +194,7 @@ grub_video_gop_fill_real_mode_info (unsigned mode, switch (in->pixel_format) { case GRUB_EFI_GOT_RGBA8: + case GRUB_EFI_GOT_BLT_ONLY: out->red_mask_size = 8; out->red_field_pos = 0; out->green_mask_size = 8; @@ -227,7 +235,7 @@ grub_video_gop_fill_real_mode_info (unsigned mode, return GRUB_ERR_NONE; } -static grub_err_t +static void grub_video_gop_fill_mode_info (unsigned mode, struct grub_efi_gop_mode_info *in, struct grub_video_mode_info *out) @@ -252,8 +260,6 @@ grub_video_gop_fill_mode_info (unsigned mode, out->blit_format = GRUB_VIDEO_BLIT_FORMAT_BGRA_8888; out->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - - return GRUB_ERR_NONE; } static int @@ -266,10 +272,9 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo grub_efi_uintn_t size; grub_efi_status_t status; struct grub_efi_gop_mode_info *info = NULL; - grub_err_t err; struct grub_video_mode_info mode_info; - - status = efi_call_4 (gop->query_mode, gop, mode, &size, &info); + + status = gop->query_mode (gop, mode, &size, &info); if (status) { @@ -277,12 +282,7 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo continue; } - err = grub_video_gop_fill_mode_info (mode, info, &mode_info); - if (err) - { - grub_errno = GRUB_ERR_NONE; - continue; - } + grub_video_gop_fill_mode_info (mode, info, &mode_info); if (hook (&mode_info, hook_arg)) return 1; } @@ -308,7 +308,7 @@ grub_video_gop_get_edid (struct grub_video_edid_info *edid_info) char edidname[] = "agp-internal-edid"; grub_size_t datasize; grub_uint8_t *data; - data = grub_efi_get_variable (edidname, &efi_var_guid, &datasize); + grub_efi_get_variable (edidname, &efi_var_guid, &datasize, (void **) &data); if (data && datasize > 16) { copy_size = datasize - 16; @@ -390,7 +390,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, found = 1; } } - + if (!found) { unsigned mode; @@ -399,8 +399,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height, { grub_efi_uintn_t size; grub_efi_status_t status; - - status = efi_call_4 (gop->query_mode, gop, mode, &size, &info); + + status = gop->query_mode (gop, mode, &size, &info); if (status) { info = 0; @@ -461,40 +461,39 @@ grub_video_gop_setup (unsigned int width, unsigned int height, old_mode = gop->mode->mode; restore_needed = 1; } - efi_call_2 (gop->set_mode, gop, best_mode); + gop->set_mode (gop, best_mode); } info = gop->mode->info; - err = grub_video_gop_fill_mode_info (gop->mode->mode, info, - &framebuffer.mode_info); - if (err) - { - grub_dprintf ("video", "GOP: couldn't fill mode info\n"); - return err; - } + grub_video_gop_fill_mode_info (gop->mode->mode, info, + &framebuffer.mode_info); framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base; framebuffer.offscreen = grub_malloc (framebuffer.mode_info.height - * framebuffer.mode_info.width + * framebuffer.mode_info.width * sizeof (struct grub_efi_gop_blt_pixel)); buffer = framebuffer.offscreen; - + if (!buffer) { grub_dprintf ("video", "GOP: couldn't allocate shadow\n"); + + if (info->pixel_format == GRUB_EFI_GOT_BLT_ONLY) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + grub_errno = 0; - err = grub_video_gop_fill_mode_info (gop->mode->mode, info, - &framebuffer.mode_info); + grub_video_gop_fill_mode_info (gop->mode->mode, info, + &framebuffer.mode_info); buffer = framebuffer.ptr; } - + grub_dprintf ("video", "GOP: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, framebuffer.mode_info.height, framebuffer.mode_info.bpp); - + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, buffer); @@ -503,15 +502,15 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: Couldn't create FB target\n"); return err; } - + err = grub_video_fb_set_active_render_target (framebuffer.render_target); - + if (err) { grub_dprintf ("video", "GOP: Couldn't set FB target\n"); return err; } - + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); @@ -519,7 +518,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: Couldn't set palette\n"); else grub_dprintf ("video", "GOP: Success\n"); - + return err; } @@ -528,10 +527,10 @@ grub_video_gop_swap_buffers (void) { if (framebuffer.offscreen) { - efi_call_10 (gop->blt, gop, framebuffer.offscreen, - GRUB_EFI_BLT_BUFFER_TO_VIDEO, 0, 0, 0, 0, - framebuffer.mode_info.width, framebuffer.mode_info.height, - framebuffer.mode_info.width * 4); + gop->blt (gop, framebuffer.offscreen, + GRUB_EFI_BLT_BUFFER_TO_VIDEO, 0, 0, 0, 0, + framebuffer.mode_info.width, framebuffer.mode_info.height, + framebuffer.mode_info.width * 4); } return GRUB_ERR_NONE; } @@ -618,7 +617,7 @@ GRUB_MOD_FINI(efi_gop) { if (restore_needed) { - efi_call_2 (gop->set_mode, gop, old_mode); + gop->set_mode (gop, old_mode); restore_needed = 0; } if (gop) diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c index 044af1d20..d53079e0b 100644 --- a/grub-core/video/efi_uga.c +++ b/grub-core/video/efi_uga.c @@ -32,9 +32,9 @@ GRUB_MOD_LICENSE ("GPLv3+"); -static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; +static grub_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; static struct grub_efi_uga_draw_protocol *uga; -static grub_uint32_t uga_fb; +static grub_uint64_t uga_fb; static grub_uint32_t uga_pitch; static struct @@ -52,7 +52,7 @@ static struct #define FBTEST_COUNT 8 static int -find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) +find_line_len (grub_uint64_t *fb_base, grub_uint32_t *line_len) { grub_uint32_t *base = (grub_uint32_t *) (grub_addr_t) *fb_base; int i; @@ -67,7 +67,7 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) { if ((base[j] & RGB_MASK) == RGB_MAGIC) { - *fb_base = (grub_uint32_t) (grub_addr_t) base; + *fb_base = (grub_uint64_t) (grub_addr_t) base; *line_len = j << 2; return 1; @@ -84,7 +84,7 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) /* Context for find_framebuf. */ struct find_framebuf_ctx { - grub_uint32_t *fb_base; + grub_uint64_t *fb_base; grub_uint32_t *line_len; int found; }; @@ -100,7 +100,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); subclass = (grub_pci_read (addr) >> 16) & 0xffff; - if (subclass != GRUB_PCI_CLASS_SUBCLASS_VGA) + if (subclass != GRUB_PCI_CLASS_DISPLAY_VGA) return 0; /* Enable MEM address spaces */ @@ -110,7 +110,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) { int i; - grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", + grub_dprintf ("video", "Display controller: %d:%d.%d\nDevice id: %x\n", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), pciid); addr += 8; @@ -129,7 +129,9 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) if (i == 5) break; - old_bar2 = grub_pci_read (addr + 4); + i++; + addr += 4; + old_bar2 = grub_pci_read (addr); } else old_bar2 = 0; @@ -138,10 +140,15 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) base64 <<= 32; base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); - grub_dprintf ("fb", "%s(%d): 0x%llx\n", + grub_dprintf ("video", "%s(%d): 0x%" PRIxGRUB_UINT64_T "\n", ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? - "VMEM" : "MMIO"), i, - (unsigned long long) base64); + "VMEM" : "MMIO"), type == GRUB_PCI_ADDR_MEM_TYPE_64 ? i - 1 : i, + base64); + +#if GRUB_CPU_SIZEOF_VOID_P == 4 + if (old_bar2) + continue; +#endif if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! ctx->found)) { @@ -149,12 +156,6 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) if (find_line_len (ctx->fb_base, ctx->line_len)) ctx->found++; } - - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - i++; - addr += 4; - } } } @@ -162,7 +163,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) } static int -find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) +find_framebuf (grub_uint64_t *fb_base, grub_uint32_t *line_len) { struct find_framebuf_ctx ctx = { .fb_base = fb_base, @@ -185,13 +186,13 @@ check_protocol (void) grub_uint32_t width, height, depth, rate, pixel; int ret; - if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate)) + if (c->get_mode (c, &width, &height, &depth, &rate)) return 0; grub_efi_set_text_mode (0); pixel = RGB_MAGIC; - efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel, - GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0); + c->blt (c, (struct grub_efi_uga_pixel *) &pixel, + GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0); ret = find_framebuf (&uga_fb, &uga_pitch); grub_efi_set_text_mode (1); @@ -235,7 +236,7 @@ grub_video_uga_setup (unsigned int width, unsigned int height, grub_uint32_t d; grub_uint32_t r; - if ((! efi_call_5 (uga->get_mode, uga, &w, &h, &d, &r)) && + if ((! uga->get_mode (uga, &w, &h, &d, &r)) && ((! width) || (width == w)) && ((! height) || (height == h)) && ((! depth) || (depth == d))) diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c index a2f639f66..cb8490e35 100644 --- a/grub-core/video/emu/sdl.c +++ b/grub-core/video/emu/sdl.c @@ -18,6 +18,9 @@ #define grub_video_render_target grub_video_fbrender_target +#include +#include + #include #include #include @@ -25,11 +28,22 @@ #include #include #include +#ifdef HAVE_SDL2 +#include +#else #include +#endif GRUB_MOD_LICENSE ("GPLv3+"); -static SDL_Surface *window = 0; +#ifdef HAVE_SDL2 +static SDL_Window *window = NULL; +static SDL_Texture *texture = NULL; +static SDL_Renderer *renderer = NULL; +#else +static SDL_Surface *window = NULL; +#endif +static SDL_Surface *surface = NULL; static struct grub_video_render_target *sdl_render_target; static struct grub_video_mode_info mode_info; @@ -40,10 +54,10 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, static grub_err_t grub_video_sdl_init (void) { - window = 0; + window = NULL; if (SDL_Init (SDL_INIT_VIDEO) < 0) - return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't init SDL: %s", + return grub_error (GRUB_ERR_BAD_DEVICE, "could not init SDL: %s", SDL_GetError ()); grub_memset (&mode_info, 0, sizeof (mode_info)); @@ -55,7 +69,7 @@ static grub_err_t grub_video_sdl_fini (void) { SDL_Quit (); - window = 0; + window = NULL; grub_memset (&mode_info, 0, sizeof (mode_info)); @@ -72,7 +86,7 @@ get_mask_size (grub_uint32_t mask) static grub_err_t grub_video_sdl_setup (unsigned int width, unsigned int height, - unsigned int mode_type, unsigned int mode_mask) + unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) { int depth; int flags = 0; @@ -91,62 +105,95 @@ grub_video_sdl_setup (unsigned int width, unsigned int height, height = 600; } +#ifdef HAVE_SDL2 + window = SDL_CreateWindow ("grub-emu", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width, height, flags); + if(window == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not open window: %s", + SDL_GetError ()); + renderer = SDL_CreateRenderer (window, -1, 0); + if (renderer == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not open renderer: %s", + SDL_GetError ()); + texture = SDL_CreateTexture (renderer, + SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + width, height); + if (texture == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not create texture: %s", + SDL_GetError ()); + + /* + * An empty surface that acts as the pixel buffer, the texture will receive the pixels + * from here. + */ + surface = SDL_CreateRGBSurface (0, width, height, depth, 0, 0, 0, 0); + if (surface == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not open surface: %s", + SDL_GetError ()); +#else if ((mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) || !(mode_mask & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) flags |= SDL_DOUBLEBUF; window = SDL_SetVideoMode (width, height, depth, flags | SDL_HWSURFACE); - if (! window) + if (window == NULL) window = SDL_SetVideoMode (width, height, depth, flags | SDL_SWSURFACE); - if (! window) - return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't open window: %s", + if (window == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not open window: %s", SDL_GetError ()); + surface = window; +#endif grub_memset (&sdl_render_target, 0, sizeof (sdl_render_target)); - mode_info.width = window->w; - mode_info.height = window->h; mode_info.mode_type = 0; - if (window->flags & SDL_DOUBLEBUF) + mode_info.width = surface->w; + mode_info.height = surface->h; +#ifndef HAVE_SDL2 + if (surface->flags & SDL_DOUBLEBUF) mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - if (window->format->palette) +#endif + if (surface->format->palette) mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; else mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_RGB; - mode_info.bpp = window->format->BitsPerPixel; - mode_info.bytes_per_pixel = window->format->BytesPerPixel; - mode_info.pitch = window->pitch; + mode_info.bpp = surface->format->BitsPerPixel; + mode_info.bytes_per_pixel = surface->format->BytesPerPixel; + mode_info.pitch = surface->pitch; /* In index color mode, number of colors. In RGB mode this is 256. */ - if (window->format->palette) + if (surface->format->palette) mode_info.number_of_colors - = 1 << window->format->BitsPerPixel; + = 1 << surface->format->BitsPerPixel; else mode_info.number_of_colors = 256; - if (! window->format->palette) + if (! surface->format->palette) { mode_info.red_mask_size - = get_mask_size (window->format->Rmask >> window->format->Rshift); - mode_info.red_field_pos = window->format->Rshift; + = get_mask_size (surface->format->Rmask >> surface->format->Rshift); + mode_info.red_field_pos = surface->format->Rshift; mode_info.green_mask_size - = get_mask_size (window->format->Gmask >> window->format->Gshift); - mode_info.green_field_pos = window->format->Gshift; + = get_mask_size (surface->format->Gmask >> surface->format->Gshift); + mode_info.green_field_pos = surface->format->Gshift; mode_info.blue_mask_size - = get_mask_size (window->format->Bmask >> window->format->Bshift); - mode_info.blue_field_pos = window->format->Bshift; + = get_mask_size (surface->format->Bmask >> surface->format->Bshift); + mode_info.blue_field_pos = surface->format->Bshift; mode_info.reserved_mask_size - = get_mask_size (window->format->Amask >> window->format->Ashift); - mode_info.reserved_field_pos = window->format->Ashift; + = get_mask_size (surface->format->Amask >> surface->format->Ashift); + mode_info.reserved_field_pos = surface->format->Ashift; mode_info.blit_format = grub_video_get_blit_format (&mode_info); } err = grub_video_fb_create_render_target_from_pointer (&sdl_render_target, &mode_info, - window->pixels); + surface->pixels); if (err) return err; @@ -163,7 +210,7 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data) { unsigned i; - if (window->format->palette) + if (surface->format->palette) { SDL_Color *tmp; if (start >= mode_info.number_of_colors) @@ -172,15 +219,23 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, if (start + count > mode_info.number_of_colors) count = mode_info.number_of_colors - start; - tmp = grub_malloc (count * sizeof (tmp[0])); + tmp = grub_calloc (count, sizeof (tmp[0])); for (i = 0; i < count; i++) { tmp[i].r = palette_data[i].r; tmp[i].g = palette_data[i].g; tmp[i].b = palette_data[i].b; +#ifdef HAVE_SDL2 + tmp[i].a = palette_data[i].a; +#else tmp[i].unused = palette_data[i].a; +#endif } +#ifdef HAVE_SDL2 + SDL_SetPaletteColors (surface->format->palette, tmp, 0 /* firstcolor */, count); +#else SDL_SetColors (window, tmp, start, count); +#endif grub_free (tmp); } @@ -190,9 +245,22 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, static grub_err_t grub_video_sdl_swap_buffers (void) { - if (SDL_Flip (window) < 0) - return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't swap buffers: %s", +#ifdef HAVE_SDL2 + if (SDL_UpdateTexture (texture, NULL, surface->pixels, surface->w * sizeof (Uint32)) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not update texture: %s", SDL_GetError ()); + if (SDL_RenderClear (renderer) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not clear renderer: %s", + SDL_GetError ()); + if (SDL_RenderCopy (renderer, texture, NULL, NULL) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not copy texture to renderer: %s", + SDL_GetError ()); + SDL_RenderPresent (renderer); +#else + if (SDL_Flip (window) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "could not swap buffers: %s", + SDL_GetError ()); +#endif return GRUB_ERR_NONE; } diff --git a/grub-core/video/fb/fbblit.c b/grub-core/video/fb/fbblit.c index d55924837..1010ef393 100644 --- a/grub-core/video/fb/fbblit.c +++ b/grub-core/video/fb/fbblit.c @@ -466,7 +466,7 @@ grub_video_fbblit_replace_24bit_indexa (struct grub_video_fbblit_info *dst, for (i = 0; i < width; i++) { register grub_uint32_t col; - if (*srcptr == 0xf0) + if (*srcptr == 0xf0) col = palette[16]; else col = palette[*srcptr & 0xf]; @@ -478,7 +478,7 @@ grub_video_fbblit_replace_24bit_indexa (struct grub_video_fbblit_info *dst, *dstptr++ = col >> 0; *dstptr++ = col >> 8; *dstptr++ = col >> 16; -#endif +#endif srcptr++; } @@ -651,7 +651,7 @@ grub_video_fbblit_blend_24bit_indexa (struct grub_video_fbblit_info *dst, for (i = 0; i < width; i++) { register grub_uint32_t col; - if (*srcptr != 0xf0) + if (*srcptr != 0xf0) { col = palette[*srcptr & 0xf]; #ifdef GRUB_CPU_WORDS_BIGENDIAN @@ -662,7 +662,7 @@ grub_video_fbblit_blend_24bit_indexa (struct grub_video_fbblit_info *dst, *dstptr++ = col >> 0; *dstptr++ = col >> 8; *dstptr++ = col >> 16; -#endif +#endif } else dstptr += 3; diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c index 11816d07a..49fa16b92 100644 --- a/grub-core/video/fb/fbfill.c +++ b/grub-core/video/fb/fbfill.c @@ -31,16 +31,16 @@ #include #include #include +#include #include /* Generic filler that works for every supported mode. */ static void grub_video_fbfill (struct grub_video_fbblit_info *dst, grub_video_color_t color, int x, int y, - int width, int height) + unsigned int width, unsigned int height) { - int i; - int j; + unsigned int i, j; for (j = 0; j < height; j++) for (i = 0; i < width; i++) @@ -52,16 +52,17 @@ grub_video_fbfill (struct grub_video_fbblit_info *dst, static void grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst, grub_video_color_t color, int x, int y, - int width, int height) + unsigned int width, unsigned int height) { - int i; - int j; + unsigned int i, j; grub_uint32_t *dstptr; grub_size_t rowskip; /* Calculate the number of bytes to advance from the end of one line to the beginning of the next line. */ - rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) + return; /* Get the start address. */ dstptr = grub_video_fb_get_video_ptr (dst, x, y); @@ -81,10 +82,9 @@ grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst, static void grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, grub_video_color_t color, int x, int y, - int width, int height) + unsigned int width, unsigned int height) { - int i; - int j; + unsigned int i, j; grub_size_t rowskip; grub_uint8_t *dstptr; #ifndef GRUB_CPU_WORDS_BIGENDIAN @@ -98,7 +98,9 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, #endif /* Calculate the number of bytes to advance from the end of one line to the beginning of the next line. */ - rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) + return; /* Get the start address. */ dstptr = grub_video_fb_get_video_ptr (dst, x, y); @@ -122,16 +124,17 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst, static void grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, grub_video_color_t color, int x, int y, - int width, int height) + unsigned int width, unsigned int height) { - int i; - int j; + unsigned int i, j; grub_size_t rowskip; grub_uint16_t *dstptr; /* Calculate the number of bytes to advance from the end of one line to the beginning of the next line. */ - rowskip = (dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width); + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) + return; /* Get the start address. */ dstptr = grub_video_fb_get_video_ptr (dst, x, y); @@ -151,17 +154,18 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst, static void grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst, grub_video_color_t color, int x, int y, - int width, int height) + unsigned int width, unsigned int height) { - int i; - int j; + unsigned int i, j; grub_size_t rowskip; grub_uint8_t *dstptr; grub_uint8_t fill = (grub_uint8_t)color & 0xFF; /* Calculate the number of bytes to advance from the end of one line to the beginning of the next line. */ - rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width; + if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) || + grub_sub (dst->mode_info->pitch, rowskip, &rowskip)) + return; /* Get the start address. */ dstptr = grub_video_fb_get_video_ptr (dst, x, y); diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c index b98bb51fe..25ef39f47 100644 --- a/grub-core/video/fb/fbutil.c +++ b/grub-core/video/fb/fbutil.c @@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source, case 1: if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) { - int bit_index = y * source->mode_info->width + x; + grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; grub_uint8_t *ptr = source->data + bit_index / 8; int bit_pos = 7 - bit_index % 8; color = (*ptr >> bit_pos) & 0x01; @@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source, case 1: if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) { - int bit_index = y * source->mode_info->width + x; + grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; grub_uint8_t *ptr = source->data + bit_index / 8; int bit_pos = 7 - bit_index % 8; *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos); diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c index 1a602c8b2..fa4ebde26 100644 --- a/grub-core/video/fb/video_fb.c +++ b/grub-core/video/fb/video_fb.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -753,7 +754,7 @@ grub_video_fb_unmap_color_int (struct grub_video_fbblit_info * source, *alpha = 0; return; } - + /* If we have an out-of-bounds color, return transparent black. */ if (color > 255) { @@ -1140,7 +1141,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) /* 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) + && (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) @@ -1154,7 +1155,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) 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) + dst_x, dst_y) % sizeof (grub_uint16_t) == 0 && linelen % sizeof (grub_uint16_t) == 0 && linedelta % sizeof (grub_uint16_t) == 0) @@ -1169,7 +1170,7 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) { grub_uint8_t *src, *dst; DO_SCROLL - } + } } /* 4. Fill empty space with specified color. In this implementation @@ -1417,15 +1418,23 @@ doublebuf_blit_update_screen (void) { if (framebuffer.current_dirty.first_line <= framebuffer.current_dirty.last_line) - 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, - framebuffer.back_target->mode_info.pitch - * (framebuffer.current_dirty.last_line - - framebuffer.current_dirty.first_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; @@ -1439,7 +1448,7 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **back, volatile void *framebuf) { grub_err_t err; - grub_size_t page_size = mode_info.pitch * mode_info.height; + 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) @@ -1482,12 +1491,23 @@ doublebuf_pageflipping_update_screen (void) last_line = framebuffer.previous_dirty.last_line; if (first_line <= last_line) - 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, - framebuffer.back_target->mode_info.pitch - * (last_line - first_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; @@ -1517,7 +1537,13 @@ doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info, volatile void *page1_ptr) { grub_err_t err; - grub_size_t page_size = mode_info->pitch * mode_info->height; + 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) @@ -1589,7 +1615,7 @@ grub_video_fb_setup (unsigned int mode_type, unsigned int mode_mask, 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); diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index b7f911926..a0bb9af09 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -219,7 +219,7 @@ grub_vbe_disable_mtrr (int mtrr) } /* Call VESA BIOS 0x4f09 to set palette data, return status. */ -static grub_vbe_status_t +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) @@ -237,7 +237,7 @@ grub_vbe_bios_set_palette_data (grub_uint32_t color_count, } /* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */ -grub_vbe_status_t +grub_vbe_status_t grub_vbe_bios_get_controller_info (struct grub_vbe_info_block *ci) { struct grub_bios_int_registers regs; @@ -251,7 +251,7 @@ grub_vbe_bios_get_controller_info (struct grub_vbe_info_block *ci) } /* Call VESA BIOS 0x4f01 to get VBE Mode Information, return status. */ -grub_vbe_status_t +grub_vbe_status_t grub_vbe_bios_get_mode_info (grub_uint32_t mode, struct grub_vbe_mode_info_block *mode_info) { @@ -285,7 +285,7 @@ grub_vbe_bios_set_mode (grub_uint32_t mode, } /* Call VESA BIOS 0x4f03 to return current VBE Mode, return status. */ -grub_vbe_status_t +grub_vbe_status_t grub_vbe_bios_get_mode (grub_uint32_t *mode) { struct grub_bios_int_registers regs; @@ -298,7 +298,7 @@ grub_vbe_bios_get_mode (grub_uint32_t *mode) return regs.eax & 0xffff; } -grub_vbe_status_t +grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *dac_mask_size) { struct grub_bios_int_registers regs; @@ -346,7 +346,7 @@ grub_vbe_bios_get_memory_window (grub_uint32_t window, } /* Call VESA BIOS 0x4f06 to set scanline length (in bytes), return status. */ -grub_vbe_status_t +grub_vbe_status_t grub_vbe_bios_set_scanline_length (grub_uint32_t length) { struct grub_bios_int_registers regs; @@ -354,14 +354,14 @@ grub_vbe_bios_set_scanline_length (grub_uint32_t length) regs.ecx = length; regs.eax = 0x4f06; /* BL = 2, Set Scan Line in Bytes. */ - regs.ebx = 0x0002; + 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_status_t grub_vbe_bios_get_scanline_length (grub_uint32_t *length) { struct grub_bios_int_registers regs; @@ -377,7 +377,7 @@ grub_vbe_bios_get_scanline_length (grub_uint32_t *length) } /* Call VESA BIOS 0x4f07 to set display start, return status. */ -static grub_vbe_status_t +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; @@ -390,7 +390,7 @@ grub_vbe_bios_set_display_start (grub_uint32_t x, grub_uint32_t y) regs.edx = y; regs.eax = 0x4f07; /* BL = 80h, Set Display Start during Vertical Retrace. */ - regs.ebx = 0x0080; + regs.ebx = 0x0080; regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x10, ®s); @@ -401,7 +401,7 @@ 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 +grub_vbe_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x, grub_uint32_t *y) { @@ -419,7 +419,7 @@ grub_vbe_bios_get_display_start (grub_uint32_t *x, } /* Call VESA BIOS 0x4f0a. */ -grub_vbe_status_t +grub_vbe_status_t grub_vbe_bios_get_pm_interface (grub_uint16_t *segment, grub_uint16_t *offset, grub_uint16_t *length) { @@ -514,7 +514,7 @@ grub_vbe_probe (struct grub_vbe_info_block *info_block) /* Use low memory scratch area as temporary storage for VESA BIOS call. */ - vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + 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)); @@ -574,7 +574,7 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height) /* Use low memory scratch area as temporary storage for VESA BIOS calls. */ flat_panel_info = (struct grub_vbe_flat_panel_info *) - (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + sizeof (struct grub_video_edid_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) @@ -676,7 +676,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, == GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL) { struct grub_vbe_palette_data *palette - = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + = (struct grub_vbe_palette_data *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR); unsigned i; /* Make sure that the BIOS can reach the palette. */ @@ -896,7 +896,7 @@ vbe2videoinfo (grub_uint32_t mode, 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; @@ -923,10 +923,10 @@ vbe2videoinfo (grub_uint32_t mode, break; case 8: mode_info->bytes_per_pixel = 1; - break; + break; case 4: mode_info->bytes_per_pixel = 0; - break; + break; } if (controller_info.version >= 0x300) @@ -976,7 +976,7 @@ grub_video_vbe_iterate (int (*hook) (const struct grub_video_mode_info *info, vo 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_type, grub_video_mode_type_t mode_mask) { grub_uint16_t *p; @@ -1193,7 +1193,7 @@ grub_video_vbe_print_adapter_specific_info (void) 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)); diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c index 01f47112d..50d0b5e02 100644 --- a/grub-core/video/i386/pc/vga.c +++ b/grub-core/video/i386/pc/vga.c @@ -48,7 +48,7 @@ static struct int back_page; } framebuffer; -static unsigned char +static unsigned char grub_vga_set_mode (unsigned char mode) { struct grub_bios_int_registers regs; @@ -127,7 +127,7 @@ grub_video_vga_setup (unsigned int width, unsigned int height, vga_height = height ? : 480; - framebuffer.temporary_buffer = grub_malloc (vga_height * VGA_WIDTH); + framebuffer.temporary_buffer = grub_calloc (vga_height, VGA_WIDTH); framebuffer.front_page = 0; framebuffer.back_page = 0; if (!framebuffer.temporary_buffer) @@ -182,10 +182,10 @@ grub_video_vga_setup (unsigned int width, unsigned int height, 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); diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c index 17a3dbbb5..ca3d3c3b2 100644 --- a/grub-core/video/ieee1275.c +++ b/grub-core/video/ieee1275.c @@ -93,10 +93,9 @@ grub_video_ieee1275_init (void) grub_memset (&framebuffer, 0, sizeof(framebuffer)); - if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS) - && !grub_ieee1275_get_integer_property (grub_ieee1275_chosen, - "stdout", &stdout_ihandle, - sizeof (stdout_ihandle), &actual) + if (!grub_ieee1275_get_integer_property (grub_ieee1275_chosen, + "stdout", &stdout_ihandle, + sizeof (stdout_ihandle), &actual) && actual == sizeof (stdout_ihandle)) have_setcolors = 1; @@ -234,7 +233,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int 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) { @@ -261,7 +260,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, grub_video_ieee1275_set_palette (0, framebuffer.mode_info.number_of_colors, grub_video_fbstd_colors); - + return err; } diff --git a/grub-core/video/radeon_fuloong2e.c b/grub-core/video/radeon_fuloong2e.c index b4da34b5e..f1b4c591b 100644 --- a/grub-core/video/radeon_fuloong2e.c +++ b/grub-core/video/radeon_fuloong2e.c @@ -72,10 +72,10 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + 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); @@ -139,7 +139,7 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, framebuffer.mapped = 1; /* Prevent garbage from appearing on the screen. */ - grub_memset (framebuffer.ptr, 0x55, + grub_memset (framebuffer.ptr, 0x55, framebuffer.mode_info.height * framebuffer.mode_info.pitch); #ifndef TEST @@ -152,7 +152,7 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, return err; err = grub_video_fb_set_active_render_target (framebuffer.render_target); - + if (err) return err; diff --git a/grub-core/video/radeon_yeeloong3a.c b/grub-core/video/radeon_yeeloong3a.c index 52614feb6..61b70ef26 100644 --- a/grub-core/video/radeon_yeeloong3a.c +++ b/grub-core/video/radeon_yeeloong3a.c @@ -71,10 +71,10 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_DISPLAY_VGA || pciid != 0x96151002) return 0; - + *found = 1; addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); @@ -137,7 +137,7 @@ grub_video_radeon_yeeloong3a_setup (unsigned int width, unsigned int height, #endif /* Prevent garbage from appearing on the screen. */ - grub_memset (framebuffer.ptr, 0, + grub_memset (framebuffer.ptr, 0, framebuffer.mode_info.height * framebuffer.mode_info.pitch); #ifndef TEST @@ -150,7 +150,7 @@ grub_video_radeon_yeeloong3a_setup (unsigned int width, unsigned int height, return err; err = grub_video_fb_set_active_render_target (framebuffer.render_target); - + if (err) return err; diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c index 31359a4c9..631a89356 100644 --- a/grub-core/video/readers/jpeg.c +++ b/grub-core/video/readers/jpeg.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -109,9 +110,17 @@ static grub_uint8_t grub_jpeg_get_byte (struct grub_jpeg_data *data) { grub_uint8_t r; + grub_ssize_t bytes_read; r = 0; - grub_file_read (data->file, &r, 1); + bytes_read = grub_file_read (data->file, &r, 1); + + if (bytes_read != 1) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: unexpected end of data"); + return 0; + } return r; } @@ -120,9 +129,17 @@ static grub_uint16_t grub_jpeg_get_word (struct grub_jpeg_data *data) { grub_uint16_t r; + grub_ssize_t bytes_read; r = 0; - grub_file_read (data->file, &r, sizeof (grub_uint16_t)); + bytes_read = grub_file_read (data->file, &r, sizeof (grub_uint16_t)); + + if (bytes_read != sizeof (grub_uint16_t)) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: unexpected end of data"); + return 0; + } return grub_be_to_cpu16 (r); } @@ -135,6 +152,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data) if (data->bit_mask == 0) { data->bit_save = grub_jpeg_get_byte (data); + if (grub_errno != GRUB_ERR_NONE) { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: file read error"); + return 0; + } if (data->bit_save == JPEG_ESC_CHAR) { if (grub_jpeg_get_byte (data) != 0) @@ -143,6 +165,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data) "jpeg: invalid 0xFF in data stream"); return 0; } + if (grub_errno != GRUB_ERR_NONE) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: file read error"); + return 0; + } } data->bit_mask = 0x80; } @@ -161,7 +188,7 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num) return 0; msb = value = grub_jpeg_get_bit (data); - for (i = 1; i < num; i++) + for (i = 1; i < num && grub_errno == GRUB_ERR_NONE; i++) value = (value << 1) + (grub_jpeg_get_bit (data) != 0); if (!msb) value += 1 - (1 << num); @@ -199,9 +226,17 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); + if (next_marker > data->file->size) + { + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: invalid huffman table"); + } + while (data->file->offset + sizeof (count) + 1 <= next_marker) { id = grub_jpeg_get_byte (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; ac = (id >> 4) & 1; id &= 0xF; if (id > 1) @@ -217,6 +252,9 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) n += count[i]; id += ac * 2; + if (data->huff_value[id] != NULL) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: attempt to reallocate huffman table"); data->huff_value[id] = grub_malloc (n); if (grub_errno) return grub_errno; @@ -252,11 +290,21 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + if (next_marker > data->file->size) + { + /* Should never be set beyond the size of the file. */ + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid next reference"); + } while (data->file->offset + sizeof (data->quan_table[id]) + 1 <= next_marker) { id = grub_jpeg_get_byte (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if (id >= 0x10) /* Upper 4-bit is precision. */ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: only 8-bit precision is supported"); @@ -288,6 +336,13 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + if (data->image_height != 0 || data->image_width != 0) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: cannot have duplicate SOF0 markers"); + if (grub_jpeg_get_byte (data) != 8) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: only 8-bit precision is supported"); @@ -295,7 +350,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) data->image_height = grub_jpeg_get_word (data); data->image_width = grub_jpeg_get_word (data); - if ((!data->image_height) || (!data->image_width)) + grub_dprintf ("jpeg", "image height: %d\n", data->image_height); + grub_dprintf ("jpeg", "image width: %d\n", data->image_width); + + if ((!data->image_height) || (!data->image_width) || + (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX)) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size"); cc = grub_jpeg_get_byte (data); @@ -313,6 +372,8 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); ss = grub_jpeg_get_byte (data); /* Sampling factor. */ + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if (!id) { grub_uint8_t vs, hs; @@ -327,7 +388,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) else if (ss != JPEG_SAMPLING_1x1) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: sampling method not supported"); + data->comp_index[id][0] = grub_jpeg_get_byte (data); + if (data->comp_index[id][0] > 1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: too many quantization tables"); } if (data->file->offset != next_marker) @@ -488,7 +553,7 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du) } } -static void +static grub_err_t grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) { int h1, h2, qt; @@ -503,6 +568,9 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) data->dc_value[id] += grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1)); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + du[0] = data->dc_value[id] * (int) data->quan_table[qt][0]; pos = 1; while (pos < ARRAY_SIZE (data->quan_table[qt])) @@ -516,11 +584,22 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) val = grub_jpeg_get_number (data, num & 0xF); num >>= 4; pos += num; + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + if (pos >= ARRAY_SIZE (jpeg_zigzag_order)) + { + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: invalid position in zigzag order!?"); + } + du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; pos++; } grub_jpeg_idct_transform (du); + return GRUB_ERR_NONE; } static void @@ -579,7 +658,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) data_offset += grub_jpeg_get_word (data); cc = grub_jpeg_get_byte (data); - + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if (cc != 3 && cc != 1) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: component count must be 1 or 3"); @@ -592,18 +672,29 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) id = grub_jpeg_get_byte (data) - 1; if ((id < 0) || (id >= 3)) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); - + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; ht = grub_jpeg_get_byte (data); data->comp_index[id][1] = (ht >> 4); data->comp_index[id][2] = (ht & 0xF) + 2; + + if ((data->comp_index[id][1] < 0) || (data->comp_index[id][1] > 3) || + (data->comp_index[id][2] < 0) || (data->comp_index[id][2] > 3)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid hufftable index"); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; } grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */ grub_jpeg_get_word (data); - + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if (data->file->offset != data_offset) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos"); + if (*data->bitmap) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: too many start of scan blocks"); + if (grub_video_bitmap_create (data->bitmap, data->image_width, data->image_height, GRUB_VIDEO_BLIT_FORMAT_RGB_888)) @@ -617,15 +708,27 @@ static grub_err_t grub_jpeg_decode_data (struct grub_jpeg_data *data) { unsigned c1, vb, hb, nr1, nc1; + unsigned stride_a, stride_b, stride; int rst = data->dri; + grub_err_t err = GRUB_ERR_NONE; vb = 8 << data->log_vs; hb = 8 << data->log_hs; nr1 = (data->image_height + vb - 1) >> (3 + data->log_vs); nc1 = (data->image_width + hb - 1) >> (3 + data->log_hs); + if (data->bitmap_ptr == NULL) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: attempted to decode data before start of stream"); + + if (grub_mul(vb, data->image_width, &stride_a) || + grub_mul(hb, nc1, &stride_b) || + grub_sub(stride_a, stride_b, &stride)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: cannot decode image with these dimensions"); + for (; data->r1 < nr1 && (!data->dri || rst); - data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) + data->r1++, data->bitmap_ptr += stride * 3) for (c1 = 0; c1 < nc1 && (!data->dri || rst); c1++, rst--, data->bitmap_ptr += hb * 3) { @@ -634,17 +737,22 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) for (r2 = 0; r2 < (1U << data->log_vs); r2++) for (c2 = 0; c2 < (1U << data->log_hs); c2++) - grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]); + { + err = grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]); + if (err != GRUB_ERR_NONE) + return err; + } if (data->color_components >= 3) { - grub_jpeg_decode_du (data, 1, data->cbdu); - grub_jpeg_decode_du (data, 2, data->crdu); + err = grub_jpeg_decode_du (data, 1, data->cbdu); + if (err != GRUB_ERR_NONE) + return err; + err = grub_jpeg_decode_du (data, 2, data->crdu); + if (err != GRUB_ERR_NONE) + return err; } - if (grub_errno) - return grub_errno; - nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb; nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb; diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c index 777e71334..aa7524b7d 100644 --- a/grub-core/video/readers/png.c +++ b/grub-core/video/readers/png.c @@ -23,6 +23,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -99,7 +100,7 @@ struct grub_png_data unsigned image_width, image_height; int bpp, is_16bit; - int raw_bytes, is_gray, is_alpha, is_palette; + int raw_bytes, is_alpha, is_palette; int row_bytes, color_bits; grub_uint8_t *image_data; @@ -141,6 +142,7 @@ static grub_uint8_t grub_png_get_byte (struct grub_png_data *data) { grub_uint8_t r; + grub_ssize_t bytes_read = 0; if ((data->inside_idat) && (data->idat_remain == 0)) { @@ -174,7 +176,14 @@ grub_png_get_byte (struct grub_png_data *data) } r = 0; - grub_file_read (data->file, &r, 1); + bytes_read = grub_file_read (data->file, &r, 1); + + if (bytes_read != 1) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: unexpected end of data"); + return 0; + } if (data->inside_idat) data->idat_remain--; @@ -230,15 +239,16 @@ grub_png_decode_image_palette (struct grub_png_data *data, if (len == 0) return GRUB_ERR_NONE; - for (i = 0; 3 * i < len && i < 256; i++) + grub_errno = GRUB_ERR_NONE; + for (i = 0; 3 * i < len && i < 256 && grub_errno == GRUB_ERR_NONE; i++) for (j = 0; j < 3; j++) data->palette[i][j] = grub_png_get_byte (data); - for (i *= 3; i < len; i++) + for (i *= 3; i < len && grub_errno == GRUB_ERR_NONE; i++) grub_png_get_byte (data); grub_png_get_dword (data); - return GRUB_ERR_NONE; + return grub_errno; } static grub_err_t @@ -248,16 +258,27 @@ grub_png_decode_image_header (struct grub_png_data *data) int color_bits; enum grub_video_blit_format blt; + if (data->image_width || data->image_height) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: two image headers found"); + data->image_width = grub_png_get_dword (data); data->image_height = grub_png_get_dword (data); - if ((!data->image_height) || (!data->image_width)) + grub_dprintf ("png", "image height: %d\n", data->image_height); + grub_dprintf ("png", "image width: %d\n", data->image_width); + + if ((!data->image_height) || (!data->image_width) || + (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX)) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size"); color_bits = grub_png_get_byte (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; data->is_16bit = (color_bits == 16); color_type = grub_png_get_byte (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; /* According to PNG spec, no other types are valid. */ if ((color_type & ~(PNG_COLOR_MASK_ALPHA | PNG_COLOR_MASK_COLOR)) @@ -279,13 +300,13 @@ grub_png_decode_image_header (struct grub_png_data *data) data->bpp = 3; else { - data->is_gray = 1; - data->bpp = 1; + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: color type not supported"); } if ((color_bits != 8) && (color_bits != 16) && (color_bits != 4 - || !(data->is_gray || data->is_palette))) + || !data->is_palette)) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: bit depth must be 8 or 16"); @@ -301,15 +322,23 @@ grub_png_decode_image_header (struct grub_png_data *data) data->bpp <<= 1; data->color_bits = color_bits; - data->row_bytes = data->image_width * data->bpp; + + if (grub_mul (data->image_width, data->bpp, &data->row_bytes)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + if (data->color_bits <= 4) - data->row_bytes = (data->image_width * data->color_bits + 7) / 8; + { + if (grub_mul (data->image_width, data->color_bits + 7, &data->row_bytes)) + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + + data->row_bytes >>= 3; + } #ifndef GRUB_CPU_WORDS_BIGENDIAN - if (data->is_16bit || data->is_gray || data->is_palette) + if (data->is_16bit || data->is_palette) #endif { - data->image_data = grub_malloc (data->image_height * data->row_bytes); + data->image_data = grub_calloc (data->image_height, data->row_bytes); if (grub_errno) return grub_errno; @@ -331,14 +360,20 @@ grub_png_decode_image_header (struct grub_png_data *data) if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: compression method not supported"); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: filter method not supported"); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if (grub_png_get_byte (data) != PNG_INTERLACE_NONE) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: interlace method not supported"); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; /* Skip crc checksum. */ grub_png_get_dword (data); @@ -407,6 +442,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len) for (i = len; i < ht->max_length; i++) n += ht->maxval[i]; + if (n > ht->num_values) + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: out of range inserting huffman table item"); + return; + } + for (i = 0; i < n; i++) ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1]; @@ -440,7 +482,7 @@ grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht) int code, i; code = 0; - for (i = 0; i < ht->max_length; i++) + for (i = 0; i < ht->max_length && grub_errno == GRUB_ERR_NONE; i++) { code = (code << 1) + grub_png_get_bits (data, 1); if (code < ht->maxval[i]) @@ -495,8 +537,14 @@ grub_png_init_dynamic_block (struct grub_png_data *data) grub_uint8_t lens[DEFLATE_HCLEN_MAX]; nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) || (nb > DEFLATE_HCLEN_MAX)) @@ -524,7 +572,7 @@ grub_png_init_dynamic_block (struct grub_png_data *data) data->dist_offset); prev = 0; - for (i = 0; i < nl + nd; i++) + for (i = 0; i < nl + nd && grub_errno == GRUB_ERR_NONE; i++) { int n, code; struct huff_table *ht; @@ -578,7 +626,7 @@ static grub_err_t grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n) { if (--data->raw_bytes < 0) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflown"); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflow"); if (data->cur_column == 0) { @@ -709,20 +757,30 @@ grub_png_read_dynamic_block (struct grub_png_data *data) int len, dist, pos; n -= 257; + if (((unsigned int) n) >= ARRAY_SIZE (cplens)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: invalid huff code"); len = cplens[n]; if (cplext[n]) len += grub_png_get_bits (data, cplext[n]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; n = grub_png_get_huff_code (data, &data->dist_table); + if (((unsigned int) n) >= ARRAY_SIZE (cpdist)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "png: invalid huff code"); dist = cpdist[n]; if (cpdext[n]) dist += grub_png_get_bits (data, cpdext[n]); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; pos = data->wp - dist; if (pos < 0) pos += WSIZE; - while (len > 0) + while (len > 0 && grub_errno == GRUB_ERR_NONE) { data->slide[data->wp] = data->slide[pos]; grub_png_output_byte (data, data->slide[data->wp]); @@ -750,7 +808,11 @@ grub_png_decode_image_data (struct grub_png_data *data) int final; cmf = grub_png_get_byte (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; flg = grub_png_get_byte (data); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; if ((cmf & 0xF) != Z_DEFLATED) return grub_error (GRUB_ERR_BAD_FILE_TYPE, @@ -765,7 +827,11 @@ grub_png_decode_image_data (struct grub_png_data *data) int block_type; final = grub_png_get_bits (data, 1); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; block_type = grub_png_get_bits (data, 2); + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; switch (block_type) { @@ -781,7 +847,7 @@ grub_png_decode_image_data (struct grub_png_data *data) grub_png_get_byte (data); grub_png_get_byte (data); - for (i = 0; i < len; i++) + for (i = 0; i < len && grub_errno == GRUB_ERR_NONE; i++) grub_png_output_byte (data, grub_png_get_byte (data)); break; @@ -850,27 +916,8 @@ grub_png_convert_image (struct grub_png_data *data) int shift; int mask = (1 << data->color_bits) - 1; unsigned j; - if (data->is_gray) - { - /* Generic formula is - (0xff * i) / ((1U << data->color_bits) - 1) - but for allowed bit depth of 1, 2 and for it's - equivalent to - (0xff / ((1U << data->color_bits) - 1)) * i - Precompute the multipliers to avoid division. - */ - const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 }; - for (i = 0; i < (1U << data->color_bits); i++) - { - grub_uint8_t col = multipliers[data->color_bits] * i; - palette[i][0] = col; - palette[i][1] = col; - palette[i][2] = col; - } - } - else - grub_memcpy (palette, data->palette, 3 << data->color_bits); + grub_memcpy (palette, data->palette, 3 << data->color_bits); d1c = d1; d2c = d2; for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3, @@ -907,60 +954,6 @@ grub_png_convert_image (struct grub_png_data *data) } return; } - - if (data->is_gray) - { - switch (data->bpp) - { - case 4: - /* 16-bit gray with alpha. */ - for (i = 0; i < (data->image_width * data->image_height); - i++, d1 += 4, d2 += 4) - { - d1[R4] = d2[3]; - d1[G4] = d2[3]; - d1[B4] = d2[3]; - d1[A4] = d2[1]; - } - break; - case 2: - if (data->is_16bit) - /* 16-bit gray without alpha. */ - { - for (i = 0; i < (data->image_width * data->image_height); - i++, d1 += 4, d2 += 2) - { - d1[R3] = d2[1]; - d1[G3] = d2[1]; - d1[B3] = d2[1]; - } - } - else - /* 8-bit gray with alpha. */ - { - for (i = 0; i < (data->image_width * data->image_height); - i++, d1 += 4, d2 += 2) - { - d1[R4] = d2[1]; - d1[G4] = d2[1]; - d1[B4] = d2[1]; - d1[A4] = d2[0]; - } - } - break; - /* 8-bit gray without alpha. */ - case 1: - for (i = 0; i < (data->image_width * data->image_height); - i++, d1 += 3, d2++) - { - d1[R3] = d2[0]; - d1[G3] = d2[0]; - d1[B3] = d2[0]; - } - break; - } - return; - } { /* Only copy the upper 8 bit. */ @@ -1036,6 +1029,8 @@ grub_png_decode_png (struct grub_png_data *data) len = grub_png_get_dword (data); type = grub_png_get_dword (data); + if (grub_errno != GRUB_ERR_NONE) + break; data->next_offset = data->file->offset + len + 4; switch (type) diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c index 7cb9d1d2a..9c35bf29d 100644 --- a/grub-core/video/readers/tga.c +++ b/grub-core/video/readers/tga.c @@ -127,7 +127,7 @@ tga_load_palette (struct tga_data *data) 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; @@ -340,6 +340,13 @@ grub_video_reader_tga (struct grub_video_bitmap **bitmap, 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) { diff --git a/grub-core/video/sis315_init.c b/grub-core/video/sis315_init.c index ae5c1419c..09c3c7bbe 100644 --- a/grub-core/video/sis315_init.c +++ b/grub-core/video/sis315_init.c @@ -1,4 +1,4 @@ -static const struct { grub_uint8_t reg; grub_uint8_t val; } sr_dump [] = +static const struct { grub_uint8_t reg; grub_uint8_t val; } sr_dump [] = { { 0x28, 0x81 }, { 0x2a, 0x00 }, diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c index 22a0c85a6..ad3bb4dc7 100644 --- a/grub-core/video/sis315pro.c +++ b/grub-core/video/sis315pro.c @@ -100,10 +100,10 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + 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); @@ -218,7 +218,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, #ifndef TEST /* Prevent garbage from appearing on the screen. */ - grub_memset (framebuffer.ptr, 0, + grub_memset (framebuffer.ptr, 0, framebuffer.mode_info.height * framebuffer.mode_info.pitch); grub_arch_sync_dma_caches (framebuffer.ptr, framebuffer.mode_info.height @@ -231,7 +231,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, | 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_COLOR, GRUB_VGA_IO_MISC_WRITE + GRUB_MACHINE_PCI_IO_BASE); grub_vga_sr_write (0x86, 5); @@ -335,7 +335,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, { 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); diff --git a/grub-core/video/sm712.c b/grub-core/video/sm712.c index 10c46eb65..e8967308d 100644 --- a/grub-core/video/sm712.c +++ b/grub-core/video/sm712.c @@ -167,7 +167,7 @@ enum 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_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, @@ -372,10 +372,10 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); - if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA + 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); @@ -471,7 +471,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, #if !defined (TEST) && !defined(GENINIT) /* Prevent garbage from appearing on the screen. */ - grub_memset ((void *) framebuffer.cached_ptr, 0, + grub_memset ((void *) framebuffer.cached_ptr, 0, framebuffer.mode_info.height * framebuffer.mode_info.pitch); #endif @@ -482,7 +482,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, 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_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 @@ -694,7 +694,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, 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); diff --git a/grub-core/video/video.c b/grub-core/video/video.c index 983424107..8937da745 100644 --- a/grub-core/video/video.c +++ b/grub-core/video/video.c @@ -491,13 +491,13 @@ parse_modespec (const char *current_mode, int *width, int *height, int *depth) current_mode); param++; - + *width = grub_strtoul (value, 0, 0); if (grub_errno != GRUB_ERR_NONE) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid video mode specification `%s'"), current_mode); - + /* Find height value. */ value = param; param = grub_strchr(param, 'x'); @@ -513,13 +513,13 @@ parse_modespec (const char *current_mode, int *width, int *height, int *depth) { /* We have optional color depth value. */ param++; - + *height = grub_strtoul (value, 0, 0); if (grub_errno != GRUB_ERR_NONE) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid video mode specification `%s'"), current_mode); - + /* Convert color depth value. */ value = param; *depth = grub_strtoul (value, 0, 0); diff --git a/include/grub/acpi.h b/include/grub/acpi.h index 84f49487d..1046f22d7 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -81,6 +81,7 @@ struct grub_acpi_fadt #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; @@ -112,7 +113,7 @@ struct grub_acpi_madt_entry_lapic grub_uint8_t acpiid; grub_uint8_t apicid; grub_uint32_t flags; -}; +} GRUB_PACKED; struct grub_acpi_madt_entry_ioapic { @@ -121,7 +122,7 @@ struct grub_acpi_madt_entry_ioapic grub_uint8_t pad; grub_uint32_t address; grub_uint32_t global_sys_interrupt; -}; +} GRUB_PACKED; struct grub_acpi_madt_entry_interrupt_override { @@ -148,7 +149,7 @@ struct grub_acpi_madt_entry_sapic grub_uint8_t pad; grub_uint32_t global_sys_interrupt_base; grub_uint64_t addr; -}; +} GRUB_PACKED; struct grub_acpi_madt_entry_lsapic { @@ -160,7 +161,7 @@ struct grub_acpi_madt_entry_lsapic 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 { @@ -172,13 +173,65 @@ struct grub_acpi_madt_entry_platform_int_source 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); @@ -244,4 +297,7 @@ enum 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/arc/arc.h b/include/grub/arc/arc.h index 999de7196..6d14b9748 100644 --- a/include/grub/arc/arc.h +++ b/include/grub/arc/arc.h @@ -184,7 +184,7 @@ struct grub_arc_firmware_vector 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; @@ -227,7 +227,7 @@ struct grub_arc_firmware_vector void *setfileinformation; void *flushallcaches; void *testunicodecharacter; - + /* 0x90. */ struct grub_arc_display_status * (*getdisplaystatus) (grub_arc_fileno_t fileno); }; diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h index 2e98a6689..5b8fb14e0 100644 --- a/include/grub/arm/linux.h +++ b/include/grub/arm/linux.h @@ -22,22 +22,7 @@ #include "system.h" -#define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818 - -struct linux_arm_kernel_header { - grub_uint32_t code0; - grub_uint32_t reserved1[8]; - grub_uint32_t magic; - grub_uint32_t start; /* _start */ - grub_uint32_t end; /* _edata */ - grub_uint32_t reserved2[4]; - grub_uint32_t hdr_offset; -}; - -#if defined(__arm__) -# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE -# define linux_arch_kernel_header linux_arm_kernel_header -#endif +#include #if defined GRUB_MACHINE_UBOOT # include diff --git a/include/grub/arm/system.h b/include/grub/arm/system.h index f62c18c13..f15ce9751 100644 --- a/include/grub/arm/system.h +++ b/include/grub/arm/system.h @@ -1,6 +1,7 @@ #ifndef GRUB_SYSTEM_CPU_HEADER #define GRUB_SYSTEM_CPU_HEADER +#include #include enum diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h deleted file mode 100644 index 4269adc6d..000000000 --- a/include/grub/arm64/linux.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_ARM64_LINUX_HEADER -#define GRUB_ARM64_LINUX_HEADER 1 - -#define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */ - -/* From linux/Documentation/arm64/booting.txt */ -struct linux_arm64_kernel_header -{ - grub_uint32_t code0; /* Executable code */ - grub_uint32_t code1; /* Executable code */ - grub_uint64_t text_offset; /* Image load offset */ - grub_uint64_t res0; /* reserved */ - grub_uint64_t res1; /* reserved */ - grub_uint64_t res2; /* reserved */ - grub_uint64_t res3; /* reserved */ - grub_uint64_t res4; /* reserved */ - grub_uint32_t magic; /* Magic number, little endian, "ARM\x64" */ - grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ -}; - -#if defined(__aarch64__) -# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE -# define linux_arch_kernel_header linux_arm64_kernel_header -#endif - -#endif /* ! GRUB_ARM64_LINUX_HEADER */ diff --git a/include/grub/auth.h b/include/grub/auth.h index 747334451..21d5190f0 100644 --- a/include/grub/auth.h +++ b/include/grub/auth.h @@ -33,5 +33,6 @@ 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/bitmap.h b/include/grub/bitmap.h index 5728f8ca3..431048936 100644 --- a/include/grub/bitmap.h +++ b/include/grub/bitmap.h @@ -23,6 +23,9 @@ #include #include #include +#include + +#define IMAGE_HW_MAX_PX 16384 struct grub_video_bitmap { @@ -79,6 +82,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) 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)); \ +}) + 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 927a7cba5..7230bc91f 100644 --- a/include/grub/bitmap_scale.h +++ b/include/grub/bitmap_scale.h @@ -65,7 +65,7 @@ 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); diff --git a/include/grub/buffer.h b/include/grub/buffer.h new file mode 100644 index 000000000..bb5e3cd92 --- /dev/null +++ b/include/grub/buffer.h @@ -0,0 +1,144 @@ +/* + * 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/charset.h b/include/grub/charset.h index d14faea32..31a3b52dd 100644 --- a/include/grub/charset.h +++ b/include/grub/charset.h @@ -49,7 +49,7 @@ #define GRUB_UTF16_LOWER_SURROGATE(code) \ (0xDC00 | (((code) - GRUB_UCS2_LIMIT) & 0x3ff)) -/* Process one character from UTF8 sequence. +/* 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 @@ -317,7 +317,7 @@ 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, +grub_unicode_get_comb_start (const grub_uint32_t *str, const grub_uint32_t *cur); #endif diff --git a/include/grub/command.h b/include/grub/command.h index eee4e847e..2a6f7f846 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -86,6 +86,11 @@ 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 diff --git a/include/grub/compiler-rt-emu.h b/include/grub/compiler-rt-emu.h index b21425d9e..fde620ac1 100644 --- a/include/grub/compiler-rt-emu.h +++ b/include/grub/compiler-rt-emu.h @@ -74,6 +74,11 @@ 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); diff --git a/include/grub/compiler-rt.h b/include/grub/compiler-rt.h index 7591980b4..17828b322 100644 --- a/include/grub/compiler-rt.h +++ b/include/grub/compiler-rt.h @@ -115,7 +115,7 @@ int EXPORT_FUNC (__clzsi2) (grub_uint32_t val); #endif -#if defined(__riscv) || defined(__sparc__) +#if defined(__mips__) || defined(__riscv) || defined(__sparc__) int EXPORT_FUNC (__clzdi2) (grub_uint64_t val); #endif diff --git a/include/grub/compiler.h b/include/grub/compiler.h index c9e1d7a73..0c5519387 100644 --- a/include/grub/compiler.h +++ b/include/grub/compiler.h @@ -30,10 +30,10 @@ /* Does this compiler support compile-time error attributes? */ #if GNUC_PREREQ(4,3) -# define ATTRIBUTE_ERROR(msg) \ +# define GRUB_ATTRIBUTE_ERROR(msg) \ __attribute__ ((__error__ (msg))) #else -# define ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn)) +# define GRUB_ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn)) #endif #if GNUC_PREREQ(4,4) @@ -48,4 +48,12 @@ # 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/crypto.h b/include/grub/crypto.h index a24e89dd9..31c87c302 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -28,7 +28,7 @@ #include #include -typedef enum +typedef enum { GPG_ERR_NO_ERROR, GPG_ERR_BAD_MPI, @@ -56,7 +56,6 @@ 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, @@ -73,7 +72,7 @@ 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 +enum gcry_cipher_modes { GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */ GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */ @@ -327,13 +326,13 @@ gcry_err_code_t grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher, void *out, const 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; diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 32f564ae0..81e631778 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -20,6 +20,7 @@ #define GRUB_CRYPTODISK_HEADER 1 #include +#include #include #include #ifdef GRUB_UTIL @@ -48,11 +49,20 @@ typedef enum #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; @@ -60,14 +70,49 @@ 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; - grub_disk_addr_t offset; - grub_disk_addr_t total_length; + /* + * 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; @@ -106,9 +151,8 @@ struct grub_cryptodisk_dev struct grub_cryptodisk_dev *next; struct grub_cryptodisk_dev **prev; - grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid, - int boot_only); - grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev); + 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; @@ -130,13 +174,16 @@ grub_cryptodisk_dev_unregister (grub_cryptodisk_dev_t 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_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); @@ -156,4 +203,8 @@ grub_util_get_geli_uuid (const char *dev); 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/datetime.h b/include/grub/datetime.h index fef281404..bcec636f0 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -48,21 +48,21 @@ grub_err_t grub_set_datetime (struct grub_datetime *datetime); int grub_get_weekday (struct grub_datetime *datetime); const char *grub_get_weekday_name (struct grub_datetime *datetime); -void grub_unixtime2datetime (grub_int32_t nix, +void grub_unixtime2datetime (grub_int64_t nix, struct grub_datetime *datetime); static inline int -grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) +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, 31 + 28, 31 + 28 + 31, 31 + 28 + 31 + 30, - 31 + 28 + 31 + 30 + 31, + 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, diff --git a/include/grub/disk.h b/include/grub/disk.h index 316659fee..fbf23df7f 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -27,6 +27,8 @@ #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. */ @@ -58,7 +60,7 @@ struct grub_disk_memberlist; #endif typedef enum - { + { GRUB_DISK_PULL_NONE, GRUB_DISK_PULL_REMOVABLE, GRUB_DISK_PULL_RESCAN, @@ -108,9 +110,9 @@ extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list); struct grub_partition; -typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector, - unsigned offset, unsigned length, - void *data); +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 @@ -161,9 +163,26 @@ 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 @@ -171,9 +190,45 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; #define GRUB_DISK_MAX_MAX_AGGLOMERATE ((1 << (30 - GRUB_DISK_CACHE_BITS - GRUB_DISK_SECTOR_BITS)) - 1) -/* Return value of grub_disk_get_size() in case disk size is unknown. */ +/* 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); +} + /* This is called from the memory manager. */ void grub_disk_cache_invalidate_all (void); @@ -212,7 +267,7 @@ extern grub_err_t (*EXPORT_VAR(grub_disk_write_weak)) (grub_disk_t disk, const void *buf); -grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk); +grub_uint64_t EXPORT_FUNC(grub_disk_native_sectors) (grub_disk_t disk); #if DISK_CACHE_STATS void diff --git a/include/grub/diskfilter.h b/include/grub/diskfilter.h index 8deb1a8c3..f020d025b 100644 --- a/include/grub/diskfilter.h +++ b/include/grub/diskfilter.h @@ -103,12 +103,12 @@ struct grub_diskfilter_lv { struct grub_diskfilter_segment { grub_uint64_t start_extent; grub_uint64_t extent_count; - enum + enum { GRUB_DISKFILTER_STRIPED = 0, GRUB_DISKFILTER_MIRROR = 1, GRUB_DISKFILTER_RAID4 = 4, - GRUB_DISKFILTER_RAID5 = 5, + GRUB_DISKFILTER_RAID5 = 5, GRUB_DISKFILTER_RAID6 = 6, GRUB_DISKFILTER_RAID10 = 10, } type; diff --git a/include/grub/dl.h b/include/grub/dl.h index f03c03561..84509c5c1 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -98,7 +98,7 @@ grub_mod_fini (void) #endif #else #ifdef __APPLE__ -#define GRUB_MOD_SECTION(x) _ ## x , _ ##x +#define GRUB_MOD_SECTION(x) _ ## x , _ ##x #else #define GRUB_MOD_SECTION(x) . ## x #endif @@ -119,7 +119,7 @@ grub_mod_fini (void) #define ATTRIBUTE_USED __unused__ #endif #define GRUB_MOD_LICENSE(license) \ - static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "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 @@ -174,7 +174,7 @@ typedef struct grub_dl_dep *grub_dl_dep_t; struct grub_dl { char *name; - int ref_count; + grub_uint64_t ref_count; int persistent; grub_dl_dep_t dep; grub_dl_segment_t segment; @@ -203,9 +203,10 @@ 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); -void grub_dl_unload_unneeded (void); -int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); -int EXPORT_FUNC(grub_dl_unref) (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 @@ -299,6 +300,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, #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 diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index addcbfa8f..b686e8afe 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -149,6 +149,11 @@ { 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 } \ @@ -284,11 +289,21 @@ { 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 } \ @@ -314,24 +329,59 @@ { 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 } \ + { 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 } \ + { 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 } \ + { 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 } \ + { 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 @@ -406,7 +456,7 @@ struct grub_efi_sal_system_table_translation_register_descriptor struct grub_efi_sal_system_table_purge_translation_coherence { grub_uint8_t type; - grub_uint8_t reserved[3]; + grub_uint8_t reserved[3]; grub_uint32_t ndomains; grub_uint64_t coherence; }; @@ -511,9 +561,13 @@ 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 grub_int8_t grub_efi_int8_t; typedef grub_uint8_t grub_efi_uint8_t; @@ -521,12 +575,28 @@ 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_intn_t grub_efi_status_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 #define GRUB_EFI_ERROR_CODE(value) \ ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) @@ -579,24 +649,6 @@ 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; - -struct grub_efi_packed_guid -{ - grub_uint32_t data1; - grub_uint16_t data2; - grub_uint16_t data3; - grub_uint8_t data4[8]; -} GRUB_PACKED; -typedef struct grub_efi_packed_guid grub_efi_packed_guid_t; - /* XXX although the spec does not specify the padding, this actually must have the padding! */ struct grub_efi_memory_descriptor @@ -625,6 +677,7 @@ 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) /* The End of Device Path nodes. */ #define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f) @@ -633,13 +686,16 @@ 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_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_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))) #define GRUB_EFI_NEXT_DEVICE_PATH(dp) \ - ((grub_efi_device_path_t *) ((char *) (dp) \ - + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) + (GRUB_EFI_DEVICE_PATH_VALID (dp) \ + ? ((grub_efi_device_path_t *) \ + ((char *) (dp) + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) \ + : NULL) /* Hardware Device Path. */ #define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1 @@ -679,7 +735,7 @@ 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_efi_packed_guid_t vendor_guid; + grub_packed_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; @@ -879,6 +935,15 @@ struct grub_efi_sata_device_path } 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 /* Media Device Path. */ @@ -914,7 +979,7 @@ 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_efi_packed_guid_t vendor_guid; + grub_packed_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; @@ -933,7 +998,7 @@ 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_efi_packed_guid_t guid; + grub_packed_guid_t guid; } GRUB_PACKED; typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t; @@ -942,7 +1007,7 @@ 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_efi_packed_guid_t guid; + grub_packed_guid_t guid; } GRUB_PACKED; typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t; @@ -1004,8 +1069,8 @@ 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; + 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; @@ -1054,209 +1119,210 @@ struct grub_efi_boot_services grub_efi_table_header_t hdr; grub_efi_tpl_t - (*raise_tpl) (grub_efi_tpl_t new_tpl); + (__grub_efi_api *raise_tpl) (grub_efi_tpl_t new_tpl); void - (*restore_tpl) (grub_efi_tpl_t old_tpl); + (__grub_efi_api *restore_tpl) (grub_efi_tpl_t old_tpl); grub_efi_status_t - (*allocate_pages) (grub_efi_allocate_type_t type, - grub_efi_memory_type_t memory_type, - grub_efi_uintn_t pages, - grub_efi_physical_address_t *memory); + (__grub_efi_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); grub_efi_status_t - (*free_pages) (grub_efi_physical_address_t memory, - grub_efi_uintn_t pages); + (__grub_efi_api *free_pages) (grub_efi_physical_address_t memory, + grub_efi_uintn_t pages); grub_efi_status_t - (*get_memory_map) (grub_efi_uintn_t *memory_map_size, - grub_efi_memory_descriptor_t *memory_map, - grub_efi_uintn_t *map_key, - grub_efi_uintn_t *descriptor_size, - grub_efi_uint32_t *descriptor_version); + (__grub_efi_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); grub_efi_status_t - (*allocate_pool) (grub_efi_memory_type_t pool_type, - grub_efi_uintn_t size, - void **buffer); + (__grub_efi_api *allocate_pool) (grub_efi_memory_type_t pool_type, + grub_efi_uintn_t size, + void **buffer); grub_efi_status_t - (*free_pool) (void *buffer); + (__grub_efi_api *free_pool) (void *buffer); grub_efi_status_t - (*create_event) (grub_efi_uint32_t type, - grub_efi_tpl_t notify_tpl, - void (*notify_function) (grub_efi_event_t event, - void *context), - void *notify_context, - grub_efi_event_t *event); + (__grub_efi_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); grub_efi_status_t - (*set_timer) (grub_efi_event_t event, - grub_efi_timer_delay_t type, - grub_efi_uint64_t trigger_time); - - grub_efi_status_t - (*wait_for_event) (grub_efi_uintn_t num_events, - grub_efi_event_t *event, - grub_efi_uintn_t *index); + (__grub_efi_api *set_timer) (grub_efi_event_t event, + grub_efi_timer_delay_t type, + grub_efi_uint64_t trigger_time); grub_efi_status_t - (*signal_event) (grub_efi_event_t event); + (__grub_efi_api *wait_for_event) (grub_efi_uintn_t num_events, + grub_efi_event_t *event, + grub_efi_uintn_t *index); grub_efi_status_t - (*close_event) (grub_efi_event_t event); + (__grub_efi_api *signal_event) (grub_efi_event_t event); grub_efi_status_t - (*check_event) (grub_efi_event_t event); - - grub_efi_status_t - (*install_protocol_interface) (grub_efi_handle_t *handle, - grub_efi_guid_t *protocol, - grub_efi_interface_type_t protocol_interface_type, - void *protocol_interface); + (__grub_efi_api *close_event) (grub_efi_event_t event); grub_efi_status_t - (*reinstall_protocol_interface) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, - void *old_interface, - void *new_interface); + (__grub_efi_api *check_event) (grub_efi_event_t event); grub_efi_status_t - (*uninstall_protocol_interface) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, - void *protocol_interface); + (__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); grub_efi_status_t - (*handle_protocol) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, - void **protocol_interface); + (__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); void *reserved; grub_efi_status_t - (*register_protocol_notify) (grub_efi_guid_t *protocol, - grub_efi_event_t event, - void **registration); + (__grub_efi_api *register_protocol_notify) (grub_guid_t *protocol, + grub_efi_event_t event, + void **registration); grub_efi_status_t - (*locate_handle) (grub_efi_locate_search_type_t search_type, - grub_efi_guid_t *protocol, - void *search_key, - grub_efi_uintn_t *buffer_size, - grub_efi_handle_t *buffer); + (__grub_efi_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); grub_efi_status_t - (*locate_device_path) (grub_efi_guid_t *protocol, - grub_efi_device_path_t **device_path, - grub_efi_handle_t *device); + (__grub_efi_api *locate_device_path) (grub_guid_t *protocol, + grub_efi_device_path_t **device_path, + grub_efi_handle_t *device); grub_efi_status_t - (*install_configuration_table) (grub_efi_guid_t *guid, void *table); + (__grub_efi_api *install_configuration_table) (grub_guid_t *guid, + void *table); grub_efi_status_t - (*load_image) (grub_efi_boolean_t boot_policy, - grub_efi_handle_t parent_image_handle, - grub_efi_device_path_t *file_path, - void *source_buffer, - grub_efi_uintn_t source_size, - grub_efi_handle_t *image_handle); + (__grub_efi_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); grub_efi_status_t - (*start_image) (grub_efi_handle_t image_handle, - grub_efi_uintn_t *exit_data_size, - grub_efi_char16_t **exit_data); + (__grub_efi_api *start_image) (grub_efi_handle_t image_handle, + grub_efi_uintn_t *exit_data_size, + grub_efi_char16_t **exit_data); grub_efi_status_t - (*exit) (grub_efi_handle_t image_handle, - grub_efi_status_t exit_status, - grub_efi_uintn_t exit_data_size, - grub_efi_char16_t *exit_data) __attribute__((noreturn)); + (__grub_efi_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); grub_efi_status_t - (*unload_image) (grub_efi_handle_t image_handle); + (__grub_efi_api *unload_image) (grub_efi_handle_t image_handle); grub_efi_status_t - (*exit_boot_services) (grub_efi_handle_t image_handle, - grub_efi_uintn_t map_key); + (__grub_efi_api *exit_boot_services) (grub_efi_handle_t image_handle, + grub_efi_uintn_t map_key); grub_efi_status_t - (*get_next_monotonic_count) (grub_efi_uint64_t *count); + (__grub_efi_api *get_next_monotonic_count) (grub_efi_uint64_t *count); grub_efi_status_t - (*stall) (grub_efi_uintn_t microseconds); + (__grub_efi_api *stall) (grub_efi_uintn_t microseconds); grub_efi_status_t - (*set_watchdog_timer) (grub_efi_uintn_t timeout, - grub_efi_uint64_t watchdog_code, - grub_efi_uintn_t data_size, - grub_efi_char16_t *watchdog_data); + (__grub_efi_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); grub_efi_status_t - (*connect_controller) (grub_efi_handle_t controller_handle, - grub_efi_handle_t *driver_image_handle, - grub_efi_device_path_protocol_t *remaining_device_path, - grub_efi_boolean_t recursive); + (__grub_efi_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); grub_efi_status_t - (*disconnect_controller) (grub_efi_handle_t controller_handle, - grub_efi_handle_t driver_image_handle, - grub_efi_handle_t child_handle); + (__grub_efi_api *disconnect_controller) (grub_efi_handle_t controller_handle, + grub_efi_handle_t driver_image_handle, + grub_efi_handle_t child_handle); grub_efi_status_t - (*open_protocol) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, - void **protocol_interface, - grub_efi_handle_t agent_handle, - grub_efi_handle_t controller_handle, - grub_efi_uint32_t attributes); + (__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); grub_efi_status_t - (*close_protocol) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, - grub_efi_handle_t agent_handle, - grub_efi_handle_t controller_handle); + (__grub_efi_api *close_protocol) (grub_efi_handle_t handle, + grub_guid_t *protocol, + grub_efi_handle_t agent_handle, + grub_efi_handle_t controller_handle); grub_efi_status_t - (*open_protocol_information) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, - grub_efi_open_protocol_information_entry_t **entry_buffer, - grub_efi_uintn_t *entry_count); + (__grub_efi_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); grub_efi_status_t - (*protocols_per_handle) (grub_efi_handle_t handle, - grub_efi_packed_guid_t ***protocol_buffer, - grub_efi_uintn_t *protocol_buffer_count); + (__grub_efi_api *protocols_per_handle) (grub_efi_handle_t handle, + grub_packed_guid_t ***protocol_buffer, + grub_efi_uintn_t *protocol_buffer_count); grub_efi_status_t - (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type, - grub_efi_guid_t *protocol, - void *search_key, - grub_efi_uintn_t *no_handles, - grub_efi_handle_t **buffer); + (__grub_efi_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); grub_efi_status_t - (*locate_protocol) (grub_efi_guid_t *protocol, - void *registration, - void **protocol_interface); + (__grub_efi_api *locate_protocol) (grub_guid_t *protocol, + void *registration, + void **protocol_interface); grub_efi_status_t - (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...); + (__grub_efi_api *install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...); grub_efi_status_t - (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...); + (__grub_efi_api *uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...); grub_efi_status_t - (*calculate_crc32) (void *data, - grub_efi_uintn_t data_size, - grub_efi_uint32_t *crc32); + (__grub_efi_api *calculate_crc32) (void *data, + grub_efi_uintn_t data_size, + grub_efi_uint32_t *crc32); void - (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length); + (__grub_efi_api *copy_mem) (void *destination, void *source, grub_efi_uintn_t length); void - (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value); + (__grub_efi_api *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; @@ -1265,67 +1331,67 @@ struct grub_efi_runtime_services grub_efi_table_header_t hdr; grub_efi_status_t - (*get_time) (grub_efi_time_t *time, - grub_efi_time_capabilities_t *capabilities); + (__grub_efi_api *get_time) (grub_efi_time_t *time, + grub_efi_time_capabilities_t *capabilities); grub_efi_status_t - (*set_time) (grub_efi_time_t *time); + (__grub_efi_api *set_time) (grub_efi_time_t *time); grub_efi_status_t - (*get_wakeup_time) (grub_efi_boolean_t *enabled, - grub_efi_boolean_t *pending, - grub_efi_time_t *time); + (__grub_efi_api *get_wakeup_time) (grub_efi_boolean_t *enabled, + grub_efi_boolean_t *pending, + grub_efi_time_t *time); grub_efi_status_t - (*set_wakeup_time) (grub_efi_boolean_t enabled, - grub_efi_time_t *time); + (__grub_efi_api *set_wakeup_time) (grub_efi_boolean_t enabled, + grub_efi_time_t *time); grub_efi_status_t - (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size, - grub_efi_uintn_t descriptor_size, - grub_efi_uint32_t descriptor_version, - grub_efi_memory_descriptor_t *virtual_map); + (__grub_efi_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); grub_efi_status_t - (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address); + (__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 }} + { 0x8BE4DF61, 0x93CA, 0x11d2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }} grub_efi_status_t - (*get_variable) (grub_efi_char16_t *variable_name, - const grub_efi_guid_t *vendor_guid, - grub_efi_uint32_t *attributes, - grub_efi_uintn_t *data_size, - void *data); + (__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); grub_efi_status_t - (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size, - grub_efi_char16_t *variable_name, - grub_efi_guid_t *vendor_guid); + (__grub_efi_api *get_next_variable_name) (grub_efi_uintn_t *variable_name_size, + grub_efi_char16_t *variable_name, + grub_guid_t *vendor_guid); grub_efi_status_t - (*set_variable) (grub_efi_char16_t *variable_name, - const grub_efi_guid_t *vendor_guid, - grub_efi_uint32_t attributes, - grub_efi_uintn_t data_size, - void *data); + (__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); grub_efi_status_t - (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count); + (__grub_efi_api *get_next_high_monotonic_count) (grub_efi_uint32_t *high_count); void - (*reset_system) (grub_efi_reset_type_t reset_type, - grub_efi_status_t reset_status, - grub_efi_uintn_t data_size, - grub_efi_char16_t *reset_data); + (__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); }; typedef struct grub_efi_runtime_services grub_efi_runtime_services_t; struct grub_efi_configuration_table { - grub_efi_packed_guid_t vendor_guid; + grub_packed_guid_t vendor_guid; void *vendor_table; } GRUB_PACKED; typedef struct grub_efi_configuration_table grub_efi_configuration_table_t; @@ -1337,33 +1403,42 @@ struct grub_efi_serial_io_interface { grub_efi_uint32_t revision; void (*reset) (void); - grub_efi_status_t (*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 (*set_control_bits) (struct grub_efi_serial_io_interface *this, - grub_efi_uint32_t flags); - void (*get_control_bits) (void); - grub_efi_status_t (*write) (struct grub_efi_serial_io_interface *this, - grub_efi_uintn_t *buf_size, - void *buffer); - grub_efi_status_t (*read) (struct grub_efi_serial_io_interface *this, - grub_efi_uintn_t *buf_size, - void *buffer); + + 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 - (*reset) (struct grub_efi_simple_input_interface *this, - grub_efi_boolean_t extended_verification); + (__grub_efi_api *reset) (struct grub_efi_simple_input_interface *this, + grub_efi_boolean_t extended_verification); grub_efi_status_t - (*read_key_stroke) (struct grub_efi_simple_input_interface *this, - grub_efi_input_key_t *key); + (__grub_efi_api *read_key_stroke) (struct grub_efi_simple_input_interface *this, + grub_efi_input_key_t *key); grub_efi_event_t wait_for_key; }; @@ -1375,76 +1450,77 @@ struct grub_efi_key_data { }; typedef struct grub_efi_key_data grub_efi_key_data_t; -typedef grub_efi_status_t (*grub_efi_key_notify_function_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 - (*reset) (struct grub_efi_simple_text_input_ex_interface *this, - grub_efi_boolean_t extended_verification); + 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 - (*read_key_stroke) (struct grub_efi_simple_text_input_ex_interface *this, - grub_efi_key_data_t *key_data); + 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_event_t wait_for_key; - grub_efi_status_t - (*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 *set_state) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_key_toggle_state_t *key_toggle_state); - grub_efi_status_t - (*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); + 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 - (*unregister_key_notify) (struct grub_efi_simple_text_input_ex_interface *this, - void *notification_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 - (*reset) (struct grub_efi_simple_text_output_interface *this, - grub_efi_boolean_t extended_verification); + (__grub_efi_api *reset) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t extended_verification); grub_efi_status_t - (*output_string) (struct grub_efi_simple_text_output_interface *this, - grub_efi_char16_t *string); + (__grub_efi_api *output_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); grub_efi_status_t - (*test_string) (struct grub_efi_simple_text_output_interface *this, - grub_efi_char16_t *string); + (__grub_efi_api *test_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); grub_efi_status_t - (*query_mode) (struct grub_efi_simple_text_output_interface *this, - grub_efi_uintn_t mode_number, - grub_efi_uintn_t *columns, - grub_efi_uintn_t *rows); + (__grub_efi_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); grub_efi_status_t - (*set_mode) (struct grub_efi_simple_text_output_interface *this, - grub_efi_uintn_t mode_number); + (__grub_efi_api *set_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number); grub_efi_status_t - (*set_attributes) (struct grub_efi_simple_text_output_interface *this, - grub_efi_uintn_t attribute); + (__grub_efi_api *set_attributes) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t attribute); grub_efi_status_t - (*clear_screen) (struct grub_efi_simple_text_output_interface *this); + (__grub_efi_api *clear_screen) (struct grub_efi_simple_text_output_interface *this); grub_efi_status_t - (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this, - grub_efi_uintn_t column, - grub_efi_uintn_t row); + (__grub_efi_api *set_cursor_position) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t column, + grub_efi_uintn_t row); grub_efi_status_t - (*enable_cursor) (struct grub_efi_simple_text_output_interface *this, - grub_efi_boolean_t visible); + (__grub_efi_api *enable_cursor) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t visible); grub_efi_simple_text_output_mode_t *mode; }; @@ -1465,18 +1541,18 @@ typedef struct grub_efi_pxe_mode typedef struct grub_efi_pxe { grub_uint64_t rev; - void (*start) (void); - void (*stop) (void); - void (*dhcp) (void); - void (*discover) (void); - void (*mftp) (void); - void (*udpwrite) (void); - void (*udpread) (void); - void (*setipfilter) (void); - void (*arp) (void); - void (*setparams) (void); - void (*setstationip) (void); - void (*setpackets) (void); + 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; @@ -1545,23 +1621,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 (*unload) (grub_efi_handle_t image_handle); + grub_efi_status_t (__grub_efi_api *unload) (grub_efi_handle_t image_handle); }; typedef struct grub_efi_loaded_image grub_efi_loaded_image_t; struct grub_efi_disk_io { grub_efi_uint64_t revision; - grub_efi_status_t (*read) (struct grub_efi_disk_io *this, - grub_efi_uint32_t media_id, - grub_efi_uint64_t offset, - grub_efi_uintn_t buffer_size, - void *buffer); - grub_efi_status_t (*write) (struct grub_efi_disk_io *this, - grub_efi_uint32_t media_id, - grub_efi_uint64_t offset, - grub_efi_uintn_t buffer_size, - void *buffer); + 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); }; typedef struct grub_efi_disk_io grub_efi_disk_io_t; @@ -1625,41 +1701,60 @@ enum struct grub_efi_simple_network { grub_uint64_t revision; - grub_efi_status_t (*start) (struct grub_efi_simple_network *this); - grub_efi_status_t (*stop) (struct grub_efi_simple_network *this); - grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this, - grub_efi_uintn_t extra_rx, - grub_efi_uintn_t extra_tx); - void (*reset) (void); - grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this); - grub_efi_status_t (*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 (*station_address) (void); - void (*statistics) (void); - void (*mcastiptomac) (void); - void (*nvdata) (void); - grub_efi_status_t (*get_status) (struct grub_efi_simple_network *this, - grub_uint32_t *int_status, - void **txbuf); - grub_efi_status_t (*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 (*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 (*waitforpacket) (void); + + 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; @@ -1669,93 +1764,80 @@ struct grub_efi_block_io { grub_efi_uint64_t revision; grub_efi_block_io_media_t *media; - grub_efi_status_t (*reset) (struct grub_efi_block_io *this, - grub_efi_boolean_t extended_verification); - grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this, - grub_efi_uint32_t media_id, - grub_efi_lba_t lba, - grub_efi_uintn_t buffer_size, - void *buffer); - grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this, - grub_efi_uint32_t media_id, - grub_efi_lba_t lba, - grub_efi_uintn_t buffer_size, - void *buffer); - grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this); + 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); }; typedef struct grub_efi_block_io grub_efi_block_io_t; -#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ - || defined(__riscv) +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; -#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_7(func, a, b, c, d, e, f, g) func(a, b, c, d, e, f, g) -#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) +typedef grub_guid_t grub_efi_rng_algorithm_t; -#else +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; -#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_7(func, a, b, c, d, e, f, g) \ - efi_wrap_7(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)) -#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 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; -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_7) (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 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 +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; #endif /* ! GRUB_EFI_API_HEADER */ diff --git a/include/grub/efi/cc.h b/include/grub/efi/cc.h new file mode 100644 index 000000000..978e0cdfe --- /dev/null +++ b/include/grub/efi/cc.h @@ -0,0 +1,151 @@ +/* + * 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 7c358fcdb..008ac5896 100644 --- a/include/grub/efi/console_control.h +++ b/include/grub/efi/console_control.h @@ -23,6 +23,8 @@ #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 } \ @@ -39,18 +41,18 @@ typedef enum grub_efi_screen_mode grub_efi_screen_mode_t; struct grub_efi_console_control_protocol { grub_efi_status_t - (*get_mode) (struct grub_efi_console_control_protocol *this, - grub_efi_screen_mode_t *mode, - grub_efi_boolean_t *uga_exists, - grub_efi_boolean_t *std_in_locked); + (__grub_efi_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); grub_efi_status_t - (*set_mode) (struct grub_efi_console_control_protocol *this, - grub_efi_screen_mode_t mode); + (__grub_efi_api *set_mode) (struct grub_efi_console_control_protocol *this, + grub_efi_screen_mode_t mode); grub_efi_status_t - (*lock_std_in) (struct grub_efi_console_control_protocol *this, - grub_efi_char16_t *password); + (__grub_efi_api *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 new file mode 100644 index 000000000..c2d2a03b0 --- /dev/null +++ b/include/grub/efi/debug.h @@ -0,0 +1,41 @@ +/* + * 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 index a0140b81c..43c0c4372 100644 --- a/include/grub/efi/edid.h +++ b/include/grub/efi/edid.h @@ -43,7 +43,7 @@ struct grub_efi_edid_override { }; typedef struct grub_efi_edid_override grub_efi_edid_override_t; - + struct grub_efi_active_edid { diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index e90e00dc4..a5cd99e5a 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -23,18 +23,32 @@ #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_efi_guid_t *protocol, +void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_guid_t *protocol, void *registration); grub_efi_handle_t * EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type, - grub_efi_guid_t *protocol, + grub_guid_t *protocol, void *search_key, grub_efi_uintn_t *num_handles); void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, + grub_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 * @@ -74,32 +88,51 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo grub_efi_uintn_t descriptor_size, grub_efi_uint32_t descriptor_version, grub_efi_memory_descriptor_t *virtual_map); -void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable, - const grub_efi_guid_t *guid, - grub_size_t *datasize_out); +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_efi_guid_t *guid, + 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, +extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, char **device, char **path); -#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) +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 *); -#include -grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); +#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); -#endif -grub_addr_t grub_efi_modules_addr (void); +grub_addr_t grub_efi_section_addr (const char *section); void grub_efi_mm_init (void); void grub_efi_mm_fini (void); diff --git a/include/grub/efi/graphics_output.h b/include/grub/efi/graphics_output.h index 129777411..044e786b8 100644 --- a/include/grub/efi/graphics_output.h +++ b/include/grub/efi/graphics_output.h @@ -28,7 +28,8 @@ typedef enum { GRUB_EFI_GOT_RGBA8, GRUB_EFI_GOT_BGRA8, - GRUB_EFI_GOT_BITMASK + GRUB_EFI_GOT_BITMASK, + GRUB_EFI_GOT_BLT_ONLY, } grub_efi_gop_pixel_format_t; @@ -82,26 +83,26 @@ struct grub_efi_gop_mode struct grub_efi_gop; typedef grub_efi_status_t -(*grub_efi_gop_query_mode_t) (struct grub_efi_gop *this, - grub_efi_uint32_t mode_number, - grub_efi_uintn_t *size_of_info, - struct grub_efi_gop_mode_info **info); +(__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); typedef grub_efi_status_t -(*grub_efi_gop_set_mode_t) (struct grub_efi_gop *this, - grub_efi_uint32_t mode_number); +(__grub_efi_api *grub_efi_gop_set_mode_t) (struct grub_efi_gop *this, + grub_efi_uint32_t mode_number); typedef grub_efi_status_t -(*grub_efi_gop_blt_t) (struct grub_efi_gop *this, - void *buffer, - grub_efi_uintn_t operation, - grub_efi_uintn_t sx, - grub_efi_uintn_t sy, - grub_efi_uintn_t dx, - grub_efi_uintn_t dy, - grub_efi_uintn_t width, - grub_efi_uintn_t height, - grub_efi_uintn_t delta); +(__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); struct grub_efi_gop { diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 0ed8781f0..9887e14b2 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -48,6 +48,17 @@ #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 @@ -77,6 +88,8 @@ struct grub_pe32_coff_header #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 @@ -218,6 +231,8 @@ struct grub_pe64_optional_header #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 @@ -254,11 +269,14 @@ struct grub_pe32_section_table #define GRUB_PE32_SIGNATURE_SIZE 4 -struct grub_pe32_header -{ - /* This should be filled in with GRUB_PE32_MSDOS_STUB. */ - grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; +#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 +{ /* This is always PE\0\0. */ char signature[GRUB_PE32_SIGNATURE_SIZE]; @@ -283,22 +301,24 @@ 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_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_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 struct grub_pe32_symbol { diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h new file mode 100644 index 000000000..49a9ad01c --- /dev/null +++ b/include/grub/efi/sb.h @@ -0,0 +1,46 @@ +/* + * 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/include/grub/efi/tpm.h b/include/grub/efi/tpm.h index 3ea6b4de1..6c6802ee5 100644 --- a/include/grub/efi/tpm.h +++ b/include/grub/efi/tpm.h @@ -62,42 +62,42 @@ typedef struct tdTCG_PCR_EVENT TCG_PCR_EVENT; struct grub_efi_tpm_protocol { - grub_efi_status_t (*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 (*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 (*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 (*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 (*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); + 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; @@ -151,46 +151,43 @@ typedef struct tdEFI_TCG2_EVENT EFI_TCG2_EVENT; struct grub_efi_tpm2_protocol { - grub_efi_status_t (*get_capability) (struct grub_efi_tpm2_protocol *this, - EFI_TCG2_BOOT_SERVICE_CAPABILITY * - ProtocolCapability); - grub_efi_status_t (*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 (*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 (*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 (*get_active_pcr_blanks) (struct grub_efi_tpm2_protocol * - this, - grub_efi_uint32_t * - ActivePcrBanks); - grub_efi_status_t (*set_active_pcr_banks) (struct grub_efi_tpm2_protocol * - this, - grub_efi_uint32_t - ActivePcrBanks); - grub_efi_status_t (*get_result_of_set_active_pcr_banks) (struct - grub_efi_tpm2_protocol - *this, - grub_efi_uint32_t * - OperationPresent, - grub_efi_uint32_t * - Response); + 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; diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h index a31f2672e..1ea157a7e 100644 --- a/include/grub/efi/uga_draw.h +++ b/include/grub/efi/uga_draw.h @@ -46,30 +46,30 @@ struct grub_efi_uga_pixel struct grub_efi_uga_draw_protocol { grub_efi_status_t - (*get_mode) (struct grub_efi_uga_draw_protocol *this, - grub_uint32_t *width, - grub_uint32_t *height, - grub_uint32_t *depth, - grub_uint32_t *refresh_rate); + (__grub_efi_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); grub_efi_status_t - (*set_mode) (struct grub_efi_uga_draw_protocol *this, - grub_uint32_t width, - grub_uint32_t height, - grub_uint32_t depth, - grub_uint32_t refresh_rate); + (__grub_efi_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); grub_efi_status_t - (*blt) (struct grub_efi_uga_draw_protocol *this, - struct grub_efi_uga_pixel *blt_buffer, - enum grub_efi_uga_blt_operation blt_operation, - grub_efi_uintn_t src_x, - grub_efi_uintn_t src_y, - grub_efi_uintn_t dest_x, - grub_efi_uintn_t dest_y, - grub_efi_uintn_t width, - grub_efi_uintn_t height, - grub_efi_uintn_t delta); + (__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); }; 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 5325e5839..d6a868e94 100644 --- a/include/grub/efiemu/efiemu.h +++ b/include/grub/efiemu/efiemu.h @@ -176,26 +176,26 @@ grub_err_t grub_efiemu_loadcore_load (void); struct grub_efiemu_configuration_table { struct grub_efiemu_configuration_table *next; - grub_efi_guid_t guid; + grub_guid_t guid; void * (*get_table) (void *data); void (*unload) (void *data); void *data; }; struct grub_efiemu_configuration_table32 { - grub_efi_packed_guid_t vendor_guid; + grub_packed_guid_t vendor_guid; grub_efi_uint32_t vendor_table; } GRUB_PACKED; typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t; struct grub_efiemu_configuration_table64 { - grub_efi_packed_guid_t vendor_guid; + grub_packed_guid_t vendor_guid; grub_efi_uint64_t vendor_table; } GRUB_PACKED; typedef struct grub_efiemu_configuration_table64 grub_efiemu_configuration_table64_t; -grub_err_t grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid); +grub_err_t grub_efiemu_unregister_configuration_table (grub_guid_t guid); grub_err_t -grub_efiemu_register_configuration_table (grub_efi_guid_t guid, +grub_efiemu_register_configuration_table (grub_guid_t guid, void * (*get_table) (void *data), void (*unload) (void *data), void *data); diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h index 36d2dedf4..2ff429845 100644 --- a/include/grub/efiemu/runtime.h +++ b/include/grub/efiemu/runtime.h @@ -29,7 +29,7 @@ struct grub_efiemu_ptv_rel struct efi_variable { - grub_efi_packed_guid_t guid; + grub_packed_guid_t guid; grub_uint32_t namelen; grub_uint32_t size; grub_efi_uint32_t attributes; diff --git a/include/grub/elf.h b/include/grub/elf.h index c478933ee..bd313a70b 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -23,6 +23,7 @@ /* Standard ELF types. */ #include +#include /* Type for a 16-bit quantity. */ typedef grub_uint16_t Elf32_Half; @@ -56,6 +57,9 @@ 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. */ @@ -248,6 +252,7 @@ typedef struct #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 @@ -566,6 +571,7 @@ 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). */ @@ -2531,6 +2537,43 @@ typedef Elf32_Addr Elf32_Conflict; #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 @@ -2548,6 +2591,7 @@ 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) @@ -2557,6 +2601,10 @@ typedef Elf32_Xword Elf_Xword; #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; @@ -2573,14 +2621,19 @@ 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_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_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 diff --git a/include/grub/emu/exec.h b/include/grub/emu/exec.h index d1073ef86..1b61b4a2e 100644 --- a/include/grub/emu/exec.h +++ b/include/grub/emu/exec.h @@ -23,6 +23,8 @@ #include #include +#include + pid_t grub_util_exec_pipe (const char *const *argv, int *fd); pid_t @@ -32,7 +34,7 @@ int grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, const char *stdout_file, const char *stderr_file); int -grub_util_exec (const char *const *argv); +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); diff --git a/include/grub/emu/hostfile.h b/include/grub/emu/hostfile.h index cfb1e2b56..a61568e36 100644 --- a/include/grub/emu/hostfile.h +++ b/include/grub/emu/hostfile.h @@ -22,6 +22,7 @@ #include #include #include +#include #include int @@ -29,7 +30,7 @@ grub_util_is_directory (const char *path); int grub_util_is_special_file (const char *path); int -grub_util_is_regular (const char *path); +EXPORT_FUNC(grub_util_is_regular) (const char *path); char * grub_util_path_concat (size_t n, ...); diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index ce464cfd0..fefbec499 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -31,7 +31,7 @@ #include extern int verbosity; -extern const char *program_name; +extern const char *EXPORT_VAR(program_name); void grub_init_all (void); void grub_fini_all (void); @@ -47,6 +47,7 @@ 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; @@ -56,6 +57,9 @@ void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...) __attribute__ ((format ( 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 @@ -71,4 +75,9 @@ grub_util_fopen (const char *path, const char *mode); 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/env.h b/include/grub/env.h index 76f832eb9..6b9379a30 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -45,6 +45,7 @@ struct grub_env_var 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); void EXPORT_FUNC(grub_env_unset) (const char *name); struct grub_env_var *EXPORT_FUNC(grub_env_update_get_sorted) (void); diff --git a/include/grub/err.h b/include/grub/err.h index 24ba9f5f5..202fa8a7a 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -72,7 +72,10 @@ typedef enum GRUB_ERR_NET_PACKET_TOO_BIG, GRUB_ERR_NET_NO_DOMAIN, GRUB_ERR_EOF, - GRUB_ERR_BAD_SIGNATURE + GRUB_ERR_BAD_SIGNATURE, + GRUB_ERR_BAD_FIRMWARE, + GRUB_ERR_STILL_REFERENCED, + GRUB_ERR_RECURSION_DEPTH } grub_err_t; @@ -85,7 +88,8 @@ struct grub_error_saved extern grub_err_t EXPORT_VAR(grub_errno); extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG]; -grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...); +grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...) + __attribute__ ((format (GNU_PRINTF, 2, 3))); void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_error_push) (void); int EXPORT_FUNC(grub_error_pop) (void); diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h index 19fe59266..fe9248b8b 100644 --- a/include/grub/extcmd.h +++ b/include/grub/extcmd.h @@ -62,6 +62,13 @@ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name, 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, diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h index 4205eb917..78a1ab3b4 100644 --- a/include/grub/fbutil.h +++ b/include/grub/fbutil.h @@ -31,14 +31,19 @@ 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. */ +/* + * 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 + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel; + 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, diff --git a/include/grub/file.h b/include/grub/file.h index 31567483c..a5bf3a792 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -90,6 +90,10 @@ enum grub_file_type 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. */ diff --git a/include/grub/fs.h b/include/grub/fs.h index 302e48d4b..df4c93b16 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -23,6 +23,7 @@ #include #include #include +#include #include /* For embedding types. */ @@ -39,7 +40,7 @@ struct grub_dirhook_info unsigned mtimeset:1; unsigned case_insensitive:1; unsigned inodeset:1; - grub_int32_t mtime; + grub_int64_t mtime; grub_uint64_t inode; }; @@ -57,6 +58,9 @@ struct grub_fs /* 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); @@ -81,7 +85,7 @@ struct grub_fs grub_err_t (*fs_uuid) (grub_device_t device, char **uuid); /* Get writing time of filesystem. */ - grub_err_t (*fs_mtime) (grub_device_t device, grub_int32_t *timebuf); + grub_err_t (*fs_mtime) (grub_device_t device, grub_int64_t *timebuf); #ifdef GRUB_UTIL /* Determine sectors available for embedding. */ diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h index 4203c8fb9..c9e12db82 100644 --- a/include/grub/gfxmenu_view.h +++ b/include/grub/gfxmenu_view.h @@ -55,9 +55,9 @@ 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); diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h index 7a93f4329..292ea03f1 100644 --- a/include/grub/gpt_partition.h +++ b/include/grub/gpt_partition.h @@ -22,15 +22,6 @@ #include #include -struct grub_gpt_part_guid -{ - grub_uint32_t data1; - grub_uint16_t data2; - grub_uint16_t data3; - grub_uint8_t data4[8]; -} GRUB_PACKED; -typedef struct grub_gpt_part_guid grub_gpt_part_guid_t; - #define GRUB_GPT_PARTITION_TYPE_EMPTY \ { 0x0, 0x0, 0x0, \ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \ @@ -70,13 +61,13 @@ struct grub_gpt_header struct grub_gpt_partentry { - grub_gpt_part_guid_t type; - grub_gpt_part_guid_t guid; + grub_guid_t type; + grub_guid_t guid; grub_uint64_t start; grub_uint64_t end; grub_uint64_t attrib; char name[72]; -} GRUB_PACKED; +}; grub_err_t grub_gpt_partition_map_iterate (grub_disk_t disk, diff --git a/include/grub/hfsplus.h b/include/grub/hfsplus.h index 117740ae2..2d8336aff 100644 --- a/include/grub/hfsplus.h +++ b/include/grub/hfsplus.h @@ -113,6 +113,8 @@ struct grub_hfsplus_data 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; @@ -248,7 +250,7 @@ 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, + 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, diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index 524d47a1f..523dd8621 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -97,7 +97,7 @@ grub_err_t grub_netbsd_load_elf_meta64 (struct grub_relocator *relocator, const char *filename, grub_addr_t *kern_end); -grub_err_t grub_bsd_add_meta (grub_uint32_t type, +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, int argc, char **argv, diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index ce30e7fb0..6e0a8e5be 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -19,6 +19,8 @@ #ifndef GRUB_I386_LINUX_HEADER #define GRUB_I386_LINUX_HEADER 1 +#include + #define GRUB_LINUX_I386_MAGIC_SIGNATURE 0x53726448 /* "HdrS" */ #define GRUB_LINUX_DEFAULT_SETUP_SECTS 4 #define GRUB_LINUX_INITRD_MAX_ADDRESS 0x37FFFFFF @@ -49,6 +51,9 @@ /* 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 \ @@ -67,6 +72,16 @@ #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 @@ -75,22 +90,273 @@ #define GRUB_E820_NVS 4 #define GRUB_E820_BADRAM 5 -struct grub_e820_mmap +#define GRUB_E820_MAX_ENTRIES_ZEROPAGE 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 { grub_uint64_t addr; grub_uint64_t size; grub_uint32_t type; } GRUB_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; + +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. */ + 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. */ +/* For the Linux/i386 boot protocol version 2.10. */ struct linux_i386_kernel_header { grub_uint8_t code1[0x0020]; @@ -132,11 +398,11 @@ struct linux_i386_kernel_header 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 initrd_addr_max; /* Highest address for initrd */ grub_uint32_t kernel_alignment; grub_uint8_t relocatable; grub_uint8_t min_alignment; - grub_uint8_t pad[2]; + grub_uint16_t xloadflags; grub_uint32_t cmdline_size; grub_uint32_t hardware_subarch; grub_uint64_t hardware_subarch_data; @@ -148,182 +414,93 @@ struct linux_i386_kernel_header grub_uint32_t handover_offset; } GRUB_PACKED; -/* Boot parameters for Linux based on 2.6.12. This is used by the setup - sectors of Linux, and must be simulated by GRUB on EFI, because - the setup sectors depend on BIOS. */ +/* + * 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. + */ struct linux_kernel_params { - grub_uint8_t video_cursor_x; /* 0 */ - grub_uint8_t video_cursor_y; - - grub_uint16_t ext_mem; /* 2 */ - - grub_uint16_t video_page; /* 4 */ - grub_uint8_t video_mode; /* 6 */ - grub_uint8_t video_width; /* 7 */ - - grub_uint8_t padding1[0xa - 0x8]; - - grub_uint16_t video_ega_bx; /* a */ - - grub_uint8_t padding2[0xe - 0xc]; - - grub_uint8_t video_height; /* e */ - grub_uint8_t have_vga; /* f */ - grub_uint16_t font_size; /* 10 */ - - grub_uint16_t lfb_width; /* 12 */ - grub_uint16_t lfb_height; /* 14 */ - grub_uint16_t lfb_depth; /* 16 */ - grub_uint32_t lfb_base; /* 18 */ - grub_uint32_t lfb_size; /* 1c */ - - grub_uint16_t cl_magic; /* 20 */ - grub_uint16_t cl_offset; - - grub_uint16_t lfb_line_len; /* 24 */ - grub_uint8_t red_mask_size; /* 26 */ - grub_uint8_t red_field_pos; - grub_uint8_t green_mask_size; - grub_uint8_t green_field_pos; - grub_uint8_t blue_mask_size; - grub_uint8_t blue_field_pos; - grub_uint8_t reserved_mask_size; - grub_uint8_t reserved_field_pos; - grub_uint16_t vesapm_segment; /* 2e */ - grub_uint16_t vesapm_offset; /* 30 */ - grub_uint16_t lfb_pages; /* 32 */ - grub_uint16_t vesa_attrib; /* 34 */ - grub_uint32_t capabilities; /* 36 */ - grub_uint32_t ext_lfb_base; /* 3a */ - - grub_uint8_t padding3[0x40 - 0x3e]; - - 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_uint64_t acpi_rsdp_addr; /* 70 */ - - grub_uint8_t padding5[0x80 - 0x78]; - - 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]; + 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 */ + /* + * 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_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; + { + 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; struct - { - grub_uint32_t padding7_1; /* 1b8 */ - grub_uint32_t padding7_2; /* 1bc */ - grub_uint32_t efi_signature; /* 1c0 */ - grub_uint32_t efi_system_table; /* 1c4 */ - grub_uint32_t efi_mem_desc_size; /* 1c8 */ - grub_uint32_t efi_mem_desc_version; /* 1cc */ - grub_uint32_t efi_mmap; /* 1d0 */ - grub_uint32_t efi_mmap_size; /* 1d4 */ + { + grub_uint32_t 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_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 */ - } v0208; - }; + { + 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 alt_mem; /* 1e0 */ - - grub_uint8_t padding8[0x1e8 - 0x1e4]; - - grub_uint8_t mmap_size; /* 1e8 */ - - grub_uint8_t padding9[0x1f1 - 0x1e9]; - - /* Linux setup header copy - BEGIN. */ - 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_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 pad1[3]; - 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; - /* Linux setup header copy - END. */ - - grub_uint8_t _pad7[40]; + 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_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */ + 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; #endif /* ! ASM_FILE */ diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h index 5cb607fb4..c64529630 100644 --- a/include/grub/i386/memory.h +++ b/include/grub/i386/memory.h @@ -20,7 +20,8 @@ #ifndef GRUB_MEMORY_CPU_HEADER #define GRUB_MEMORY_CPU_HEADER 1 -#define PAGE_SHIFT 12 +#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 diff --git a/include/grub/i386/msr.h b/include/grub/i386/msr.h new file mode 100644 index 000000000..1e838c022 --- /dev/null +++ b/include/grub/i386/msr.h @@ -0,0 +1,74 @@ +/* + * 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/openbsd_bootarg.h b/include/grub/i386/openbsd_bootarg.h index 9ebe6b4e4..8c28246d5 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. diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h index f349b5c2b..71e7584eb 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -188,14 +188,14 @@ struct grub_vbe_flat_panel_info /* Prototypes for helper functions. */ /* Call VESA BIOS 0x4f00 to get VBE Controller Information, return status. */ -grub_vbe_status_t +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_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_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 @@ -205,13 +205,13 @@ 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_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_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_status_t grub_vbe_bios_get_display_start (grub_uint32_t *x, grub_uint32_t *y); @@ -224,7 +224,7 @@ grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block); 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_status_t grub_vbe_bios_get_pm_interface (grub_uint16_t *seg, grub_uint16_t *offset, grub_uint16_t *length); diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h index 947e62fa1..3c96d3e0b 100644 --- a/include/grub/i386/tsc.h +++ b/include/grub/i386/tsc.h @@ -47,6 +47,11 @@ grub_get_tsc (void) /* 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); return (((grub_uint64_t) hi) << 32) | lo; } diff --git a/include/grub/ieee1275/alloc.h b/include/grub/ieee1275/alloc.h new file mode 100644 index 000000000..67a785657 --- /dev/null +++ b/include/grub/ieee1275/alloc.h @@ -0,0 +1,39 @@ +/* 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/console.h b/include/grub/ieee1275/console.h index bdd98fe06..a8094d381 100644 --- a/include/grub/ieee1275/console.h +++ b/include/grub/ieee1275/console.h @@ -28,7 +28,7 @@ void grub_console_init_lately (void); /* Finish the console system. */ void grub_console_fini (void); -const char * +struct grub_serial_port * grub_ofserial_add_port (const char *name); #endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 73e2f4644..c445d0499 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -24,6 +24,9 @@ #include #include +#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0) +#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1) + struct grub_ieee1275_mem_region { unsigned int start; @@ -57,6 +60,7 @@ 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 @@ -85,14 +89,6 @@ extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu); extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *) GRUB_IEEE1275_ENTRY_FN_ATTRIBUTE; -/* Static heap, used only if FORCE_CLAIM is set, - happens on Open Hack'Ware. Should be in platform-specific - header but is used only on PPC anyway. -*/ -#define GRUB_IEEE1275_STATIC_HEAP_START 0x1000000 -#define GRUB_IEEE1275_STATIC_HEAP_LEN 0x1000000 - - enum grub_ieee1275_flag { /* Old World Macintosh firmware fails seek when "dev:0" is opened. */ @@ -113,25 +109,13 @@ enum grub_ieee1275_flag /* OLPC / XO firmware hangs when accessing USB devices. */ GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY, - /* Open Hack'Ware stops when trying to set colors */ - GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS, - - /* Open Hack'Ware stops when grub_ieee1275_interpret is used. */ - GRUB_IEEE1275_FLAG_CANNOT_INTERPRET, - - /* Open Hack'Ware has no memory map, just claim what we need. */ - GRUB_IEEE1275_FLAG_FORCE_CLAIM, - - /* Open Hack'Ware don't support the ANSI sequence. */ - GRUB_IEEE1275_FLAG_NO_ANSI, - /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM, /* OLPC / XO firmware has the cursor ON/OFF routines. */ GRUB_IEEE1275_FLAG_HAS_CURSORONOFF, - /* Some PowerMacs claim to use 2 address cells but in fact use only 1. + /* 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. */ @@ -148,6 +132,20 @@ enum grub_ieee1275_flag 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, }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/include/grub/ieee1275/tpm.h b/include/grub/ieee1275/tpm.h new file mode 100644 index 000000000..fe5cb4713 --- /dev/null +++ b/include/grub/ieee1275/tpm.h @@ -0,0 +1,30 @@ +/* + * 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 133a37c8d..6121c1e66 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -29,7 +29,9 @@ enum OBJ_TYPE_CONFIG, OBJ_TYPE_PREFIX, OBJ_TYPE_PUBKEY, - OBJ_TYPE_DTB + OBJ_TYPE_DTB, + OBJ_TYPE_DISABLE_SHIM_LOCK, + OBJ_TYPE_DISABLE_CLI }; /* The module header. */ diff --git a/include/grub/key_protector.h b/include/grub/key_protector.h new file mode 100644 index 000000000..00b15c13d --- /dev/null +++ b/include/grub/key_protector.h @@ -0,0 +1,47 @@ +/* + * 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/linux.h b/include/grub/linux.h index 594a3f307..a96ac2048 100644 --- a/include/grub/linux.h +++ b/include/grub/linux.h @@ -21,4 +21,4 @@ grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx); grub_err_t grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, - char *argv[], void *target); + void *target); diff --git a/include/grub/list.h b/include/grub/list.h index b13acb962..21f4b4b44 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -40,7 +40,7 @@ void EXPORT_FUNC(grub_list_remove) (grub_list_t item); static inline void * grub_bad_type_cast_real (int line, const char *file) - ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); + GRUB_ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); static inline void * grub_bad_type_cast_real (int line, const char *file) diff --git a/include/grub/loader.h b/include/grub/loader.h index 7f82a499f..97f231054 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -33,12 +33,18 @@ 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); + /* Unset current loader, if any. */ void EXPORT_FUNC (grub_loader_unset) (void); diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h new file mode 100644 index 000000000..40531fa82 --- /dev/null +++ b/include/grub/lockdown.h @@ -0,0 +1,44 @@ +/* + * 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_LOCKDOWN_H +#define GRUB_LOCKDOWN_H 1 + +#include + +#define GRUB_LOCKDOWN_DISABLED 0 +#define GRUB_LOCKDOWN_ENABLED 1 + +#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) +{ +} + +static inline int +grub_is_lockdown (void) +{ + return GRUB_LOCKDOWN_DISABLED; +} +#endif +#endif /* ! GRUB_LOCKDOWN_H */ diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h new file mode 100644 index 000000000..d460267be --- /dev/null +++ b/include/grub/loongarch64/efi/memory.h @@ -0,0 +1,24 @@ +/* + * 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 new file mode 100644 index 000000000..8ba355385 --- /dev/null +++ b/include/grub/loongarch64/reloc.h @@ -0,0 +1,113 @@ +/* + * 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 new file mode 100644 index 000000000..f9a14d4cf --- /dev/null +++ b/include/grub/loongarch64/setjmp.h @@ -0,0 +1,27 @@ +/* + * 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/i386/wrmsr.h b/include/grub/loongarch64/time.h similarity index 61% rename from include/grub/i386/wrmsr.h rename to include/grub/loongarch64/time.h index dea60aed1..eefcd2788 100644 --- a/include/grub/i386/wrmsr.h +++ b/include/grub/loongarch64/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2019 Free Software Foundation, Inc. + * 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 @@ -16,20 +16,13 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_WRMSR_H -#define GRUB_WRMSR_H 1 - -/* - * TODO: Add a general protection exception handler. - * Accessing a reserved or unimplemented MSR address results in a GP#. - */ +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 static inline void -grub_msr_write(grub_uint32_t msr_id, grub_uint64_t msr_value) +grub_cpu_idle(void) { - grub_uint32_t low = msr_value, high = msr_value >> 32; - - asm volatile ("wrmsr" : : "c" (msr_id), "a" (low), "d" (high)); + asm volatile ("idle 0"); } -#endif /* GRUB_WRMSR_H */ +#endif diff --git a/include/grub/loongarch64/types.h b/include/grub/loongarch64/types.h new file mode 100644 index 000000000..fddf38378 --- /dev/null +++ b/include/grub/loongarch64/types.h @@ -0,0 +1,34 @@ +/* + * 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/menu_viewer.h b/include/grub/menu_viewer.h index c6513c4e8..604c07ad1 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/loongson/serial.h b/include/grub/mips/loongson/serial.h index 45e6d8457..b35455929 100644 --- a/include/grub/mips/loongson/serial.h +++ b/include/grub/mips/loongson/serial.h @@ -30,4 +30,4 @@ #else #endif -#endif +#endif diff --git a/include/grub/mips/qemu_mips/serial.h b/include/grub/mips/qemu_mips/serial.h index 1708678dc..c4d8d6326 100644 --- a/include/grub/mips/qemu_mips/serial.h +++ b/include/grub/mips/qemu_mips/serial.h @@ -21,4 +21,4 @@ #define GRUB_MACHINE_SERIAL_PORTS { 0xb40003f8 } -#endif +#endif diff --git a/include/grub/misc.h b/include/grub/misc.h index ee48eb7a7..e087e7b3e 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -28,10 +28,10 @@ #include #define ALIGN_UP(addr, align) \ - ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1)) + (((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)) #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } @@ -64,6 +64,45 @@ grub_stpcpy (char *dest, const char *src) return d - 1; } +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) @@ -232,7 +271,8 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) while (*s1 && *s2 && --n) { - if (grub_tolower (*s1) != grub_tolower (*s2)) + if (grub_tolower ((grub_uint8_t) *s1) + != grub_tolower ((grub_uint8_t) *s2)) break; s1++; @@ -243,11 +283,59 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) - (int) grub_tolower ((grub_uint8_t) *s2); } -unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); -unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); +/* + * 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); static inline long -grub_strtol (const char *str, char **end, int base) +grub_strtol (const char * restrict str, const char ** const restrict end, int base) { int negative = 0; unsigned long long magnitude; @@ -286,8 +374,6 @@ 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; 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; -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))); /* Replace all `ch' characters of `input' with `with' and copy the result into `output'; return EOS address of `output'. */ @@ -322,10 +408,13 @@ 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))); 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))); @@ -334,11 +423,17 @@ int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, 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; + void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, grub_uint64_t d, grub_uint64_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))) @@ -404,10 +499,6 @@ void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); void grub_reboot (void) __attribute__ ((noreturn)); #endif -#if defined (__clang__) && !defined (GRUB_UTIL) -void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void); -#endif - #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. */ @@ -440,6 +531,22 @@ grub_error_load (const struct grub_error_saved *save) 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 { @@ -463,4 +570,9 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file, #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 28e2e53eb..51ec0b8f9 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -20,6 +20,7 @@ #ifndef GRUB_MM_H #define GRUB_MM_H 1 +#include #include #include #include @@ -28,7 +29,25 @@ # 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); @@ -37,6 +56,40 @@ void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); 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__); @@ -45,8 +98,11 @@ void grub_mm_check_real (const char *file, int line); /* Set this variable to 1 when you want to trace all memory function calls. */ extern int EXPORT_VAR(grub_mm_debug); -void grub_mm_dump_free (void); -void grub_mm_dump (unsigned lineno); +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) #define grub_malloc(size) \ grub_debug_malloc (GRUB_FILE, __LINE__, size) @@ -63,6 +119,8 @@ void grub_mm_dump (unsigned lineno); #define grub_free(ptr) \ grub_debug_free (GRUB_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 index c2c4cb151..96c2d816b 100644 --- a/include/grub/mm_private.h +++ b/include/grub/mm_private.h @@ -20,16 +20,29 @@ #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 @@ -48,12 +61,37 @@ typedef struct grub_mm_header #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; @@ -61,4 +99,17 @@ typedef struct grub_mm_region 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/multiboot.h b/include/grub/multiboot.h index bd0a9873e..d8847f753 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -74,7 +74,7 @@ grub_err_t grub_multiboot_set_video_mode (void); #endif #define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT 1 -#define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER 2 +#define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER 2 grub_err_t grub_multiboot_set_console (int console_type, int accepted_consoles, diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h index 502d34ef1..b90aa6989 100644 --- a/include/grub/multiboot2.h +++ b/include/grub/multiboot2.h @@ -66,7 +66,7 @@ grub_err_t grub_multiboot2_set_video_mode (void); #endif #define GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT 1 -#define GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER 2 +#define GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER 2 grub_err_t grub_multiboot2_set_console (int console_type, int accepted_consoles, diff --git a/include/grub/net.h b/include/grub/net.h index 4a9069a14..58a4f83fc 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -35,12 +35,12 @@ enum 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_TCP_RESERVE_SIZE = GRUB_NET_TCP_HEADER_SIZE + GRUB_NET_OUR_IPV4_HEADER_SIZE + GRUB_NET_MAX_LINK_HEADER_SIZE }; -typedef enum grub_link_level_protocol_id +typedef enum grub_link_level_protocol_id { GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET } grub_link_level_protocol_id_t; @@ -64,7 +64,8 @@ typedef enum grub_net_interface_flags typedef enum grub_net_card_flags { GRUB_NET_CARD_HWADDRESS_IMMUTABLE = 1, - GRUB_NET_CARD_NO_MANUAL_INTERFACES = 2 + 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; @@ -149,7 +150,7 @@ struct grub_net_card struct grub_net_network_level_interface; -typedef enum grub_network_level_protocol_id +typedef enum grub_network_level_protocol_id { GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV, GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4, @@ -182,11 +183,11 @@ typedef struct grub_net_network_level_netaddress { struct { grub_uint32_t base; - int masksize; + int masksize; } ipv4; struct { grub_uint64_t base[2]; - int masksize; + int masksize; } ipv6; }; } grub_net_network_level_netaddress_t; @@ -252,7 +253,7 @@ 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 { struct grub_net_app_protocol *next; struct grub_net_app_protocol **prev; @@ -270,12 +271,14 @@ 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); @@ -454,22 +457,24 @@ struct grub_net_bootp_packet enum { - GRUB_NET_BOOTP_PAD = 0x00, - GRUB_NET_BOOTP_NETMASK = 0x01, - GRUB_NET_BOOTP_ROUTER = 0x03, - GRUB_NET_BOOTP_DNS = 0x06, - GRUB_NET_BOOTP_HOSTNAME = 0x0c, - GRUB_NET_BOOTP_DOMAIN = 0x0f, - GRUB_NET_BOOTP_ROOT_PATH = 0x11, - GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12, + 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_END = 0xff + GRUB_NET_BOOTP_CLIENT_UUID = 97, + GRUB_NET_BOOTP_END = 255 }; struct grub_net_network_level_interface * @@ -510,12 +515,18 @@ grub_net_addr_cmp (const grub_net_network_level_address_t *a, #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); @@ -529,16 +540,7 @@ void grub_bootp_fini (void); void grub_dns_init (void); void grub_dns_fini (void); -static inline void -grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter) -{ - inter->card->num_ifaces--; - *inter->prev = inter->next; - if (inter->next) - inter->next->prev = inter->prev; - inter->next = 0; - inter->prev = 0; -} +void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter); void grub_net_tcp_retransmit (void); @@ -567,6 +569,8 @@ 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; diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index 8d9d08113..8eb211ba8 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -29,4 +29,4 @@ 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 +#endif diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h index 23a935e98..534ee433c 100644 --- a/include/grub/net/ethernet.h +++ b/include/grub/net/ethernet.h @@ -29,13 +29,13 @@ typedef enum GRUB_NET_ETHERTYPE_IP6 = 0x86DD, } grub_net_ethertype_t; -grub_err_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_err_t grub_net_recv_ethernet_packet (struct grub_net_buff *nb, struct grub_net_card *card); -#endif +#endif diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h index ab9d68f98..e21a5eebc 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -58,7 +58,7 @@ grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, struct grub_net_buff *nb, grub_net_ip_protocol_t proto); -grub_err_t +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, @@ -95,4 +95,4 @@ grub_net_icmp6_send_request (struct grub_net_network_level_interface *inf, grub_err_t grub_net_icmp6_send_router_solicit (struct grub_net_network_level_interface *inf); -#endif +#endif diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h index 17f38cfa0..3cd8feb45 100644 --- a/include/grub/net/udp.h +++ b/include/grub/net/udp.h @@ -48,4 +48,4 @@ grub_net_send_udp_packet (const grub_net_udp_socket_t socket, struct grub_net_buff *nb); -#endif +#endif diff --git a/include/grub/ns8250.h b/include/grub/ns8250.h index 7947ba9c9..556c0fa60 100644 --- a/include/grub/ns8250.h +++ b/include/grub/ns8250.h @@ -70,6 +70,19 @@ /* 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 diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h index d1a6af696..77b182acf 100644 --- a/include/grub/ntfs.h +++ b/include/grub/ntfs.h @@ -89,6 +89,30 @@ enum #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 GRUB_NTFS_ATTRIBUTE_HEADER_SIZE 16 + +/* + * 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 + */ + +/* 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 + +/* Offsets for values needed for resident data. */ +#define GRUB_NTFS_ATTRIBUTE_RES_LENGTH 16 +#define GRUB_NTFS_ATTRIBUTE_RES_OFFSET 20 + +/* 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, @@ -134,6 +158,7 @@ struct grub_ntfs_attr grub_uint8_t *attr_cur, *attr_nxt, *attr_end; grub_uint32_t save_pos; grub_uint8_t *sbuf; + grub_uint8_t *end; struct grub_ntfs_file *mft; }; diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 871e1cd4c..442dc31de 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -118,9 +118,9 @@ #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 0x1 -#define GRUB_KERNEL_MIPS_ARC_MOD_ALIGN 0x1 -#define GRUB_KERNEL_MIPS_QEMU_MIPS_MOD_ALIGN 0x1 +#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 diff --git a/include/grub/osdep/hostfile_aros.h b/include/grub/osdep/hostfile_aros.h index a059c0fa4..3c67b7bc4 100644 --- a/include/grub/osdep/hostfile_aros.h +++ b/include/grub/osdep/hostfile_aros.h @@ -68,7 +68,13 @@ grub_util_rename (const char *from, const char *to) return rename (from, to); } -#define grub_util_mkdir(a) mkdir ((a), 0755) +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 { diff --git a/include/grub/osdep/hostfile_unix.h b/include/grub/osdep/hostfile_unix.h index 9ffe46fa3..9e6d647b8 100644 --- a/include/grub/osdep/hostfile_unix.h +++ b/include/grub/osdep/hostfile_unix.h @@ -71,7 +71,13 @@ grub_util_rename (const char *from, const char *to) return rename (from, to); } -#define grub_util_mkdir(a) mkdir ((a), 0755) +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. */ diff --git a/include/grub/osdep/major.h b/include/grub/osdep/major.h new file mode 100644 index 000000000..84a9159af --- /dev/null +++ b/include/grub/osdep/major.h @@ -0,0 +1,33 @@ +/* + * 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/partition.h b/include/grub/partition.h index 7adb7ec6e..c4d71d0ee 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -51,11 +51,14 @@ struct grub_partition_map 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 + /* 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); + grub_disk_addr_t **sectors, + int warn_short); #endif }; typedef struct grub_partition_map *grub_partition_map_t; @@ -84,7 +87,7 @@ struct grub_partition /* The type partition map. */ grub_partition_map_t partmap; - /* The type of partition whne it's on MSDOS. + /* The type of partition when it's on MSDOS. Used for embedding detection. */ grub_uint8_t msdostype; }; diff --git a/include/grub/parttool.h b/include/grub/parttool.h index 4e8f8d5e5..4799a22c5 100644 --- a/include/grub/parttool.h +++ b/include/grub/parttool.h @@ -32,7 +32,7 @@ struct grub_parttool_args int set; union { - int bool; + int b; char *str; }; }; diff --git a/include/grub/pci.h b/include/grub/pci.h index 262c89b74..d4ce92b2d 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -80,8 +80,13 @@ #define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9 #define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 -#define GRUB_PCI_CLASS_SUBCLASS_VGA 0x0300 -#define GRUB_PCI_CLASS_SUBCLASS_USB 0x0c03 + +#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 diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h index 3c7683fad..4eb207018 100644 --- a/include/grub/powerpc/ieee1275/ieee1275.h +++ b/include/grub/powerpc/ieee1275/ieee1275.h @@ -25,4 +25,7 @@ #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/relocator.h b/include/grub/relocator.h index 24d8672d2..bda322057 100644 --- a/include/grub/relocator.h +++ b/include/grub/relocator.h @@ -41,7 +41,7 @@ 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_alloc_chunk_align (struct grub_relocator *rel, grub_relocator_chunk_t *out, grub_phys_addr_t min_addr, grub_phys_addr_t max_addr, @@ -49,6 +49,35 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, 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 diff --git a/include/grub/relocator_private.h b/include/grub/relocator_private.h index 1c563cb64..d8e972e01 100644 --- a/include/grub/relocator_private.h +++ b/include/grub/relocator_private.h @@ -65,19 +65,19 @@ void grub_cpu_relocator_jumper (void *rels, grub_addr_t addr); struct grub_relocator_mmap_event { enum { - IN_REG_START = 0, - IN_REG_END = 1, - REG_BEG_START = 2, + 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_START = 4, REG_FIRMWARE_END = REG_FIRMWARE_START | 1, /* To track the regions already in heap. */ - FIRMWARE_BLOCK_START = 6, + FIRMWARE_BLOCK_START = 6, FIRMWARE_BLOCK_END = FIRMWARE_BLOCK_START | 1, #endif #if GRUB_RELOCATOR_HAVE_LEFTOVERS - REG_LEFTOVER_START = 8, + REG_LEFTOVER_START = 8, REG_LEFTOVER_END = REG_LEFTOVER_START | 1, #endif COLLISION_START = 10, @@ -99,7 +99,7 @@ struct grub_relocator_mmap_event }; }; -/* Return 0 on failure, 1 on success. The failure here +/* 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, diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h deleted file mode 100644 index 512b777c8..000000000 --- a/include/grub/riscv32/linux.h +++ /dev/null @@ -1,41 +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_RISCV32_LINUX_HEADER -#define GRUB_RISCV32_LINUX_HEADER 1 - -#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */ - -/* From linux/Documentation/riscv/booting.txt */ -struct linux_riscv_kernel_header -{ - grub_uint32_t code0; /* Executable code */ - grub_uint32_t code1; /* Executable code */ - grub_uint64_t text_offset; /* Image load offset */ - grub_uint64_t res0; /* reserved */ - grub_uint64_t res1; /* reserved */ - grub_uint64_t res2; /* reserved */ - grub_uint64_t res3; /* reserved */ - grub_uint64_t res4; /* reserved */ - grub_uint32_t magic; /* Magic number, little endian, "RSCV" */ - grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ -}; - -#define linux_arch_kernel_header linux_riscv_kernel_header - -#endif /* ! GRUB_RISCV32_LINUX_HEADER */ diff --git a/include/grub/riscv64/linux.h b/include/grub/riscv64/linux.h deleted file mode 100644 index 3630c30fb..000000000 --- a/include/grub/riscv64/linux.h +++ /dev/null @@ -1,43 +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_RISCV64_LINUX_HEADER -#define GRUB_RISCV64_LINUX_HEADER 1 - -#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */ - -#define GRUB_EFI_PE_MAGIC 0x5A4D - -/* From linux/Documentation/riscv/booting.txt */ -struct linux_riscv_kernel_header -{ - grub_uint32_t code0; /* Executable code */ - grub_uint32_t code1; /* Executable code */ - grub_uint64_t text_offset; /* Image load offset */ - grub_uint64_t res0; /* reserved */ - grub_uint64_t res1; /* reserved */ - grub_uint64_t res2; /* reserved */ - grub_uint64_t res3; /* reserved */ - grub_uint64_t res4; /* reserved */ - grub_uint32_t magic; /* Magic number, little endian, "RSCV" */ - grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ -}; - -#define linux_arch_kernel_header linux_riscv_kernel_header - -#endif /* ! GRUB_RISCV64_LINUX_HEADER */ diff --git a/include/grub/safemath.h b/include/grub/safemath.h new file mode 100644 index 000000000..e032f63a0 --- /dev/null +++ b/include/grub/safemath.h @@ -0,0 +1,54 @@ +/* + * 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 360c2be1f..e5b4d8450 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -318,7 +318,7 @@ 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 *, char const *); +void grub_script_yyerror (struct grub_parser_param *, const char *); /* Commands to execute, don't use these directly. */ grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd); @@ -359,13 +359,10 @@ struct grub_script_function /* The script function. */ struct grub_script *func; - /* The flags. */ - unsigned flags; - /* The next element. */ struct grub_script_function *next; - int references; + unsigned executing; }; typedef struct grub_script_function *grub_script_function_t; diff --git a/include/grub/sdl.h b/include/grub/sdl.h index e4efdc9b1..8f10b8817 100644 --- a/include/grub/sdl.h +++ b/include/grub/sdl.h @@ -15,10 +15,24 @@ * 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_SetColors) (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 d80347df3..3eabaf0cc 100644 --- a/include/grub/search.h +++ b/include/grub/search.h @@ -19,11 +19,22 @@ #ifndef GRUB_SEARCH_HEADER #define GRUB_SEARCH_HEADER 1 -void grub_search_fs_file (const char *key, const char *var, int no_floppy, +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, int no_floppy, +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, int no_floppy, +void grub_search_label (const char *key, const char *var, + enum search_flags flags, char **hints, unsigned nhints); #endif diff --git a/include/grub/serial.h b/include/grub/serial.h index 67379de45..d7e063578 100644 --- a/include/grub/serial.h +++ b/include/grub/serial.h @@ -86,9 +86,22 @@ struct grub_serial_port */ union { + struct + { + bool use_mmio; + union + { #if defined(__mips__) || defined (__i386__) || defined (__x86_64__) - grub_port_t port; + 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; @@ -177,7 +190,12 @@ grub_serial_config_defaults (struct grub_serial_port *port) #if defined(__mips__) || defined (__i386__) || defined (__x86_64__) void grub_ns8250_init (void); -char *grub_serial_ns8250_add_port (grub_port_t port); +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); @@ -189,8 +207,11 @@ grub_efiserial_init (void); #ifdef GRUB_MACHINE_ARC void grub_arcserial_init (void); -const char * -grub_arcserial_add_port (const char *path); +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); @@ -202,4 +223,7 @@ 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 diff --git a/include/grub/smbios.h b/include/grub/smbios.h new file mode 100644 index 000000000..15ec260b3 --- /dev/null +++ b/include/grub/smbios.h @@ -0,0 +1,69 @@ +/* + * 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/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h index 4b18468d8..ccc71aac6 100644 --- a/include/grub/sparc64/ieee1275/ieee1275.h +++ b/include/grub/sparc64/ieee1275/ieee1275.h @@ -25,6 +25,9 @@ #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 */ diff --git a/include/grub/stack_protector.h b/include/grub/stack_protector.h new file mode 100644 index 000000000..e4849b2a0 --- /dev/null +++ b/include/grub/stack_protector.h @@ -0,0 +1,46 @@ +/* + * 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/term.h b/include/grub/term.h index 8117e2a24..7f1a14c84 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -75,9 +75,11 @@ /* 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, + GRUB_TERM_COLOR_STANDARD = 0, /* The user defined colors for normal text. */ GRUB_TERM_COLOR_NORMAL, /* The user defined colors for highlighted text. */ @@ -327,6 +329,8 @@ grub_term_unregister_output (grub_term_output_t term) void 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_getkeystatus) (void); +int EXPORT_FUNC(grub_key_is_interrupt) (int key); void grub_cls (void); void EXPORT_FUNC(grub_refresh) (void); void grub_puts_terminal (const char *str, struct grub_term_output *term); @@ -362,8 +366,8 @@ grub_term_gotoxy (struct grub_term_output *term, struct grub_term_coordinate pos term->gotoxy (term, pos); } -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) @@ -374,20 +378,20 @@ static inline void grub_setcolorstate (grub_term_color_state state) { struct grub_term_output *term; - + FOR_ACTIVE_TERM_OUTPUTS(term) grub_term_setcolorstate (term, state); } /* 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); } -static inline void +static inline void grub_term_cls (struct grub_term_output *term) { if (term->cls) diff --git a/include/grub/time.h b/include/grub/time.h index c919c1f0b..32f0afaf8 100644 --- a/include/grub/time.h +++ b/include/grub/time.h @@ -30,6 +30,8 @@ grub_cpu_idle(void) } #endif +#define NSEC_PER_SEC ((grub_int64_t) 1000000000) + void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms); grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void); diff --git a/include/grub/tpm.h b/include/grub/tpm.h index dfcbe8372..d09783dac 100644 --- a/include/grub/tpm.h +++ b/include/grub/tpm.h @@ -19,6 +19,8 @@ #ifndef GRUB_TPM_HEADER #define GRUB_TPM_HEADER 1 +#include + #define GRUB_STRING_PCR 8 #define GRUB_BINARY_PCR 9 @@ -34,49 +36,14 @@ #define EV_IPL 0x0d -/* TCG_PassThroughToTPM Input Parameter Block. */ -typedef struct -{ - grub_uint16_t IPBLength; - grub_uint16_t Reserved1; - grub_uint16_t OPBLength; - grub_uint16_t Reserved2; - grub_uint8_t TPMOperandIn[1]; -} GRUB_PACKED PassThroughToTPM_InputParamBlock; - -/* TCG_PassThroughToTPM Output Parameter Block. */ -typedef struct -{ - grub_uint16_t OPBLength; - grub_uint16_t Reserved; - grub_uint8_t TPMOperandOut[1]; -} GRUB_PACKED PassThroughToTPM_OutputParamBlock; - -typedef struct -{ - grub_uint16_t tag; - grub_uint32_t paramSize; - grub_uint32_t ordinal; - grub_uint32_t pcrNum; - /* The 160 bit value representing the event to be recorded. */ - grub_uint8_t inDigest[SHA1_DIGEST_SIZE]; -} GRUB_PACKED ExtendIncoming; - -/* TPM_Extend Outgoing Operand. */ -typedef struct -{ - grub_uint16_t tag; - grub_uint32_t paramSize; - grub_uint32_t returnCode; - /* The PCR value after execution of the command. */ - grub_uint8_t outDigest[SHA1_DIGEST_SIZE]; -} GRUB_PACKED ExtendOutgoing; - grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description); -grub_err_t grub_tpm_init (void); -grub_err_t grub_tpm_execute (PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf); -grub_err_t grub_tpm_log_event (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/types.h b/include/grub/types.h index 035a4b528..45079bf65 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -20,6 +20,7 @@ #define GRUB_TYPES_HEADER 1 #include +#include #ifndef GRUB_UTIL #include #endif @@ -72,14 +73,30 @@ # 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 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; @@ -105,6 +122,7 @@ 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" @@ -123,6 +141,7 @@ 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" @@ -151,15 +170,25 @@ typedef grub_int32_t grub_ssize_t; #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)] /* The type for representing a file offset. */ -typedef grub_uint64_t grub_off_t; +typedef grub_uint64_t grub_off_t; +#define PRIxGRUB_OFFSET PRIxGRUB_UINT64_T +#define PRIuGRUB_OFFSET PRIuGRUB_UINT64_T /* The type for representing a disk block address. */ -typedef grub_uint64_t grub_disk_addr_t; +typedef grub_uint64_t grub_disk_addr_t; +#define PRIxGRUB_DISK_ADDR PRIxGRUB_UINT64_T /* Byte-orders. */ static inline grub_uint16_t grub_swap_bytes16(grub_uint16_t _x) @@ -167,8 +196,8 @@ static inline grub_uint16_t grub_swap_bytes16(grub_uint16_t _x) return (grub_uint16_t) ((_x << 8) | (_x >> 8)); } -#define grub_swap_bytes16_compile_time(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) -#define grub_swap_bytes32_compile_time(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000UL) >> 24)) +#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) \ ({ \ grub_uint64_t _x = (x); \ @@ -317,6 +346,46 @@ static inline void grub_set_unaligned64 (void *ptr, grub_uint64_t val) dd->d = val; } -#define GRUB_CHAR_BIT 8 +/* + * 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); \ +}) +#else +# define grub_absolute_pointer(val) ((void *) (val)) +#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/unicode.h b/include/grub/unicode.h index a0403e91f..9360b0b97 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -147,7 +147,9 @@ struct grub_unicode_glyph 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; @@ -293,7 +295,7 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) grub_memcpy (out, in, sizeof (*in)); if (in->ncomb > ARRAY_SIZE (out->combining_inline)) { - out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0])); + out->combining_ptr = grub_calloc (in->ncomb, sizeof (out->combining_ptr[0])); if (!out->combining_ptr) { grub_free (out); @@ -315,7 +317,7 @@ grub_unicode_set_glyph (struct grub_unicode_glyph *out, grub_memcpy (out, in, sizeof (*in)); if (in->ncomb > ARRAY_SIZE (out->combining_inline)) { - out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0])); + 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, @@ -354,7 +356,7 @@ 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, +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 512ae1dd0..0f346af12 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -23,6 +23,10 @@ #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; @@ -130,7 +134,7 @@ struct grub_usb_controller_dev /* Value is calculated/estimated in driver - some TDs should be */ /* reserved for posible concurrent control or "interrupt" transfers */ grub_size_t max_bulk_tds; - + /* The next host controller. */ struct grub_usb_controller_dev *next; }; @@ -167,14 +171,14 @@ struct grub_usb_configuration struct grub_usb_desc_config *descconf; /* Interfaces associated to this configuration. */ - struct grub_usb_interface interf[32]; + 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 { + enum { PORT_STATE_NORMAL = 0, PORT_STATE_WAITING_FOR_STABLE_POWER = 1, PORT_STATE_FAILED_DEVICE = 2, @@ -191,7 +195,7 @@ struct grub_usb_device struct grub_usb_controller controller; /* Device configurations (after opening the device). */ - struct grub_usb_configuration config[8]; + struct grub_usb_configuration config[GRUB_USB_MAX_CONF]; /* Device address. */ int addr; @@ -203,7 +207,7 @@ struct grub_usb_device int initialized; /* Data toggle values (used for bulk transfers only). */ - int toggle[256]; + int toggle[GRUB_USB_MAX_TOGGLE]; /* Used by libusb wrapper. Schedulded for removal. */ void *data; diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index aef482cb9..039ebed65 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -63,7 +63,7 @@ struct grub_usb_transfer struct grub_usb_device *dev; struct grub_usb_transaction *transactions; - + int last_trans; /* Index of last processed transaction in OHCI/UHCI driver. */ diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 2631b1074..5c0a52ca2 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -63,6 +63,12 @@ /* 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 } @@ -103,6 +109,7 @@ enum grub_install_plat 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 @@ -122,7 +129,10 @@ enum grub_install_options { GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, - GRUB_INSTALL_OPTIONS_DTB + 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; @@ -183,7 +193,9 @@ grub_install_generate_image (const char *dir, const char *prefix, char *config_path, const struct grub_install_image_target_desc *image_target, int note, - grub_compression_t comp, const char *dtb_file); + 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); @@ -193,13 +205,13 @@ 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 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 add_rs_codes, int warn_short_mbr_gap); char * grub_install_get_image_targets_string (void); @@ -229,11 +241,11 @@ void grub_install_sgi_setup (const char *install_device, const char *imgfile, const char *destname); -int +int grub_install_compress_gzip (const char *src, const char *dest); -int +int grub_install_compress_lzop (const char *src, const char *dest); -int +int grub_install_compress_xz (const char *src, const char *dest); void @@ -265,4 +277,28 @@ 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 index 573c7ea81..a3acffb88 100644 --- a/include/grub/util/libnvpair.h +++ b/include/grub/util/libnvpair.h @@ -29,9 +29,15 @@ typedef void nvlist_t; -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 *); +#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 */ diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h index ba9f568f6..9d74f82c5 100644 --- a/include/grub/util/mkimage.h +++ b/include/grub/util/mkimage.h @@ -24,6 +24,7 @@ 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; @@ -50,12 +51,12 @@ grub_mkimage_load_image64 (const char *kernel_path, 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 **core_img, size_t *core_size, + 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 **core_img, size_t *core_size, + int note, char *sbat, char **core_img, size_t *core_size, Elf64_Addr target_addr, struct grub_mkimage_layout *layout); diff --git a/include/grub/verify.h b/include/grub/verify.h index ea0491433..672ae1692 100644 --- a/include/grub/verify.h +++ b/include/grub/verify.h @@ -24,6 +24,7 @@ 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. */ @@ -64,7 +65,10 @@ struct grub_file_verifier grub_err_t (*verify_string) (char *str, enum grub_verify_string_type type); }; -extern struct grub_file_verifier *grub_file_verifiers; +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) @@ -78,7 +82,7 @@ grub_verifier_unregister (struct grub_file_verifier *ver) grub_list_remove (GRUB_AS_LIST (ver)); } -grub_err_t -grub_verify_string (char *str, enum grub_verify_string_type type); +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/vgaregs.h b/include/grub/vgaregs.h index 1a666a1f0..0c9e985cf 100644 --- a/include/grub/vgaregs.h +++ b/include/grub/vgaregs.h @@ -50,8 +50,8 @@ 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_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, diff --git a/include/grub/video.h b/include/grub/video.h index 52c3fd71e..9dac0f379 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -413,7 +413,7 @@ 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; + for (p = &grub_video_adapter_list; *p && (*p)->prio > adapter->prio; p = &((*p)->next)); adapter->next = *p; *p = adapter; @@ -497,7 +497,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); diff --git a/include/grub/x86_64/cmos.h b/include/grub/x86_64/cmos.h new file mode 100644 index 000000000..03722f805 --- /dev/null +++ b/include/grub/x86_64/cmos.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/zfs/spa.h b/include/grub/zfs/spa.h index 8dd1fa8e3..5afbe4ecd 100644 --- a/include/grub/zfs/spa.h +++ b/include/grub/zfs/spa.h @@ -44,9 +44,9 @@ * 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), 1ULL << (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), 1ULL << (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) diff --git a/include/grub/zfs/zap_leaf.h b/include/grub/zfs/zap_leaf.h index 95c67dcba..11447c166 100644 --- a/include/grub/zfs/zap_leaf.h +++ b/include/grub/zfs/zap_leaf.h @@ -70,7 +70,6 @@ typedef struct zap_leaf_phys { */ grub_uint16_t l_hash[0]; - grub_properly_aligned_t l_entries[0]; } zap_leaf_phys_t; typedef union zap_leaf_chunk { diff --git a/include/grub/zfs/zio.h b/include/grub/zfs/zio.h index 19ce136bb..997b0c4d4 100644 --- a/include/grub/zfs/zio.h +++ b/include/grub/zfs/zio.h @@ -89,6 +89,7 @@ enum zio_compress { ZIO_COMPRESS_GZIP9, ZIO_COMPRESS_ZLE, ZIO_COMPRESS_LZ4, + ZIO_COMPRESS_ZSTD, ZIO_COMPRESS_FUNCTIONS }; diff --git a/include/multiboot2.h b/include/multiboot2.h index 5693923c0..a039aa043 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -244,7 +244,7 @@ struct multiboot_tag_mmap multiboot_uint32_t size; multiboot_uint32_t entry_size; multiboot_uint32_t entry_version; - struct multiboot_mmap_entry entries[0]; + struct multiboot_mmap_entry entries[0]; }; struct multiboot_vbe_info_block @@ -388,7 +388,7 @@ struct multiboot_tag_efi_mmap multiboot_uint32_t descr_size; multiboot_uint32_t descr_vers; multiboot_uint8_t efi_mmap[0]; -}; +}; struct multiboot_tag_efi32_ih { diff --git a/include/xen/arch-x86/xen-x86_32.h b/include/xen/arch-x86/xen-x86_32.h index 7eca6cd41..9ca33d824 100644 --- a/include/xen/arch-x86/xen-x86_32.h +++ b/include/xen/arch-x86/xen-x86_32.h @@ -1,8 +1,8 @@ /****************************************************************************** * 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 diff --git a/include/xen/arch-x86/xen-x86_64.h b/include/xen/arch-x86/xen-x86_64.h index 5e18613bd..17b438406 100644 --- a/include/xen/arch-x86/xen-x86_64.h +++ b/include/xen/arch-x86/xen-x86_64.h @@ -1,8 +1,8 @@ /****************************************************************************** * 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 diff --git a/include/xen/arch-x86/xen.h b/include/xen/arch-x86/xen.h index 56be26cb6..2ca71fcdd 100644 --- a/include/xen/arch-x86/xen.h +++ b/include/xen/arch-x86/xen.h @@ -1,8 +1,8 @@ /****************************************************************************** * 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 @@ -152,7 +152,7 @@ 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 + * 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 diff --git a/include/xen/io/console.h b/include/xen/io/console.h index e2cd97f77..649601896 100644 --- a/include/xen/io/console.h +++ b/include/xen/io/console.h @@ -1,8 +1,8 @@ /****************************************************************************** * 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 diff --git a/include/xen/io/protocols.h b/include/xen/io/protocols.h index 80b196bc3..d05c40505 100644 --- a/include/xen/io/protocols.h +++ b/include/xen/io/protocols.h @@ -1,6 +1,6 @@ /****************************************************************************** * 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 diff --git a/include/xen/io/ring.h b/include/xen/io/ring.h index 73e13d7ae..91b3092e7 100644 --- a/include/xen/io/ring.h +++ b/include/xen/io/ring.h @@ -1,6 +1,6 @@ /****************************************************************************** * ring.h - * + * * Shared producer-consumer ring macros. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -47,7 +47,7 @@ typedef unsigned int RING_IDX; /* * 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 + * 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) \ @@ -61,7 +61,7 @@ typedef unsigned int RING_IDX; /* * 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. * @@ -71,7 +71,7 @@ typedef unsigned int RING_IDX; * * 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. @@ -139,15 +139,15 @@ 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 + * + * 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 + * + * 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 + * + * 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. */ @@ -235,26 +235,26 @@ typedef struct __name##_back_ring __name##_back_ring_t /* * 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 diff --git a/include/xen/xen-compat.h b/include/xen/xen-compat.h index 3eb80a02d..2508645b5 100644 --- a/include/xen/xen-compat.h +++ b/include/xen/xen-compat.h @@ -1,8 +1,8 @@ /****************************************************************************** * 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 diff --git a/include/xen/xen.h b/include/xen/xen.h index 308109f17..692f97a5b 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -1,8 +1,8 @@ /****************************************************************************** * 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 @@ -157,11 +157,11 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #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 @@ -211,7 +211,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); * (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: @@ -257,13 +257,13 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); * 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. @@ -655,7 +655,7 @@ typedef struct vcpu_time_info vcpu_time_info_t; 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 + * 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 @@ -718,7 +718,7 @@ struct shared_info { * 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 @@ -729,7 +729,7 @@ struct shared_info { * 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 diff --git a/po/arabic.sed b/po/arabic.sed index b5b5db661..3fbee7248 100644 --- a/po/arabic.sed +++ b/po/arabic.sed @@ -73,9 +73,11 @@ s,%\([0-9]*\)لد,%\1ld,g s,%\([0-9]*\)للد,%\1lld,g s,%\([0-9\.\*]*\)س,%\1s,g -s,%\([0-9]*\)لو,%\1lu,g +s,%\([0-9\.\*]*\)م,%\1m,g s,%\([0-9]*\)و,%\1u,g +s,%\([0-9]*\)لو,%\1lu,g s,%\([0-9]*\)للو,%\1llu,g +s,%\([0-9]*\)زو,%\1zu,g s,%\([0-9]*\)كس,%\1x,g s,%\([0-9]*\)لكس,%\1lx,g s,%\([0-9]*\)للكس,%\1llx,g diff --git a/po/cyrillic.sed b/po/cyrillic.sed index ffad0ed8c..472f09529 100644 --- a/po/cyrillic.sed +++ b/po/cyrillic.sed @@ -96,9 +96,11 @@ s,%\([0-9]*\)лд,%\1ld,g s,%\([0-9]*\)ллд,%\1lld,g s,%\([0-9\.\*]*\)с,%\1s,g -s,%\([0-9]*\)лу,%\1lu,g +s,%\([0-9\.\*]*\)м,%\1m,g s,%\([0-9]*\)у,%\1u,g +s,%\([0-9]*\)лу,%\1lu,g s,%\([0-9]*\)ллу,%\1llu,g +s,%\([0-9]*\)зу,%\1zu,g s,%\([0-9]*\)ѯ,%\1x,g s,%\([0-9]*\)лѯ,%\1lx,g s,%\([0-9]*\)ллѯ,%\1llx,g diff --git a/po/gettext-patches/0001-Support-POTFILES-shell.patch b/po/gettext-patches/0001-Support-POTFILES-shell.patch new file mode 100644 index 000000000..5a5d1ec00 --- /dev/null +++ b/po/gettext-patches/0001-Support-POTFILES-shell.patch @@ -0,0 +1,54 @@ +From d5bbd8f60aacb0f73ea5a0bde999152c467d0e78 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 1 Mar 2020 11:57:58 +0000 +Subject: [PATCH 1/4] Support POTFILES-shell + +--- + gettext-runtime/po/Makefile.in.in | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index fabdc76c9..32e9323d3 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -142,7 +142,7 @@ stamp-po: $(srcdir)/$(DOMAIN).pot + # The determination of whether the package xyz is a GNU one is based on the + # heuristic whether some file in the top level directory mentions "GNU xyz". + # If GNU 'find' is available, we avoid grepping through monster files. +-$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed ++$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell.in remove-potcdate.sed + if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ + LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \ + else \ +@@ -175,7 +175,27 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ +- esac ++ esac; \ ++ case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ ++ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ ++ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ ++ --add-comments=TRANSLATORS: @XGETTEXT_EXTRA_OPTIONS@ \ ++ --files-from=$(srcdir)/POTFILES-shell.in \ ++ --copyright-holder='$(COPYRIGHT_HOLDER)' \ ++ --msgid-bugs-address="$$msgid_bugs_address" \ ++ --join-existing --language=Shell --keyword=gettext_quoted \ ++ ;; \ ++ *) \ ++ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ ++ --add-comments=TRANSLATORS: @XGETTEXT_EXTRA_OPTIONS@ \ ++ --files-from=$(srcdir)/POTFILES-shell.in \ ++ --copyright-holder='$(COPYRIGHT_HOLDER)' \ ++ --package-name="$${package_gnu}@PACKAGE@" \ ++ --package-version='@VERSION@' \ ++ --msgid-bugs-address="$$msgid_bugs_address" \ ++ --join-existing --language=Shell --keyword=gettext_quoted \ ++ ;; \ ++ esac; \ + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ +-- +2.17.1 + diff --git a/po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch b/po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch new file mode 100644 index 000000000..2767ed65e --- /dev/null +++ b/po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch @@ -0,0 +1,46 @@ +From fd17c51f2e6c87427679fbdfb5f6224ff48795db Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 1 Mar 2020 12:00:41 +0000 +Subject: [PATCH 2/4] Handle gettext_printf shell function + +Extract gettext_printf arguments. + +Run grub.d.sed over strings extracted from util/grub.d/, in order to set +c-format flags (xgettext refuses to include these itself for strings it +extracted from a shell file, but these really are c-format). +--- + gettext-runtime/po/Makefile.in.in | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index 32e9323d3..32e0c99a2 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -183,7 +183,8 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell + --files-from=$(srcdir)/POTFILES-shell.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ +- --join-existing --language=Shell --keyword=gettext_quoted \ ++ --join-existing --language=Shell \ ++ --keyword=gettext_quoted --keyword=gettext_printf \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ +@@ -193,10 +194,13 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell + --package-name="$${package_gnu}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ +- --join-existing --language=Shell --keyword=gettext_quoted \ ++ --join-existing --language=Shell \ ++ --keyword=gettext_quoted --keyword=gettext_printf \ + ;; \ + esac; \ + test ! -f $(DOMAIN).po || { \ ++ sed -f grub.d.sed < $(DOMAIN).po > $(DOMAIN).1po && \ ++ mv $(DOMAIN).1po $(DOMAIN).po; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ +-- +2.17.1 + diff --git a/po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch b/po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch new file mode 100644 index 000000000..414161133 --- /dev/null +++ b/po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch @@ -0,0 +1,34 @@ +From 156c523e2945c9b43c5500fb93988b0dd2f08d75 Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Sun, 1 Mar 2020 12:09:25 +0000 +Subject: [PATCH 3/4] Make msgfmt output in little-endian + +GRUB expects this. +--- + gettext-runtime/po/Makefile.in.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index 32e0c99a2..f3ef54c39 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -84,13 +84,13 @@ CATALOGS = @CATALOGS@ + + .po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ +- $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ ++ $(MSGFMT) --endianness=little -c -o t-$@ $< && mv t-$@ $@ + + .po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ +- echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ +- cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo ++ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) --endianness=little -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ ++ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) --endianness=little -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + + .sin.sed: + sed -e '/^#/d' $< > t-$@ +-- +2.17.1 + diff --git a/po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch b/po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch new file mode 100644 index 000000000..790521d3f --- /dev/null +++ b/po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch @@ -0,0 +1,26 @@ +From f36f12e77798223ee7ee882c0d09e0e63db11454 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 1 Mar 2020 12:14:07 +0000 +Subject: [PATCH 4/4] Use @SHELL rather than /bin/sh + +/bin/sh might not exist. +--- + gettext-runtime/po/Makefile.in.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index f3ef54c39..285a55a9d 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -16,7 +16,7 @@ VERSION = @VERSION@ + PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + + SED = @SED@ +-SHELL = /bin/sh ++SHELL = @SHELL@ + @SET_MAKE@ + + srcdir = @srcdir@ +-- +2.17.1 + diff --git a/po/greek.sed b/po/greek.sed index 93556c386..0e81625fb 100644 --- a/po/greek.sed +++ b/po/greek.sed @@ -98,9 +98,11 @@ s,%\([0-9]*\)λδ,%\1ld,g s,%\([0-9]*\)λλδ,%\1lld,g s,%\([0-9\.\*]*\)σ,%\1s,g -s,%\([0-9]*\)λυ,%\1lu,g +s,%\([0-9\.\*]*\)μ,%\1m,g s,%\([0-9]*\)υ,%\1u,g +s,%\([0-9]*\)λυ,%\1lu,g s,%\([0-9]*\)λλυ,%\1llu,g +s,%\([0-9]*\)ζυ,%\1zu,g s,%\([0-9]*\)ξ,%\1x,g s,%\([0-9]*\)λξ,%\1lx,g s,%\([0-9]*\)λλξ,%\1llx,g diff --git a/po/hebrew.sed b/po/hebrew.sed index a47bc6a28..33174bbdc 100644 --- a/po/hebrew.sed +++ b/po/hebrew.sed @@ -81,9 +81,11 @@ s,%\([0-9]*\)לד,%\1ld,g s,%\([0-9]*\)ללד,%\1lld,g s,%\([0-9\.\*]*\)ש,%\1s,g -s,%\([0-9]*\)לוּ,%\1lu,g +s,%\([0-9\.\*]*\)מ,%\1m,g s,%\([0-9]*\)וּ,%\1u,g +s,%\([0-9]*\)לוּ,%\1lu,g s,%\([0-9]*\)ללוּ,%\1llu,g +s,%\([0-9]*\)זוּ,%\1zu,g s,%\([0-9]*\)כּס,%\1x,g s,%\([0-9]*\)לכּס,%\1lx,g s,%\([0-9]*\)ללכּס,%\1llx,g diff --git a/tests/ahci_test.in b/tests/ahci_test.in index 7df560462..70646a24e 100644 --- a/tests/ahci_test.in +++ b/tests/ahci_test.in @@ -22,26 +22,31 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: Don't mess with real devices when OS is active *-emu) - exit 0;; + exit 77;; # FIXME: qemu gets bonito DMA wrong mipsel-loongson) - exit 0;; + exit 77;; # PLATFORM: no AHCI on ARC and qemu-mips platforms mips*-arc | mips*-qemu_mips) - exit 0;; + exit 77;; # FIXME: No native drivers are available for those - powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi) - exit 0;; + powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi | loongarch64-efi) + exit 77;; esac -imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 +outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 echo "hello" > "$outfile" tar cf "$imgfile" "$outfile" -if [ "$(echo "nativedisk; source '(ahci0)/$outfile';" | "${grubshell}" --qemu-opts="-drive id=disk,file=$imgfile,if=none -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 " | tail -n 1)" != "Hello World" ]; then +v=$(echo "nativedisk; source '(ahci0)/$outfile';" | + "${grubshell}" --qemu-opts="-drive id=disk,file=$imgfile,if=none + -device ahci,id=ahci + -device ide-hd,drive=disk,bus=ahci.0") +v=$(echo "$v" | tail -n 1) +if [ "$v" != "Hello World" ]; then rm "$imgfile" rm "$outfile" exit 1 diff --git a/tests/asn1_test.in b/tests/asn1_test.in new file mode 100644 index 000000000..8f18ee6bb --- /dev/null +++ b/tests/asn1_test.in @@ -0,0 +1,11 @@ +#! @BUILD_SHEBANG@ +set -e + +. "@builddir@/grub-core/modinfo.sh" + +out=`echo functional_test asn1_test | @builddir@/grub-shell` + +if [ "$(echo "$out" | tail -n 1)" != "ALL TESTS PASSED" ]; then + echo "ASN.1 test failure: $out" + exit 1 +fi diff --git a/tests/btrfs_test.in b/tests/btrfs_test.in index 0c9bf3a68..0d098c9a2 100644 --- a/tests/btrfs_test.in +++ b/tests/btrfs_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.btrfs >/dev/null 2>&1; then echo "mkfs.btrfs not installed; cannot test btrfs." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" btrfs diff --git a/tests/cdboot_test.in b/tests/cdboot_test.in index 75acdfedb..f00cdec58 100644 --- a/tests/cdboot_test.in +++ b/tests/cdboot_test.in @@ -22,18 +22,19 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: emu is different *-emu) - exit 0;; + exit 77;; # PLATFORM: Flash targets i386-qemu | i386-coreboot | mips-qemu_mips | mipsel-qemu_mips) - exit 0;; + exit 77;; # FIXME: currently grub-shell uses only -kernel for loongson mipsel-loongson) - exit 0;; + exit 77;; # FIXME: OFW fails to open CD-ROM i386-ieee1275) - exit 0;; + exit 77;; esac -if [ "$(echo hello | "${grubshell}" --boot=cd)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --boot=cd) +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/core_compress_test.in b/tests/core_compress_test.in index 9d216ebcf..24a811418 100644 --- a/tests/core_compress_test.in +++ b/tests/core_compress_test.in @@ -22,15 +22,17 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # FIXME: Only mips currently supports configurable core compression *-emu | i386-* | x86_64-* | sparc64-* | ia64-*) - exit 0 + exit 77 ;; esac -if [ "$(echo hello | "${grubshell}" --grub-mkimage-extra=--compress=xz)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --grub-mkimage-extra=--compress=xz) +if [ "$v" != "Hello World" ]; then exit 1 fi -if [ "$(echo hello | "${grubshell}" --grub-mkimage-extra=--compress=none)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --grub-mkimage-extra=--compress=none) +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/cpio_test.in b/tests/cpio_test.in index 5742cf17b..e2e668cf6 100644 --- a/tests/cpio_test.in +++ b/tests/cpio_test.in @@ -4,7 +4,7 @@ set -e if ! which cpio >/dev/null 2>&1; then echo "cpio not installed; cannot test cpio." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" cpio_bin diff --git a/tests/ehci_test.in b/tests/ehci_test.in index b197f8cdc..bf823a5de 100644 --- a/tests/ehci_test.in +++ b/tests/ehci_test.in @@ -22,26 +22,31 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: Don't mess with real devices when OS is active *-emu) - exit 0;; + exit 77;; # FIXME: qemu gets bonito DMA wrong mipsel-loongson) - exit 0;; + exit 77;; # PLATFORM: no USB on ARC and qemu-mips platforms mips*-arc | mips*-qemu_mips) - exit 0;; + exit 77;; # FIXME: No native drivers are available for those - powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi) - exit 0;; + powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi | loongarch64-efi) + exit 77;; esac -imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 +outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 echo "hello" > "$outfile" tar cf "$imgfile" "$outfile" -if [ "$(echo "nativedisk; source '(usb0)/$outfile';" | "${grubshell}" --qemu-opts="-device ich9-usb-ehci1 -drive id=my_usb_disk,file=$imgfile,if=none -device usb-storage,drive=my_usb_disk" | tail -n 1)" != "Hello World" ]; then +v=$(echo "nativedisk; source '(usb0)/$outfile';" | + "${grubshell}" --qemu-opts="-device ich9-usb-ehci1 + -drive id=my_usb_disk,file=$imgfile,if=none + -device usb-storage,drive=my_usb_disk") +v=$(echo "$v" | tail -n 1) +if [ "$v" != "Hello World" ]; then rm "$imgfile" rm "$outfile" exit 1 diff --git a/tests/erofs_test.in b/tests/erofs_test.in new file mode 100644 index 000000000..51111627a --- /dev/null +++ b/tests/erofs_test.in @@ -0,0 +1,20 @@ +#!@BUILD_SHEBANG@ + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 99 +fi + +if ! which mkfs.erofs >/dev/null 2>&1; then + echo "mkfs.erofs not installed; cannot test erofs." + exit 99 +fi + +"@builddir@/grub-fs-tester" erofs_compact +"@builddir@/grub-fs-tester" erofs_extended +"@builddir@/grub-fs-tester" erofs_chunk diff --git a/tests/exfat_test.in b/tests/exfat_test.in index cd3cd4cb2..7939f25d2 100644 --- a/tests/exfat_test.in +++ b/tests/exfat_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.exfat >/dev/null 2>&1; then echo "mkfs.exfat not installed; cannot test exFAT." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" exfat diff --git a/tests/ext234_test.in b/tests/ext234_test.in index 4f1eb527e..4df696710 100644 --- a/tests/ext234_test.in +++ b/tests/ext234_test.in @@ -7,22 +7,22 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.ext2 >/dev/null 2>&1; then echo "mkfs.ext2 not installed; cannot test ext2." - exit 77 + exit 99 fi if ! which mkfs.ext3 >/dev/null 2>&1; then echo "mkfs.ext3 not installed; cannot test ext3." - exit 77 + exit 99 fi if ! which mkfs.ext4 >/dev/null 2>&1; then echo "mkfs.ext4 not installed; cannot test ext4." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" ext2_old diff --git a/tests/f2fs_test.in b/tests/f2fs_test.in index 1ea77c826..85f8cc8bc 100644 --- a/tests/f2fs_test.in +++ b/tests/f2fs_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.f2fs >/dev/null 2>&1; then echo "mkfs.f2fs not installed; cannot test f2fs." - exit 77 + exit 99 fi diff --git a/tests/fat_test.in b/tests/fat_test.in index b6b4748ca..8a2b37c5c 100644 --- a/tests/fat_test.in +++ b/tests/fat_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.vfat >/dev/null 2>&1; then echo "mkfs.vfat not installed; cannot test FAT." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" vfat16a diff --git a/tests/fddboot_test.in b/tests/fddboot_test.in index 2d7dfc889..6ef49efcb 100644 --- a/tests/fddboot_test.in +++ b/tests/fddboot_test.in @@ -22,30 +22,31 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: emu is different *-emu) - exit 0;; + exit 77;; # PLATFORM: Flash targets i386-qemu | i386-coreboot | mips-qemu_mips | mipsel-qemu_mips) - exit 0;; + exit 77;; # FIXME: currently grub-shell uses only -kernel for loongson mipsel-loongson) - exit 0;; + exit 77;; # FIXME: We don't support EFI floppy boot in grub-mkrescue *-efi) - exit 0;; + exit 77;; # FIXME: no floppy support i386-multiboot) - exit 0;; + exit 77;; # FIXME: QEMU firmware crashes when trying to boot from floppy sparc64-ieee1275) - exit 0;; + exit 77;; # FIXME: QEMU doesn't emulate SCSI floppies mipsel-arc | mips-arc) - exit 0;; + exit 77;; # PLATFORM: powerpc doesn't boot from floppy except OldWorld Macs which we don't support anyway powerpc-ieee1275) - exit 0;; + exit 77;; esac -if [ "$(echo hello | "${grubshell}" --boot=fd --mkrescue-arg="--compress=xz --fonts= --locales= --themes= -no-pad")" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --boot=fd --mkrescue-arg="--compress=xz --fonts= --locales= --themes= -no-pad") +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/gettext_strings_test.in b/tests/gettext_strings_test.in index 813999ebe..1c37fe41b 100644 --- a/tests/gettext_strings_test.in +++ b/tests/gettext_strings_test.in @@ -2,7 +2,7 @@ cd '@srcdir@' -tdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" +tdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" || exit 99 xgettext -f po/POTFILES.in -L C -o "$tdir/"skip.pot -x po/grub.pot --keyword=grub_util_info --keyword=grub_dprintf:1,2 --keyword=grub_register_command --keyword=grub_register_extcmd --keyword=grub_efiemu_resolve_symbol --keyword=grub_efiemu_register_symbol --keyword=grub_dl_load --keyword=grub_crypto_lookup_md_by_name --keyword=grub_crypto_lookup_cipher_by_name --keyword=grub_efiemu_resolve_symbol --keyword=alias --keyword=grub_ieee1275_get_property:2 --keyword=grub_ieee1275_find_device --keyword=grub_ieee1275_get_integer_property:2 --keyword=INIT_IEEE1275_COMMON:2 --keyword=grub_boot_time --keyword=grub_env_get --keyword=grub_env_set --keyword=grub_register_variable_hook --keyword=grub_fatal --keyword=__asm__ --keyword=volatile --keyword=__volatile__ --keyword=grub_error:2 --from-code=iso-8859-1 xgettext -f po/POTFILES.in -L C -o "$tdir/"skip2.pot -x po/grub.pot --keyword=volatile:2 --keyword=__volatile__:2 --keyword=grub_dprintf:2 --from-code=iso-8859-1 diff --git a/tests/grub_cmd_cryptomount.in b/tests/grub_cmd_cryptomount.in new file mode 100644 index 000000000..eaa187efa --- /dev/null +++ b/tests/grub_cmd_cryptomount.in @@ -0,0 +1,199 @@ +#! @BUILD_SHEBANG@ -e + +# Run all grub cryptomount tests in a Qemu instance +# 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 . + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + echo "not root; cannot test cryptomount." + exit 99 +fi + +if ! which cryptsetup >/dev/null 2>&1; then + echo "cryptsetup not installed; cannot test cryptomount." + exit 99 +fi + +if ! which mkfs.vfat >/dev/null 2>&1; then + echo "mkfs.vfat not installed; cannot test cryptomount." + exit 99 +fi + +COMMON_OPTS='${V:+--debug=$V} --cs-opts="--pbkdf-force-iterations 1000"' + +debug=${GRUB_SHELL_DEFAULT_DEBUG:-$GRUB_TEST_DEFAULT_DEBUG} + +_testcase() { + local EXPECTEDRES=$1 + local LOGPREFIX=$2 + local res=0 + local output + shift 2 + + # Create a subdir in TMPDIR for each testcase + _TMPDIR=${TMPDIR:-/tmp} + TMPDIR=${_TMPDIR}/`echo -n "$(date +%s).${LOGPREFIX}" | sed -e 's,[ /],_,g' -e 's,:$,,g'` + export TMPDIR + mkdir -p "$TMPDIR" + set -- "$@" $([ "${EXPECTEDRES}" -eq 1 ] && echo "--xfail") + + output=`"$@" 2>&1` || res=$? + if [ -z "$debug" ]; then + if ! rmdir "$TMPDIR" >/dev/null 2>&1; then + echo + echo "Note: Temporary directory cannot be removed:" + echo " $TMPDIR" + echo " Please inspect and remove manually." + echo + fi + fi + TMPDIR=$_TMPDIR + + if [ "$res" -eq "$EXPECTEDRES" ]; then + if [ "$res" -eq 0 ]; then + echo $LOGPREFIX PASS + else + echo $LOGPREFIX XFAIL + fi + else + echo "Error[$res]: $output" + if [ "$res" -eq 0 ]; then + echo $LOGPREFIX XPASS + elif [ "$res" -eq 1 ]; then + echo $LOGPREFIX FAIL + else + # Any exit code other than 1 or 0, indicates a hard error, + # not a test error + echo $LOGPREFIX ERROR + return 99 + fi + return 1 + fi +} + +testcase() { _testcase 0 "$@"; } +testcase_fail() { _testcase 1 "$@"; } + +### LUKS1 tests +eval testcase "'LUKS1 test cryptsetup defaults:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS + +eval testcase "'LUKS1 test with twofish cipher:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + "--cs-opts='--cipher twofish-xts-plain64'" + +eval testcase "'LUKS1 test key file support:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + --keyfile + +eval testcase "'LUKS1 test key file with offset:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + --keyfile --cs-opts="--keyfile-offset=237" + +eval testcase "'LUKS1 test key file with offset and size:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + --keyfile "--cs-opts='--keyfile-offset=237 --keyfile-size=1023'" + +eval testcase "'LUKS1 test detached header support:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + --detached-header + +eval testcase "'LUKS1 test both detached header and key file:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + --keyfile --detached-header + +### LUKS2 tests (mirroring the LUKS1 tests above) +LUKS2_COMMON_OPTS="--luks=2 --cs-opts=--pbkdf=pbkdf2" +eval testcase "'LUKS2 test cryptsetup defaults:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS + +eval testcase "'LUKS2 test with twofish cipher:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + "--cs-opts='--cipher twofish-xts-plain64'" + +eval testcase "'LUKS2 test key file support:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + --keyfile + +eval testcase "'LUKS2 test key file with offset:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + --keyfile --cs-opts="--keyfile-offset=237" + +eval testcase "'LUKS2 test key file with offset and size:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + --keyfile "--cs-opts='--keyfile-offset=237 --keyfile-size=1023'" + +eval testcase "'LUKS2 test detached header support:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + --detached-header + +eval testcase "'LUKS2 test both detached header and key file:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + --keyfile --detached-header + +### LUKS1 specific tests +# Tests for xts-plain and xts-plain64 modes +eval testcase "'LUKS1 test cryptsetup xts-plain:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + "--cs-opts='--cipher aes-xts-plain'" + +eval testcase "'LUKS1 test cryptsetup xts-plain64:'" \ + @builddir@/grub-shell-luks-tester --luks=1 $COMMON_OPTS \ + "--cs-opts='--cipher aes-xts-plain64'" + +### LUKS2 specific tests +eval testcase "'LUKS2 test with 1k sector size:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + "--cs-opts='--sector-size 1024'" + +eval testcase "'LUKS2 test with 2k sector size:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + "--cs-opts='--sector-size 2048'" + +eval testcase "'LUKS2 test with 4k sector size:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + "--cs-opts='--sector-size 4096'" + +eval testcase "'LUKS2 test with non-default key slot:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + "--cs-opts='--key-slot 5'" + +eval testcase "'LUKS2 test with different metadata size:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + "--cs-opts='--luks2-metadata-size 512k'" + +# TODO: Expect a failure with LUKS2 volumes with argon2 key derivation +eval testcase_fail "'LUKS2 test with argon2 pbkdf:'" \ + @builddir@/grub-shell-luks-tester --luks=2 $COMMON_OPTS \ + "--cs-opts='--pbkdf-memory 32'" "--cs-opts='--pbkdf-parallel 1'" + +# Add good password to second slot and change first slot to unchecked password +csscript=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 99 +cat >$csscript <<'EOF' + CSOPTS="--pbkdf-force-iterations 1000 --pbkdf=pbkdf2 --force-password" + cryptsetup $CSOPTS --key-file $lukskeyfile luksAddKey $luksdiskfile $lukskeyfile + echo "newpass" | cryptsetup $CSOPTS --key-file $lukskeyfile --key-slot 0 luksChangeKey $luksdiskfile +EOF + +eval testcase "'LUKS2 test with second key slot and first slot using different password:'" \ + @builddir@/grub-shell-luks-tester $LUKS2_COMMON_OPTS $COMMON_OPTS \ + "--cs-script='$csscript'" + +test -n "$debug" || rm "$csscript" +exit 0 diff --git a/tests/grub_cmd_date.in b/tests/grub_cmd_date.in index f7c9ca004..4903ad6cc 100644 --- a/tests/grub_cmd_date.in +++ b/tests/grub_cmd_date.in @@ -5,11 +5,12 @@ set -e # FIXME: OpenBIOS on sparc64 doesn't implement RTC if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = sparc64-ieee1275 ]; then - exit 0 + exit 77 fi pdt="$(date -u +%s)" -dt=`echo date | @builddir@/grub-shell | sed 's, [A-Z][a-z]*$,,'` +dt="$(echo date | @builddir@/grub-shell)" +dt="$(echo "$dt" | sed 's, [A-Z][a-z]*$,,')" dtg="$(date -u -d "$dt" +%s)" ndt="$(date -u +%s)" diff --git a/tests/grub_cmd_set_date.in b/tests/grub_cmd_set_date.in index aac120a6c..17673cd8a 100644 --- a/tests/grub_cmd_set_date.in +++ b/tests/grub_cmd_set_date.in @@ -6,15 +6,15 @@ set -e case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # FIXME: OpenBIOS on sparc64 doesn't implement RTC sparc64-ieee1275) - exit 0;; + exit 77;; # PLATFORM: ARC doesn't provide any way to set time *-arc) - exit 0;; + exit 77;; # PLATFORM: EMU doesn't provide any way to set time # Even if it did we'd need some kind of sandbox to avoid # modifying real system time. *-emu) - exit 0;; + exit 77;; esac out=$(cat <$non_empty <$outfile <$tmp error_if_not "`head -n1 $tmp|tail -n1`" '{ test_blockarg { true } }' diff --git a/tests/grub_script_eval.in b/tests/grub_script_eval.in index c97b78d77..9c6211042 100644 --- a/tests/grub_script_eval.in +++ b/tests/grub_script_eval.in @@ -3,4 +3,12 @@ eval echo "Hello world" valname=tst eval $valname=hi -echo $tst \ No newline at end of file +echo $tst + +if eval " +false +"; then + echo should have failed +else + echo failed as expected +fi diff --git a/tests/grub_script_expansion.in b/tests/grub_script_expansion.in index 9d0dcdd29..98d5a9068 100644 --- a/tests/grub_script_expansion.in +++ b/tests/grub_script_expansion.in @@ -17,7 +17,8 @@ set -e # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . -disks=`echo ls | @builddir@/grub-shell| grep -av '^Network protocols:$'| grep -av '^tftp http $'` +disks=`echo ls | @builddir@/grub-shell` +disks=`echo "$disks"| grep -av '^Network protocols:$'| grep -av '^tftp http $'` other=`echo insmod regexp\; echo \* | @builddir@/grub-shell` for d in $disks; do if echo "$d" |grep ',' >/dev/null; then diff --git a/tests/gzcompress_test.in b/tests/gzcompress_test.in index 42c8fe7c4..8e7e6a633 100644 --- a/tests/gzcompress_test.in +++ b/tests/gzcompress_test.in @@ -21,9 +21,10 @@ grubshell=@builddir@/grub-shell if ! which gzip >/dev/null 2>&1; then echo "gzip not installed; cannot test gzip compression." - exit 77 + exit 99 fi -if [ "$(echo hello | "${grubshell}" --mkrescue-arg=--compress=gz)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --mkrescue-arg=--compress=gz) +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/hddboot_test.in b/tests/hddboot_test.in index 6d70847a5..764e0da1c 100644 --- a/tests/hddboot_test.in +++ b/tests/hddboot_test.in @@ -22,16 +22,17 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: emu is different *-emu) - exit 0;; + exit 77;; # PLATFORM: Flash targets i386-qemu | i386-coreboot | mips-qemu_mips | mipsel-qemu_mips) - exit 0;; + exit 77;; # FIXME: currently grub-shell uses only -kernel for loongson mipsel-loongson) - exit 0;; + exit 77;; esac -if [ "$(echo hello | "${grubshell}" --boot=hd)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --boot=hd) +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/help_test.in b/tests/help_test.in index b08cf2013..9c8ca52c8 100644 --- a/tests/help_test.in +++ b/tests/help_test.in @@ -8,9 +8,12 @@ Show a help message. -h, --help Display this help and exit. -u, --usage Display the usage of this command and exit. -Hello World" -outpu="$(echo 'help help; hello' | @builddir@/grub-shell)" -if [ "$template" != "$outpu" ]; then + +To enable less(1)-like paging, \"set pager=1\". +Hello World" +output="$(echo 'help help; hello' | @builddir@/grub-shell)" + +if [ "$template" != "$output" ]; then exit 1 fi diff --git a/tests/hfs_test.in b/tests/hfs_test.in index d7ec56bef..960f1cbd0 100644 --- a/tests/hfs_test.in +++ b/tests/hfs_test.in @@ -7,17 +7,17 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.hfs >/dev/null 2>&1; then echo "mkfs.hfs not installed; cannot test HFS." - exit 77 + exit 99 fi -if ! modprobe mac-roman; then +if ! grep -q mac_roman /proc/modules && ! modprobe mac_roman; then echo "no mac-roman support; cannot test HFS." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" hfs diff --git a/tests/hfsplus_test.in b/tests/hfsplus_test.in index 85f1c37dc..f727cf0e2 100644 --- a/tests/hfsplus_test.in +++ b/tests/hfsplus_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.hfsplus >/dev/null 2>&1; then echo "mkfs.hfsplus not installed; cannot test hfsplus." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" hfsplus diff --git a/tests/iso9660_ce_loop.iso.gz b/tests/iso9660_ce_loop.iso.gz new file mode 100644 index 000000000..9c53c569b Binary files /dev/null and b/tests/iso9660_ce_loop.iso.gz differ diff --git a/tests/iso9660_ce_loop2.iso.gz b/tests/iso9660_ce_loop2.iso.gz new file mode 100644 index 000000000..f59e67647 Binary files /dev/null and b/tests/iso9660_ce_loop2.iso.gz differ diff --git a/tests/iso9660_early_ce.iso.gz b/tests/iso9660_early_ce.iso.gz new file mode 100644 index 000000000..df4ef5fb2 Binary files /dev/null and b/tests/iso9660_early_ce.iso.gz differ diff --git a/tests/iso9660_test.in b/tests/iso9660_test.in index 571b938d7..a1f752adf 100644 --- a/tests/iso9660_test.in +++ b/tests/iso9660_test.in @@ -4,7 +4,7 @@ set -e if ! which xorriso >/dev/null 2>&1; then echo "xorriso not installed; cannot test iso9660." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" joliet @@ -12,4 +12,42 @@ fi "@builddir@/grub-fs-tester" rockridge_joliet "@builddir@/grub-fs-tester" joliet_1999 "@builddir@/grub-fs-tester" rockridge_1999 -"@builddir@/grub-fs-tester" rockridge_joliet_1999 \ No newline at end of file +"@builddir@/grub-fs-tester" rockridge_joliet_1999 + +echo "Testing for proper recognition of CE loops ... " +for fs in iso9660_ce_loop iso9660_ce_loop2; do + tempdir=`mktemp -d "${TMPDIR:-/tmp}/${0##*/}.$(date '+%Y%m%d%H%M%S%N').${fs}.XXX"` || + { echo "Failed to make temporary directory"; exit 99; } + gunzip <"$srcdir"/tests/${fs}.iso.gz >"${tempdir}/${fs}.iso" || exit 99 + output=$(LC_ALL=C timeout -s KILL "60" \ + "@builddir@/grub-fstest" "${tempdir}/${fs}.iso" ls / ) || ret=$? + rm -rf "$tempdir" + if [ "${ret:-0}" -ne 0 -o -n "$output" ]; then + echo "FAIL ($fs)" + exit 1 + fi +done +echo "PASS" + +echo "Testing for proper handling of early CE ... " +fs=iso9660_early_ce +tempdir=`mktemp -d "${TMPDIR:-/tmp}/${0##*/}.$(date '+%Y%m%d%H%M%S%N').${fs}.XXX"` || + { echo "Failed to make temporary directory"; exit 99; } +gunzip <"$srcdir"/tests/${fs}.iso.gz >"${tempdir}/${fs}.iso" || exit 99 +ret=0 +output=$(LC_ALL=C timeout -s KILL "60" \ + "@builddir@/grub-fstest" "${tempdir}/${fs}.iso" ls / ) || ret=$? +rm -rf "$tempdir" +if [ "${ret:-0}" -ne 0 ]; then + echo "... grub-fstest returns $ret" + echo "FAIL ($fs)" + exit 1 +fi +# Before comparing: remove trailing blank added by grub-fstest +output=$(echo -n $output) +if [ x"$output" != x"RockRidgeName:x" ]; then + echo "... found: '$output' , expected: 'RockRidgeName:x'" + echo "FAIL ($fs)" + exit 1 +fi +echo "PASS" diff --git a/tests/jfs_test.in b/tests/jfs_test.in index 6cf7576b3..d13780e23 100644 --- a/tests/jfs_test.in +++ b/tests/jfs_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.jfs >/dev/null 2>&1; then echo "mkfs.jfs not installed; cannot test JFS." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" jfs diff --git a/tests/luks1_test.in b/tests/luks1_test.in new file mode 100644 index 000000000..cd28fd714 --- /dev/null +++ b/tests/luks1_test.in @@ -0,0 +1,23 @@ +#!@BUILD_SHEBANG@ + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 99 +fi + +if ! which mkfs.ext2 >/dev/null 2>&1; then + echo "mkfs.ext2 not installed; cannot test luks." + exit 99 +fi + +if ! which cryptsetup >/dev/null 2>&1; then + echo "cryptsetup not installed; cannot test luks." + exit 99 +fi + +"@builddir@/grub-fs-tester" luks1 diff --git a/tests/luks2_test.in b/tests/luks2_test.in new file mode 100644 index 000000000..6a26ba626 --- /dev/null +++ b/tests/luks2_test.in @@ -0,0 +1,23 @@ +#!@BUILD_SHEBANG@ + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 99 +fi + +if ! which mkfs.ext2 >/dev/null 2>&1; then + echo "mkfs.ext2 not installed; cannot test luks2." + exit 99 +fi + +if ! which cryptsetup >/dev/null 2>&1; then + echo "cryptsetup not installed; cannot test luks2." + exit 99 +fi + +"@builddir@/grub-fs-tester" luks2 diff --git a/tests/lzocompress_test.in b/tests/lzocompress_test.in index 4e5f7e078..915f74bd9 100644 --- a/tests/lzocompress_test.in +++ b/tests/lzocompress_test.in @@ -21,9 +21,10 @@ grubshell=@builddir@/grub-shell if ! which lzop >/dev/null 2>&1; then echo "lzop not installed; cannot test lzo compression." - exit 77 + exit 99 fi -if [ "$(echo hello | "${grubshell}" --mkrescue-arg=--compress=lzo)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --mkrescue-arg=--compress=lzo) +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/minixfs_test.in b/tests/minixfs_test.in index 3b16a4de0..c62f56c8b 100644 --- a/tests/minixfs_test.in +++ b/tests/minixfs_test.in @@ -7,27 +7,22 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.minix >/dev/null 2>&1; then echo "mkfs.minix not installed; cannot test minixfs." - exit 77 + exit 99 fi if ! mkfs.minix -h | grep -- -v > /dev/null; then echo "mkfs.minix doesn't support minix2fs; cannot test minix*fs." - exit 77 + exit 99 fi if ! mkfs.minix -h | grep -- -3 > /dev/null; then echo "mkfs.minix doesn't support minix3fs; cannot test minix*fs." - exit 77 -fi - -if ! mkfs.minix -h | grep -- -B > /dev/null; then - echo "mkfs.minix doesn't support variable block size; cannot test minix*fs." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" minix diff --git a/tests/netboot_test.in b/tests/netboot_test.in index 9f71e3d88..510c9c34b 100644 --- a/tests/netboot_test.in +++ b/tests/netboot_test.in @@ -22,24 +22,25 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: emu is different *-emu) - exit 0;; + exit 77;; # PLATFORM: Flash targets i386-qemu | i386-coreboot | mips-qemu_mips | mipsel-qemu_mips) - exit 0;; + exit 77;; # FIXME: currently grub-shell uses only -kernel for loongson mipsel-loongson) - exit 0;; + exit 77;; # FIXME: no rtl8139 support i386-multiboot) - exit 0;; + exit 77;; # FIXME: We don't fully support netboot on ARC *-arc) - exit 0;; + exit 77;; # FIXME: Many QEMU firmware have no netboot capability *-efi | i386-ieee1275 | powerpc-ieee1275 | sparc64-ieee1275) - exit 0;; + exit 77;; esac -if [ "$(echo hello | "${grubshell}" --boot=net)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --boot=net) +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/nilfs2_test.in b/tests/nilfs2_test.in index ad44d5b33..8cc93754c 100644 --- a/tests/nilfs2_test.in +++ b/tests/nilfs2_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.nilfs2 >/dev/null 2>&1; then echo "mkfs.nilfs2 not installed; cannot test nilfs2." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" nilfs2 diff --git a/tests/ntfs_test.in b/tests/ntfs_test.in index 9eb7b01f6..c2b08d27f 100644 --- a/tests/ntfs_test.in +++ b/tests/ntfs_test.in @@ -7,17 +7,17 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.ntfs >/dev/null 2>&1; then echo "mkfs.ntfs not installed; cannot test ntfs." - exit 77 + exit 99 fi if ! which setfattr >/dev/null 2>&1; then echo "setfattr not installed; cannot test ntfs." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" ntfs diff --git a/tests/ohci_test.in b/tests/ohci_test.in index 8693f8c47..a40d3bc0a 100644 --- a/tests/ohci_test.in +++ b/tests/ohci_test.in @@ -22,26 +22,31 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: Don't mess with real devices when OS is active *-emu) - exit 0;; + exit 77;; # FIXME: qemu gets bonito DMA wrong mipsel-loongson) - exit 0;; + exit 77;; # PLATFORM: no USB on ARC and qemu-mips platforms mips*-arc | mips*-qemu_mips) - exit 0;; + exit 77;; # FIXME: No native drivers are available for those - powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi) - exit 0;; + powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi | loongarch64-efi) + exit 77;; esac -imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 +outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 echo "hello" > "$outfile" tar cf "$imgfile" "$outfile" -if [ "$(echo "nativedisk; source '(usb0)/$outfile';" | "${grubshell}" --qemu-opts="-device pci-ohci -drive id=my_usb_disk,file=$imgfile,if=none -device usb-storage,drive=my_usb_disk" | tail -n 1)" != "Hello World" ]; then +v=$(echo "nativedisk; source '(usb0)/$outfile';" | + "${grubshell}" --qemu-opts="-device pci-ohci + -drive id=my_usb_disk,file=$imgfile,if=none + -device usb-storage,drive=my_usb_disk") +v=$(echo "$v" | tail -n 1) +if [ "$v" != "Hello World" ]; then rm "$imgfile" rm "$outfile" exit 1 diff --git a/tests/partmap_test.in b/tests/partmap_test.in index 6ef518b0a..4138e88fe 100644 --- a/tests/partmap_test.in +++ b/tests/partmap_test.in @@ -19,6 +19,8 @@ set -e parted=parted grubshell=@builddir@/grub-shell +PATH="$PATH:/sbin:/usr/sbin" + . "@builddir@/grub-core/modinfo.sh" create_disk_image () { @@ -43,7 +45,7 @@ check_output () { for dsk in $@; do if ! grep "($dsk)" "${outfile}" >/dev/null then - echo "($dsk): disk/partiton not found" + echo "($dsk): disk/partiton not found in: $(cat "${outfile}")" exit 1 fi done @@ -58,8 +60,8 @@ list_parts () { shift echo ls | "${grubshell}" --disk="${imgfile}" \ - --modules=$mod | tr -d "\n\r" > "${outfile}" - cat "${outfile}" + --modules=$mod > "${outfile}" + cat "${outfile}" | tr -d "\n\r" echo } @@ -70,39 +72,39 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in powerpc-ieee1275) disk=ieee1275//pci@80000000/mac-io@4/ata-3@20000/disk@0 # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label. - exit 0 + exit 77 ;; sparc64-ieee1275) disk=ieee1275//pci@1fe\,0/pci-ata@5/ide0@500/disk@0 # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label. - exit 0 + exit 77 ;; i386-ieee1275) disk=ieee1275/d # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label. - exit 0 + exit 77 ;; mips-arc) # FIXME: ARC firmware has bugs which prevent it from accessing hard disk w/o dvh disklabel. - exit 0 ;; + exit 77 ;; mipsel-arc) disk=arc/scsi0/disk0/rdisk0 ;; arm*-efi) - disk=hd3 + disk=hd2 ;; *) disk=hd0 ;; esac -if ! which parted >/dev/null 2>&1; then - echo "parted not installed; cannot test partmap" - exit 77 +if ! which ${parted} >/dev/null 2>&1; then + echo "${parted} not installed; cannot test partmap" + exit 99 fi -imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 +outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 # # MSDOS partition types diff --git a/tests/pata_test.in b/tests/pata_test.in index 4b18fdef3..4d0e7d573 100644 --- a/tests/pata_test.in +++ b/tests/pata_test.in @@ -25,28 +25,31 @@ indisk=ata0 case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: Don't mess with real devices when OS is active *-emu) - exit 0;; + exit 77;; # PLATFORM: no ATA on ARC platforms (they use SCSI) *-arc) - exit 0;; + exit 77;; + # QEMU: no ATA on Q35 machine type (they use AHCI) + i386-efi) + exit 77;; # FIXME: No native drivers are available for those - powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi) - exit 0;; + powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi | loongarch64-efi) + exit 77;; i386-ieee1275) disk=hdb indisk=ata1 ;; esac -imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 +outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 echo "hello" > "$outfile" tar cf "$imgfile" "$outfile" -if [ "$(echo "nativedisk; source '($indisk)/$outfile';" | "${grubshell}" --qemu-opts="-$disk $imgfile")" != "Hello World" ]; then - rm "$imgfile" +v=$(echo "nativedisk; source '($indisk)/$outfile';" | "${grubshell}" --qemu-opts="-$disk $imgfile") +if [ "$v" != "Hello World" ]; then rm "$outfile" exit 1 fi diff --git a/tests/pseries_test.in b/tests/pseries_test.in index 655eb4f3a..9b4090cf5 100644 --- a/tests/pseries_test.in +++ b/tests/pseries_test.in @@ -20,7 +20,7 @@ grubshell=@builddir@/grub-shell . "@builddir@/grub-core/modinfo.sh" if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" != powerpc-ieee1275 ]; then - exit 0 + exit 77 fi if [ "$(echo hello | "${grubshell}" --pseries --timeout=180 --boot=cd)" != "Hello World" ]; then diff --git a/tests/reiserfs_test.in b/tests/reiserfs_test.in index b5fed7635..37226c01b 100644 --- a/tests/reiserfs_test.in +++ b/tests/reiserfs_test.in @@ -7,14 +7,15 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.reiserfs >/dev/null 2>&1; then echo "mkfs.reiserfs not installed; cannot test reiserfs." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" reiserfs -"@builddir@/grub-fs-tester" reiserfs_old +# Kernels since at least 4.15 can not mount ReiserFS filesystems of the old format. +#"@builddir@/grub-fs-tester" reiserfs_old diff --git a/tests/romfs_test.in b/tests/romfs_test.in index 98bb50c32..f968e9b7d 100644 --- a/tests/romfs_test.in +++ b/tests/romfs_test.in @@ -4,7 +4,7 @@ set -e if ! which genromfs >/dev/null 2>&1; then echo "genromfs not installed; cannot test romfs." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" romfs diff --git a/tests/serial_test.in b/tests/serial_test.in new file mode 100644 index 000000000..48655d4b9 --- /dev/null +++ b/tests/serial_test.in @@ -0,0 +1,55 @@ +#! @BUILD_SHEBANG@ +# 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 . + +set -e +grubshell=@builddir@/grub-shell + +. "@builddir@/grub-core/modinfo.sh" + +case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + # PLATFORM: emu is different. + *-emu) + exit 77;; + # PLATFORM: Flash targets. + i386-qemu | i386-coreboot | mips-qemu_mips | mipsel-qemu_mips) + exit 77;; + # FIXME: Currently grub-shell uses only -kernel for loongson. + mipsel-loongson) + exit 77;; + # FIXME: How do we setup serial ports in QEMU for these platforms? + *-ieee1275) + exit 77;; +esac + +# Figure out the PCI device ID that the serial device will be on. +output=$(echo terminal_output | "${grubshell}" --qemu-opts="-device pci-serial") +PCIID=$(echo "$output" | grep -o "serial_pci,..:..\.." | cut -d, -f2) + +if [ -z "$PCIID" ]; then + echo "Failed to find QEMU serial device." >&2 + echo "${output}" >&2 + exit 99 +fi + +# Test serial output via an emulated PCI serial card. +output=$(echo "terminal_output; hello" | \ + "${grubshell}" --serial="pci,${PCIID}" \ + --qemu-opts="-chardev file,path=/dev/stdout,id=ser1 -device pci-serial,chardev=ser1") + +v=$(echo -e "$output" | tail -n1) +if [ "$v" != "Hello World" ]; then + exit 1 +fi diff --git a/tests/squashfs_test.in b/tests/squashfs_test.in index 2f044f95d..15e70218f 100644 --- a/tests/squashfs_test.in +++ b/tests/squashfs_test.in @@ -4,7 +4,7 @@ set -e if ! which mksquashfs >/dev/null 2>&1; then echo "mksquashfs not installed; cannot test squashfs." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" squash4_gzip diff --git a/tests/syslinux_test.in b/tests/syslinux_test.in index 4ea86390e..44d3cdf7a 100644 --- a/tests/syslinux_test.in +++ b/tests/syslinux_test.in @@ -2,7 +2,7 @@ set -e -outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 "@builddir@/grub-syslinux2cfg" -r "@abs_top_srcdir@/tests/syslinux/ubuntu10.04" "@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/isolinux.cfg" -o "$outfile" diff --git a/tests/tar_test.in b/tests/tar_test.in index 6e2f2de8b..97944b243 100644 --- a/tests/tar_test.in +++ b/tests/tar_test.in @@ -4,7 +4,7 @@ set -e if ! which tar >/dev/null 2>&1; then echo "tar not installed; cannot test tar." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" tarfs diff --git a/tests/test_sha512sum.in b/tests/test_sha512sum.in index 027092a8b..b2bd89609 100644 --- a/tests/test_sha512sum.in +++ b/tests/test_sha512sum.in @@ -1,7 +1,8 @@ #! @BUILD_SHEBANG@ +set -e # create a randome file -file="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +file="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 cat >$file <$outfile1 <$outfile2 SHA1=`cat $outfile1 | tr -d '\n' | cut -f1 -d\ ` diff --git a/tests/tpm2_key_protector_test.in b/tests/tpm2_key_protector_test.in new file mode 100644 index 000000000..fae27f9e4 --- /dev/null +++ b/tests/tpm2_key_protector_test.in @@ -0,0 +1,340 @@ +#! @BUILD_SHEBANG@ -e + +# Test GRUBs ability to unseal a LUKS key with TPM 2.0 +# 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 . + +grubshell=@builddir@/grub-shell + +. "@builddir@/grub-core/modinfo.sh" + +if [ x${grub_modinfo_platform} != xemu ]; then + exit 77 +fi + +builddir="@builddir@" + +# Force build directory components +PATH="${builddir}:${PATH}" +export PATH + +if [ "x${EUID}" = "x" ] ; then + EUID=`id -u` +fi + +if [ "${EUID}" != 0 ] ; then + echo "not root; cannot test tpm2." + exit 99 +fi + +if ! command -v cryptsetup >/dev/null 2>&1; then + echo "cryptsetup not installed; cannot test tpm2." + exit 99 +fi + +if ! grep -q tpm_vtpm_proxy /proc/modules && ! modprobe tpm_vtpm_proxy; then + echo "no tpm_vtpm_proxy support; cannot test tpm2." + exit 99 +fi + +if ! command -v swtpm >/dev/null 2>&1; then + echo "swtpm not installed; cannot test tpm2." + exit 99 +fi + +if ! command -v tpm2_startup >/dev/null 2>&1; then + echo "tpm2-tools not installed; cannot test tpm2." + exit 99 +fi + +tpm2testdir="`mktemp -d "${TMPDIR:-/tmp}/$(basename "$0").XXXXXXXXXX"`" || exit 99 + +disksize=20M + +luksfile=${tpm2testdir}/luks.disk +lukskeyfile=${tpm2testdir}/password.txt + +# Choose a low iteration number to reduce the time to decrypt the disk +csopt="--type luks2 --pbkdf pbkdf2 --iter-time 1000" + +tpm2statedir=${tpm2testdir}/tpm +tpm2ctrl=${tpm2statedir}/ctrl +tpm2log=${tpm2statedir}/logfile + +sealedkey=${tpm2testdir}/sealed.tpm + +timeout=20 + +testoutput=${tpm2testdir}/testoutput + +vtext="TEST VERIFIED" + +ret=0 + +# Create the password file +echo -n "top secret" > "${lukskeyfile}" + +# Setup LUKS2 image +truncate -s ${disksize} "${luksfile}" || exit 99 +cryptsetup luksFormat -q ${csopt} "${luksfile}" "${lukskeyfile}" || exit 99 + +# Write vtext into the first block of the LUKS2 image +luksdev=/dev/mapper/`basename "${tpm2testdir}"` +cryptsetup open --key-file "${lukskeyfile}" "${luksfile}" `basename "${luksdev}"` || exit 99 +echo "${vtext}" > "${luksdev}" +cryptsetup close "${luksdev}" + +# Shutdown the swtpm instance on exit +cleanup() { + RET=$? + if [ -e "${tpm2ctrl}" ]; then + swtpm_ioctl -s --unix "${tpm2ctrl}" + fi + if [ "${RET}" -eq 0 ]; then + rm -rf "$tpm2testdir" || : + fi +} +trap cleanup EXIT INT TERM KILL QUIT + +mkdir -p "${tpm2statedir}" + +# Create the swtpm chardev instance +swtpm chardev --vtpm-proxy --tpmstate dir="${tpm2statedir}" \ + --tpm2 --ctrl type=unixio,path="${tpm2ctrl}" \ + --flags startup-clear --daemon > "${tpm2log}" || ret=$? +if [ "${ret}" -ne 0 ]; then + echo "Failed to start swtpm chardev: ${ret}" >&2 + exit 99 +fi + +# Wait for tpm2 chardev +tpm2timeout=${GRUB_TEST_SWTPM_DEFAULT_TIMEOUT:-3} +for count in `seq 1 ${tpm2timeout}`; do + sleep 1 + + tpm2dev=$(grep "New TPM device" "${tpm2log}" | cut -d' ' -f 4) + if [ -c "${tpm2dev}" ]; then + break + elif [ "${count}" -eq "${tpm2timeout}" ]; then + echo "TPM device did not appear." >&2 + exit 99 + fi +done + +# Export the TCTI variable for tpm2-tools +export TPM2TOOLS_TCTI="device:${tpm2dev}" + +# Extend PCR 0 +tpm2_pcrextend 0:sha256=$(echo "test0" | sha256sum | cut -d ' ' -f 1) || exit 99 + +# Extend PCR 1 +tpm2_pcrextend 1:sha256=$(echo "test1" | sha256sum | cut -d ' ' -f 1) || exit 99 + +tpm2_seal_unseal() { + srk_alg="$1" + handle_type="$2" + srk_test="$3" + + grub_srk_alg=${srk_alg} + + extra_opt="" + extra_grub_opt="" + + persistent_handle="0x81000000" + + grub_cfg=${tpm2testdir}/testcase.cfg + + if [ "${handle_type}" = "persistent" ]; then + extra_opt="--tpm2-srk=${persistent_handle}" + fi + + if [ "${srk_alg}" != "default" ]; then + extra_opt="${extra_opt} --tpm2-asymmetric=${srk_alg}" + fi + + # Seal the password with grub-protect + grub-protect ${extra_opt} \ + --tpm2-device="${tpm2dev}" \ + --action=add \ + --protector=tpm2 \ + --tpm2key \ + --tpm2-bank=sha256 \ + --tpm2-pcrs=0,1 \ + --tpm2-keyfile="${lukskeyfile}" \ + --tpm2-outfile="${sealedkey}" || ret=$? + if [ "${ret}" -ne 0 ]; then + echo "Failed to seal the secret key: ${ret}" >&2 + return 99 + fi + + # Flip the asymmetric algorithm in grub.cfg to trigger fallback SRKs + if [ "${srk_test}" = "fallback_srk" ]; then + if [ -z "${srk_alg##RSA*}" ]; then + grub_srk_alg="ECC" + elif [ -z "${srk_alg##ECC*}" ]; then + grub_srk_alg="RSA" + fi + fi + + if [ "${grub_srk_alg}" != "default" ] && [ "${handle_type}" != "persistent" ]; then + extra_grub_opt="-a ${grub_srk_alg}" + fi + + # Write the TPM unsealing script + cat > "${grub_cfg}" < "${testoutput}" || ret=$? + + # Remove the persistent handle + if [ "${handle_type}" = "persistent" ]; then + grub-protect \ + --tpm2-device="${tpm2dev}" \ + --protector=tpm2 \ + --action=remove \ + --tpm2-srk=${persistent_handle} \ + --tpm2-evict || : + fi + + if [ "${ret}" -eq 0 ]; then + if ! grep -q "^${vtext}$" "${testoutput}"; then + echo "error: test not verified [`cat ${testoutput}`]" >&2 + return 1 + fi + else + echo "grub-emu exited with error: ${ret}" >&2 + return 99 + fi +} + +tpm2_seal_unseal_nv() { + handle_type="$1" + key_type="$2" + + extra_opt="" + extra_grub_opt="" + + if [ "$handle_type" = "nvindex" ]; then + nv_index="0x1000000" + else + nv_index="0x81000000" + fi + + if [ "$key_type" = "tpm2key" ]; then + extra_opt="--tpm2key" + else + extra_grub_opt="--pcrs=0,1" + fi + + grub_cfg=${tpm2testdir}/testcase.cfg + + # Seal the key into a NV index guarded by PCR 0 and 1 + grub-protect ${extra_opt} \ + --tpm2-device="${tpm2dev}" \ + --action=add \ + --protector=tpm2 \ + --tpm2-bank=sha256 \ + --tpm2-pcrs=0,1 \ + --tpm2-keyfile="${lukskeyfile}" \ + --tpm2-nvindex="${nv_index}" || ret=$? + if [ "${ret}" -ne 0 ]; then + echo "Failed to seal the secret key into ${nv_index}: ${ret}" >&2 + return 99 + fi + + # Write the TPM unsealing script + cat > ${grub_cfg} < "${testoutput}" || ret=$? + + # Remove the object from the NV index + grub-protect \ + --tpm2-device="${tpm2dev}" \ + --protector=tpm2 \ + --action=remove \ + --tpm2-nvindex=${nv_index} \ + --tpm2-evict || : + + if [ "${ret}" -eq 0 ]; then + if ! grep -q "^${vtext}$" "${testoutput}"; then + echo "error: test not verified [`cat ${testoutput}`]" >&2 + return 1 + fi + else + echo "grub-emu exited with error: ${ret}" >&2 + return 99 + fi +} + +# Testcases for SRK mode +declare -a srktests=() +srktests+=("default transient no_fallback_srk") +srktests+=("RSA transient no_fallback_srk") +srktests+=("ECC transient no_fallback_srk") +srktests+=("RSA persistent no_fallback_srk") +srktests+=("ECC persistent no_fallback_srk") +srktests+=("RSA transient fallback_srk") +srktests+=("ECC transient fallback_srk") + +exit_status=0 + +for i in "${!srktests[@]}"; do + tpm2_seal_unseal ${srktests[$i]} || ret=$? + if [ "${ret}" -eq 0 ]; then + echo "TPM2 [SRK][${srktests[$i]}]: PASS" + elif [ "${ret}" -eq 1 ]; then + echo "TPM2 [SRK][${srktests[$i]}]: FAIL" + ret=0 + exit_status=1 + else + echo "Unexpected failure [SRK][${srktests[$i]}]" >&2 + exit ${ret} + fi +done + +# Testcases for NV index mode +declare -a nvtests=() +nvtests+=("persistent raw") +nvtests+=("nvindex raw") +nvtests+=("nvindex tpm2key") + +for i in "${!nvtests[@]}"; do + tpm2_seal_unseal_nv ${nvtests[$i]} || ret=$? + if [ "${ret}" -eq 0 ]; then + echo "TPM2 [NV Index][${nvtests[$i]}]: PASS" + elif [ "${ret}" -eq 1 ]; then + echo "TPM2 [NV Index][${nvtests[$i]}]: FAIL" + ret=0 + exit_status=1 + else + echo "Unexpected failure [NV index][${nvtests[$i]}]" >&2 + exit ${ret} + fi +done + +exit ${exit_status} diff --git a/tests/udf_test.in b/tests/udf_test.in index fb92f0173..302b28ab2 100644 --- a/tests/udf_test.in +++ b/tests/udf_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkudffs >/dev/null 2>&1; then echo "mkudffs not installed; cannot test UDF." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" udf diff --git a/tests/uhci_test.in b/tests/uhci_test.in index f0eec5032..de199a281 100644 --- a/tests/uhci_test.in +++ b/tests/uhci_test.in @@ -22,26 +22,31 @@ grubshell=@builddir@/grub-shell case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in # PLATFORM: Don't mess with real devices when OS is active *-emu) - exit 0;; + exit 77;; # FIXME: qemu gets bonito DMA wrong mipsel-loongson) - exit 0;; + exit 77;; # PLATFORM: no USB on ARC and qemu-mips platforms mips*-arc | mips*-qemu_mips) - exit 0;; + exit 77;; # FIXME: No native drivers are available for those - powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi) - exit 0;; + powerpc-ieee1275 | sparc64-ieee1275 | arm*-efi | loongarch64-efi) + exit 77;; esac -imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 +outfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99 echo "hello" > "$outfile" tar cf "$imgfile" "$outfile" -if [ "$(echo "nativedisk; source '(usb0)/$outfile';" | "${grubshell}" --qemu-opts="-device ich9-usb-uhci1 -drive id=my_usb_disk,file=$imgfile,if=none -device usb-storage,drive=my_usb_disk" | tail -n 1)" != "Hello World" ]; then +v=$(echo "nativedisk; source '(usb0)/$outfile';" | + "${grubshell}" --qemu-opts="-device ich9-usb-uhci1 + -drive id=my_usb_disk,file=$imgfile,if=none + -device usb-storage,drive=my_usb_disk") +v=$(echo "$v" | tail -n 1) +if [ "$v" != "Hello World" ]; then rm "$imgfile" rm "$outfile" exit 1 diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in index bc14a05ca..cac58dafa 100644 --- a/tests/util/grub-fs-tester.in +++ b/tests/util/grub-fs-tester.in @@ -1,12 +1,58 @@ #!@BUILD_SHEBANG@ set -e +export BLKID_FILE=/dev/null + +# We can't have this set, or filesystem tests will fail. +unset SOURCE_DATE_EPOCH + +[ "${GRUB_TEST_DEFAULT_DEBUG:-0}" -gt 1 ] && set -x fs="$1" +builddir="@builddir@" GRUBFSTEST="@builddir@/grub-fstest" +GRUBPROBE="@builddir@/grub-probe" -tempdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 +tempdir=`mktemp -d "${TMPDIR:-/tmp}/${0##*/}.$(date '+%Y%m%d%H%M%S%N').${fs}.XXX"` || +{ echo "Failed to make temporary directory"; exit 99; } + +# xorriso -as mkisofs options to ignore locale when processing file names and +# FSLABEL. This is especially needed for the conversion to Joliet UCS-2. +XORRISOFS_CHARSET="-input-charset UTF-8 -output-charset UTF-8" +DMNAME="${tempdir##*/}" +PASS="${PASS:-pass}" + +MOUNTS= +LODEVICES= +cleanup() { + if [ -n "$fs" -a -z "${fs##*zfs*}" -a -n "$FSLABEL" ]; then + zpool list "$FSLABEL" 2>/dev/null && + while ! zpool export "$FSLABEL" ; do + sleep 1; + done + fi + + for i in $MOUNTS; do + umount "$i" || : + done + + if [ -e /dev/mapper/"$DMNAME" ]; then + cryptsetup close --disable-locks "$DMNAME" + fi + + for lodev in $LODEVICES; do + local i=600 + while losetup -l -O NAME | grep -q "^$lodev\$"; do + losetup -d "$lodev" || sleep 1 + [ "$((i--))" = "0" ] && break + done + done + return 0 +} +trap cleanup EXIT INT +# This is for bash, dash and ash do not recognize ERR +trap cleanup ERR || : # This wrapper is to ease insertion of valgrind or time statistics run_it () { @@ -35,7 +81,12 @@ run_grubfstest () { need_images="$need_images $FSIMAGEP${i}.img"; done - run_it -c $NEED_IMAGES_N $need_images "$@" + case x"$fs" in + xluks*) + echo -n "$PASS" | run_it -C -c $NEED_IMAGES_N $need_images "$@";; + *) + run_it -c $NEED_IMAGES_N $need_images "$@";; + esac } # OS LIMITATION: GNU/Linux has no AFS support, so we use a premade image and a reference tar file. I.a. no multiblocksize test @@ -43,32 +94,34 @@ run_grubfstest () { MINLOGSECSIZE=9 MAXLOGSECSIZE=9 case x"$fs" in + xluks2) + MAXLOGSECSIZE=12;; xntfs*) MINLOGSECSIZE=8 MAXLOGSECSIZE=12;; xvfat*|xmsdos*) MINLOGSECSIZE=9 - # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096 + # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096 MAXLOGSECSIZE=12;; xext*) MINLOGSECSIZE=8 MAXLOGSECSIZE=12;; xbtrfs*) - MINLOGSECSIZE=8 - # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096 + MINLOGSECSIZE=12 + # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096 MAXLOGSECSIZE=12;; xxfs) MINLOGSECSIZE=9 - # OS LIMITATION: GNU/Linux doesn't accept > 4096 + # OS LIMITATION: GNU/Linux doesn't accept > 4096 MAXLOGSECSIZE=12;; xxfs_crc) MINLOGSECSIZE=9 - # OS LIMITATION: GNU/Linux doesn't accept > 1024 + # OS LIMITATION: GNU/Linux doesn't accept > 1024 MAXLOGSECSIZE=10;; xzfs*) - # OS LIMITATION: zfs-fuse hangs when creating zpool with sectors <=256B. + # OS LIMITATION: zfs-fuse hangs when creating zpool with sectors <=256B. MINLOGSECSIZE=9 - # OS LIMITATION: zfs-fuse fails with >= 32K sectors. + # OS LIMITATION: zfs-fuse fails with >= 32K sectors. # OS limitation: zfs-fuse always uses ashift=9 with loop devices MAXLOGSECSIZE=9;; esac @@ -92,7 +145,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do ;; xexfat*) MINBLKSIZE=$SECSIZE - # It could go further but it requires more and more space + # It could go further but it requires more and more space MAXBLKSIZE=8286208 ;; xhfs) @@ -121,47 +174,49 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do MAXBLKSIZE=4096 ;; xreiserfs*) - MINBLKSIZE=512 - # OS LIMITATION: 8192 isn't supported. + # OS LIMITATION: mkreiserfs says block sizes smaller than 4 KiB are + # not supported and bails. Its been this way since at least 2014. + MINBLKSIZE=4096 + # OS LIMITATION: 8192 isn't supported. MAXBLKSIZE=4096 ;; x"mdraid"*) MINBLKSIZE=4096 - # OS LIMITATION: Linux oopses with >=32768K + # OS LIMITATION: Linux oopses with >=32768K MAXBLKSIZE=$((16384*1024)) ;; x"lvm_raid1"* | x"lvm_raid4" | x"lvm_raid5" | x"lvm_raid6") - # OS LIMITATION: Linux crashes with less than 16384 + # OS LIMITATION: Linux crashes with less than 16384 MINBLKSIZE=16384 - # Could go further but what's the point? + # Could go further but what's the point? MAXBLKSIZE=$((65536*1024)) ;; x"lvm_mirrorall") MINBLKSIZE=2048 - # Could go further but what's the point? + # Could go further but what's the point? MAXBLKSIZE=$((65536*1024)) ;; x"lvm_mirror1") MINBLKSIZE=4096 - # Could go further but what's the point? + # Could go further but what's the point? MAXBLKSIZE=$((65536*1024)) ;; x"lvm_stripe") MINBLKSIZE=4096 - # Could go further but what's the point? + # Could go further but what's the point? MAXBLKSIZE=$((65536*1024)) ;; x"lvm"*) MINBLKSIZE=1024 - # Could go further but what's the point? + # Could go further but what's the point? MAXBLKSIZE=$((65536*1024)) ;; - xext4_encrypt) - # OS LIMITATION: Linux currently only allows the 'encrypt' feature - # in combination with block_size = PAGE_SIZE (4096 bytes on x86). - MINBLKSIZE=$(getconf PAGE_SIZE) - MAXBLKSIZE=$MINBLKSIZE - ;; + xext4_encrypt) + # OS LIMITATION: Linux currently only allows the 'encrypt' feature + # in combination with block_size = PAGE_SIZE (4096 bytes on x86). + MINBLKSIZE=$(getconf PAGE_SIZE) + MAXBLKSIZE=$MINBLKSIZE + ;; xext*) MINBLKSIZE=1024 if [ $MINBLKSIZE -lt $SECSIZE ]; then @@ -172,9 +227,13 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do xsquash*) MINBLKSIZE=4096 MAXBLKSIZE=1048576;; + x"erofs_"*) + MINBLKSIZE=4096 + MAXBLKSIZE=4096 + ;; xxfs|xf2fs) MINBLKSIZE=$SECSIZE - # OS Limitation: GNU/Linux doesn't accept > 4096 + # OS Limitation: GNU/Linux doesn't accept > 4096 MAXBLKSIZE=4096;; xxfs_crc) # OS Limitation: GNU/Linux doesn't accept != 1024 @@ -188,13 +247,13 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do MAXBLKSIZE=8192;; xufs*) MINBLKSIZE=4096 - # OS Limitation: Linux rejects 65536 blocks. + # OS Limitation: Linux rejects 65536 blocks. MAXBLKSIZE=32768;; xminix3) - # OS LIMITATION: Linux rejects non-power-of-two blocks. - # OS LIMITATION: Linux rejects > 4096. + # OS LIMITATION: Linux rejects non-power-of-two blocks. + # OS LIMITATION: Linux rejects > 4096. MINBLKSIZE=1024 - MAXBLKSIZE=4096;; + MAXBLKSIZE=1024;; esac if test "$BLKSTEP" -eq 0; then blksizes="$(powrange "$MINBLKSIZE" "$MAXBLKSIZE")" @@ -239,17 +298,17 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do unset NEED_IMAGES; case x$fs in - # RAID 1 has to work with even one device of the set. + # RAID 1 has to work with even one device of the set. xzfs_mirror | x"mdraid"*"_raid1" | xlvm_mirrorall | xlvm_raid1all) NEED_IMAGES_N=1;; - # Degrade raidz by removing 3 devices + # Degrade raidz by removing 3 devices xzfs_raidz3) NEED_IMAGES_N=$((NDEVICES-3));; - # Degrade raidz by removing 2 devices + # Degrade raidz by removing 2 devices xzfs_raidz2 | x"mdraid"*"_raid6" | x"lvm_raid6") NEED_IMAGES_N=$((NDEVICES-2));; - # Degrade raidz and btrfs RAID1 by removing one device - xbtrfs_raid1 | xbtrfs_raid10 | xzfs_raidz | x"mdraid"*"_raid4" \ + # Degrade raidz and btrfs RAID1 by removing one device + xbtrfs_raid1 | xbtrfs_raid10 | xzfs_raidz | x"mdraid"*"_raid4" \ | x"mdraid"*"_raid5" | x"mdraid"*"_raid10" | xlvm_mirror1 \ | x"lvm_raid1" | x"lvm_raid4" | x"lvm_raid5") NEED_IMAGES_N=$((NDEVICES-1));; @@ -273,10 +332,10 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do done if test "$CFILESRC" = "" ; then echo "Couldn't find compressible file" >&2 - exit 1 + exit 99 fi case x"$fs" in - # FS LIMITATION: 8.3 names + # FS LIMITATION: 8.3 names xmsdos*) CFILE="american.eng";; xiso9660) @@ -284,75 +343,77 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do *) CFILE="american-english";; esac - # OS LIMITATION: Limited by NAME_MAX (usually 255) in GNU/Linux + # OS LIMITATION: Limited by NAME_MAX (usually 255) in GNU/Linux LONGNAME="qwertzuiopasdfghjklyxcvbnm1234567890qwertzuiopasdfghjklyxcvbnm1234567890oiewqfiewioqoiqoiurqruewqoiuwoieoiiuewqroreqiufieiuwrnureweriuvceoiroiewqoiricdsalkcndsakfirefoiwqeoircorejwoijfreoijojoiewjfwnfcoirenfoirefnreoifenoiwfnoi" rm -rf "$MASTER" case x"$fs" in - # FS LIMITATION: HFS+ label is at most 255 UTF-16 chars + # FS LIMITATION: HFS+ label is at most 255 UTF-16 chars # OS LIMITATION: Linux HFS+ tools check UTF-8 length and don't # handle out-of-BMP characters x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap") FSLABEL="grub_;/testé䏌䐓䏕киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoiq" ;; - # FS LIMITATION: btrfs label is at most 255 UTF-8 chars + # FS LIMITATION: btrfs label is at most 255 UTF-8 chars x"btrfs"*) FSLABEL="grub_;/testé莭莽😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoi";; - # FS LIMITATION: f2fs label is at most 512 UTF-16 chars + # FS LIMITATION: f2fs label is at most 512 UTF-16 chars x"f2fs") FSLABEL="grub_;/testé䏌䐓䏕киритiurewfceniuewruewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoirvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoircreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoiq";; - # FS LIMITATION: exfat is at most 15 UTF-16 chars + # FS LIMITATION: exfat is at most 22 bytes of UTF-16 chars x"exfat") - FSLABEL="géт ;/莭莽😁кир";; - # FS LIMITATION: ntfs label is at most ?? UTF-16 chars + FSLABEL="éт ;/莭莽😁";; + # FS LIMITATION: ntfs label is at most ?? UTF-16 chars x"ntfs"*) FSLABEL="grub_;/testéтi u莭😁茝кириrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvniwnivrewiuvcrewvnuewvrrrewniureifiuewifjiww";; - # FS LIMITATION: nilfs2 label is at most 80 UTF-8 characters + # FS LIMITATION: nilfs2 label is at most 80 UTF-8 characters x"nilfs2") FSLABEL="grub_;/testéтi u😁莽茝кириrewfceniuewruevrewnuuireurevueurnievrewfne";; - # FS LIMITATION: afs and iso9660 label is at most 32 UTF-8 characters + # FS LIMITATION: afs and iso9660 label is at most 32 UTF-8 characters x"afs" | xiso9660 | xrockridge | xrockridge_joliet\ - | xiso9660_1999 | xrockridge_1999 | xrockridge_joliet_1999) + | xiso9660_1999 | xrockridge_1999\ + | xrockridge_joliet_1999 | xziso9660) FSLABEL="gr_;/é莭莽😁кирит u";; - # FS LIMITATION: bfs label is at most 32 UTF-8 characters - # OS LIMITATION: bfs label can't contain ; or / + # FS LIMITATION: bfs label is at most 32 UTF-8 characters + # OS LIMITATION: bfs label can't contain ; or / x"bfs") FSLABEL="grub_é莭莽😁кирит u";; - # FS LIMITATION: Joliet label is at most 16 UTF-16 characters + # FS LIMITATION: Joliet label is at most 16 UTF-16 characters # OS LIMITATION: xorriso doesn't handle out-of-BMP characters xjoliet | xjoliet_1999) FSLABEL="g;/_é䏌䐓䏕䎛䎾䏴кит u" #FSLABEL="g;/_é莭莽😁кит u" ;; - # FS LIMITATION: reiserfs, extN and jfs label is at most 16 UTF-8 characters - x"reiserfs_old" | x"reiserfs" | x"ext"* | x"lvm"* | x"mdraid"* | x"jfs" | x"jfs_caseins") + # FS LIMITATION: reiserfs, extN, jfs and erofs label is at most 16 UTF-8 characters + x"reiserfs_old" | x"reiserfs" | x"ext"* | x"lvm"* | x"luks"* | x"mdraid"* | x"jfs" | x"jfs_caseins" | x"erofs_"*) FSLABEL="g;/éт 莭😁";; - # FS LIMITATION: No underscore, space, semicolon, slash or international characters in UFS* in label. Limited to 32 UTF-8 characters + # FS LIMITATION: No underscore, space, semicolon, slash or international characters in UFS* in label. Limited to 32 UTF-8 characters x"ufs1" | x"ufs1_sun" | x"ufs2") FSLABEL="grubtest""ieurrucnenreeiurueurewf";; - # FS LIMITATION: XFS label is at most 12 UTF-8 characters + # FS LIMITATION: XFS label is at most 12 UTF-8 characters x"xfs"|x"xfs_crc") FSLABEL="géт 😁к";; - # FS LIMITATION: FAT labels limited to 11 characters, no international characters or lowercase + # FS LIMITATION: FAT labels limited to 11 characters, no international characters or lowercase + # and excluding the restricted characters in "*?.,;:/\|+=<>[]" x"vfat"* | xmsdos*) - FSLABEL="GRUBTEST ;_";; - # FS LIMITATION: AFFS is latin1. At most 29 characters + FSLABEL="G~!@#\$%^&(_";; + # FS LIMITATION: AFFS is latin1. At most 29 characters x"affs" | xaffs_intl) FSLABEL="grub_tt? #*w;/e£@¡¤½¾{[]}<>.,";; - # FS LIMITATION: SFS is latin1. At most 30 characters + # FS LIMITATION: SFS is latin1. At most 30 characters x"sfs"*) FSLABEL="GRUB tt öäüé;/àèç åø¿ª©þð׫»µ¬";; - # FS LIMITATION: HFS is Mac-Roman. At most 27 characters + # FS LIMITATION: HFS is Mac-Roman. At most 27 characters x"hfs") FSLABEL="grub_t;/estéàèèéie fiucnree";; - # FS LIMITATION: UDF label is either up to 127 latin1 characters or 63 UTF-16 ones + # FS LIMITATION: UDF label is either up to 127 latin1 characters or 63 UTF-16 ones # OS LIMITATION: Linux UDF tools force ASCII label ... x"udf") FSLABEL="grub_;/testurewfceniuewruevrewnuuireurevueurnievr";; - # FS LIMITATION: ZFS doesn't accept non-ASCII in label - # FIXME: since this is used as a path component for mount it's very limited in length + # FS LIMITATION: ZFS doesn't accept non-ASCII in label + # FIXME: since this is used as a path component for mount it's very limited in length xzfs_* | xzfs) FSLABEL="grub_testieufiue r";; esac @@ -362,7 +423,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do xlvm*) LVMBLKMUL=$(((5800 * 1048576) / (8 * BLKSIZE * NDEVICES))) DISKSIZE=$((8*BLKSIZE*LVMBLKMUL));; - # FS LIMITATION: some fs have disk size limit + # FS LIMITATION: some fs have disk size limit x"vfat12" | xmsdos12) DISKSIZE=$((4000*BLKSIZE));; x"vfat12a" | xmsdos12a) @@ -398,7 +459,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do BIGBLOCKCNT=$((5000 * 1048576)) case x"$fs" in - # FS LIMITATION: small filesystems + # FS LIMITATION: small filesystems x"vfat12" | xmsdos12) if [ $BLKSIZE -le 4096 ]; then BIGBLOCKCNT=0 @@ -431,8 +492,8 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do BIGBLOCKCNT=30000000;; xexfat) - # Big blocks waste really a lot of space. - # Not much is left. + # Big blocks waste really a lot of space. + # Not much is left. if [ $BLKSIZE = 2097152 ]; then BIGBLOCKCNT=4500000000 fi @@ -440,50 +501,50 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do BIGBLOCKCNT=3500000000 fi ;; - # FS LIMITATION: romfs image is limited to 4G. + # FS LIMITATION: romfs image is limited to 4G. x"romfs") BIGBLOCKCNT=$((4000 * 1048576));; - # FS LIMITATION: These FS have uint32 as file size field + # FS LIMITATION: These FS have uint32 as file size field x"vfat"* | xmsdos* | x"cpio_crc" | x"cpio_newc" | x"cpio_bin" | x"cpio_hpbin" | xsfs*) BIGBLOCKCNT=4294967295;; # FS LIMITATION: These FS have int32 as file size field # FIXME: not so sure about AFFS # OS LIMITATION: minix2/minix3 could be formatted in a way to permit more. x"minix3" | x"minix2" | x"hfs"| x"affs" | xaffs_intl | xreiserfs_old | xext2_old) - BIGBLOCKCNT=$((16#7fffffff));; + BIGBLOCKCNT=$((0x7fffffff));; - # FS LIMITATION: redundant storage - # We have only limited space. Mirroring multiplies it very effectively. + # FS LIMITATION: redundant storage + # We have only limited space. Mirroring multiplies it very effectively. xmdraid* | xlvm* | xzfs_mirror | xbtrfs_raid1) BIGBLOCKCNT=$((100 * 1048576));; - # We already test the FS for big files separately. Save some time here. + # We already test the FS for big files separately. Save some time here. x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*) BIGBLOCKCNT=$((100 * 1048576));; - # OS LIMITATION: bfs_fuse bugs beyond that + # OS LIMITATION: bfs_fuse bugs beyond that xbfs) BIGBLOCKCNT=$((800 * 1048576));; esac NOSYMLINK=n case x"$fs" in - # FS LIMITATION: no symlinks on FAT, exFAT, HFS, plain ISO9660 and Joliet - # OS LIMITATION: ntfs-3g creates interix symlinks which aren't real symlinks + # FS LIMITATION: no symlinks on FAT, exFAT, HFS, plain ISO9660 and Joliet + # OS LIMITATION: ntfs-3g creates interix symlinks which aren't real symlinks x"vfat"* | xmsdos* | x"hfs" | x"exfat" | x"ntfs"* \ | xiso9660 | xjoliet| xiso9660_1999 | xjoliet_1999) NOSYMLINK=y;; esac NOHARDLINK=n case x"$fs" in - # FS LIMITATION: no hardlinks on BFS, exfat, fat, hfs and SFS + # FS LIMITATION: no hardlinks on BFS, exfat, fat, hfs and SFS xbfs | xexfat | x"vfat"* | xmsdos* | xhfs | xsfs | xsfs_caseins) NOHARDLINK=y;; - # GRUB LIMITATION: no hardlink support on newc and hfs+ + # GRUB LIMITATION: no hardlink support on newc and hfs+ xcpio_crc | xcpio_newc | xhfsplus*) NOHARDLINK=y;; esac - # FS LIMITATION: some filesystems limit file name size + # FS LIMITATION: some filesystems limit file name size case x"$fs" in x"cpio_ustar") LONGNAME="`echo $LONGNAME |head -c 99`";; @@ -497,78 +558,84 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do LONGNAME="`echo $LONGNAME |head -c 60`";; x"udf") LONGNAME="`echo $LONGNAME |head -c 192`";; - # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999 + # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999 xjoliet | xjoliet_1999) LONGNAME="`echo $LONGNAME |head -c 103`";; xiso9660_1999) LONGNAME="`echo $LONGNAME |head -c 207`";; - # FS LIMITATION: 8.3 + # FS LIMITATION: 8.3 xmsdos*) LONGNAME="qwertzui.opa";; esac NOFILETIME=n NOFSTIME=n case x"$fs" in - # FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check it. - # FS LIMITATION: as far as I know those FS don't store their last modification date. + # FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check it. + # FS LIMITATION: as far as I know those FS don't store their last modification date. x"jfs_caseins" | x"jfs" | x"xfs" | x"xfs_crc" | x"btrfs"* | x"reiserfs_old" | x"reiserfs" \ | x"bfs" | x"afs" | x"f2fs" \ | x"tarfs" | x"cpio_"* | x"minix" | x"minix2" \ | x"minix3" | x"ntfs"* | x"udf" | x"sfs"*) NOFSTIME=y;; - # OS LIMITATION: Linux doesn't update fstime. + # OS LIMITATION: Linux doesn't update fstime. # OS LIMITATION: Linux apparently uses localtime instead of UTC xhfs) NOFILETIME=y; NOFSTIME=y;; - # GRUB LIMITATION: FAT and exFAT use localtime. Unusable for GRUB + # GRUB LIMITATION: FAT and exFAT use localtime. Unusable for GRUB x"vfat"* | x"msdos"* | x"exfat") NOFILETIME=y; NOFSTIME=y;; - # FS LIMITATION: romfs has no timestamps. + # FS LIMITATION: romfs has no timestamps. x"romfs") NOFILETIME=y; NOFSTIME=y;; esac NOFSLABEL=n case x"$fs" in - # FS LIMITATION: these filesystems have no label. + # FS LIMITATION: these filesystems have no label. x"cpio_"* | x"tarfs" | x"squash4_"* | x"minix" | x"minix2" \ | x"minix3" | xreiserfs_old) NOFSLABEL=y;; + x"erofs_"*) + MKFS_EROFS_VERSION=$(mkfs.erofs -V 2>/dev/null | tr ' ' '\n' | grep '^[0-9]') + # check if the version is at least 1.6 + if [ $(sort -V <(echo "$MKFS_EROFS_VERSION") <(echo "1.6") | head -n 1) != "1.6" ]; then + NOFSLABEL=y + fi esac PDIRCOMPNUM=210 PDIR2COMPNUM=210 case x$fs in - # OS LIMITATION: bfs_fuse bugs beyond that + # OS LIMITATION: bfs_fuse bugs beyond that xbfs) PDIRCOMPNUM=10 PDIR2COMPNUM=10;; - # OS LIMITATION: Linux supports only inline symlinks + # OS LIMITATION: Linux supports only inline symlinks xudf) if [ $BLKSIZE = 1024 ]; then PDIR2COMPNUM=113 fi ;; - # FS LIMITATION: at most 255 on path length - # FS LIMITATION: at most 100 on symlink length + # FS LIMITATION: at most 255 on path length + # FS LIMITATION: at most 100 on symlink length xcpio_ustar) PDIRCOMPNUM=84 PDIR2COMPNUM=30;; - # OS LIMITATION: Linux supports only symlink at most one block long on reiserfs + # OS LIMITATION: Linux supports only symlink at most one block long on reiserfs xreiserfs | xreiserfs_old) if [ $BLKSIZE = 512 ]; then PDIR2COMPNUM=114 fi ;; - # FS LIMITATION: SFS assumes that symlink - # with header fit in one block. - # FIXME: not sure about it. + # FS LIMITATION: SFS assumes that symlink + # with header fit in one block. + # FIXME: not sure about it. xsfs | xsfs_caseins) if [ $BLKSIZE = 512 ]; then PDIR2COMPNUM=147 fi ;; - # FS LIMITATION: AFFS assumes that symlink - # with rather larger header fit in one block. - # FIXME: not sure about it. + # FS LIMITATION: AFFS assumes that symlink + # with rather larger header fit in one block. + # FIXME: not sure about it. xaffs | xaffs_intl) if [ $BLKSIZE = 512 ]; then PDIR2COMPNUM=97 @@ -577,7 +644,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do PDIR="" - # OS LIMITATION: Limited by PATH_MAX (usually 1024) + # OS LIMITATION: Limited by PATH_MAX (usually 1024) for i in $(range 0 $((PDIRCOMPNUM-1)) 1); do PDIR="$PDIR/$i"; if test $((i%3)) = 0; then @@ -586,7 +653,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do done PDIR2="" - # OS LIMITATION: Limited by PATH_MAX (usually 1024) + # OS LIMITATION: Limited by PATH_MAX (usually 1024) for i in $(range 0 $((PDIR2COMPNUM-1)) 1); do PDIR2="${PDIR2}/$i"; if test $((i%3)) = 0; then @@ -597,26 +664,24 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do PFIL="p.img" unset LODEVICES - GENERATED=n LODEVICES= MOUNTDEVICE= case x"$fs" in x"tarfs" | x"cpio_"*| x"ziso9660" | x"romfs" | x"squash4_"*\ - | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet \ + | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet \ | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 \ - | xrockridge_joliet_1999) + | xrockridge_joliet_1999 | x"erofs_"*) MNTPOINTRW="$MASTER" MNTPOINTRO="$MASTER" - GENERATED=y mkdir -p "$MASTER";; - # No mkfs for GNU/Linux. Just unpack preformatted empty image + # No mkfs for GNU/Linux. Just unpack preformatted empty image *) mkdir -p "$MNTPOINTRW" mkdir -p "$MNTPOINTRO" for i in $(range 0 $((NDEVICES-1)) 1); do dd if=/dev/zero of="$FSIMAGEP${i}.img" count=1 bs=1 seek=$((DISKSIZE-1)) &> /dev/null - LODEVICE=$(losetup --find --show "$FSIMAGEP${i}.img") + LODEVICE=$(losetup --find --show "$FSIMAGEP${i}.img") || exit 99 LODEVICES="$LODEVICES $LODEVICE" if test "$i" = 0; then MOUNTDEVICE="$LODEVICE" @@ -651,27 +716,27 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do MOUNTFS="btrfs" ;; x"exfat") - "mkfs.$fs" -s $((BLKSIZE/512)) -n "$FSLABEL" "${MOUNTDEVICE}" + "mkfs.$fs" -c $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}" MOUNTOPTS="iocharset=utf8," MOUNTFS="exfat-fuse";; x"minix") "mkfs.minix" "${MOUNTDEVICE}" ;; - # mkfs.hfs and mkfs.hfsplus don't fill UUID. + # mkfs.hfs and mkfs.hfsplus don't fill UUID. x"hfsplus") "mkfs.hfsplus" -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}" - dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8 ;; + dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x468)) conv=notrunc count=8 ;; x"hfsplus_wrap") "mkfs.hfsplus" -w -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}" - dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8 + dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x468)) conv=notrunc count=8 MOUNTFS="hfsplus";; x"hfsplus_casesens") "mkfs.hfsplus" -s -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}" - dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#468)) conv=notrunc count=8 + dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x468)) conv=notrunc count=8 MOUNTFS="hfsplus";; x"hfs") "mkfs.hfs" -b $BLKSIZE -v "`echo $FSLABEL |recode utf8..macroman`" -h "${MOUNTDEVICE}" - dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((16#474)) conv=notrunc count=8 + dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x474)) conv=notrunc count=8 MOUNTOPTS="iocharset=utf8,codepage=macroman," ;; x"vfat"*|xmsdos*) @@ -689,7 +754,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do "mkfs.minix" -v "${MOUNTDEVICE}" MOUNTFS="minix";; x"minix3") - "mkfs.minix" -B $BLKSIZE -3 "${MOUNTDEVICE}" + "mkfs.minix" -3 "${MOUNTDEVICE}" MOUNTFS="minix";; x"ntfs"*) "mkfs.ntfs" -s "$SECSIZE" -c "$BLKSIZE" -L "$FSLABEL" -Q -q "${MOUNTDEVICE}" @@ -720,7 +785,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do sleep 1 "zfs" create -o casesensitivity=insensitive "$FSLABEL"/"grub fs" sleep 1;; - x"zfs_lzjb" | xzfs_gzip | xzfs_zle) + x"zfs_lzjb" | xzfs_gzip | xzfs_zle | xzfs_zstd) "zpool" create -O compression=${fs/zfs_/} -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}" sleep 1 "zfs" create -o compression=${fs/zfs_/} "$FSLABEL"/"grub fs" @@ -750,7 +815,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do sleep 1 "zfs" create "$FSLABEL"/"grub fs" sleep 1;; - x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"*) + x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"* | x"erofs_"*) INSTDEVICE=/dev/null;; x"reiserfs") "mkfs.reiserfs" --format=3.6 -b $BLKSIZE -l "$FSLABEL" -q "${MOUNTDEVICE}" ;; @@ -795,8 +860,14 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do MOUNTDEVICE="/dev/mapper/grub_test-testvol" MOUNTFS=ext2 "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; + x"luks"*) + echo -n "$PASS" | cryptsetup luksFormat --type "$fs" --sector-size $SECSIZE --pbkdf pbkdf2 --force-password --disable-locks $LODEVICE + echo -n "$PASS" | cryptsetup open --disable-locks $LODEVICE "$DMNAME" + MOUNTDEVICE="/dev/mapper/${DMNAME}" + MOUNTFS=ext2 + "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; xf2fs) - "mkfs.f2fs" -l "$FSLABEL" -q "${LODEVICES[0]}" ;; + "mkfs.f2fs" -l "$FSLABEL" -q "${MOUNTDEVICE}" ;; xnilfs2) "mkfs.nilfs2" -L "$FSLABEL" -b $BLKSIZE -q "${MOUNTDEVICE}" ;; xext2_old) @@ -807,10 +878,10 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O meta_bg,^resize_inode -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" MOUNTFS=ext4 ;; - xext4_encrypt) - MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O encrypt -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" - MOUNTFS=ext4 - ;; + xext4_encrypt) + MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.ext4" -O encrypt -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" + MOUNTFS=ext4 + ;; xext*) MKE2FS_DEVICE_SECTSIZE=$SECSIZE "mkfs.$fs" -b $BLKSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; xxfs) @@ -820,45 +891,45 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do "mkfs.xfs" -m crc=1 -b size=$BLKSIZE -s size=$SECSIZE -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; *) echo "Add appropriate mkfs command here" - exit 1 + exit 99 ;; esac BASEFILE="1.img" NASTYFILE=".?*\\!\"#%@\$%&'()+ ,-.:;<=>^{_}[]\`|~." case x"$fs" in - # FS LIMITATION: AFFS and SFS don't accept : + # FS LIMITATION: AFFS and SFS don't accept : xsfs*) NASTYFILE=".?*\\!\"#%@\$%&'()+ ,-.;<=>^{_}[]\`|~.";; - # FS LIMITATION: AFFS is limited in file name length (30) + # FS LIMITATION: AFFS is limited in file name length (30) x"affs" | xaffs_intl) NASTYFILE=".?*\\!\"#@\$'()+ ,-;<=>^{_}[]\`|~.";; - # FS LIMITATION: hfs, minix and minix2 are limited in file name length (30 or 31) + # FS LIMITATION: hfs, minix and minix2 are limited in file name length (30 or 31) x"hfs" | x"minix" | x"minix2") NASTYFILE=".?*\\!\"#@\$&'()+ ,-:;<=>{}[]\`|~.";; - # FS LIMITATION: FAT doesn't accept ?, *, \, ", :, <, >, | - # FS LIMITATION: FAT discards dots at the end. + # FS LIMITATION: FAT doesn't accept ?, *, \, ", :, <, >, | + # FS LIMITATION: FAT discards dots at the end. x"vfat"* | x"exfat") NASTYFILE=".!#%@\$%&'()+ ,-.;=^{_}[]\`~";; - # FS LIMITATION: 8.3 limitations apply + # FS LIMITATION: 8.3 limitations apply x"msdos"*) NASTYFILE="!#%@\$%&.;=^";; - # FS LIMITATION: No ' ', '*', '/', ':', ';', '?', '\\' in joliet - # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999 + # FS LIMITATION: No ' ', '*', '/', ':', ';', '?', '\\' in joliet + # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999 xjoliet | xjoliet_1999) NASTYFILE=".!\"#%@\$%&'()+,-.<=>^{_}[]\`|~.";; - # FS LIMITATION: iso9660 accepts only [0-9A-Z_]*, 32 characters at most + # FS LIMITATION: iso9660 accepts only [0-9A-Z_]*, 32 characters at most xiso9660) NASTYFILE="0123456789_acefghijknopqrvwxyz";; esac case x"$fs" in - # FS LIMITATION: HFS, AFFS and SFS use legacy codepage (mac-roman or latin1) + # FS LIMITATION: HFS, AFFS and SFS use legacy codepage (mac-roman or latin1) x"sfs"* | x"hfs" | x"affs" | xaffs_intl) IFILE="éàèüöäëñ" ISYM="ëñéüöäàè" ;; - # FS LIMITATION: filename length limitation. + # FS LIMITATION: filename length limitation. x"minix" | x"minix2") IFILE="éàèüö😁ñкиΕλκά" ISYM="Ελκάкиéà😁öäëñ" @@ -866,21 +937,21 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do xminix3) IFILE="éàèüöäëñкирица莭茝Ελλικά😁😜😒" ISYM="Ελλικά😁😜😒莭茝кирицаéàèüöäëñ";; - # GRUB LIMITATION: HFS+ uses NFD. GRUB doesn't handle NF conversion. + # GRUB LIMITATION: HFS+ uses NFD. GRUB doesn't handle NF conversion. # OS LIMITATION: Linux doesn't handle out-of-BMP characters for UTF-16 x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap") IFILE="éàèüöäëñкирилица䏌䐓䏕Ελληνικα̍䏌䐓䏕" ISYM="Ελληνικα̍кирилица䏌䐓䏕éàèüöäëñ䏌䐓䏕" ;; - # GRUB LIMITATION: On case-insensitive ZFS isn't supported with non-uppercase characters + # GRUB LIMITATION: On case-insensitive ZFS isn't supported with non-uppercase characters xzfs_caseins) IFILE="ÉÀÈÜÖÄËÑКИРИЛИЦА莭莽茝ΕΛΛΗΝΙΚΆ😁😜😒" ISYM="ΕΛΛΗΝΙΚΆКИРИЛИЦА😁😜😒ÉÀÈÜÖÄËÑ莭莽茝";; - # FS LIMITATION: 8.3 CP437 + # FS LIMITATION: 8.3 CP437 x"msdos"*) IFILE="éàèüöäëñ.éàè" ;; - # FS LIMITATION: iso9660 is ASCII-only. + # FS LIMITATION: iso9660 is ASCII-only. x"iso9660") IFILE="abcdefghijkmmnop" ;; @@ -907,13 +978,29 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do GRUBDEVICE="mduuid/`mdadm --detail --export $MOUNTDEVICE | grep MD_UUID=|sed 's,MD_UUID=,,g;s,:,,g'`";; xlvm*) GRUBDEVICE="lvm/grub_test-testvol";; + xluks*) + if test x"$fs" = xluks2 && ! (cryptsetup luksDump --debug-json --disable-locks $LODEVICE | grep -q "\"sector_size\":$SECSIZE"); then + echo "Unexpected sector size for $LODEVICE (expected: $SECSIZE)" + exit 1 + fi + + UUID=$(cryptsetup luksUUID --disable-locks $LODEVICE | tr -d '-') + PROBE_UUID=$("$GRUBPROBE" --device $MOUNTDEVICE --target=cryptodisk_uuid | tr -d '-') + if [ x"$UUID" != x"$PROBE_UUID" ]; then + echo "UUID FAIL" + echo "$UUID" + echo "$PROBE_UUID" + exit 1 + fi + GRUBDEVICE="cryptouuid/${UUID}" + ;; esac GRUBDIR="($GRUBDEVICE)" case x"$fs" in x"zfs"*) OSDIR="grub fs/" GRUBDIR="($GRUBDEVICE)/grub fs@";; - x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"* | xafs) + x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"* | xafs | x"erofs_"*) ;; *) if ! mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRW" -o ${MOUNTOPTS}${SELINUXOPTS}rw ; then @@ -923,21 +1010,19 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do sleep 1 done done - for i in $(range 0 $((NDEVICES-1)) 1); do - rm "$FSIMAGEP${i}.img" - done - exit 1; + exit 99; fi + MOUNTS="$MOUNTS $MNTPOINTRW" ;; esac case x"$fs" in - # FS LIMITATION: redundant storage + # FS LIMITATION: redundant storage xmdraid* | xlvm*) BLOCKCNT=1048576;; x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*) BLOCKCNT=1048576;; - # FS LIMITATION: small filesystems + # FS LIMITATION: small filesystems x"vfat16a" | x"msdos16a") BLOCKCNT=65536;; x"vfat12a" | xmsdos12a) @@ -967,31 +1052,23 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do x"ntfscomp") setfattr -h -v 0x00000800 -n system.ntfs_attrib_be "$MNTPOINTRW/$OSDIR";; esac - # OS LIMITATION: No AFS support under GNU/Linux + # OS LIMITATION: No AFS support under GNU/Linux mkdir "$MNTPOINTRW/$OSDIR/sdir" mkdir -p "$MNTPOINTRW/$OSDIR/$PDIR" - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/sdir/2.img" - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$BASEFILE" - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$NASTYFILE" - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$IFILE" - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$LONGNAME" - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$PDIR/$PFIL" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/sdir/2.img" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$BASEFILE" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$NASTYFILE" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$IFILE" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$LONGNAME" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$PDIR/$PFIL" if [ $PDIR != $PDIR2 ]; then - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/${PDIR2}/$PFIL" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/${PDIR2}/$PFIL" fi - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/CaSe" + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/CaSe" if [ x$CASESENS = xy ]; then - "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/cAsE" - fi - if (test x$fs = xvfat12a || test x$fs = xmsdos12a) && test x$BLKSIZE = x131072; then - # With this config there isn't enough space for full copy. - # Copy as much as we can - cp "${CFILESRC}" "$MNTPOINTRW/$OSDIR/${CFILE}" &> /dev/null; - else - - cp "${CFILESRC}" "$MNTPOINTRW/$OSDIR/${CFILE}"; - + "$builddir"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/cAsE" fi + dd if="${CFILESRC}" of="$MNTPOINTRW/$OSDIR/${CFILE}" bs=1024 count=1024 if [ x$NOSYMLINK != xy ]; then ln -s "$BASEFILE" "$MNTPOINTRW/$OSDIR/$BASESYM" @@ -1020,44 +1097,75 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do (cd "$MASTER"; find . | cpio -o -H "$(echo ${fs} | sed 's@^cpio_@@')" > "${FSIMAGEP}0.img" ) ;; x"ziso9660") FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso -compliance rec_mtime -set_filter_r --zisofs -- -zisofs default -as mkisofs -iso-level 3 -graft-points -R -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" -- -set_filter_r --zisofs -- -zisofs default -add /="$MASTER" ;; - x"iso9660") + xorriso -compliance rec_mtime -as mkisofs $XORRISOFS_CHARSET -iso-level 3 -graft-points -R -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" -- -add /="$MASTER" -- -zisofs default -set_filter_r --zisofs / -- ;; + x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999) FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; - x"joliet") - FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; - x"rockridge") - FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; - x"rockridge_joliet") - FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; - x"iso9660_1999") - FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; - x"joliet_1999") - FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; - x"rockridge_1999") - FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; - x"rockridge_joliet_1999") - FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); - xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; + XORRISO_ARGS="-compliance rec_mtime" + + if [ -z "${fs##*rockridge*}" ]; then + XORRISO_ARGS="$XORRISO_ARGS -rockridge on" + else + XORRISO_ARGS="$XORRISO_ARGS -rockridge off" + fi + + XORRISO_ARGS="$XORRISO_ARGS -as mkisofs $XORRISOFS_CHARSET -graft-points" + + if [ -z "${fs##*1999*}" ]; then + XORRISO_ARGS="$XORRISO_ARGS -iso-level 4" + else + XORRISO_ARGS="$XORRISO_ARGS -iso-level 3" + fi + + if [ -z "${fs##*joliet*}" ]; then + XORRISO_ARGS="$XORRISO_ARGS -J -joliet-long" + fi + + xorriso $XORRISO_ARGS -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGEP}0.img" /="$MASTER" ;; x"romfs") genromfs -V "$FSLABEL" -f "${FSIMAGEP}0.img" -d "$MASTER" ;; xsquash4_*) echo mksquashfs "$MASTER" "${FSIMAGEP}0.img" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE mksquashfs "$MASTER" "${FSIMAGEP}0.img" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE ;; + x"erofs_compact") + cmd="mkfs.erofs" + if [ x"$NOFSLABEL" != xy ]; then + cmd="$cmd -L \"$FSLABEL\"" + fi + cmd="$cmd -Eforce-inode-compact ${FSIMAGEP}0.img $MNTPOINTRW" + echo $cmd + eval $cmd + unset cmd + ;; + x"erofs_extended") + cmd="mkfs.erofs" + if [ x"$NOFSLABEL" != xy ]; then + cmd="$cmd -L \"$FSLABEL\"" + fi + cmd="$cmd -Eforce-inode-extended ${FSIMAGEP}0.img $MNTPOINTRW" + echo $cmd + eval $cmd + unset cmd + ;; + x"erofs_chunk") + cmd="mkfs.erofs" + if [ x"$NOFSLABEL" != xy ]; then + cmd="$cmd -L \"$FSLABEL\"" + fi + cmd="$cmd --chunksize=1048576 ${FSIMAGEP}0.img $MNTPOINTRW" + echo $cmd + eval $cmd + unset cmd + ;; x"bfs") sleep 1 fusermount -u "$MNTPOINTRW" + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" ;; xlvm*) sleep 1 for try in $(range 0 20 1); do if umount "$MNTPOINTRW" ; then + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" break; fi sleep 1; @@ -1066,10 +1174,20 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do sleep 1 vgchange -a n grub_test ;; + xluks*) + for try in $(range 0 20 1); do + if umount "$MNTPOINTRW" ; then + break; + fi + done + UMOUNT_TIME=$(date -u "+%Y-%m-%d %H:%M:%S") + cryptsetup close --disable-locks "$DMNAME" + ;; xmdraid*) sleep 1 for try in $(range 0 20 1); do if umount "$MNTPOINTRW" ; then + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" break; fi sleep 1; @@ -1082,6 +1200,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do sleep 1 for try in $(range 0 20 1); do if umount "$MNTPOINTRW" ; then + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" break; fi sleep 1; @@ -1108,16 +1227,29 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do ;; xsquash4_*) ;; + x"erofs_"*) + ;; xlvm*) vgchange -a y grub_test sleep 1 - mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;; + mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro + MOUNTS="$MOUNTS $MNTPOINTRO" + ;; + xluks*) + echo -n "$PASS" | cryptsetup open --disable-locks $LODEVICE "$DMNAME" + mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro + MOUNTS="$MOUNTS $MNTPOINTRO" + ;; xmdraid*) mdadm --assemble /dev/md/"${fs}_$NDEVICES" $LODEVICES sleep 1 - mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;; + mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro + MOUNTS="$MOUNTS $MNTPOINTRO" + ;; *) - mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;; + mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro + MOUNTS="$MOUNTS $MNTPOINTRO" + ;; esac run_grubfstest ls -- -la @@ -1164,8 +1296,8 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do fi if [ x$NOFILETIME != xy ]; then - filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$BASEFILE"|awk '{print $6; }') - if echo "$LSROUT" | grep -F "$filtime $BASEFILE" > /dev/null; then + filetime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$BASEFILE"|awk '{print $6; }') + if echo "$LSROUT" | grep -F "$filetime $BASEFILE" > /dev/null; then : else echo TIME FAIL @@ -1174,8 +1306,8 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do exit 1 fi - filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$LONGNAME"|awk '{print $6; }') - if echo "$LSROUT" | grep -F "$filtime $LONGNAME" > /dev/null; then + filetime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$LONGNAME"|awk '{print $6; }') + if echo "$LSROUT" | grep -F "$filetime $LONGNAME" > /dev/null; then : else echo LONG TIME FAIL @@ -1288,7 +1420,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do exit 1 fi - # Inconsistencies between GRUB and blkid. + # Inconsistencies between GRUB and blkid. case x"$fs" in x"iso9660" | x"ziso9660" | xrockridge | xjoliet | xrockridge_joliet | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) ;; x"zfs"*) @@ -1309,6 +1441,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do : else echo UUID FAIL + echo "$FSUUID" echo "$LSOUT" echo "$GRUBUUID" for lodev in $LODEVICES; do @@ -1317,12 +1450,12 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do exit 1 fi ;; - # FS LIMITATION: romfs, cpio, tar, squash4, minix, AFS, old reiserfs and minix2 - # have no UUID. - # GRUB LIMITATION: use creation date for squash4, AFFS and SFS? - # GRUB LIMITATION: use tags serials on UDF? - # GRUB LIMITATION: use root ctime on cpio, tar, minix*, UDF, reiserfs_old? - # GRUB LIMITATION: Support Atari UUIDs + # FS LIMITATION: romfs, cpio, tar, squash4, minix, AFS, old reiserfs and minix2 + # have no UUID. + # GRUB LIMITATION: use creation date for squash4, AFFS and SFS? + # GRUB LIMITATION: use tags serials on UDF? + # GRUB LIMITATION: use root ctime on cpio, tar, minix*, UDF, reiserfs_old? + # GRUB LIMITATION: Support Atari UUIDs x"romfs" | x"cpio_"* | x"tarfs" | x"squash4_"* | x"minix" \ | x"minix2" | x"minix3" | x"affs" | xaffs_intl \ | x"udf" | xvfat12a | xvfat16a | xmsdos12a | xmsdos16a | xafs | xsfs* \ @@ -1351,6 +1484,12 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do # With some abstractions like mdraid flushing to disk # may be delayed for a long time. FSTIME="$UMOUNT_TIME";; + xsquash*) + # Creating the squash image may take more than a few + # seconds. Use the more accurate timestamp from the + # superblock. + FSTIME="$(unsquashfs -UTC -s "${FSIMAGEP}0.img" | grep ^Creation | awk '{print $6 " " $7 " " $8 " " $9 " " $10; }')" + FSTIME="$(date -d "$FSTIME" -u '+%Y-%m-%d %H:%M:%S')";; *) FSTIME="$(TZ=UTC ls --time-style="+%Y-%m-%d_%H:%M:%S" -l -d "${FSIMAGEP}0.img"|awk '{print $6; }'|sed 's,_, ,g')";; esac @@ -1360,7 +1499,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do FSTIMEM2="$(date -d "$FSTIME UTC -2 second" -u "+%Y-%m-%d %H:%M:%S")" FSTIMEM3="$(date -d "$FSTIME UTC -3 second" -u "+%Y-%m-%d %H:%M:%S")" - if echo "$LSOUT" | grep -F 'Last modification time '"$FSTIME" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM1" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM2" || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM3" > /dev/null; then + if echo "$LSOUT" | grep -F 'Last modification time '"$FSTIME" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM1" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM2" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM3" > /dev/null; then : else echo FSTIME FAIL @@ -1430,7 +1569,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do echo NREAD FAIL exit 1 fi - # Reference archive contains original name + # Reference archive contains original name if run_grubfstest cmp "$GRUBDIR/$LONGNAME" "$MNTPOINTRO/$OSDIR/$LONGNAME" ; then : else @@ -1527,7 +1666,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do sleep 1; done sleep 5;; - x"tarfs" | x"cpio_"* | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | xiso9660 | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) + x"tarfs" | x"cpio_"* | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | xiso9660 | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999 | x"erofs_"*) rm -rf "$MNTPOINTRW";; x"afs") rm -rf "$MNTPOINTRO" @@ -1536,6 +1675,8 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do sleep 1 umount "$MNTPOINTRO" || true umount "$MNTPOINTRW" || true + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRO||g;")" + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" esac sleep 1 case x"$fs" in @@ -1547,9 +1688,12 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do vgchange -a n grub_test sleep 1 ;; + xluks*) + cryptsetup close --disable-locks "$DMNAME" + ;; esac case x"$fs" in - x"tarfs" | x"cpio_"* | x"iso9660" | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) ;; + x"tarfs" | x"cpio_"* | x"iso9660" | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999 | x"erofs_"*) ;; *) for lodev in $LODEVICES; do while ! losetup -d "$lodev"; do diff --git a/tests/util/grub-shell-luks-tester.in b/tests/util/grub-shell-luks-tester.in new file mode 100644 index 000000000..aa454d136 --- /dev/null +++ b/tests/util/grub-shell-luks-tester.in @@ -0,0 +1,378 @@ +#! @BUILD_SHEBANG@ -e + +# Test GRUBs ability to read various LUKS containers +# 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 . + +# Initialize some variables. +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" +builddir="@builddir@" +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_TARNAME=@PACKAGE_TARNAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ + +# Force build directory components +PATH="${builddir}:$PATH" +export PATH + +grub_shell_opts= +disk= +disksize=20M +detached_header= +keyfile= +keyfile_offset= +keyfile_size= +KEYFILE_SIZE_MAX=4096 +expected_res=0 + +debug="${GRUB_SHELL_LUKS_DEFAULT_DEBUG:-$GRUB_TEST_DEFAULT_DEBUG}" +GRUB_SHELL_LUKS_TIMEOUT=${GRUB_SHELL_LUKS_TIMEOUT:-${GRUB_SHELL_DEFAULT_TIMEOUT:-600s}} + +# Usage: usage +# Print the usage. +usage () { + cat <. +EOF +} + +. "${builddir}/grub-core/modinfo.sh" + +# Check the arguments. +for option in "$@"; do + case "$option" in + -h | --help) + usage + exit 0 ;; + -v | --version) + echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + exit 0 ;; + -d | --debug) + debug=$((${debug:-0}+1)) ;; + --debug=*) + debug=$((`echo "$option" | sed -e 's/--debug=//'`)) ;; + --modules=*) + ms=`echo "$option" | sed -e 's/--modules=//'` + modules="$modules,$ms" ;; + --qemu-opts=*) + qs=`echo "$option" | sed -e 's/--qemu-opts=//'` + qemuopts="$qemuopts $qs" ;; + --cs-opts=*) + qs=`echo "$option" | sed -e 's/--cs-opts=//'` + csopts="$csopts $qs" ;; + --cs-script=*) + qs=`echo "$option" | sed -e 's/--cs-script=//'` + csscripts="$csscripts $qs" ;; + --luks=*) + qs=`echo "$option" | sed -e 's/--luks=//'` + csopts="$csopts --type luks$qs" ;; + --detached-header) + detached_header=1 ;; + --keyfile=*) + qs=`echo "$option" | sed -e 's/--keyfile=//'` + keyfile="$qs" ;; + --keyfile) + keyfile=1 ;; + --disksize=*) + qs=`echo "$option" | sed -e 's/--disksize=//'` + disksize="$qs" ;; + --xfail) + expected_res=1 ;; + -*) + echo "Unrecognized option \`$option'" 1>&2 + usage + exit 3 + ;; + *) + if [ "x${source}" != x ] ; then + echo "too many parameters at the end" 1>&2 + usage + exit 4 + fi + source="${option}" ;; + esac +done + +[ "${debug:-0}" -gt 1 ] && set -x + +grub_shell_opts="$grub_shell_opts --timeout=${GRUB_SHELL_LUKS_TIMEOUT}" + +if [ "${debug:-0}" -gt 2 ]; then + grub_shell_opts="$grub_shell_opts --qemu-opts=-nographic" +fi + +# Make sure that the dm-crypto device is shutdown +cleanup() { + RET=$? + if [ -e "$luksdev" ]; then + cryptsetup close "$luksdev" + fi + if [ -z "$debug" ] && [ "$RET" -eq "$expected_res" ]; then + rm -rf "$lukstestdir" || : + fi +} +trap cleanup EXIT INT TERM KILL QUIT + +get_random_bytes() { + local NUM_BYTES=$1 + dd if=/dev/urandom bs=512 count=$((($NUM_BYTES / 512)+2)) 2>/dev/null \ + | tr -d '\0' | dd bs=1 count=$(($NUM_BYTES)) 2>/dev/null +} + +# Create a random directory to be hold generated files +lukstestdir="`mktemp -d "${TMPDIR:-/tmp}/$(basename "$0").XXXXXXXXXX"`" || exit 20 +luksfile=$lukstestdir/luks.disk +lukshdrfile=$lukstestdir/luks.header +luksdiskfile=${detached_header:+$lukshdrfile} +luksdiskfile=${luksdiskfile:-$luksfile} +lukskeyfile=$lukstestdir/luks.key +vfile=$lukstestdir/mnt/test.verify +vtext="TEST VERIFIED" +testvars=$lukstestdir/testvars +testcase=$lukstestdir/testcase.cfg +testoutput=$lukstestdir/testoutput +password=testpass + +[ -n "$debug" ] && echo "LUKS TEST directory: $lukstestdir" >&2 + +# If testing keyfiles, create a big one. +if [ -e "$keyfile" ]; then + password=`cat "$keyfile"` +elif [ -n "$keyfile" ]; then + password=`get_random_bytes $KEYFILE_SIZE_MAX` +fi + +if [ -n "$detached_header" ]; then + csopts="$csopts --header $lukshdrfile" +fi + +# Create the key file +echo -n "$password" > $lukskeyfile + +# Create a very small LUKS container for the test +truncate -s $disksize $luksfile || exit 21 + +# Format the luks disk file +cryptsetup luksFormat -q $csopts ${luksfile} ${lukskeyfile} || exit 22 +if [ -z "$detached_header" ]; then + cryptomount_opts="$cryptomount_opts -u $(cryptsetup luksUUID ${luksdiskfile})" +elif [ -z "$disk" ]; then + # In detached header mode, so must pass the disk to cryptomount. + # Is this always correct? + disk=hd0 +fi + +# Run any cryptsetup scripts +export luksdiskfile +export lukskeyfile +for csscript in $csscripts; do + [ -f "$csscript" ] && . $csscript +done + +# Look for --keyfile-offset and --keyfile-size options in the cryptsetup +# options, and process them specially. +csopen_opts= +get_args=0 +varname= +for option in $csopts; do + if [ "$get_args" -gt 0 ]; then + csopen_opts=" $csopen_opts $option" + get_args=$(($get_args - 1)) + eval ${varname}=$option + continue + fi + + case "$option" in + --keyfile-offset) + varname=keyfile_offset + get_args=1 ;; + --keyfile-offset=*) + keyfile_offset=`echo "$option" | sed -e 's/--keyfile-offset=//'` ;; + --keyfile-size | -l) + varname=keyfile_size + get_args=1 ;; + --keyfile-size=*) + keyfile_size=`echo "$option" | sed -e 's/--keyfile-size=//'` ;; + *) + continue ;; + esac + + csopen_opts=" $csopen_opts $option" +done + +# Open LUKS device +luksdev=/dev/mapper/`basename $lukstestdir` +cryptsetup open ${detached_header:+--header $lukshdrfile} $csopen_opts \ + --key-file $lukskeyfile $luksfile `basename $luksdev` || exit 23 + +# Make filesystem on the luks disk +mkfs.vfat $luksdev >/dev/null 2>&1 || exit 24 + +# Add verification file to filesystem +mkdir $lukstestdir/mnt +mount $luksdev $lukstestdir/mnt || exit 25 +echo "$vtext" > $vfile + +# Unmount filesystem +umount $lukstestdir/mnt || exit 26 + +. "@builddir@/grub-core/modinfo.sh" + +if [ x"${grub_modinfo_platform}" = xemu ]; then + grub_testvars="(host)$testvars" + grub_key_file="(host)$lukskeyfile" + grub_lukshdr_file="(host)$lukshdrfile" +else + grub_testvars="/testvars" + grub_key_file="/keyfile" + grub_lukshdr_file="/luks.header" +fi + + +# Can not use --disk with a raw LUKS container because it appears qemu +# tries to convert the image to and is failing with: +# "Parameter 'key-secret' is required for cipher" +qemuopts="$qemuopts -drive file=$luksfile,media=disk,format=raw" + +# Add crypto modules +modules="$modules cryptodisk luks luks2 fat" + +# Create randomly generated trim line +trim_line=`mktemp -u XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` + +# Create vars to import into grub script +cat >$testvars <>$testvars +fi + +# Create testcase script +cat >$testcase <<'EOF' +set debug=all +search -n -f --set=testvarsdev /testvars +if [ "$?" -ne 0 ]; then + echo; echo "$trim_line" + echo "Could not find testvars file." + ${halt_cmd} +fi +set debug= + +. ($testvarsdev)/testvars + +# If key file exists, use it instead of password +if [ -e "$grub_key_file" ]; then + cryptomount_opts="$cryptomount_opts -k $grub_key_file" +else + cryptomount_opts="$cryptomount_opts -p $grub_password" +fi + +if [ -n "$grub_keyfile_offset" ]; then + cryptomount_opts="$cryptomount_opts -O $grub_keyfile_offset" +fi + +if [ -n "$grub_keyfile_size" ]; then + cryptomount_opts="$cryptomount_opts -S $grub_keyfile_size" +fi + +if [ -e "$grub_lukshdr_file" ]; then + cryptomount_opts="$cryptomount_opts -H $grub_lukshdr_file" +fi + +cdisk=crypto0 + +if test -n "$grub_debug" -a "$grub_debug" -gt 0; then + echo cmd: cryptomount $cryptomount_opts $disk + echo -n "devices: " + ls +fi + +if test -n "$grub_debug" -a "$grub_debug" -gt 1; then + set debug=all +fi +cryptomount $cryptomount_opts $disk +ret="$?" +if test -n "$grub_debug" -a "$grub_debug" -eq 2; then + set debug= +fi + +echo; echo "$trim_line" +if test $ret -eq 0; then + cat ($cdisk)/$vfilename +else + echo "cryptomount failed: $ret" +fi +EOF + +grub_shell_opts="$grub_shell_opts --trim=${trim_line}" +if [ -n "$keyfile" ]; then + grub_shell_opts="$grub_shell_opts --files=${keyfile:+${grub_key_file}=${lukskeyfile}}" +fi + +if [ -n "$detached_header" ]; then + grub_shell_opts="$grub_shell_opts --files=${detached_header:+${grub_lukshdr_file}=${lukshdrfile}}" +fi + +# Run the test in grub-shell +@builddir@/grub-shell ${debug:+--debug=$debug} $grub_shell_opts \ + --modules="$modules" --qemu-opts="$qemuopts" \ + --files="${grub_testvars}=${testvars}" "$testcase" \ + >$testoutput +ret=$? + +if [ "$ret" -eq 0 ]; then + if ! grep -q "^${vtext}$" "$testoutput"; then + echo "error: test not verified [`cat $testoutput`]" >&2 + exit 1 + fi +else + echo "grub-shell exited with error: $ret" >&2 + exit 27 +fi + +exit $ret diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 93e9f5148..8baa3667a 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -32,6 +32,7 @@ PATH="${builddir}:$PATH" export PATH trim=0 +trim_head=664cbea8-132f-4770-8aa4-1696d59ac35c # Usage: usage # Print the usage. @@ -59,8 +60,22 @@ Report bugs to . EOF } +# Exec given argv and only show its output on STDERR if it returns an +# error status. +exec_show_error () { + v=`$@ 2>&1` + ret=$? + if [ "$ret" != 0 ]; then + echo "$v" >&2 + exit $ret + fi +} + +work_directory=${WORKDIR:-`mktemp -d "${TMPDIR:-/tmp}/grub-shell.XXXXXXXXXX"`} || exit 1 + . "${builddir}/grub-core/modinfo.sh" -qemuopts="${GRUB_QEMU_OPTS}" +qemuopts=${GRUB_QEMU_OPTS} +emuopts= serial_port=com0 serial_null= halt_cmd=halt @@ -68,7 +83,7 @@ pseries=n disk="hda " case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in *-emu) - device_map=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + device_map="$work_directory/device.map" boot=emu console=console disk=0 @@ -84,6 +99,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in serial_null="-serial null" netbootext=elf trim=1 + qemuopts="-M mac99,via=pmu $qemuopts" ;; sparc64-ieee1275) @@ -166,21 +182,92 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in boot=cd console=console trim=1 - qemuopts="-bios OVMF-ia32.fd $qemuopts" + pflash=${srcdir}/OVMF32.fd + pflash_code=${srcdir}/OVMF32_CODE.fd + pflash_vars=${srcdir}/OVMF32_VARS.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + if [ -f "$pflash_vars" ]; then + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + fi + else + pflash=/usr/share/qemu/OVMF32.fd + pflash_code=/usr/share/OVMF/OVMF32_CODE_4M.secboot.fd + pflash_vars=/usr/share/OVMF/OVMF32_VARS_4M.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + else + echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2 + exit 1 + fi + fi + qemuopts="-machine q35 $qemuopts" ;; x86_64-efi) qemu=qemu-system-x86_64 boot=cd console=console trim=1 - qemuopts="-bios OVMF.fd $qemuopts" + pflash=${srcdir}/OVMF.fd + pflash_code=${srcdir}/OVMF_CODE.fd + pflash_vars=${srcdir}/OVMF_VARS.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + if [ -f "$pflash_vars" ]; then + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + fi + else + pflash=/usr/share/qemu/OVMF.fd + pflash_code=/usr/share/OVMF/OVMF_CODE.fd + pflash_vars=/usr/share/OVMF/OVMF_VARS.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + else + echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2 + exit 1 + fi + fi ;; arm64-efi) qemu=qemu-system-aarch64 boot=hd console=console trim=1 - qemuopts="-machine virt -cpu cortex-a57 -bios /usr/share/qemu-efi/QEMU_EFI.fd $qemuopts" + pflash=${srcdir}/AAVMF.fd + pflash_code=${srcdir}/AAVMF_CODE.fd + pflash_vars=${srcdir}/AAVMF_VARS.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + if [ -f "$pflash_vars" ]; then + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + fi + else + pflash=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd + pflash_code=/usr/share/AAVMF/AAVMF_CODE.fd + pflash_vars=/usr/share/AAVMF/AAVMF_VARS.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + else + echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2 + exit 1 + fi + fi + qemuopts="-machine virt -cpu cortex-a57 $qemuopts" disk="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file=" serial_port= ;; @@ -189,18 +276,61 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in boot=hd console=console trim=1 - qemuopts="-machine virt -bios /usr/share/ovmf-arm/QEMU_EFI.fd $qemuopts" + pflash=${srcdir}/AAVMF32.fd + pflash_code=${srcdir}/AAVMF32_CODE.fd + pflash_vars=${srcdir}/AAVMF32_VARS.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + if [ -f "$pflash_vars" ]; then + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + fi + else + pflash=/usr/share/AAVMF/AAVMF32.fd + pflash_code=/usr/share/AAVMF/AAVMF32_CODE.fd + pflash_vars=/usr/share/AAVMF/AAVMF32_VARS.fd + if [ -f "$pflash" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,snapshot=on,file=$pflash $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,unit=0,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,unit=1,snapshot=on,file=$pflash_vars $qemuopts" + else + echo "Firmware not found, please install either the appropriate Debian package or an appropriately named copy in the source directory." >&2 + exit 1 + fi + fi + qemuopts="-machine virt $qemuopts" disk="device virtio-blk-device,drive=hd1 -drive if=none,id=hd1,file=" serial_port=efi0 ;; + loongarch64-efi) + qemu=qemu-system-loongarch64 + boot=hd + console=console + trim=1 + qemuopts="-machine virt -cpu la464-loongarch-cpu -smp 4 -nographic -m 3G \ + -bios QEMU_EFI.fd -L ${srcdir} -L /usr/share/edk2/loongarch64 \ + -L /usr/share/qemu-efi-loongarch64 $qemuopts" + disk="device virtio-blk-pci,drive=hd1 -drive if=none,id=hd1,file=" + serial_port= + ;; *) boot=hd qemu=qemu-system-i386 console=console;; esac -timeout=60 +case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + # Only add the RNG device for EFI platforms because we currently only + # support Stack Smashing protection on EFI. + *-efi) + qemuopts="$qemuopts -device virtio-rng-pci" ;; +esac + +timeout=${GRUB_SHELL_DEFAULT_TIMEOUT:-60} mkimage_extra_arg= +debug=${GRUB_SHELL_DEFAULT_DEBUG:-$GRUB_TEST_DEFAULT_DEBUG} # Check the arguments. for option in "$@"; do @@ -212,10 +342,17 @@ for option in "$@"; do echo "$0 (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; --trim) - trim=1 + trim=1 ;; + --trim=*) + trim=2 + trim_head=`echo "$option" | sed -e 's/--trim=//' -e 's/,/ /g'` ;; + --no-trim) + trim=0 ;; --debug) - debug=1 ;; + debug=$((debug+1)) ;; + --debug=*) + debug=$((`echo "$option" | sed -e 's/--debug=//'`)) ;; --modules=*) ms=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'` modules="$modules $ms" ;; @@ -225,21 +362,26 @@ for option in "$@"; do --mkrescue-arg=*) mkr=`echo "$option" | sed -e 's/--mkrescue-arg=//' -e 's/,/ /g'` mkrescue_args="$mkrescue_args $mkr" ;; - --qemu=*) - qemu=`echo "$option" | sed -e 's/--qemu=//' -e 's/,/ /g'`;; --pseries) qemu=qemu-system-ppc64 serial_port=ieee1275/hvterm serial_null= - qemuopts="$qemuopts -M pseries -no-reboot" + qemuopts="$(echo $qemuopts | sed -E 's/-M [^ ]+//') -M pseries -no-reboot" trim=1 pseries=y ;; + --serial=*) + serial_port=`echo "$option" | sed -e 's/--serial=//'`;; + --qemu=*) + qemu=`echo "$option" | sed -e 's/--qemu=//' -e 's/,/ /g'`;; --qemu-opts=*) - qs=`echo "$option" | sed -e 's/--qemu-opts=//'` - qemuopts="$qemuopts $qs" ;; + qs=`echo "$option" | sed -e 's/--qemu-opts=//'` + qemuopts="$qemuopts $qs" ;; + --emu-opts=*) + qs=`echo "$option" | sed -e 's/--emu-opts=//'` + emuopts="$emuopts $qs" ;; --disk=*) - dsk=`echo "$option" | sed -e 's/--disk=//'` + dsk=`echo "$option" | sed -e 's/--disk=//'` if [ ${grub_modinfo_platform} = emu ]; then echo "(hd$disk) $dsk" >> "$device_map" disk="$((disk+1))" @@ -248,7 +390,7 @@ for option in "$@"; do echo "Too many disks" 1>&2 exit 1; fi - qemuopts="$qemuopts -$disk$dsk" + qemuopts="$qemuopts -$disk$dsk" if [ "$disk" = "hda " ]; then disk="hdb "; elif [ "$disk" = "hdb " ]; then @@ -261,7 +403,7 @@ for option in "$@"; do fi ;; --timeout=*) - timeout=`echo "$option" | sed -e 's/--timeout=//'` + timeout=`echo "$option" | sed -e 's/--timeout=//'` ;; # Intentionally undocumented @@ -271,7 +413,7 @@ for option in "$@"; do mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;; --boot=*) - dev=`echo "$option" | sed -e 's/--boot=//'` + dev=`echo "$option" | sed -e 's/--boot=//'` if [ "$dev" = "fd" ] ; then boot=fd; elif [ "$dev" = "hd" ] ; then boot=hd; elif [ "$dev" = "cd" ] ; then boot=cd; @@ -300,19 +442,26 @@ for option in "$@"; do esac done +[ "${debug:-0}" -gt 1 ] && set -x + if [ "x${source}" = x ] ; then - tmpfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + tmpfile="$work_directory/testcase.cfg" while read REPLY; do echo "$REPLY" >> ${tmpfile} done source=${tmpfile} fi -cfgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 +cfgfile="$work_directory/grub.cfg" cat <${cfgfile} grubshell=yes +halt_cmd=${halt_cmd} +export halt_cmd enable_progress_indicator=0 export enable_progress_indicator +if [ "${grub_modinfo_platform}" == efi ]; then + gdbinfo +fi EOF @@ -336,13 +485,12 @@ terminal_input ${term} terminal_output ${term} EOF -trim_head=664cbea8-132f-4770-8aa4-1696d59ac35c - if [ $trim = 1 ]; then - echo "echo $trim_head" >>${cfgfile} + echo "echo; echo $trim_head" >>${cfgfile} fi -rom_directory=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 +rom_directory="$work_directory/rom_directory" +mkdir -p "$rom_directory" for mod in ${modules} do @@ -361,9 +509,12 @@ echo "${halt_cmd}" >>${cfgfile} test -z "$debug" || echo "GRUB script: ${cfgfile}" >&2 test -z "$debug" || echo "GRUB testcase script: ${tmpfile}" >&2 + +goutfile="$work_directory/grub-qemu.log" +test -z "$debug" || echo "GRUB output log: ${goutfile}" >&2 test -z "$debug" || echo "Boot device: ${boot}" >&2 -isofile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 +isofile="$work_directory/grub.iso" test -z "$debug" || echo "GRUB ISO file: ${isofile}" >&2 test -z "$debug" || echo "GRUB ROM directory: ${rom_directory}" >&2 @@ -375,21 +526,31 @@ if test -z "$debug"; then # workaround unfortunately causes qemu to issue a warning 'externally # provided fw_cfg item names should be prefixed with "opt/"', but there # doesn't seem to be a better option. - qemuopts="${qemuopts} -fw_cfg name=etc/sercon-port,string=0" + # + # SeaBIOS is used for i386, except on EFI. + if [ ${grub_modinfo_target_cpu} == 'i386' ] && [ ${grub_modinfo_platform} != 'efi' ]; then + qemuopts="${qemuopts} -fw_cfg name=etc/sercon-port,string=0" + fi fi if [ x$boot != xnet ] && [ x$boot != xemu ]; then - pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ + pkgdatadir="${builddir}" \ + exec_show_error "${builddir}/grub-mkrescue" \ + ${debug:+$([ "$debug" -gt 2 ] && echo -n "--verbose")} \ + "--output=${isofile}" \ + "--override-directory=${builddir}/grub-core" \ --rom-directory="${rom_directory}" \ - --locale-directory="@srcdir@/po" \ - --themes-directory="@srcdir@/themes" \ + --locale-directory="${srcdir}/po" \ + --themes-directory="${srcdir}/themes" \ $mkimage_extra_arg ${mkrescue_args} \ "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \ - ${files} >/dev/null 2>&1 + ${files} || exit $? fi if [ x$boot = xhd ]; then if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi ]; then device="device virtio-blk-device,drive=hd0 -drive if=none,id=hd0,file=" + elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = loongarch64-efi ]; then + device="device virtio-blk-pci,drive=grubdisk -drive if=none,id=grubdisk,file=" elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = mips-arc ]; then device="hdb " else @@ -400,6 +561,8 @@ fi if [ x$boot = xcd ]; then if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi ]; then device="device virtio-blk-device,drive=cd0 -drive if=none,id=cd0,media=cdrom,file=" + elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = loongarch64-efi ]; then + device="device virtio-blk-pci,drive=grubcd -drive if=none,id=grubcd,media=cdrom,file=" elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ] && [ x$pseries != xy ] ; then device="-drive if=ide,media=cdrom,file=" else @@ -433,7 +596,7 @@ if [ x$boot = xmips_qemu ]; then fi if [ x$boot = xcoreboot ]; then - imgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + imgfile="$work_directory/coreboot.img" cp "${GRUB_COREBOOT_ROM}" "${imgfile}" "${GRUB_CBFSTOOL}" "${imgfile}" add-payload -f "${rom_directory}/coreboot.elf" -n fallback/payload bootdev="-bios ${imgfile}" @@ -452,8 +615,8 @@ fi do_trim () { - if [ $trim = 1 ]; then - awk '{ if (have_head == 1) print $0; } /664cbea8-132f-4770-8aa4-1696d59ac35c/ { have_head=1; }' + if [ $trim = 1 ] || [ $trim = 2 ]; then + awk '{ if (have_head == 1) print $0; } /^'"$trim_head"'/ { have_head=1; }' else cat fi @@ -475,22 +638,34 @@ copy_extra_files() { done } +setup_qemu_logger() { + cat < "$work_directory/qemu-pipe" | tr -d "\r" | tee "${goutfile}" | do_trim & +} + +ret=0 +mkfifo "$work_directory/qemu-pipe" if [ x$boot = xnet ]; then - netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 - pkgdatadir="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null + netdir="$work_directory/netdir" + mkdir -p "$netdir" + pkgdatadir="${builddir}" "${builddir}/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null cp "${cfgfile}" "$netdir/boot/grub/grub.cfg" cp "${source}" "$netdir/boot/grub/testcase.cfg" [ -z "$files" ] || copy_extra_files "$netdir" $files - timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim + cat >"$work_directory/run.sh" <"$work_directory/run.sh" <"$work_directory/run.sh" < "$work_directory/qemu-pipe" || ret=$? +fi + +wait +rm -f "$work_directory/qemu-pipe" + +if [ "$ret" -ne 0 ]; then + # If QEMU failure, keep generated files to reproduce + exit $ret +fi + if [ x$boot = xcoreboot ]; then test -n "$debug" || rm -f "${imgfile}" +elif [ x$boot = xemu ]; then + test -n "$debug" || rm -rf "$rootdir" + test -n "$debug" || rm -f "$roottar" fi test -n "$debug" || rm -f "${isofile}" test -n "$debug" || rm -rf "${rom_directory}" -test -n "$debug" || rm -f "${tmpfile}" "${cfgfile}" -exit 0 +test -n "$debug" || rm -f "${tmpfile}" "${cfgfile}" "${goutfile}" +test -n "$debug" || rm -f "$work_directory/run.sh" +test -n "$debug" || rmdir "$work_directory" + +exit $ret diff --git a/tests/xfs_test.in b/tests/xfs_test.in index 03a351359..5e029c182 100644 --- a/tests/xfs_test.in +++ b/tests/xfs_test.in @@ -7,12 +7,12 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which mkfs.xfs >/dev/null 2>&1; then echo "mkfs.xfs not installed; cannot test xfs." - exit 77 + exit 99 fi diff --git a/tests/xzcompress_test.in b/tests/xzcompress_test.in index 03bfb5e95..6ef73e41e 100644 --- a/tests/xzcompress_test.in +++ b/tests/xzcompress_test.in @@ -21,9 +21,10 @@ grubshell=@builddir@/grub-shell if ! which xz >/dev/null 2>&1; then echo "xz not installed; cannot test xz compression." - exit 77 + exit 99 fi -if [ "$(echo hello | "${grubshell}" --mkrescue-arg=--compress=xz)" != "Hello World" ]; then +v=$(echo hello | "${grubshell}" --mkrescue-arg=--compress=xz) +if [ "$v" != "Hello World" ]; then exit 1 fi diff --git a/tests/zfs_test.in b/tests/zfs_test.in index eee62c10d..0d0a57f7d 100644 --- a/tests/zfs_test.in +++ b/tests/zfs_test.in @@ -7,18 +7,19 @@ if [ "x$EUID" = "x" ] ; then fi if [ "$EUID" != 0 ] ; then - exit 77 + exit 99 fi if ! which zpool >/dev/null 2>&1; then echo "zpool not installed; cannot test zfs." - exit 77 + exit 99 fi "@builddir@/grub-fs-tester" zfs "@builddir@/grub-fs-tester" zfs_lzjb "@builddir@/grub-fs-tester" zfs_gzip "@builddir@/grub-fs-tester" zfs_zle +"@builddir@/grub-fs-tester" zfs_zstd "@builddir@/grub-fs-tester" zfs_raidz3 "@builddir@/grub-fs-tester" zfs_raidz2 "@builddir@/grub-fs-tester" zfs_raidz diff --git a/util/bash-completion.d/Makefile.am b/util/bash-completion.d/Makefile.am index 136287cf1..33fff9546 100644 --- a/util/bash-completion.d/Makefile.am +++ b/util/bash-completion.d/Makefile.am @@ -1,13 +1,117 @@ - bash_completion_source = grub-completion.bash.in bash_completion_script = grub +grub_bios_setup_source = grub-bios-setup.bash.in +grub_bios_setup_script = @grub_bios_setup@ +grub_editenv_source = grub-editenv.bash.in +grub_editenv_script = @grub_editenv@ +grub_install_source = grub-install.bash.in +grub_install_script = @grub_install@ +grub_mkconfig_source = grub-mkconfig.bash.in +grub_mkconfig_script = @grub_mkconfig@ +grub_mkfont_source = grub-mkfont.bash.in +grub_mkfont_script = @grub_mkfont@ +grub_mkimage_source = grub-mkimage.bash.in +grub_mkimage_script = @grub_mkimage@ +grub_mkpasswd_pbkdf2_source = grub-mkpasswd-pbkdf2.bash.in +grub_mkpasswd_pbkdf2_script = @grub_mkpasswd_pbkdf2@ +grub_mkrescue_source = grub-mkrescue.bash.in +grub_mkrescue_script = @grub_mkrescue@ +grub_probe_source = grub-probe.bash.in +grub_probe_script = @grub_probe@ +grub_reboot_source = grub-reboot.bash.in +grub_reboot_script = @grub_reboot@ +grub_script_check_source = grub-script-check.bash.in +grub_script_check_script = @grub_script_check@ +grub_set_default_source = grub-set-default.bash.in +grub_set_default_script = @grub_set_default@ +grub_sparc64_setup_source = grub-sparc64-setup.bash.in +grub_sparc64_setup_script = @grub_sparc64_setup@ -EXTRA_DIST = $(bash_completion_source) +EXTRA_DIST = $(bash_completion_source) \ + $(grub_bios_setup_source) \ + $(grub_editenv_source) \ + $(grub_install_source) \ + $(grub_mkconfig_source) \ + $(grub_mkfont_source) \ + $(grub_mkimage_source) \ + $(grub_mkpasswd_pbkdf2_source) \ + $(grub_mkrescue_source) \ + $(grub_probe_source) \ + $(grub_reboot_source) \ + $(grub_script_check_source) \ + $(grub_set_default_source) \ + $(grub_sparc64_setup_source) -CLEANFILES = $(bash_completion_script) config.log +CLEANFILES = $(bash_completion_script) \ + $(grub_bios_setup_script) \ + $(grub_editenv_script) \ + $(grub_install_script) \ + $(grub_mkconfig_script) \ + $(grub_mkfont_script) \ + $(grub_mkimage_script) \ + $(grub_mkpasswd_pbkdf2_script) \ + $(grub_mkrescure_script) \ + $(grub_probe_script) \ + $(grub_reboot_script) \ + $(grub_script_check_script) \ + $(grub_set_default_script) \ + $(grub_sparc64_setup_script) \ + config.log -bashcompletiondir = $(sysconfdir)/bash_completion.d -bashcompletion_DATA = $(bash_completion_script) +bashcompletiondir = $(datarootdir)/bash-completion/completions +bashcompletion_DATA = $(bash_completion_script) \ + $(grub_bios_setup_script) \ + $(grub_editenv_script) \ + $(grub_install_script) \ + $(grub_mkconfig_script) \ + $(grub_mkfont_script) \ + $(grub_mkimage_script) \ + $(grub_mkpasswd_pbkdf2_script) \ + $(grub_mkrescure_script) \ + $(grub_probe_script) \ + $(grub_reboot_script) \ + $(grub_script_check_script) \ + $(grub_set_default_script) \ + $(grub_sparc64_setup_script) $(bash_completion_script): $(bash_completion_source) $(top_builddir)/config.status $(top_builddir)/config.status --file=$@:$< + +$(grub_bios_setup_script): $(grub_bios_setup_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_editenv_script): $(grub_editenv_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_install_script): $(grub_install_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_mkconfig_script): $(grub_mkconfig_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_mkfont_script): $(grub_mkfont_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_mkimage_script): $(grub_mkimage_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_mkpasswd_pbkdf2_script): $(grub_mkpasswd_pbkdf2_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_mkrescue_script): $(grub_mkrescue_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_probe_script): $(grub_probe_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_reboot_script): $(grub_reboot_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_script_check_script): $(grub_script_check_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_set_default_script): $(grub_set_default_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< + +$(grub_sparc64_setup_script): $(grub_sparc64_setup_source) $(top_builddir)/config.status + $(top_builddir)/config.status --file=$@:$< diff --git a/util/bash-completion.d/grub-bios-setup.bash.in b/util/bash-completion.d/grub-bios-setup.bash.in new file mode 100644 index 000000000..2d362b5e2 --- /dev/null +++ b/util/bash-completion.d/grub-bios-setup.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-bios-setup@ +# +# 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 . + +_grub_bios_setup () { + . @datarootdir@/bash-completion/completions/grub && __grub_setup +} +complete -F _grub_bios_setup -o filenames @grub_bios_setup@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in index 44bf135b9..749a5d3cf 100644 --- a/util/bash-completion.d/grub-completion.bash.in +++ b/util/bash-completion.d/grub-completion.bash.in @@ -52,14 +52,18 @@ __grubcomp () { COMPREPLY=() ;; *) - local IFS=' '$'\t'$'\n' - COMPREPLY=($(compgen -P "${2-}" -W "${1-}" -S "${4-}" -- "$cur")) + local line IFS=' '$'\t'$'\n' + COMPREPLY=() + while read -r line; do + COMPREPLY+=("${line}") + done < <(compgen -P "${2-}" -W "${1-}" -S "${4-}" -- "$cur") ;; esac } # Function that return long options from the help of the command # - arg: $1 (optional) command to get the long options from +# shellcheck disable=SC2120 __grub_get_options_from_help () { local prog @@ -112,41 +116,45 @@ __grub_get_last_option () { __grub_list_menuentries () { local cur="${COMP_WORDS[COMP_CWORD]}" - local config_file=$(__grub_dir)/grub.cfg + local config_file + config_file=$(__grub_dir)/grub.cfg if [ -f "$config_file" ];then - local IFS=$'\n' - COMPREPLY=( $(compgen \ - -W "$( awk -F "[\"']" '/menuentry/ { print $2 }' $config_file )" \ - -- "$cur" )) #'# Help emacs syntax highlighting + local line IFS=$'\n' + COMPREPLY=() + while read -r line; do + COMPREPLY+=("${line}") + done < <(compgen \ + -W "$( awk -F "[\"']" '/menuentry/ { print $2 }' $config_file )" \ + -- "$cur" ) #'# Help emacs syntax highlighting fi } __grub_list_modules () { - local grub_dir=$(__grub_dir) - local IFS=$'\n' - COMPREPLY=( $( compgen -f -X '!*/*.mod' -- "${grub_dir}/$cur" | { - while read -r tmp; do - [ -n $tmp ] && { - tmp=${tmp##*/} - printf '%s\n' ${tmp%.mod} - } - done - } - )) + local grub_dir + grub_dir=$(__grub_dir) + local line tmp IFS=$'\n' + COMPREPLY=() + while read -r line; do + COMPREPLY+=("${line}") + done < <(compgen -f -X '!*/*.mod' -- "${grub_dir}/$cur" | { + while read -r tmp; do + [ -n "$tmp" ] && { + tmp=${tmp##*/} + printf '%s\n' ${tmp%.mod} + } + done + }) } # # grub-set-default & grub-reboot # -_grub_set_entry () { - local cur prev split=false +__grub_set_entry () { + local cur prev words cword split + _init_completion -s || return COMPREPLY=() - cur=`_get_cword` - prev=${COMP_WORDS[COMP_CWORD-1]} - - _split_longopt && split=true case "$prev" in --boot-directory) @@ -165,26 +173,14 @@ _grub_set_entry () { fi } -__grub_set_default_program="@grub_set_default@" -have ${__grub_set_default_program} && \ - complete -F _grub_set_entry -o filenames ${__grub_set_default_program} -unset __grub_set_default_program - -__grub_reboot_program="@grub_reboot@" -have ${__grub_reboot_program} && \ - complete -F _grub_set_entry -o filenames ${__grub_reboot_program} -unset __grub_reboot_program - - # # grub-editenv # -_grub_editenv () { - local cur prev +__grub_editenv () { + local cur prev words cword + _init_completion || return COMPREPLY=() - cur=`_get_cword` - prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in create|list|set|unset) @@ -197,20 +193,14 @@ _grub_editenv () { create list set unset" } -__grub_editenv_program="@grub_editenv@" -have ${__grub_editenv_program} && \ - complete -F _grub_editenv -o filenames ${__grub_editenv_program} -unset __grub_editenv_program - - # # grub-mkconfig # -_grub_mkconfig () { - local cur prev +__grub_mkconfig () { + local cur prev words cword + _init_completion || return COMPREPLY=() - cur=`_get_cword` if [[ "$cur" == -* ]]; then __grubcomp "$(__grub_get_options_from_help)" @@ -218,23 +208,15 @@ _grub_mkconfig () { _filedir fi } -__grub_mkconfig_program="@grub_mkconfig@" -have ${__grub_mkconfig_program} && \ - complete -F _grub_mkconfig -o filenames ${__grub_mkconfig_program} -unset __grub_mkconfig_program - # # grub-setup # -_grub_setup () { - local cur prev split=false +__grub_setup () { + local cur prev words cword split + _init_completion -s || return COMPREPLY=() - cur=`_get_cword` - prev=${COMP_WORDS[COMP_CWORD-1]} - - _split_longopt && split=true case "$prev" in -d|--directory) @@ -253,30 +235,16 @@ _grub_setup () { fi } -__grub_bios_setup_program="@grub_bios_setup@" -have ${__grub_bios_setup_program} && \ - complete -F _grub_setup -o filenames ${__grub_bios_setup_program} -unset __grub_bios_setup_program - -__grub_sparc64_setup_program="@grub_sparc64_setup@" -have ${__grub_sparc64_setup_program} && \ - complete -F _grub_setup -o filenames ${__grub_sparc64_setup_program} -unset __grub_sparc64_setup_program - - # # grub-install # -_grub_install () { - local cur prev last split=false +__grub_install () { + local cur prev words cword split last + _init_completion -s || return COMPREPLY=() - cur=`_get_cword` - prev=${COMP_WORDS[COMP_CWORD-1]} last=$(__grub_get_last_option) - _split_longopt && split=true - case "$prev" in --boot-directory) _filedir -d @@ -304,20 +272,15 @@ _grub_install () { _filedir fi } -__grub_install_program="@grub_install@" -have ${__grub_install_program} && \ - complete -F _grub_install -o filenames ${__grub_install_program} -unset __grub_install_program - # # grub-mkfont # -_grub_mkfont () { - local cur +__grub_mkfont () { + local cur prev words cword + _init_completion || return COMPREPLY=() - cur=`_get_cword` if [[ "$cur" == -* ]]; then __grubcomp "$(__grub_get_options_from_help)" @@ -326,21 +289,15 @@ _grub_mkfont () { _filedir fi } -__grub_mkfont_program="@grub_mkfont@" -have ${__grub_mkfont_program} && \ - complete -F _grub_mkfont -o filenames ${__grub_mkfont_program} -unset __grub_mkfont_program - # # grub-mkrescue # -_grub_mkrescue () { - local cur prev last +__grub_mkrescue () { + local cur prev words cword last + _init_completion || return COMPREPLY=() - cur=`_get_cword` - prev=${COMP_WORDS[COMP_CWORD-1]} last=$(__grub_get_last_option) if [[ "$cur" == -* ]]; then @@ -357,23 +314,15 @@ _grub_mkrescue () { _filedir fi } -__grub_mkrescue_program="@grub_mkrescue@" -have ${__grub_mkrescue_program} && \ - complete -F _grub_mkrescue -o filenames ${__grub_mkrescue_program} -unset __grub_mkrescue_program - # # grub-mkimage # -_grub_mkimage () { - local cur prev split=false +__grub_mkimage () { + local cur prev words cword split + _init_completion -s || return COMPREPLY=() - cur=`_get_cword` - prev=${COMP_WORDS[COMP_CWORD-1]} - - _split_longopt && split=true case "$prev" in -d|--directory|-p|--prefix) @@ -399,20 +348,15 @@ _grub_mkimage () { _filedir fi } -__grub_mkimage_program="@grub_mkimage@" -have ${__grub_mkimage_program} && \ - complete -F _grub_mkimage -o filenames ${__grub_mkimage_program} -unset __grub_mkimage_program - # # grub-mkpasswd-pbkdf2 # -_grub_mkpasswd_pbkdf2 () { - local cur +__grub_mkpasswd_pbkdf2 () { + local cur prev words cword + _init_completion || return COMPREPLY=() - cur=`_get_cword` if [[ "$cur" == -* ]]; then __grubcomp "$(__grub_get_options_from_help)" @@ -421,23 +365,15 @@ _grub_mkpasswd_pbkdf2 () { _filedir fi } -__grub_mkpasswd_pbkdf2_program="@grub_mkpasswd_pbkdf2@" -have ${__grub_mkpasswd_pbkdf2_program} && \ - complete -F _grub_mkpasswd_pbkdf2 -o filenames ${__grub_mkpasswd_pbkdf2_program} -unset __grub_mkpasswd_pbkdf2_program - # # grub-probe # -_grub_probe () { - local cur prev split=false +__grub_probe () { + local cur prev words cword split + _init_completion -s || return COMPREPLY=() - cur=`_get_cword` - prev=${COMP_WORDS[COMP_CWORD-1]} - - _split_longopt && split=true case "$prev" in -t|--target) @@ -459,20 +395,15 @@ _grub_probe () { _filedir fi } -__grub_probe_program="@grub_probe@" -have ${__grub_probe_program} && \ - complete -F _grub_probe -o filenames ${__grub_probe_program} -unset __grub_probe_program - # # grub-script-check # -_grub_script_check () { - local cur +__grub_script_check () { + local cur prev words cword + _init_completion || return COMPREPLY=() - cur=`_get_cword` if [[ "$cur" == -* ]]; then __grubcomp "$(__grub_get_options_from_help)" @@ -481,10 +412,6 @@ _grub_script_check () { _filedir fi } -__grub_script_check_program="@grub_script_check@" -have ${__grub_script_check_program} && \ - complete -F _grub_script_check -o filenames ${__grub_script_check_program} - # Local variables: # mode: shell-script diff --git a/util/bash-completion.d/grub-editenv.bash.in b/util/bash-completion.d/grub-editenv.bash.in new file mode 100644 index 000000000..29b1333ea --- /dev/null +++ b/util/bash-completion.d/grub-editenv.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-editenv@ +# +# 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 . + +_grub_editenv () { + . @datarootdir@/bash-completion/completions/grub && __grub_editenv +} +complete -F _grub_editenv -o filenames @grub_editenv@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-install.bash.in b/util/bash-completion.d/grub-install.bash.in new file mode 100644 index 000000000..a89fc614a --- /dev/null +++ b/util/bash-completion.d/grub-install.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-install@ +# +# 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 . + +_grub_install () { + . @datarootdir@/bash-completion/completions/grub && __grub_install +} +complete -F _grub_install -o filenames @grub_install@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-mkconfig.bash.in b/util/bash-completion.d/grub-mkconfig.bash.in new file mode 100644 index 000000000..862e0c58f --- /dev/null +++ b/util/bash-completion.d/grub-mkconfig.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-mkconfig@ +# +# 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 . + +_grub_mkconfig () { + . @datarootdir@/bash-completion/completions/grub && __grub_mkconfig +} +complete -F _grub_mkconfig -o filenames @grub_mkconfig@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-mkfont.bash.in b/util/bash-completion.d/grub-mkfont.bash.in new file mode 100644 index 000000000..17baccdf5 --- /dev/null +++ b/util/bash-completion.d/grub-mkfont.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-mkfont@ +# +# 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 . + +_grub_mkfont () { + . @datarootdir@/bash-completion/completions/grub && __grub_mkfont +} +complete -F _grub_mkfont -o filenames @grub_mkfont@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-mkimage.bash.in b/util/bash-completion.d/grub-mkimage.bash.in new file mode 100644 index 000000000..a383ed3e9 --- /dev/null +++ b/util/bash-completion.d/grub-mkimage.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-mkimage@ +# +# 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 . + +_grub_mkimage () { + . @datarootdir@/bash-completion/completions/grub && __grub_mkimage +} +complete -F _grub_mkimage -o filenames @grub_mkimage@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-mkpasswd-pbkdf2.bash.in b/util/bash-completion.d/grub-mkpasswd-pbkdf2.bash.in new file mode 100644 index 000000000..32b8fd6eb --- /dev/null +++ b/util/bash-completion.d/grub-mkpasswd-pbkdf2.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-mkpasswd-pbkdf2@ +# +# 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 . + +_grub_mkpasswd_pbkdf2 () { + . @datarootdir@/bash-completion/completions/grub && __grub_mkpasswd_pbkdf2 +} +complete -F _grub_mkpasswd_pbkdf2 -o filenames @grub_mkpasswd_pbkdf2@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-mkrescue.bash.in b/util/bash-completion.d/grub-mkrescue.bash.in new file mode 100644 index 000000000..5968ba00e --- /dev/null +++ b/util/bash-completion.d/grub-mkrescue.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-mkresue@ +# +# 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 . + +_grub_mkrescue () { + . @datarootdir@/bash-completion/completions/grub && __grub_mkrescue +} +complete -F _grub_mkrescue -o filenames @grub_mkrescue@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-probe.bash.in b/util/bash-completion.d/grub-probe.bash.in new file mode 100644 index 000000000..08400f2f1 --- /dev/null +++ b/util/bash-completion.d/grub-probe.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-probe@ +# +# 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 . + +_grub_probe () { + . @datarootdir@/bash-completion/completions/grub && __grub_probe +} +complete -F _grub_probe -o filenames @grub_probe@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-reboot.bash.in b/util/bash-completion.d/grub-reboot.bash.in new file mode 100644 index 000000000..154aecea9 --- /dev/null +++ b/util/bash-completion.d/grub-reboot.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-reboot@ +# +# 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 . + +_grub_reboot () { + . @datarootdir@/bash-completion/completions/grub && __grub_set_entry +} +complete -F _grub_reboot -o filenames @grub_reboot@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-script-check.bash.in b/util/bash-completion.d/grub-script-check.bash.in new file mode 100644 index 000000000..22d376832 --- /dev/null +++ b/util/bash-completion.d/grub-script-check.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-script-check@ +# +# 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 . + +_grub_script_check () { + . @datarootdir@/bash-completion/completions/grub && __grub_script_check +} +complete -F _grub_script_check -o filenames @grub_script_check@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-set-default.bash.in b/util/bash-completion.d/grub-set-default.bash.in new file mode 100644 index 000000000..14501b4fb --- /dev/null +++ b/util/bash-completion.d/grub-set-default.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-set-default@ +# +# 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 . + +_grub_set_default () { + . @datarootdir@/bash-completion/completions/grub && __grub_set_entry +} +complete -F _grub_set_default -o filenames @grub_set_default@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/bash-completion.d/grub-sparc64-setup.bash.in b/util/bash-completion.d/grub-sparc64-setup.bash.in new file mode 100644 index 000000000..6123d7b7c --- /dev/null +++ b/util/bash-completion.d/grub-sparc64-setup.bash.in @@ -0,0 +1,30 @@ +# +# Bash completion for @grub-sparc64-setup@ +# +# 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 . + +_grub_sparc64_setup () { + . @datarootdir@/bash-completion/completions/grub && __grub_setup +} +complete -F _grub_sparc64_setup -o filenames @grub_sparc64_setup@ + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/util/editenv.c b/util/editenv.c index eb2d0c03a..63a503040 100644 --- a/util/editenv.c +++ b/util/editenv.c @@ -28,15 +28,23 @@ #include #include +#if !defined(_WIN32) +#include +#endif #define DEFAULT_ENVBLK_SIZE 1024 +#define GRUB_ENVBLK_MESSAGE "# WARNING: Do not edit this file by tools other than "PACKAGE"-editenv!!!\n" void grub_util_create_envblk_file (const char *name) { FILE *fp; - char *buf; - char *namenew; + char *buf, *pbuf, *namenew; +#if !defined(_WIN32) + ssize_t size = 1; + char *rename_target = xstrdup (name); + int rc; +#endif buf = xmalloc (DEFAULT_ENVBLK_SIZE); @@ -46,9 +54,13 @@ grub_util_create_envblk_file (const char *name) grub_util_error (_("cannot open `%s': %s"), namenew, strerror (errno)); - memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); - memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', - DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); + pbuf = buf; + memcpy (pbuf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); + pbuf += sizeof (GRUB_ENVBLK_SIGNATURE) - 1; + memcpy (pbuf, GRUB_ENVBLK_MESSAGE, sizeof (GRUB_ENVBLK_MESSAGE) - 1); + pbuf += sizeof (GRUB_ENVBLK_MESSAGE) - 1; + memset (pbuf , '#', + DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) - sizeof (GRUB_ENVBLK_MESSAGE) + 2); if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE) grub_util_error (_("cannot write to `%s': %s"), namenew, @@ -60,7 +72,64 @@ grub_util_create_envblk_file (const char *name) free (buf); fclose (fp); +#if defined(_WIN32) if (grub_util_rename (namenew, name) < 0) grub_util_error (_("cannot rename the file %s to %s"), namenew, name); +#else + while (1) + { + char *linkbuf; + ssize_t retsize; + + linkbuf = xmalloc (size + 1); + retsize = grub_util_readlink (rename_target, linkbuf, size); + if (retsize < 0 && (errno == ENOENT || errno == EINVAL)) + { + free (linkbuf); + break; + } + else if (retsize < 0) + { + free (linkbuf); + grub_util_error (_("cannot rename the file %s to %s: %s"), namenew, name, strerror (errno)); + } + else if (retsize == size) + { + free (linkbuf); + size += 128; + continue; + } + + linkbuf[retsize] = '\0'; + if (linkbuf[0] == '/') + { + free (rename_target); + rename_target = linkbuf; + } + else + { + char *dbuf = xstrdup (rename_target); + const char *dir = dirname (dbuf); + + free (rename_target); + rename_target = xasprintf ("%s/%s", dir, linkbuf); + free (dbuf); + free (linkbuf); + } + } + + rc = grub_util_rename (namenew, rename_target); + if (rc < 0 && errno == EXDEV) + { + rc = grub_install_copy_file (namenew, rename_target, 1); + grub_util_unlink (namenew); + } + + free (rename_target); + + if (rc < 0) + grub_util_error (_("cannot rename the file %s to %s: %s"), namenew, name, strerror (errno)); +#endif + free (namenew); } diff --git a/util/getroot.c b/util/getroot.c index 847406fba..75a7d5f21 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -47,7 +47,7 @@ #include -#if defined(HAVE_LIBZFS) && defined(HAVE_LIBNVPAIR) +#ifdef USE_LIBZFS # include # include #endif @@ -156,7 +156,7 @@ convert_system_partition_to_system_disk (const char *os_dev, int *is_part) if (stat (os_dev, &st) < 0) { - const char *errstr = strerror (errno); + const char *errstr = strerror (errno); grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot stat `%s': %s"), os_dev, errstr); grub_util_info (_("cannot stat `%s': %s"), os_dev, errstr); @@ -200,7 +200,7 @@ make_device_name (const char *drive) char *ret, *ptr; const char *iptr; - ret = xmalloc (strlen (drive) * 2); + ret = xcalloc (2, strlen (drive)); ptr = ret; for (iptr = drive; *iptr; iptr++) { @@ -293,7 +293,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) == 0); dri = make_device_name (drive); - + if (!disk && !rdisk) return dri; @@ -451,12 +451,12 @@ int grub_util_biosdisk_is_present (const char *os_dev) { int ret = (find_system_device (os_dev) != NULL); - grub_util_info ((ret ? "%s is present" : "%s is not present"), + grub_util_info ((ret ? "%s is present" : "%s is not present"), os_dev); return ret; } -#ifdef HAVE_LIBZFS +#ifdef USE_LIBZFS static libzfs_handle_t *__libzfs_handle; static void @@ -478,5 +478,5 @@ grub_get_libzfs_handle (void) return __libzfs_handle; } -#endif /* HAVE_LIBZFS */ +#endif /* USE_LIBZFS */ diff --git a/util/glue-efi.c b/util/glue-efi.c index 68f53168b..022fa42dc 100644 --- a/util/glue-efi.c +++ b/util/glue-efi.c @@ -39,13 +39,23 @@ write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename, struct grub_macho_fat_header head; struct grub_macho_fat_arch arch32, arch64; grub_uint32_t size32, size64; + long size; char *buf; fseek (in32, 0, SEEK_END); - size32 = ftell (in32); + size = ftell (in32); + if (size < 0) + grub_util_error ("cannot get end of input file '%s': %s", + name32, strerror (errno)); + size32 = (grub_uint32_t) size; fseek (in32, 0, SEEK_SET); + fseek (in64, 0, SEEK_END); - size64 = ftell (in64); + size = ftell (in64); + if (size < 0) + grub_util_error ("cannot get end of input file '%s': %s", + name64, strerror (errno)); + size64 = (grub_uint64_t) size; fseek (in64, 0, SEEK_SET); head.magic = grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC); @@ -82,7 +92,7 @@ write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename, if (fwrite (buf, 1, size32, out) != size32) { if (out_filename) - grub_util_error ("cannot write to `%s': %s", + grub_util_error ("cannot write to `%s': %s", out_filename, strerror (errno)); else grub_util_error ("cannot write to the stdout: %s", strerror (errno)); diff --git a/util/grub-editenv.c b/util/grub-editenv.c index f3662c95b..db6f187cc 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -125,6 +125,7 @@ open_envblk_file (const char *name) { FILE *fp; char *buf; + long loc; size_t size; grub_envblk_t envblk; @@ -143,7 +144,12 @@ open_envblk_file (const char *name) grub_util_error (_("cannot seek `%s': %s"), name, strerror (errno)); - size = (size_t) ftell (fp); + loc = ftell (fp); + if (loc < 0) + grub_util_error (_("cannot get file location `%s': %s"), name, + strerror (errno)); + + size = (size_t) loc; if (fseek (fp, 0, SEEK_SET) < 0) grub_util_error (_("cannot seek `%s': %s"), name, diff --git a/util/grub-file.c b/util/grub-file.c index 50c18b683..b2e7dd69f 100644 --- a/util/grub-file.c +++ b/util/grub-file.c @@ -54,7 +54,7 @@ main (int argc, char *argv[]) grub_util_host_init (&argc, &argv); - argv2 = xmalloc (argc * sizeof (argv2[0])); + argv2 = xcalloc (argc, sizeof (argv2[0])); if (argc == 2 && strcmp (argv[1], "--version") == 0) { diff --git a/util/grub-fstest.c b/util/grub-fstest.c index f14e02d97..7ff9037b8 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -69,7 +69,8 @@ enum { CMD_BLOCKLIST, CMD_TESTLOAD, CMD_ZFSINFO, - CMD_XNU_UUID + CMD_XNU_UUID, + CMD_ZFS_BOOTFS }; #define BUF_SIZE 32256 @@ -199,7 +200,7 @@ cp_hook (grub_off_t ofs, char *buf, int len, void *_ctx) static void cmd_cp (char *src, const char *dest) { - struct cp_hook_ctx ctx = + struct cp_hook_ctx ctx = { .dest = dest }; @@ -300,9 +301,15 @@ cmd_cmp (char *src, char *dest) strcpy (ptr, entry->d_name); if (grub_util_is_special_file (destnew)) - continue; + { + free (srcnew); + free (destnew); + continue; + } cmd_cmp (srcnew, destnew); + free (srcnew); + free (destnew); } grub_util_fd_closedir (dir); return; @@ -349,7 +356,7 @@ static int crc_hook (grub_off_t ofs, char *buf, int len, void *crc_ctx) { (void) ofs; - + GRUB_MD_CRC32->write(crc_ctx, buf, len); return 0; } @@ -435,6 +442,9 @@ fstest (int n) case CMD_ZFSINFO: execute_command ("zfsinfo", n, args); break; + case CMD_ZFS_BOOTFS: + execute_command ("zfs-bootfs", n, args); + break; case CMD_CP: cmd_cp (args[0], args[1]); break; @@ -483,7 +493,7 @@ fstest (int n) grub_device_close (dev); } } - + for (i = 0; i < num_disks; i++) { char *argv[2]; @@ -512,7 +522,8 @@ static struct argp_option options[] = { {N_("crc FILE"), 0, 0 , OPTION_DOC, N_("Get crc32 checksum of FILE."), 1}, {N_("blocklist FILE"), 0, 0, OPTION_DOC, N_("Display blocklist of FILE."), 1}, {N_("xnu_uuid DEVICE"), 0, 0, OPTION_DOC, N_("Compute XNU UUID of the device."), 1}, - + {N_("zfs-bootfs ZFS_DATASET"), 0, 0, OPTION_DOC, N_("Compute ZFS dataset bootpath."), 1}, + {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"skip", 's', N_("NUM"), 0, N_("Skip N bytes from output file."), 2}, {"length", 'n', N_("NUM"), 0, N_("Handle N bytes in output file."), 2}, @@ -535,10 +546,10 @@ print_version (FILE *stream, struct argp_state *state) } void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; -static error_t +static error_t argp_parser (int key, char *arg, struct argp_state *state) { - char *p; + const char *p; switch (key) { @@ -549,7 +560,7 @@ argp_parser (int key, char *arg, struct argp_state *state) case 'K': if (strcmp (arg, "prompt") == 0) { - char buf[1024]; + char buf[1024]; grub_puts_ (N_("Enter ZFS password: ")); if (grub_password_get (buf, 1023)) { @@ -650,7 +661,7 @@ argp_parser (int key, char *arg, struct argp_state *state) if (args_count < num_disks) { if (args_count == 0) - images = xmalloc (num_disks * sizeof (images[0])); + images = xcalloc (num_disks, sizeof (images[0])); images[args_count] = grub_canonicalize_file_name (arg); args_count++; return 0; @@ -706,6 +717,11 @@ argp_parser (int key, char *arg, struct argp_state *state) cmd = CMD_XNU_UUID; nparm = 0; } + else if (grub_strcmp (arg, "zfs-bootfs") == 0) + { + cmd = CMD_ZFS_BOOTFS; + nparm = 0; + } else { fprintf (stderr, _("Invalid command %s.\n"), arg); @@ -722,7 +738,7 @@ argp_parser (int key, char *arg, struct argp_state *state) struct argp argp = { options, argp_parser, N_("IMAGE_PATH COMMANDS"), - N_("Debug tool for filesystem driver."), + N_("Debug tool for filesystem driver."), NULL, NULL, NULL }; @@ -734,7 +750,7 @@ main (int argc, char *argv[]) grub_util_host_init (&argc, &argv); - args = xmalloc (argc * sizeof (args[0])); + args = xcalloc (argc, sizeof (args[0])); argp_parse (&argp, argc, argv, 0, 0, 0); diff --git a/util/grub-gen-asciih.c b/util/grub-gen-asciih.c index e35dcb78f..58a1005f3 100644 --- a/util/grub-gen-asciih.c +++ b/util/grub-gen-asciih.c @@ -29,10 +29,10 @@ #include FT_SYNTHESIS_H #undef __FTERRORS_H__ -#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { +#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { #define FT_ERRORDEF(e, v, s) [e] = s, #define FT_ERROR_END_LIST }; -#include FT_ERRORS_H +#include FT_ERRORS_H #define GRUB_FONT_DEFAULT_SIZE 16 diff --git a/util/grub-gen-widthspec.c b/util/grub-gen-widthspec.c index 33bc8cb2d..2b22290b8 100644 --- a/util/grub-gen-widthspec.c +++ b/util/grub-gen-widthspec.c @@ -29,10 +29,10 @@ #include FT_SYNTHESIS_H #undef __FTERRORS_H__ -#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { +#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { #define FT_ERRORDEF(e, v, s) [e] = s, #define FT_ERROR_END_LIST }; -#include FT_ERRORS_H +#include FT_ERRORS_H #define GRUB_FONT_DEFAULT_SIZE 16 @@ -119,7 +119,7 @@ main (int argc, char *argv[]) fprintf (stderr, "grub-gen-widthspec: error: can't set %dx%d font size", size, size); return 1; } - + for (char_code = FT_Get_First_Char (ft_face, &glyph_index); glyph_index; char_code = FT_Get_Next_Char (ft_face, char_code, &glyph_index)) diff --git a/util/grub-install-common.c b/util/grub-install-common.c index ca0ac612a..22bccb6a3 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -59,7 +59,7 @@ grub_install_help_filter (int key, const char *text, return xasprintf(text, "unicode"); case GRUB_INSTALL_OPTIONS_DIRECTORY: case GRUB_INSTALL_OPTIONS_DIRECTORY2: - return xasprintf(text, grub_util_get_pkglibdir ()); + return xasprintf(text, grub_util_get_pkglibdir ()); case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY: return xasprintf(text, grub_util_get_localedir ()); case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY: @@ -80,7 +80,7 @@ grub_install_copy_file (const char *src, const char *dst, int is_needed) { - grub_util_fd_t in, out; + grub_util_fd_t in, out; ssize_t r; grub_util_info ("copying `%s' -> `%s'", src, dst); @@ -106,7 +106,7 @@ grub_install_copy_file (const char *src, if (!grub_install_copy_buffer) grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE); - + while (1) { r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE); @@ -173,50 +173,181 @@ grub_install_mkdir_p (const char *dst) char *p; for (p = t; *p; p++) { - if (is_path_separator (*p)) + if (is_path_separator (*p) && p != t) { char s = *p; *p = '\0'; grub_util_mkdir (t); + if (!grub_util_is_directory (t)) + grub_util_error (_("failed to make directory: '%s'"), t); + *p = s; } } grub_util_mkdir (t); + if (!grub_util_is_directory (t)) + grub_util_error (_("failed to make directory: '%s'"), t); free (t); } +static int +strcmp_ext (const char *a, const char *b, const char *ext) +{ + char *bsuffix = grub_util_path_concat_ext (1, b, ext); + int r = strcmp (a, bsuffix); + + free (bsuffix); + return r; +} + +enum clean_grub_dir_mode +{ + CLEAN_NEW, + CLEAN_BACKUP, + CREATE_BACKUP, + RESTORE_BACKUP +}; + +#ifdef HAVE_ATEXIT +static size_t backup_dirs_size = 0; +static char **backup_dirs = NULL; +static pid_t backup_process = 0; +static int grub_install_backup_ponr = 0; + +void +grub_set_install_backup_ponr (void) +{ + grub_install_backup_ponr = 1; +} +#endif + static void -clean_grub_dir (const char *di) +clean_grub_dir_real (const char *di, enum clean_grub_dir_mode mode) { grub_util_fd_dir_t d; grub_util_fd_dirent_t de; + const char *suffix = ""; + + if ((mode == CLEAN_BACKUP) || (mode == RESTORE_BACKUP)) + suffix = "~"; d = grub_util_fd_opendir (di); if (!d) - grub_util_error (_("cannot open directory `%s': %s"), - di, grub_util_fd_strerror ()); + { + if (mode == CLEAN_BACKUP) + return; + grub_util_error (_("cannot open directory `%s': %s"), + di, grub_util_fd_strerror ()); + } while ((de = grub_util_fd_readdir (d))) { const char *ext = strrchr (de->d_name, '.'); - if ((ext && (strcmp (ext, ".mod") == 0 - || strcmp (ext, ".lst") == 0 - || strcmp (ext, ".img") == 0 - || strcmp (ext, ".mo") == 0) - && strcmp (de->d_name, "menu.lst") != 0) - || strcmp (de->d_name, "efiemu32.o") == 0 - || strcmp (de->d_name, "efiemu64.o") == 0) + + if ((ext && (strcmp_ext (ext, ".mod", suffix) == 0 + || strcmp_ext (ext, ".lst", suffix) == 0 + || strcmp_ext (ext, ".img", suffix) == 0 + || strcmp_ext (ext, ".efi", suffix) == 0 + || strcmp_ext (ext, ".mo", suffix) == 0) + && strcmp_ext (de->d_name, "menu.lst", suffix) != 0) + || strcmp_ext (de->d_name, "modinfo.sh", suffix) == 0 + || strcmp_ext (de->d_name, "efiemu32.o", suffix) == 0 + || strcmp_ext (de->d_name, "efiemu64.o", suffix) == 0) { - char *x = grub_util_path_concat (2, di, de->d_name); - if (grub_util_unlink (x) < 0) - grub_util_error (_("cannot delete `%s': %s"), x, - grub_util_fd_strerror ()); - free (x); + char *srcf = grub_util_path_concat (2, di, de->d_name); + + if (mode == CREATE_BACKUP) + { + char *dstf = grub_util_path_concat_ext (2, di, de->d_name, "~"); + + if (grub_util_rename (srcf, dstf) < 0) + grub_util_error (_("cannot backup `%s': %s"), srcf, + grub_util_fd_strerror ()); + free (dstf); + } + else if (mode == RESTORE_BACKUP) + { + char *dstf = grub_util_path_concat (2, di, de->d_name); + + dstf[strlen (dstf) - 1] = '\0'; + if (grub_util_rename (srcf, dstf) < 0) + grub_util_error (_("cannot restore `%s': %s"), dstf, + grub_util_fd_strerror ()); + free (dstf); + } + else + { + if (grub_util_unlink (srcf) < 0) + grub_util_error (_("cannot delete `%s': %s"), srcf, + grub_util_fd_strerror ()); + } + free (srcf); } } grub_util_fd_closedir (d); } +#ifdef HAVE_ATEXIT +static void +restore_backup_atexit (void) +{ + size_t i; + + /* + * Some child inherited atexit() handler, did not clear it, and called it. + * Thus skip clean or restore logic. + */ + if (backup_process != getpid ()) + return; + + for (i = 0; i < backup_dirs_size; i++) + { + /* + * If past point of no return simply clean the backups. Otherwise + * cleanup newly installed files, and restore the backups. + */ + if (grub_install_backup_ponr) + clean_grub_dir_real (backup_dirs[i], CLEAN_BACKUP); + else + { + clean_grub_dir_real (backup_dirs[i], CLEAN_NEW); + clean_grub_dir_real (backup_dirs[i], RESTORE_BACKUP); + } + free (backup_dirs[i]); + } + + backup_dirs_size = 0; + + free (backup_dirs); +} + +static void +append_to_backup_dirs (const char *dir) +{ + backup_dirs = xrealloc (backup_dirs, sizeof (char *) * (backup_dirs_size + 1)); + backup_dirs[backup_dirs_size] = xstrdup (dir); + backup_dirs_size++; + if (!backup_process) + { + atexit (restore_backup_atexit); + backup_process = getpid (); + } +} +#else +static void +append_to_backup_dirs (const char *dir __attribute__ ((unused))) +{ +} +#endif + +static void +clean_grub_dir (const char *di) +{ + clean_grub_dir_real (di, CLEAN_BACKUP); + clean_grub_dir_real (di, CREATE_BACKUP); + append_to_backup_dirs (di); +} + struct install_list { int is_default; @@ -234,6 +365,31 @@ char *grub_install_source_directory = NULL; char *grub_install_locale_directory = NULL; char *grub_install_themes_directory = NULL; +int +grub_install_is_short_mbrgap_supported (void) +{ + int i, j; + static const char *whitelist[] = + { + "part_msdos", "biosdisk", "affs", "afs", "bfs", "archelp", + "cpio", "cpio_be", "newc", "odc", "ext2", "fat", "exfat", + "f2fs", "fshelp", "hfs", "hfsplus", "iso9660", "jfs", "minix", + "minix2", "minix3", "minix_be", "minix2_be", "nilfs2", "ntfs", + "ntfscomp", "reiserfs", "romfs", "sfs", "tar", "udf", "ufs1", + "ufs1_be", "ufs2", "xfs" + }; + + for (i = 0; i < modules.n_entries; i++) { + for (j = 0; j < ARRAY_SIZE (whitelist); j++) + if (strcmp(modules.entries[i], whitelist[j]) == 0) + break; + if (j == ARRAY_SIZE (whitelist)) + return 0; + } + + return 1; +} + void grub_install_push_module (const char *val) { @@ -286,7 +442,7 @@ handle_install_list (struct install_list *il, const char *val, il->n_entries++; } il->n_alloc = il->n_entries + 1; - il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); + il->entries = xcalloc (il->n_alloc, sizeof (il->entries[0])); ptr = val; for (ce = il->entries; ; ce++) { @@ -307,14 +463,17 @@ handle_install_list (struct install_list *il, const char *val, static char **pubkeys; static size_t npubkeys; +static char *sbat; +static int disable_shim_lock; static grub_compression_t compression; +static int disable_cli; int grub_install_parse (int key, char *arg) { switch (key) { - case 'C': + case GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS: if (grub_strcmp (arg, "xz") == 0) { #ifdef HAVE_LIBLZMA @@ -337,6 +496,18 @@ grub_install_parse (int key, char *arg) * (npubkeys + 1)); pubkeys[npubkeys++] = xstrdup (arg); return 1; + case GRUB_INSTALL_OPTIONS_SBAT: + if (sbat) + free (sbat); + + sbat = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK: + disable_shim_lock = 1; + return 1; + case GRUB_INSTALL_OPTIONS_DISABLE_CLI: + disable_cli = 1; + return 1; case GRUB_INSTALL_OPTIONS_VERBOSITY: verbosity++; @@ -437,7 +608,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, const char *mkimage_target, int note) { const struct grub_install_image_target_desc *tgt; - const char *const compnames[] = + const char *const compnames[] = { [GRUB_COMPRESSION_AUTO] = "auto", [GRUB_COMPRESSION_NONE] = "none", @@ -450,58 +621,74 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, int dc = decompressors (); if (memdisk_path) - slen += 20 + grub_strlen (memdisk_path); + slen += sizeof (" --memdisk ''") + grub_strlen (memdisk_path); if (config_path) - slen += 20 + grub_strlen (config_path); + slen += sizeof (" --config ''") + grub_strlen (config_path); + if (dtb) + slen += sizeof (" --dtb ''") + grub_strlen (dtb); + if (sbat) + slen += sizeof (" --sbat ''") + grub_strlen (sbat); for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) - slen += 20 + grub_strlen (*pk); + slen += sizeof (" --pubkey ''") + grub_strlen (*pk); for (md = modules.entries; *md; md++) - { - slen += 10 + grub_strlen (*md); - } + slen += sizeof (" ''") + grub_strlen (*md); p = s = xmalloc (slen); if (memdisk_path) { + *p++ = ' '; p = grub_stpcpy (p, "--memdisk '"); p = grub_stpcpy (p, memdisk_path); *p++ = '\''; - *p++ = ' '; } if (config_path) { + *p++ = ' '; p = grub_stpcpy (p, "--config '"); p = grub_stpcpy (p, config_path); *p++ = '\''; + } + if (dtb) + { *p++ = ' '; + p = grub_stpcpy (p, "--dtb '"); + p = grub_stpcpy (p, dtb); + *p++ = '\''; + } + if (sbat) + { + *p++ = ' '; + p = grub_stpcpy (p, "--sbat '"); + p = grub_stpcpy (p, sbat); + *p++ = '\''; } for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) { + *p++ = ' '; p = grub_stpcpy (p, "--pubkey '"); p = grub_stpcpy (p, *pk); *p++ = '\''; - *p++ = ' '; } for (md = modules.entries; *md; md++) { + *p++ = ' '; *p++ = '\''; p = grub_stpcpy (p, *md); *p++ = '\''; - *p++ = ' '; } *p = '\0'; - grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'" - " --output '%s' " - " --dtb '%s' " - "--format '%s' --compression '%s' %s %s\n", - dir, prefix, - outname, dtb ? : "", mkimage_target, - compnames[compression], note ? "--note" : "", s); + grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'" + " --format '%s' --compression '%s'%s%s%s%s\n", + dir, prefix, outname, + mkimage_target, compnames[compression], + note ? " --note" : "", + disable_shim_lock ? " --disable-shim-lock" : "", + disable_cli ? " --disable-cli" : "", s); free (s); tgt = grub_install_get_image_target (mkimage_target); @@ -511,7 +698,8 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, grub_install_generate_image (dir, prefix, fp, outname, modules.entries, memdisk_path, pubkeys, npubkeys, config_path, tgt, - note, compression, dtb); + note, compression, dtb, sbat, + disable_shim_lock, disable_cli); while (dc--) grub_install_pop_module (); } @@ -589,7 +777,10 @@ copy_all (const char *srcd, srcf = grub_util_path_concat (2, srcd, de->d_name); if (grub_util_is_special_file (srcf) || grub_util_is_directory (srcf)) - continue; + { + free (srcf); + continue; + } dstf = grub_util_path_concat (2, dstd, de->d_name); grub_install_compress_file (srcf, dstf, 1); free (srcf); @@ -598,7 +789,7 @@ copy_all (const char *srcd, grub_util_fd_closedir (d); } -#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) +#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) static const char * get_localedir (void) { @@ -659,7 +850,7 @@ static void grub_install_copy_nls(const char *src __attribute__ ((unused)), const char *dst __attribute__ ((unused))) { -#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) +#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) char *dst_locale; dst_locale = grub_util_path_concat (2, dst, "locale"); @@ -713,31 +904,32 @@ static struct const char *platform; } platforms[GRUB_INSTALL_PLATFORM_MAX] = { - [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, - [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, - [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, - [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, - [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, - [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, - [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, - [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, - [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, - [GRUB_INSTALL_PLATFORM_I386_XEN_PVH] = { "i386", "xen_pvh" }, - [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, - [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, - [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, - [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, - [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, - [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, - [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, - [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, - [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, - [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, - [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, - [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, - [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" }, - [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" }, - }; + [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, + [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, + [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, + [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, + [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, + [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, + [GRUB_INSTALL_PLATFORM_I386_XEN_PVH] = { "i386", "xen_pvh" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, + [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, + [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, + [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, + [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64", "efi" }, + [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" }, + [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" }, + }; char * grub_install_get_platforms_string (void) @@ -765,7 +957,7 @@ grub_install_get_platforms_string (void) } ptr[-2] = 0; free (arr); - + return platforms_string; } @@ -936,7 +1128,7 @@ grub_install_get_target (const char *src) fn = grub_util_path_concat (2, src, "modinfo.sh"); f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY); if (!GRUB_UTIL_FD_IS_VALID (f)) - grub_util_error (_("%s doesn't exist. Please specify --target or --directory"), + grub_util_error (_("%s doesn't exist. Please specify --target or --directory"), fn); r = grub_util_fd_read (f, buf, sizeof (buf) - 1); if (r < 0) diff --git a/util/grub-install.c b/util/grub-install.c index 8a55ad4b8..060246589 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -86,17 +86,17 @@ enum OPTION_ROOT_DIRECTORY, OPTION_TARGET, OPTION_SETUP, - OPTION_MKRELPATH, - OPTION_MKDEVICEMAP, - OPTION_PROBE, - OPTION_EDITENV, - OPTION_ALLOW_FLOPPY, - OPTION_RECHECK, + OPTION_MKRELPATH, + OPTION_MKDEVICEMAP, + OPTION_PROBE, + OPTION_EDITENV, + OPTION_ALLOW_FLOPPY, + OPTION_RECHECK, OPTION_FORCE, OPTION_FORCE_FILE_ID, - OPTION_NO_NVRAM, - OPTION_REMOVABLE, - OPTION_BOOTLOADER_ID, + OPTION_NO_NVRAM, + OPTION_REMOVABLE, + OPTION_BOOTLOADER_ID, OPTION_EFI_DIRECTORY, OPTION_FONT, OPTION_DEBUG, @@ -114,7 +114,7 @@ enum static int fs_probe = 1; -static error_t +static error_t argp_parser (int key, char *arg, struct argp_state *state) { if (grub_install_parse (key, arg)) @@ -324,6 +324,16 @@ get_default_platform (void) return "arm64-efi"; #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) return grub_install_get_default_x86_platform (); +#elif defined (__loongarch_lp64) + return "loongarch64-efi"; +#elif defined (__riscv) +#if __riscv_xlen == 32 + return "riscv32-efi"; +#elif __riscv_xlen == 64 + return "riscv64-efi"; +#else + return NULL; +#endif #else return NULL; #endif @@ -362,7 +372,7 @@ struct argp argp = { N_("Install GRUB on your drive.")"\v" N_("INSTALL_DEVICE must be system device filename.\n" "%s copies GRUB images into %s. On some platforms, it" - " may also install GRUB into the boot sector."), + " may also install GRUB into the boot sector."), NULL, help_filter, NULL }; @@ -449,7 +459,7 @@ probe_mods (grub_disk_t disk) if (disk->dev->disk_raidname) grub_install_push_module (disk->dev->disk_raidname (disk)); } - if (raid_level == 5) + if (raid_level == 4 || raid_level == 5) grub_install_push_module ("raid5rec"); if (raid_level == 6) grub_install_push_module ("raid6rec"); @@ -477,6 +487,7 @@ have_bootdev (enum grub_install_plat pl) case GRUB_INSTALL_PLATFORM_IA64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: @@ -626,7 +637,7 @@ device_map_check_duplicates (const char *dev_map) if (! fp) return; - d = xmalloc (alloced * sizeof (d[0])); + d = xcalloc (alloced, sizeof (d[0])); while (fgets (buf, sizeof (buf), fp)) { @@ -688,7 +699,7 @@ write_to_disk (grub_device_t dev, const char *fn) core_size = grub_util_get_image_size (fn); - core_img = grub_util_read_image (fn); + core_img = grub_util_read_image (fn); grub_util_info ("writing `%s' to `%s'", fn, dev->disk->name); err = grub_disk_write (dev->disk, 0, 0, @@ -717,7 +728,7 @@ is_prep_partition (grub_device_t dev) if (grub_disk_read (dev->disk, p->offset, p->index, sizeof (gptdata), &gptdata) == 0) { - const grub_gpt_part_guid_t template = { + const grub_guid_t template = { grub_cpu_to_le32_compile_time (0x9e1a2d38), grub_cpu_to_le16_compile_time (0xc612), grub_cpu_to_le16_compile_time (0x4316), @@ -740,7 +751,7 @@ is_prep_empty (grub_device_t dev) grub_disk_addr_t dsize, addr; grub_uint32_t buffer[32768]; - dsize = grub_disk_get_size (dev->disk); + dsize = grub_disk_native_sectors (dev->disk); for (addr = 0; addr < dsize; addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE) { @@ -819,6 +830,19 @@ fill_core_services (const char *core_services) free (sysv_plist); } +#ifdef __linux__ +static void +try_open (const char *path) +{ + FILE *f; + + f = grub_util_fopen (path, "r+"); + if (f == NULL) + grub_util_error (_("Unable to open %s: %s"), path, strerror (errno)); + fclose (f); +} +#endif + int main (int argc, char *argv[]) { @@ -874,11 +898,11 @@ main (int argc, char *argv[]) const char * t; t = get_default_platform (); if (!t) - grub_util_error ("%s", + grub_util_error ("%s", _("Unable to determine your platform." " Use --target.") ); - target = xstrdup (t); + target = xstrdup (t); } grub_install_source_directory = grub_util_path_concat (2, grub_util_get_pkglibdir (), target); @@ -902,6 +926,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: @@ -949,6 +974,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: @@ -1004,6 +1030,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: @@ -1018,6 +1045,20 @@ main (int argc, char *argv[]) break; } + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: +#ifdef __linux__ + /* On Linux, ensure /dev/nvram is _functional_. */ + if (update_nvram) + try_open ("/dev/nvram"); +#endif + break; + default: + break; + } + /* Find the EFI System Partition. */ if (is_efi) @@ -1063,7 +1104,7 @@ main (int argc, char *argv[]) for (curdev = efidir_device_names; *curdev; curdev++) grub_util_pull_device (*curdev); - + efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]); if (!efidir_grub_devname) grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), @@ -1084,7 +1125,12 @@ main (int argc, char *argv[]) efidir_is_mac = 1; if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0) - grub_util_error (_("%s doesn't look like an EFI partition"), efidir); + { + if (force) + grub_util_warn (_("%s doesn't look like an EFI partition, system may not boot"), efidir); + else + grub_util_error (_("%s doesn't look like an EFI partition"), efidir); + } /* The EFI specification requires that an EFI System Partition must contain an "EFI" subdirectory, and that OS loaders are stored in @@ -1119,6 +1165,9 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM64_EFI: efi_file = "BOOTAA64.EFI"; break; + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + efi_file = "BOOTLOONGARCH64.EFI"; + break; case GRUB_INSTALL_PLATFORM_RISCV32_EFI: efi_file = "BOOTRISCV32.EFI"; break; @@ -1152,6 +1201,9 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM64_EFI: efi_file = "grubaa64.efi"; break; + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + efi_file = "grubloongarch64.efi"; + break; case GRUB_INSTALL_PLATFORM_RISCV32_EFI: efi_file = "grubriscv32.efi"; break; @@ -1211,12 +1263,12 @@ main (int argc, char *argv[]) for (curdev = macppcdir_device_names; *curdev; curdev++) grub_util_pull_device (*curdev); - + macppcdir_grub_devname = grub_util_get_grub_dev (macppcdir_device_names[0]); if (!macppcdir_grub_devname) grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), macppcdir_device_names[0]); - + macppcdir_grub_dev = grub_device_open (macppcdir_grub_devname); if (! macppcdir_grub_dev) grub_util_error ("%s", grub_errmsg); @@ -1239,13 +1291,6 @@ main (int argc, char *argv[]) } } - grub_install_copy_files (grub_install_source_directory, - grubdir, platform); - - char *envfile = grub_util_path_concat (2, grubdir, "grubenv"); - if (!grub_util_is_regular (envfile)) - grub_util_create_envblk_file (envfile); - size_t ndev = 0; /* Write device to a variable so we don't have to traverse /dev every time. */ @@ -1260,7 +1305,7 @@ main (int argc, char *argv[]) ndev++; } - grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); + grub_drives = xcalloc (ndev + 1, sizeof (grub_drives[0])); for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, curdrive++) @@ -1321,29 +1366,6 @@ main (int argc, char *argv[]) relative_grubdir = xstrdup ("/"); } - char *platname = grub_install_get_platform_name (platform); - char *platdir; - { - char *t = grub_util_path_concat (2, grubdir, - platname); - platdir = grub_canonicalize_file_name (t); - if (!platdir) - grub_util_error (_("failed to get canonical path of `%s'"), - t); - free (t); - } - load_cfg = grub_util_path_concat (2, platdir, - "load.cfg"); - - grub_util_unlink (load_cfg); - - if (debug_image && debug_image[0]) - { - load_cfg_f = grub_util_fopen (load_cfg, "wb"); - have_load_cfg = 1; - fprintf (load_cfg_f, "set debug='%s'\n", - debug_image); - } char *prefix_drive = NULL; char *install_drive = NULL; @@ -1367,6 +1389,38 @@ main (int argc, char *argv[]) } } + grub_install_copy_files (grub_install_source_directory, + grubdir, platform); + + char *envfile = grub_util_path_concat (2, grubdir, "grubenv"); + if (!grub_util_is_regular (envfile)) + grub_util_create_envblk_file (envfile); + + char *platname = grub_install_get_platform_name (platform); + char *platdir; + { + char *t = grub_util_path_concat (2, grubdir, + platname); + platdir = grub_canonicalize_file_name (t); + if (!platdir) + grub_util_error (_("failed to get canonical path of `%s'"), + t); + free (t); + } + + load_cfg = grub_util_path_concat (2, platdir, + "load.cfg"); + + grub_util_unlink (load_cfg); + + if (debug_image && debug_image[0]) + { + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "set debug='%s'\n", + debug_image); + } + if (!have_abstractions) { if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0) @@ -1460,6 +1514,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: @@ -1555,6 +1610,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_X86_64_EFI: case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: @@ -1660,6 +1716,7 @@ main (int argc, char *argv[]) break; case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: @@ -1689,7 +1746,7 @@ main (int argc, char *argv[]) { case GRUB_INSTALL_PLATFORM_I386_PC: { - char *boot_img_src = grub_util_path_concat (2, + char *boot_img_src = grub_util_path_concat (2, grub_install_source_directory, "boot.img"); char *boot_img = grub_util_path_concat (2, platdir, @@ -1708,17 +1765,22 @@ main (int argc, char *argv[]) platdir, device_map, install_device); - + /* Now perform the installation. */ if (install_bootsector) - grub_util_bios_setup (platdir, "boot.img", "core.img", - install_drive, force, - fs_probe, allow_floppy, add_rs_codes); + { + grub_util_bios_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy, add_rs_codes, + !grub_install_is_short_mbrgap_supported ()); + + grub_set_install_backup_ponr (); + } break; } case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: { - char *boot_img_src = grub_util_path_concat (2, + char *boot_img_src = grub_util_path_concat (2, grub_install_source_directory, "boot.img"); char *boot_img = grub_util_path_concat (2, platdir, @@ -1734,13 +1796,17 @@ main (int argc, char *argv[]) platdir, device_map, install_drive); - + /* Now perform the installation. */ if (install_bootsector) - grub_util_sparc_setup (platdir, "boot.img", "core.img", - install_drive, force, - fs_probe, allow_floppy, - 0 /* unused */ ); + { + grub_util_sparc_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy, + 0 /* unused */, 0 /* unused */ ); + + grub_set_install_backup_ponr (); + } break; } @@ -1767,6 +1833,8 @@ main (int argc, char *argv[]) grub_elf = grub_util_path_concat (2, core_services, "grub.elf"); grub_install_copy_file (imgfile, grub_elf, 1); + grub_set_install_backup_ponr (); + f = grub_util_fopen (mach_kernel, "a+"); if (!f) grub_util_error (_("Can't create file: %s"), strerror (errno)); @@ -1775,6 +1843,8 @@ main (int argc, char *argv[]) fill_core_services (core_services); ins_dev = grub_device_open (install_drive); + if (ins_dev == NULL) + grub_util_error ("%s", grub_errmsg); bless (ins_dev, core_services, 0); @@ -1809,6 +1879,7 @@ main (int argc, char *argv[]) { if (write_to_disk (ins_dev, imgfile)) grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); + grub_set_install_backup_ponr (); } else { @@ -1867,6 +1938,8 @@ main (int argc, char *argv[]) boot_efi = grub_util_path_concat (2, core_services, "boot.efi"); grub_install_copy_file (imgfile, boot_efi, 1); + grub_set_install_backup_ponr (); + f = grub_util_fopen (mach_kernel, "r+"); if (!f) grub_util_error (_("Can't create file: %s"), strerror (errno)); @@ -1875,6 +1948,8 @@ main (int argc, char *argv[]) fill_core_services(core_services); ins_dev = grub_device_open (install_drive); + if (ins_dev == NULL) + grub_util_error ("%s", grub_errmsg); bless (ins_dev, boot_efi, 1); if (!removable && update_nvram) @@ -1897,12 +1972,16 @@ main (int argc, char *argv[]) /* FALLTHROUGH */ case GRUB_INSTALL_PLATFORM_ARM_EFI: case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: case GRUB_INSTALL_PLATFORM_RISCV32_EFI: case GRUB_INSTALL_PLATFORM_RISCV64_EFI: case GRUB_INSTALL_PLATFORM_IA64_EFI: { char *dst = grub_util_path_concat (2, efidir, efi_file); grub_install_copy_file (imgfile, dst, 1); + + grub_set_install_backup_ponr (); + free (dst); } if (!removable && update_nvram) @@ -1954,6 +2033,14 @@ main (int argc, char *argv[]) break; } + /* + * Either there are no platform specific code, or it didn't raise + * ponr. Raise it here, because usually this is already past point + * of no return. If we leave this flag false, at exit all the modules + * will be removed from the prefix which would be very confusing. + */ + grub_set_install_backup_ponr (); + fprintf (stderr, "%s\n", _("Installation finished. No error reported.")); /* Free resources. */ diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index a39f86939..b80e15cc3 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -62,7 +62,7 @@ main (int argc, char **argv) { out = grub_util_fopen (argv[2], "w"); if (!out) - { + { if (in != stdin) fclose (in); fprintf (stderr, _("cannot open `%s': %s"), diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 9f477ff05..32c480dae 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -59,7 +59,7 @@ usage () { echo print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")" print_option_help "-h, --help" "$(gettext "print this message and exit")" - print_option_help "-v, --version" "$(gettext "print the version information and exit")" + print_option_help "-V, --version" "$(gettext "print the version information and exit")" echo gettext "Report bugs to ."; echo } @@ -140,6 +140,9 @@ GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2 GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true +# Disable os-prober by default due to security reasons. +GRUB_DISABLE_OS_PROBER="true" + # Filesystem for the device containing our userland. Used for stuff like # choosing Hurd filesystem module. GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" @@ -158,6 +161,15 @@ if test -f ${sysconfdir}/default/grub ; then . ${sysconfdir}/default/grub fi +if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then + if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then + GRUB_DISABLE_LINUX_UUID="true" + fi + if [ -z "${GRUB_DISABLE_LINUX_PARTUUID}" ]; then + GRUB_DISABLE_LINUX_PARTUUID="true" + fi +fi + # XXX: should this be deprecated at some point? if [ "x${GRUB_TERMINAL}" != "x" ] ; then GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}" @@ -192,6 +204,7 @@ export GRUB_DEVICE \ GRUB_DEVICE_PARTUUID \ GRUB_DEVICE_BOOT \ GRUB_DEVICE_BOOT_UUID \ + GRUB_DISABLE_OS_PROBER \ GRUB_FS \ GRUB_FONT \ GRUB_PRELOAD_MODULES \ @@ -212,6 +225,7 @@ export GRUB_DEFAULT \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ + GRUB_CMDLINE_LINUX_RECOVERY \ GRUB_CMDLINE_XEN \ GRUB_CMDLINE_XEN_DEFAULT \ GRUB_CMDLINE_LINUX_XEN_REPLACE \ @@ -219,11 +233,15 @@ export GRUB_DEFAULT \ GRUB_CMDLINE_NETBSD \ GRUB_CMDLINE_NETBSD_DEFAULT \ GRUB_CMDLINE_GNUMACH \ + GRUB_TOP_LEVEL \ + GRUB_TOP_LEVEL_XEN \ + GRUB_TOP_LEVEL_OS_PROBER \ GRUB_EARLY_INITRD_LINUX_CUSTOM \ GRUB_EARLY_INITRD_LINUX_STOCK \ GRUB_TERMINAL_INPUT \ GRUB_TERMINAL_OUTPUT \ GRUB_SERIAL_COMMAND \ + GRUB_DISABLE_UUID \ GRUB_DISABLE_LINUX_UUID \ GRUB_DISABLE_LINUX_PARTUUID \ GRUB_DISABLE_RECOVERY \ @@ -232,7 +250,6 @@ export GRUB_DEFAULT \ GRUB_BACKGROUND \ GRUB_THEME \ GRUB_GFXPAYLOAD_LINUX \ - GRUB_DISABLE_OS_PROBER \ GRUB_INIT_TUNE \ GRUB_SAVEDEFAULT \ GRUB_ENABLE_CRYPTODISK \ @@ -287,7 +304,11 @@ and /etc/grub.d/* files or please file a bug report with exit 1 else # none of the children aborted with error, install the new grub.cfg - mv -f ${grub_cfg}.new ${grub_cfg} + oldumask=$(umask) + umask 077 + cat ${grub_cfg}.new > ${grub_cfg} + umask $oldumask + rm -f ${grub_cfg}.new fi fi diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 0f801cab3..08953287c 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -34,7 +34,7 @@ if test "x$grub_mkrelpath" = x; then grub_mkrelpath="${bindir}/@grub_mkrelpath@" fi -if which gettext >/dev/null 2>/dev/null; then +if command -v gettext >/dev/null; then : else gettext () { @@ -156,13 +156,17 @@ prepare_grub_to_access_device () if [ "x$fs_hint" != x ]; then echo "set root='$fs_hint'" fi - if fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then + if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= - echo "if [ x\$feature_platform_search_hint = xy ]; then" - echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" - echo "else" - echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" - echo "fi" + if [ "x$hints" != x ]; then + echo "if [ x\$feature_platform_search_hint = xy ]; then" + echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" + echo "else" + echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" + echo "fi" + else + echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" + fi fi IFS="$old_ifs" } @@ -173,7 +177,7 @@ grub_get_device_id () IFS=' ' device="$1" - if fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then + if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then echo "$fs_uuid"; else echo $device |sed 's, ,_,g' @@ -200,69 +204,44 @@ version_sort () { case $version_sort_sort_has_v in yes) - LC_ALL=C sort -V;; + LC_ALL=C sort -V "$@";; no) - LC_ALL=C sort -n;; + LC_ALL=C sort -n "$@";; *) if sort -V /dev/null 2>&1; then version_sort_sort_has_v=yes - LC_ALL=C sort -V + LC_ALL=C sort -V "$@" else version_sort_sort_has_v=no - LC_ALL=C sort -n + LC_ALL=C sort -n "$@" fi;; esac } -version_test_numeric () +# Given an item as the first argument and a list as the subsequent arguments, +# returns the list with the first argument moved to the front if it exists in +# the list. +grub_move_to_front () { - version_test_numeric_a="$1" - version_test_numeric_cmp="$2" - version_test_numeric_b="$3" - if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then - case "$version_test_numeric_cmp" in - ge|eq|le) return 0 ;; - gt|lt) return 1 ;; - esac - fi - if [ "$version_test_numeric_cmp" = "lt" ] ; then - version_test_numeric_c="$version_test_numeric_a" - version_test_numeric_a="$version_test_numeric_b" - version_test_numeric_b="$version_test_numeric_c" - fi - if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then - return 0 - else - return 1 - fi -} + item="$1" + shift -version_test_gt () -{ - version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`" - version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`" - version_test_gt_cmp=gt - if [ "x$version_test_gt_b" = "x" ] ; then - return 0 - fi - case "$version_test_gt_a:$version_test_gt_b" in - *.old:*.old) ;; - *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;; - *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;; - esac - version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" - return "$?" -} - -version_find_latest () -{ - version_find_latest_a="" - for i in "$@" ; do - if version_test_gt "$i" "$version_find_latest_a" ; then - version_find_latest_a="$i" + item_found=false + for i in "$@"; do + if [ "x$i" = "x$item" ]; then + item_found=true fi done - echo "$version_find_latest_a" + + if [ "x$item_found" = xtrue ]; then + echo "$item" + fi + for i in "$@"; do + if [ "x$i" = "x$item" ]; then + continue + fi + echo "$i" + done } # One layer of quotation is eaten by "" and the second by sed; so this turns diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 0fe45a610..7624d7808 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -50,10 +50,10 @@ #include FT_SYNTHESIS_H #undef __FTERRORS_H__ -#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { +#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { #define FT_ERRORDEF(e, v, s) [e] = s, #define FT_ERROR_END_LIST }; -#include FT_ERRORS_H +#include FT_ERRORS_H #ifndef GRUB_BUILD #include "progname.h" @@ -67,6 +67,11 @@ #define GRUB_FONT_RANGE_BLOCK 1024 +#define GSUB_PTR_VALID(x, end) assert ((grub_uint8_t *) (x) <= (end)) + +#define GSUB_ARRAY_SIZE_VALID(a, sz, end) \ + assert ((sz) >= 0 && ((sz) <= ((end) - (grub_uint8_t *) (a)) / sizeof (*(a)))) + struct grub_glyph_info { struct grub_glyph_info *next; @@ -312,7 +317,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, char_code | GRUB_FONT_CODE_RIGHT_JOINED, nocut); break; } - + } for (cur = subst_leftjoin; cur; cur = cur->next) @@ -338,7 +343,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, char_code | GRUB_FONT_CODE_LEFT_JOINED, nocut); break; } - + } for (cur = subst_medijoin; cur; cur = cur->next) if (cur->from == glyph_idx) @@ -365,7 +370,7 @@ add_char (struct grub_font_info *font_info, FT_Face face, | GRUB_FONT_CODE_RIGHT_JOINED, nocut); break; } - + } } @@ -440,7 +445,7 @@ struct gsub_coverage_ranges { grub_uint16_t type; grub_uint16_t count; - struct + struct { grub_uint16_t start; grub_uint16_t end; @@ -478,7 +483,7 @@ subst (const struct gsub_substitution *sub, grub_uint32_t glyph, if (substtype == GSUB_SUBSTITUTION_DELTA) add_subst (glyph, glyph + grub_be_to_cpu16 (sub->delta), target); else if (*i >= grub_be_to_cpu16 (sub->count)) - printf (_("Out of range substitution (%d, %d)\n"), *i, + printf (_("Out of range substitution (%d, %u)\n"), *i, grub_be_to_cpu16 (sub->count)); else add_subst (glyph, grub_be_to_cpu16 (sub->repl[(*i)++]), target); @@ -487,34 +492,40 @@ subst (const struct gsub_substitution *sub, grub_uint32_t glyph, static void process_cursive (struct gsub_feature *feature, struct gsub_lookup_list *lookups, - grub_uint32_t feattag) + grub_uint32_t feattag, + grub_uint32_t num_glyphs, + grub_uint8_t *gsub_end) { int j, k; int i; + int lookup_count = grub_be_to_cpu16 (feature->lookupcount); struct glyph_replace **target = NULL; struct gsub_substitution *sub; - for (j = 0; j < grub_be_to_cpu16 (feature->lookupcount); j++) + GSUB_ARRAY_SIZE_VALID (feature->lookupindices, lookup_count, gsub_end); + + for (j = 0; j < lookup_count; j++) { int lookup_index = grub_be_to_cpu16 (feature->lookupindices[j]); + int sub_count; struct gsub_lookup *lookup; if (lookup_index >= grub_be_to_cpu16 (lookups->count)) { /* TRANSLATORS: "lookup" is taken directly from font specifications - which are formulated as "Under condition X replace LOOKUP with + which are formulated as "Under condition X replace LOOKUP with SUBSTITUITION". "*/ printf (_("Out of range lookup: %d\n"), lookup_index); continue; } lookup = (struct gsub_lookup *) - ((grub_uint8_t *) lookups + ((grub_uint8_t *) lookups + grub_be_to_cpu16 (lookups->offsets[lookup_index])); if (grub_be_to_cpu16 (lookup->type) != GSUB_SINGLE_SUBSTITUTION) { printf (_("Unsupported substitution type: %d\n"), grub_be_to_cpu16 (lookup->type)); continue; - } + } if (grub_be_to_cpu16 (lookup->flag) & ~GSUB_RTL_CHAR) { grub_util_info ("unsupported substitution flag: 0x%x", @@ -536,9 +547,14 @@ process_cursive (struct gsub_feature *feature, break; case FEATURE_MEDI: target = &subst_medijoin; - break; + break; } - for (k = 0; k < grub_be_to_cpu16 (lookup->subtablecount); k++) + + sub_count = grub_be_to_cpu16 (lookup->subtablecount); + + GSUB_ARRAY_SIZE_VALID (lookup->subtables, sub_count, gsub_end); + + for (k = 0; k < sub_count; k++) { sub = (struct gsub_substitution *) ((grub_uint8_t *) lookup + grub_be_to_cpu16 (lookup->subtables[k])); @@ -547,7 +563,7 @@ process_cursive (struct gsub_feature *feature, if (substtype != GSUB_SUBSTITUTION_MAP && substtype != GSUB_SUBSTITUTION_DELTA) { - printf (_("Unsupported substitution specification: %d\n"), + printf (_("Unsupported substitution specification: %u\n"), substtype); continue; } @@ -559,18 +575,33 @@ process_cursive (struct gsub_feature *feature, if (covertype == GSUB_COVERAGE_LIST) { struct gsub_coverage_list *cover = coverage; + int count = grub_be_to_cpu16 (cover->count); int l; - for (l = 0; l < grub_be_to_cpu16 (cover->count); l++) + + GSUB_ARRAY_SIZE_VALID (cover->glyphs, count, gsub_end); + + for (l = 0; l < count; l++) subst (sub, grub_be_to_cpu16 (cover->glyphs[l]), target, &i); } else if (covertype == GSUB_COVERAGE_RANGE) { struct gsub_coverage_ranges *cover = coverage; + int count = grub_be_to_cpu16 (cover->count); int l, m; - for (l = 0; l < grub_be_to_cpu16 (cover->count); l++) - for (m = grub_be_to_cpu16 (cover->ranges[l].start); - m <= grub_be_to_cpu16 (cover->ranges[l].end); m++) - subst (sub, m, target, &i); + + GSUB_ARRAY_SIZE_VALID (cover->ranges, count, gsub_end); + + for (l = 0; l < count; l++) + { + grub_uint16_t start = grub_be_to_cpu16 (cover->ranges[l].start); + grub_uint16_t end = grub_be_to_cpu16 (cover->ranges[l].end); + + if (start > end || end > num_glyphs) + grub_util_error ("%s", _("invalid font range")); + + for (m = start; m <= end; m++) + subst (sub, m, target, &i); + } } else /* TRANSLATORS: most font transformations apply only to @@ -579,7 +610,7 @@ process_cursive (struct gsub_feature *feature, This warning is thrown when another coverage specification is detected. */ fprintf (stderr, - _("Unsupported coverage specification: %d\n"), covertype); + _("Unsupported coverage specification: %u\n"), covertype); } } } @@ -589,6 +620,7 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) { struct gsub_header *gsub = NULL; FT_ULong gsub_len = 0; + grub_uint8_t *gsub_end = NULL; if (!FT_Load_Sfnt_Table (face, TTAG_GSUB, 0, NULL, &gsub_len)) { @@ -600,9 +632,12 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) gsub_len = 0; } } + + gsub_end = (grub_uint8_t *) gsub + gsub_len; + if (gsub) { - struct gsub_features *features + struct gsub_features *features = (struct gsub_features *) (((grub_uint8_t *) gsub) + grub_be_to_cpu16 (gsub->features_off)); struct gsub_lookup_list *lookups @@ -610,6 +645,11 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) + grub_be_to_cpu16 (gsub->lookups_off)); int i; int nfeatures = grub_be_to_cpu16 (features->count); + + GSUB_PTR_VALID (features, gsub_end); + GSUB_PTR_VALID (lookups, gsub_end); + GSUB_ARRAY_SIZE_VALID (features->features, nfeatures, gsub_end); + for (i = 0; i < nfeatures; i++) { struct gsub_feature *feature = (struct gsub_feature *) @@ -617,6 +657,9 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) + grub_be_to_cpu16 (features->features[i].offset)); grub_uint32_t feattag = grub_be_to_cpu32 (features->features[i].feature_tag); + + GSUB_PTR_VALID (feature, gsub_end); + if (feature->params) fprintf (stderr, _("WARNING: unsupported font feature parameters: %x\n"), @@ -636,7 +679,8 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) case FEATURE_FINA: case FEATURE_INIT: case FEATURE_MEDI: - process_cursive (feature, lookups, feattag); + process_cursive (feature, lookups, feattag, + face->num_glyphs, gsub_end); break; default: @@ -655,6 +699,7 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) } } } + free (gsub); } if (font_info->num_range) @@ -928,6 +973,7 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) file, output_file); } + free (font_name); fclose (file); } @@ -940,10 +986,10 @@ static struct argp_option options[] = { This option is used to chose among them, the first face being '0'. Rarely used. */ N_("select face index"), 0}, - {"range", 'r', N_("FROM-TO[,FROM-TO]"), 0, + {"range", 'r', N_("FROM-TO[,FROM-TO]"), 0, /* TRANSLATORS: It refers to the range of characters in font. */ N_("set font range"), 0}, - {"name", 'n', N_("NAME"), 0, + {"name", 'n', N_("NAME"), 0, /* TRANSLATORS: "family name" for font is just a generic name without suffix like "Bold". */ N_("set font family name"), 0}, @@ -1185,7 +1231,7 @@ main (int argc, char *argv[]) grub_util_error ("%s", _("FT_Init_FreeType fails")); { - size_t i; + size_t i; for (i = 0; i < arguments.nfiles; i++) { FT_Face ft_face; @@ -1277,11 +1323,15 @@ main (int argc, char *argv[]) if (font_verbosity > 1) print_glyphs (&arguments.font_info); + free (arguments.font_info.glyphs_sorted); + { size_t i; for (i = 0; i < arguments.nfiles; i++) free (arguments.files[i]); } + free (arguments.files); + return 0; } diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 912564e36..547f7310f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -81,6 +81,9 @@ static struct argp_option options[] = { {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, {"format", 'O', N_("FORMAT"), 0, 0, 0}, {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0}, + {"sbat", 's', 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_("disable command line interface access"), 0}, {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, { 0, 0, 0, 0, 0, 0 } }; @@ -123,7 +126,10 @@ struct arguments size_t npubkeys; char *font; char *config; + char *sbat; int note; + int disable_shim_lock; + int disable_cli; const struct grub_install_image_target_desc *image_target; grub_compression_t comp; }; @@ -224,6 +230,21 @@ argp_parser (int key, char *arg, struct argp_state *state) arguments->prefix = xstrdup (arg); break; + case 's': + if (arguments->sbat) + free (arguments->sbat); + + arguments->sbat = xstrdup (arg); + break; + + case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK: + arguments->disable_shim_lock = 1; + break; + + case GRUB_INSTALL_OPTIONS_DISABLE_CLI: + arguments->disable_cli = 1; + break; + case 'v': verbosity++; break; @@ -309,7 +330,9 @@ main (int argc, char *argv[]) arguments.memdisk, arguments.pubkeys, arguments.npubkeys, arguments.config, arguments.image_target, arguments.note, - arguments.comp, arguments.dtb); + arguments.comp, arguments.dtb, + arguments.sbat, arguments.disable_shim_lock, + arguments.disable_cli); if (grub_util_file_sync (fp) < 0) grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout", @@ -328,5 +351,8 @@ main (int argc, char *argv[]) if (arguments.output) free (arguments.output); + if (arguments.sbat) + free (arguments.sbat); + return 0; } diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index bc087c2b5..448862b2e 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,14 @@ struct section_metadata const char *strtab; }; +#define GRUB_SBAT_NOTE_NAME ".sbat" +#define GRUB_SBAT_NOTE_TYPE 0x53424154 /* "SBAT" */ + +struct grub_sbat_note { + Elf32_Nhdr header; + char name[ALIGN_UP(sizeof(GRUB_SBAT_NOTE_NAME), 4)]; +}; + static int is_relocatable (const struct grub_install_image_target_desc *image_target) { @@ -207,7 +216,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) void SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target, - int note, char **core_img, size_t *core_size, + int note, char *sbat, char **core_img, size_t *core_size, Elf_Addr target_addr, struct grub_mkimage_layout *layout) { @@ -216,10 +225,17 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc Elf_Ehdr *ehdr; Elf_Phdr *phdr; Elf_Shdr *shdr; - int header_size, footer_size = 0; + int header_size, footer_size = 0, footer_offset = 0; int phnum = 1; int shnum = 4; int string_size = sizeof (".text") + sizeof ("mods") + 1; + char *footer; + + if (sbat) + { + phnum++; + footer_size += ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4); + } if (image_target->id != IMAGE_LOONGSON_ELF) phnum += 2; @@ -247,6 +263,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc ehdr = (void *) elf_img; phdr = (void *) (elf_img + sizeof (*ehdr)); shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)); + footer = elf_img + program_size + header_size; memcpy (ehdr->e_ident, ELFMAG, SELFMAG); ehdr->e_ident[EI_CLASS] = ELFCLASSXX; if (!image_target->bigendian) @@ -284,7 +301,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc phdr->p_align = grub_host_to_target32 (layout->align > image_target->link_align ? layout->align : image_target->link_align); if (image_target->id == IMAGE_LOONGSON_ELF) - ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); else ehdr->e_flags = 0; @@ -419,6 +436,8 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE); phdr->p_memsz = 0; phdr->p_offset = grub_host_to_target32 (header_size + program_size); + footer = ptr; + footer_offset = XEN_NOTE_SIZE; } if (image_target->id == IMAGE_XEN_PVH) @@ -452,18 +471,20 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE); phdr->p_memsz = 0; phdr->p_offset = grub_host_to_target32 (header_size + program_size); + footer = ptr; + footer_offset = XEN_PVH_NOTE_SIZE; } if (note) { int note_size = sizeof (struct grub_ieee1275_note); - struct grub_ieee1275_note *note_ptr = (struct grub_ieee1275_note *) + struct grub_ieee1275_note *note_ptr = (struct grub_ieee1275_note *) (elf_img + program_size + header_size); grub_util_info ("adding CHRP NOTE segment"); note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); - note_ptr->header.n_descsz = grub_host_to_target32 (note_size); + note_ptr->header.n_descsz = grub_host_to_target32 (sizeof (struct grub_ieee1275_note_desc)); note_ptr->header.n_type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); strcpy (note_ptr->name, GRUB_IEEE1275_NOTE_NAME); note_ptr->descriptor.real_mode = grub_host_to_target32 (0xffffffff); @@ -482,6 +503,30 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc phdr->p_filesz = grub_host_to_target32 (note_size); phdr->p_memsz = 0; phdr->p_offset = grub_host_to_target32 (header_size + program_size); + footer = (elf_img + program_size + header_size + note_size); + footer_offset += note_size; + } + + if (sbat) + { + int note_size = ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4); + struct grub_sbat_note *note_ptr = (struct grub_sbat_note *) footer; + + note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_SBAT_NOTE_NAME)); + note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(layout->sbat_size, 4)); + note_ptr->header.n_type = grub_host_to_target32 (GRUB_SBAT_NOTE_TYPE); + memcpy (note_ptr->name, GRUB_SBAT_NOTE_NAME, sizeof (GRUB_SBAT_NOTE_NAME)); + memcpy ((char *)(note_ptr + 1), sbat, layout->sbat_size); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size + footer_offset); } { @@ -784,6 +829,8 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off); grub_uint64_t *gpptr = (void *) (pe_target + got_off); unsigned unmatched_adr_got_page = 0; + struct grub_loongarch64_stack stack; + grub_loongarch64_stack_init (&stack); #define MASK19 ((1 << 19) - 1) #else grub_uint32_t *tr = (void *) (pe_target + tramp_off); @@ -1123,6 +1170,71 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, } break; } + case EM_LOONGARCH: + { + grub_int64_t pc; + + grub_uint32_t *t32 = (grub_uint32_t *) target; + sym_addr += addend; + + pc = offset + target_section_addr + image_target->vaddr_offset; + + switch (ELF_R_TYPE (info)) + { + case R_LARCH_64: + { + grub_uint64_t *t64 = (grub_uint64_t *) target; + *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + 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 + -(target_section_addr + +offset + +image_target->vaddr_offset)); + break; + case R_LARCH_B26: + { + grub_int64_t off; + + off = sym_addr - pc; + + grub_loongarch64_b26 (t32, off); + } + break; + case R_LARCH_ABS_HI20: + grub_loongarch64_xxx_hi20 (t32, sym_addr); + break; + case R_LARCH_ABS64_LO20: + grub_loongarch64_abs64_lo20 (t32, sym_addr); + break; + case R_LARCH_ABS64_HI12: + grub_loongarch64_abs64_hi12 (t32, sym_addr); + break; + case R_LARCH_PCALA_HI20: + { + grub_int32_t hi20; + + hi20 = (((sym_addr + 0x800) & ~0xfffULL) - (pc & ~0xfffULL)); + + grub_loongarch64_xxx_hi20 (t32, hi20); + } + break; + case R_LARCH_ABS_LO12: + case R_LARCH_PCALA_LO12: + grub_loongarch64_xxx_lo12 (t32, sym_addr); + break; + GRUB_LOONGARCH64_RELOCATION (&stack, target, sym_addr) + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } #endif #if defined(MKIMAGE_ELF32) case EM_ARM: @@ -1232,8 +1344,7 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, grub_uint32_t *t32 = (grub_uint32_t *) target; grub_uint16_t *t16 = (grub_uint16_t *) target; grub_uint8_t *t8 = (grub_uint8_t *) target; - grub_int64_t off = (long)sym_addr - target_section_addr - offset - - image_target->vaddr_offset; + grub_int64_t off; /* * Instructions and instruction encoding are documented in the RISC-V @@ -1243,6 +1354,7 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, */ sym_addr += addend; + off = sym_addr - target_section_addr - offset - image_target->vaddr_offset; switch (ELF_R_TYPE (info)) { @@ -1294,6 +1406,7 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, } break; case R_RISCV_CALL: + case R_RISCV_CALL_PLT: { grub_uint32_t hi20, lo12; @@ -1631,6 +1744,7 @@ translate_relocation_pe (struct translate_context *ctx, } break; case EM_AARCH64: +#if defined(MKIMAGE_ELF64) switch (ELF_R_TYPE (info)) { case R_AARCH64_ABS64: @@ -1666,7 +1780,65 @@ translate_relocation_pe (struct translate_context *ctx, (unsigned int) ELF_R_TYPE (info)); break; } +#endif /* defined(MKIMAGE_ELF64) */ break; + case EM_LOONGARCH: +#if defined(MKIMAGE_ELF64) + switch (ELF_R_TYPE (info)) + { + case R_LARCH_64: + { + ctx->current_address = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_LARCH_MARK_LA: + { + ctx->current_address = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA, + addr, 0, ctx->current_address, + image_target); + } + break; + /* Relative relocations do not require fixup entries. */ + case R_LARCH_NONE: + case R_LARCH_SOP_PUSH_PCREL: + case R_LARCH_SOP_PUSH_ABSOLUTE: + case R_LARCH_SOP_PUSH_PLT_PCREL: + case R_LARCH_SOP_SUB: + case R_LARCH_SOP_SL: + case R_LARCH_SOP_SR: + case R_LARCH_SOP_ADD: + case R_LARCH_SOP_AND: + case R_LARCH_SOP_IF_ELSE: + case R_LARCH_SOP_POP_32_S_10_5: + case R_LARCH_SOP_POP_32_U_10_12: + case R_LARCH_SOP_POP_32_S_10_12: + case R_LARCH_SOP_POP_32_S_10_16: + case R_LARCH_SOP_POP_32_S_10_16_S2: + case R_LARCH_SOP_POP_32_S_5_20: + case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: + case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: + case R_LARCH_B26: + case R_LARCH_ABS_HI20: + case R_LARCH_ABS_LO12: + case R_LARCH_ABS64_LO20: + case R_LARCH_ABS64_HI12: + case R_LARCH_PCALA_HI20: + case R_LARCH_PCALA_LO12: + grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", + __FUNCTION__, + (unsigned int) addr, + (unsigned int) ctx->current_address); + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } +#endif /* defined(MKIMAGE_ELF64) */ break; #if defined(MKIMAGE_ELF32) case EM_ARM: @@ -1725,6 +1897,7 @@ translate_relocation_pe (struct translate_context *ctx, case R_RISCV_BRANCH: case R_RISCV_JAL: case R_RISCV_CALL: + case R_RISCV_CALL_PLT: case R_RISCV_PCREL_HI20: case R_RISCV_PCREL_LO12_I: case R_RISCV_PCREL_LO12_S: @@ -2041,7 +2214,7 @@ SUFFIX (is_text_section) (Elf_Shdr *s, const struct grub_install_image_target_de static int SUFFIX (is_data_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) { - if (!is_relocatable (image_target) + if (!is_relocatable (image_target) && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) @@ -2227,7 +2400,7 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path, layout->bss_start = layout->kernel_size; layout->end = layout->kernel_size; - + /* .bss */ for (i = 0, s = smd->sections; i < smd->num_sections; @@ -2294,16 +2467,16 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize); smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); - smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections); - memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections); - smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections); - memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections); + smd.addrs = xcalloc (smd.num_sections, sizeof (*smd.addrs)); + smd.vaddrs = xcalloc (smd.num_sections, sizeof (*smd.vaddrs)); SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target); if (!is_relocatable (image_target)) { Elf_Addr current_address = layout->kernel_size; + Elf_Addr bss_start = layout->kernel_size; + bool is_first = true; for (i = 0, s = smd.sections; i < smd.num_sections; @@ -2326,6 +2499,12 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, current_address = grub_host_to_target_addr (s->sh_addr) - image_target->link_addr; + if (is_first == true) + { + bss_start = current_address; + is_first = false; + } + smd.vaddrs[i] = current_address + image_target->vaddr_offset; current_address += grub_host_to_target_addr (s->sh_size); @@ -2333,6 +2512,16 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, current_address = ALIGN_UP (current_address + image_target->vaddr_offset, image_target->section_align) - image_target->vaddr_offset; + + if (image_target->id == IMAGE_YEELOONG_FLASH + || image_target->id == IMAGE_FULOONG2F_FLASH + || image_target->id == IMAGE_LOONGSON_ELF + || image_target->id == IMAGE_QEMU_MIPS_FLASH + || image_target->id == IMAGE_MIPS_ARC) + { + layout->kernel_size = bss_start; + } + layout->bss_size = current_address - layout->kernel_size; } else @@ -2390,6 +2579,10 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, layout->kernel_size += ALIGN_UP (layout->got_size, 16); } #endif + + if (image_target->id == IMAGE_EFI) + layout->kernel_size = ALIGN_UP (layout->kernel_size, + GRUB_PE32_FILE_ALIGNMENT); } else { diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index d171c2700..e2a2585a6 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -175,7 +175,7 @@ static struct console_grub_equivalence console_grub_equivalences_common[] = { {"dead_grave", '`'}, {"dead_tilde", '~'}, {"dead_diaeresis", '"'}, - + /* Following ones don't provide any useful symbols for shell. */ {"dead_cedilla", 0}, {"dead_ogonek", 0}, @@ -213,50 +213,50 @@ static struct console_grub_equivalence console_grub_equivalences_common[] = { }; static grub_uint8_t linux_to_usb_map[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_NUMDOT, GRUB_KEYBOARD_KEY_NUMDOT, - /* 0x54 */ 0, 0, - /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, + /* 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_NUMDOT, GRUB_KEYBOARD_KEY_NUMDOT, + /* 0x54 */ 0, 0, + /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, /* 0x58 */ GRUB_KEYBOARD_KEY_F12, GRUB_KEYBOARD_KEY_JP_RO, /* 0x5a */ 0, 0, /* 0x5c */ 0, 0, @@ -267,7 +267,7 @@ static grub_uint8_t linux_to_usb_map[128] = { /* 0x66 */ GRUB_KEYBOARD_KEY_HOME, GRUB_KEYBOARD_KEY_UP, /* 0x68 */ GRUB_KEYBOARD_KEY_PPAGE, GRUB_KEYBOARD_KEY_LEFT, /* 0x6a */ GRUB_KEYBOARD_KEY_RIGHT, GRUB_KEYBOARD_KEY_END, - /* 0x6c */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_NPAGE, + /* 0x6c */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_NPAGE, /* 0x6e */ GRUB_KEYBOARD_KEY_INSERT, GRUB_KEYBOARD_KEY_DELETE, /* 0x70 */ 0, 0, /* 0x72 */ 0, GRUB_KEYBOARD_KEY_JP_RO, @@ -276,7 +276,7 @@ static grub_uint8_t linux_to_usb_map[128] = { /* 0x78 */ 0, GRUB_KEYBOARD_KEY_KPCOMMA, /* 0x7a */ 0, 0, /* 0x7c */ GRUB_KEYBOARD_KEY_JP_YEN, -}; +}; static void add_special_keys (struct grub_keyboard_layout *layout) @@ -330,7 +330,7 @@ write_file (FILE *out, const char *fname, struct grub_keyboard_layout *layout) unsigned i; version = grub_cpu_to_le32_compile_time (GRUB_KEYBOARD_LAYOUTS_VERSION); - + for (i = 0; i < ARRAY_SIZE (layout->keyboard_map); i++) layout->keyboard_map[i] = grub_cpu_to_le32(layout->keyboard_map[i]); diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c index 602574d52..46f304c2b 100644 --- a/util/grub-mknetdir.c +++ b/util/grub-mknetdir.c @@ -52,7 +52,7 @@ static struct argp_option options[] = { {0, 0, 0, 0, 0, 0} }; -static error_t +static error_t argp_parser (int key, char *arg, struct argp_state *state) { if (grub_install_parse (key, arg)) @@ -86,7 +86,7 @@ argp_parser (int key, char *arg, struct argp_state *state) struct argp argp = { options, argp_parser, NULL, "\v"N_("Prepares GRUB network boot images at net_directory/subdir " - "assuming net_directory being TFTP root."), + "assuming net_directory being TFTP root."), NULL, grub_install_help_filter, NULL }; @@ -108,6 +108,7 @@ static const struct [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" }, [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }, [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64-efi", "efinet", ".efi" }, [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32-efi", "efinet", ".efi" }, [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64-efi", "efinet", ".efi" }, }; @@ -159,6 +160,9 @@ process_input_dir (const char *input_dir, enum grub_install_plat platform) grub_install_make_image_wrap (input_dir, prefix, output, 0, load_cfg, targets[platform].mkimage_target, 0); + + grub_set_install_backup_ponr (); + grub_install_pop_module (); /* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */ diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index 5805f3c10..51e706510 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -133,34 +133,24 @@ main (int argc, char *argv[]) exit(1); } - buf = xmalloc (arguments.buflen); - salt = xmalloc (arguments.saltlen); - printf ("%s", _("Enter password: ")); if (!grub_password_get (pass1, GRUB_AUTH_MAX_PASSLEN)) - { - free (buf); - free (salt); - grub_util_error ("%s", _("failure to read password")); - } + grub_util_error ("%s", _("failure to read password")); printf ("%s", _("Reenter password: ")); if (!grub_password_get (pass2, GRUB_AUTH_MAX_PASSLEN)) - { - free (buf); - free (salt); - grub_util_error ("%s", _("failure to read password")); - } + grub_util_error ("%s", _("failure to read password")); if (strcmp (pass1, pass2) != 0) { memset (pass1, 0, sizeof (pass1)); memset (pass2, 0, sizeof (pass2)); - free (buf); - free (salt); grub_util_error ("%s", _("passwords don't match")); } memset (pass2, 0, sizeof (pass2)); + buf = xmalloc (arguments.buflen); + salt = xmalloc (arguments.saltlen); + if (grub_get_random (salt, arguments.saltlen)) { memset (pass1, 0, sizeof (pass1)); @@ -189,7 +179,7 @@ main (int argc, char *argv[]) ptr = result; memcpy (ptr, "grub.pbkdf2.sha512.", sizeof ("grub.pbkdf2.sha512.") - 1); ptr += sizeof ("grub.pbkdf2.sha512.") - 1; - + grub_snprintf (ptr, sizeof ("XXXXXXXXXXXXXXXXXXX"), "%d", arguments.count); ptr += strlen (ptr); *ptr++ = '.'; diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index ce2cbc4f1..6dc71a8a1 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -150,7 +150,7 @@ enum { SYS_AREA_ARCS } system_area = SYS_AREA_AUTO; -static error_t +static error_t argp_parser (int key, char *arg, struct argp_state *state) { if (grub_install_parse (key, arg)) @@ -229,6 +229,7 @@ write_part (FILE *f, const char *srcdir) char *inname = grub_util_path_concat (2, srcdir, "partmap.lst"); char buf[260]; in = grub_util_fopen (inname, "rb"); + free (inname); if (!in) return; while (fgets (buf, 256, in)) @@ -260,7 +261,26 @@ make_image_abs (enum grub_install_plat plat, load_cfg = grub_util_make_temporary_file (); load_cfg_f = grub_util_fopen (load_cfg, "wb"); - fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid); + /* + * A UEFI bootable media should support file system transposition (e.g. extracting + * an ISO 9660 content to a FAT32 media that was formatted by the user). Therefore, + * for EFI platforms, we search for a specific UUID file rather than a partition UUID. + */ + switch (plat) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + fprintf (load_cfg_f, "search --set=root --file /.disk/%s.uuid\n", iso_uuid); + break; + default: + fprintf (load_cfg_f, "search --set=root --fs-uuid %s\n", iso_uuid); + break; + } fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n"); write_part (load_cfg_f, source_dirs[plat]); @@ -441,8 +461,8 @@ main (int argc, char *argv[]) xorriso = xstrdup ("xorriso"); label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); - argp_argv = xmalloc (sizeof (argp_argv[0]) * argc); - xorriso_tail_argv = xmalloc (sizeof (argp_argv[0]) * argc); + argp_argv = xcalloc (argc, sizeof (argp_argv[0])); + xorriso_tail_argv = xcalloc (argc, sizeof (argp_argv[0])); xorriso_tail_argc = 0; /* Program name */ @@ -457,6 +477,8 @@ main (int argc, char *argv[]) for (i = 1; i < argc; i++) { if (strcmp (argv[i], "-output") == 0) { + if (i + 1 >= argc) + grub_util_error ("%s -- '%s'", _("option requires an argument"), argv[i]); argp_argv[argp_argc++] = (char *) "--output"; i++; argp_argv[argp_argc++] = argv[i]; @@ -465,6 +487,8 @@ main (int argc, char *argv[]) switch (args_to_eat (argv[i])) { case 2: + if (i + 1 >= argc) + grub_util_error ("%s -- '%s'", _("option requires an argument"), argv[i]); argp_argv[argp_argc++] = argv[i++]; /* Fallthrough */ case 1: @@ -494,7 +518,7 @@ main (int argc, char *argv[]) xorriso_push ("-as"); xorriso_push ("mkisofs"); xorriso_push ("-graft-points"); - + iso9660_dir = grub_util_make_temporary_dir (); grub_util_info ("temporary iso9660 dir is `%s'", iso9660_dir); boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub"); @@ -530,6 +554,9 @@ main (int argc, char *argv[]) boot_grub, plat); source_dirs[plat] = xstrdup (grub_install_source_directory); } + + grub_set_install_backup_ponr (); + if (system_area == SYS_AREA_AUTO || grub_install_source_directory) { if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC] @@ -538,6 +565,7 @@ main (int argc, char *argv[]) || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) @@ -635,7 +663,7 @@ main (int argc, char *argv[]) strerror (errno)); fclose (bi); fwrite (buf, 1, 512, sa); - + grub_install_make_image_wrap_file (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], "/boot/grub", sa, sysarea_img, 0, load_cfg, @@ -644,7 +672,7 @@ main (int argc, char *argv[]) fflush (sa); grub_util_fd_sync (fileno (sa)); fclose (sa); - + if (sz > 32768) { grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later.")); @@ -738,18 +766,33 @@ main (int argc, char *argv[]) || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI] || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI]) { - char *efidir = grub_util_make_temporary_dir (); - char *efidir_efi = grub_util_path_concat (2, efidir, "efi"); - char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot"); + FILE *f; + char *efidir_efi = grub_util_path_concat (2, iso9660_dir, "efi"); + char *efidir_efi_boot = grub_util_path_concat (3, iso9660_dir, "efi", "boot"); char *imgname, *img32, *img64, *img_mac = NULL; - char *efiimgfat; + char *efiimgfat, *iso_uuid_file, *diskdir, *diskdir_uuid; grub_install_mkdir_p (efidir_efi_boot); grub_install_push_module ("part_gpt"); grub_install_push_module ("part_msdos"); + grub_install_push_module ("fat"); + /* Many modern UEFI systems also have native support for NTFS. */ + grub_install_push_module ("ntfs"); + + /* Create a '.disk/.uuid' file that can be used to locate the boot media. */ + diskdir = grub_util_path_concat (2, iso9660_dir, ".disk"); + grub_install_mkdir_p (diskdir); + iso_uuid_file = xasprintf ("%s.uuid", iso_uuid); + diskdir_uuid = grub_util_path_concat (2, diskdir, iso_uuid_file); + f = grub_util_fopen (diskdir_uuid, "wb"); + fclose (f); + free (iso_uuid_file); + free (diskdir_uuid); + free (diskdir); imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi"); make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname); @@ -757,31 +800,34 @@ main (int argc, char *argv[]) grub_install_push_module ("part_apple"); img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi"); - make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64); + make_image_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64); grub_install_pop_module (); grub_install_push_module ("part_apple"); img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi"); - make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32); + make_image_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32); grub_install_pop_module (); imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi"); - make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); + make_image_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); free (imgname); imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaa64.efi"); - make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi", + make_image_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi", imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootloongarch64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, + "loongarch64-efi", imgname); free (imgname); imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv32.efi"); - make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV32_EFI, "riscv32-efi", - imgname); + make_image_abs (GRUB_INSTALL_PLATFORM_RISCV32_EFI, "riscv32-efi", imgname); free (imgname); imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv64.efi"); - make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi", - imgname); + make_image_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi", imgname); free (imgname); if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) @@ -821,10 +867,11 @@ main (int argc, char *argv[]) xorriso_push ("-efi-boot-part"); xorriso_push ("--efi-boot-image"); - grub_util_unlink_recursive (efidir); + /* Don't unlink the efidir_efi_boot directory so that we have a duplicate on the ISO 9660 file system. */ free (efiimgfat); free (efidir_efi); - free (efidir); + grub_install_pop_module (); + grub_install_pop_module (); grub_install_pop_module (); grub_install_pop_module (); } diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c index 4907d44c0..9009648e3 100644 --- a/util/grub-mkstandalone.c +++ b/util/grub-mkstandalone.c @@ -30,6 +30,9 @@ #pragma GCC diagnostic error "-Wmissing-prototypes" #pragma GCC diagnostic error "-Wmissing-declarations" +/* use 2015-01-01T00:00:00+0000 as a stock timestamp */ +#define STABLE_EMBEDDING_TIMESTAMP 1420070400 + static char *output_image; static char **files; static int nfiles; @@ -112,7 +115,7 @@ argp_parser (int key, char *arg, struct argp_state *state) struct argp argp = { options, argp_parser, N_("[OPTION] SOURCE..."), - N_("Generate a standalone image (containing all modules) in the selected format")"\v"N_("Graft point syntax (E.g. /boot/grub/grub.cfg=./grub.cfg) is accepted"), + N_("Generate a standalone image (containing all modules) in the selected format")"\v"N_("Graft point syntax (E.g. /boot/grub/grub.cfg=./grub.cfg) is accepted"), NULL, help_filter, NULL }; @@ -184,7 +187,6 @@ add_tar_file (const char *from, struct head hd; grub_util_fd_t in; ssize_t r; - grub_uint32_t mtime = 0; grub_uint32_t size; COMPILE_TIME_ASSERT (sizeof (hd) == 512); @@ -192,8 +194,6 @@ add_tar_file (const char *from, if (grub_util_is_special_file (from)) return; - mtime = grub_util_get_mtime (from); - optr = tcn = xmalloc (strlen (to) + 1); for (iptr = to; *iptr == '/'; iptr++); for (; *iptr; iptr++) @@ -205,22 +205,43 @@ add_tar_file (const char *from, { grub_util_fd_dir_t d; grub_util_fd_dirent_t de; + char **from_files; + grub_size_t alloc = 8, used = 0; + grub_size_t i; d = grub_util_fd_opendir (from); + from_files = xmalloc (alloc * sizeof (*from_files)); while ((de = grub_util_fd_readdir (d))) { - char *fp, *tfp; if (strcmp (de->d_name, ".") == 0) continue; if (strcmp (de->d_name, "..") == 0) continue; - fp = grub_util_path_concat (2, from, de->d_name); - tfp = xasprintf ("%s/%s", to, de->d_name); - add_tar_file (fp, tfp); - free (fp); + if (alloc <= used) + { + alloc <<= 1; + from_files = xrealloc (from_files, alloc * sizeof (*from_files)); + } + from_files[used++] = xstrdup (de->d_name); } + + qsort (from_files, used, sizeof (*from_files), grub_qsort_strcmp); + + for (i = 0; i < used; i++) + { + char *fp, *tfp; + + fp = grub_util_path_concat (2, from, from_files[i]); + tfp = xasprintf ("%s/%s", to, from_files[i]); + add_tar_file (fp, tfp); + free (tfp); + free (fp); + free (from_files[i]); + } + grub_util_fd_closedir (d); + free (from_files); free (tcn); return; } @@ -234,7 +255,7 @@ add_tar_file (const char *from, memcpy (hd.gid, "0001750", 7); set_tar_value (hd.size, optr - tcn, 12); - set_tar_value (hd.mtime, mtime, 12); + set_tar_value (hd.mtime, STABLE_EMBEDDING_TIMESTAMP, 12); hd.typeflag = 'L'; memcpy (hd.magic, MAGIC, sizeof (hd.magic)); memcpy (hd.uname, "grub", 4); @@ -264,7 +285,7 @@ add_tar_file (const char *from, memcpy (hd.gid, "0001750", 7); set_tar_value (hd.size, size, 12); - set_tar_value (hd.mtime, mtime, 12); + set_tar_value (hd.mtime, STABLE_EMBEDDING_TIMESTAMP, 12); hd.typeflag = '0'; memcpy (hd.magic, MAGIC, sizeof (hd.magic)); memcpy (hd.uname, "grub", 4); @@ -273,7 +294,7 @@ add_tar_file (const char *from, compute_checksum (&hd); fwrite (&hd, 1, sizeof (hd), memdisk); - + while (1) { r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE); @@ -296,7 +317,7 @@ main (int argc, char *argv[]) grub_util_host_init (&argc, &argv); grub_util_disable_fd_syncs (); - files = xmalloc ((argc + 1) * sizeof (files[0])); + files = xcalloc (argc + 1, sizeof (files[0])); argp_parse (&argp, argc, argv, 0, 0, 0); @@ -318,6 +339,8 @@ main (int argc, char *argv[]) grub_install_copy_files (grub_install_source_directory, boot_grub, plat); + grub_set_install_backup_ponr (); + char *memdisk_img = grub_util_make_temporary_file (); memdisk = grub_util_fopen (memdisk_img, "wb"); diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c index 163529ca9..91d9e8f88 100644 --- a/util/grub-module-verifier.c +++ b/util/grub-module-verifier.c @@ -119,6 +119,39 @@ struct grub_module_verifier_arch archs[] = { R_AARCH64_PREL32, -1 } }, + { "loongarch64", 8, 0, EM_LOONGARCH, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_LARCH_NONE, + R_LARCH_64, + R_LARCH_MARK_LA, + R_LARCH_SOP_PUSH_PCREL, + R_LARCH_SOP_PUSH_ABSOLUTE, + R_LARCH_SOP_PUSH_PLT_PCREL, + R_LARCH_SOP_SUB, + R_LARCH_SOP_SL, + R_LARCH_SOP_SR, + R_LARCH_SOP_ADD, + R_LARCH_SOP_AND, + R_LARCH_SOP_IF_ELSE, + R_LARCH_SOP_POP_32_S_10_5, + R_LARCH_SOP_POP_32_U_10_12, + R_LARCH_SOP_POP_32_S_10_12, + R_LARCH_SOP_POP_32_S_10_16, + R_LARCH_SOP_POP_32_S_10_16_S2, + R_LARCH_SOP_POP_32_S_5_20, + R_LARCH_SOP_POP_32_S_0_5_10_16_S2, + R_LARCH_SOP_POP_32_S_0_10_10_16_S2, + R_LARCH_B26, + R_LARCH_ABS_HI20, + R_LARCH_ABS_LO12, + R_LARCH_ABS64_LO20, + R_LARCH_ABS64_HI12, + R_LARCH_PCALA_HI20, + R_LARCH_PCALA_LO12, + -1 + }, (int[]){ + -1 + } + }, { "riscv32", 4, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ R_RISCV_32, R_RISCV_64, diff --git a/util/grub-module-verifier32.c b/util/grub-module-verifier32.c index 257229f8f..ba7d41aaf 100644 --- a/util/grub-module-verifier32.c +++ b/util/grub-module-verifier32.c @@ -1,2 +1,4 @@ #define MODULEVERIFIER_ELF32 1 +#ifndef GRUB_MODULE_VERIFIERXX #include "grub-module-verifierXX.c" +#endif diff --git a/util/grub-module-verifier64.c b/util/grub-module-verifier64.c index 4db6b4bed..fc23ef800 100644 --- a/util/grub-module-verifier64.c +++ b/util/grub-module-verifier64.c @@ -1,2 +1,4 @@ #define MODULEVERIFIER_ELF64 1 +#ifndef GRUB_MODULE_VERIFIERXX #include "grub-module-verifierXX.c" +#endif diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c index ceb24309a..a42c20bd1 100644 --- a/util/grub-module-verifierXX.c +++ b/util/grub-module-verifierXX.c @@ -1,3 +1,12 @@ +#define GRUB_MODULE_VERIFIERXX +#if !defined(MODULEVERIFIER_ELF32) && !defined(MODULEVERIFIER_ELF64) +#if __SIZEOF_POINTER__ == 8 +#include "grub-module-verifier64.c" +#else +#include "grub-module-verifier32.c" +#endif +#endif + #include #include @@ -18,6 +27,7 @@ # define Elf_Rel Elf32_Rel # define Elf_Word Elf32_Word # define Elf_Half Elf32_Half +# define Elf_Shnum Elf32_Shnum # define Elf_Section Elf32_Section # define ELF_R_SYM(val) ELF32_R_SYM(val) # define ELF_R_TYPE(val) ELF32_R_TYPE(val) @@ -36,6 +46,7 @@ # define Elf_Rel Elf64_Rel # define Elf_Word Elf64_Word # define Elf_Half Elf64_Half +# define Elf_Shnum Elf64_Shnum # define Elf_Section Elf64_Section # define ELF_R_SYM(val) ELF64_R_SYM(val) # define ELF_R_TYPE(val) ELF64_R_TYPE(val) @@ -131,30 +142,98 @@ grub_target_to_host_real (const struct grub_module_verifier_arch *arch, grub_uin return grub_target_to_host32_real (arch, in); } +static Elf_Shdr * +get_shdr (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word index, size_t module_size) +{ + Elf_Shdr *s; + + if (grub_target_to_host (e->e_shoff) == 0) + grub_util_error ("Invalid section header offset"); + + s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + + index * grub_target_to_host16 (e->e_shentsize)); + /* Check that the header being accessed isn't outside the module size. */ + if (grub_target_to_host32 (s->sh_type) != SHT_NULL && grub_target_to_host32 (s->sh_type) != SHT_NOBITS) + { + if (grub_target_to_host (s->sh_offset) > module_size) + grub_util_error ("Section %d starts after the end of the module", index); + if (grub_target_to_host (s->sh_offset) + grub_target_to_host (s->sh_size) > module_size) + grub_util_error ("Section %d ends after the end of the module", index); + } + return s; +} + +static Elf_Shnum +get_shnum (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) +{ + Elf_Shdr *s; + Elf_Shnum shnum; + + shnum = grub_target_to_host16 (e->e_shnum); + if (shnum == SHN_UNDEF) + { + s = get_shdr (arch, e, 0, 0); + shnum = grub_target_to_host (s->sh_size); + if (shnum < SHN_LORESERVE) + grub_util_error ("Invalid number of section header table entries in sh_size: %" PRIuGRUB_UINT64_T, (grub_uint64_t) shnum); + } + else + { + if (shnum >= SHN_LORESERVE) + grub_util_error ("Invalid number of section header table entries in e_shnum: %" PRIuGRUB_UINT64_T, (grub_uint64_t) shnum); + } + + return shnum; +} + +static Elf_Word +get_shstrndx (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, size_t module_size) +{ + Elf_Shdr *s; + Elf_Word shstrndx; + + shstrndx = grub_target_to_host16 (e->e_shstrndx); + if (shstrndx == SHN_XINDEX) + { + s = get_shdr (arch, e, 0, 0); + shstrndx = grub_target_to_host (s->sh_link); + if (shstrndx < SHN_LORESERVE) + grub_util_error ("Invalid section header table index in sh_link: %d", shstrndx); + } + else + { + if (shstrndx >= SHN_LORESERVE) + grub_util_error ("Invalid section header table index in e_shstrndx: %d", shstrndx); + } + + return shstrndx; +} static Elf_Shdr * -find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *name) +find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *name, size_t module_size) { Elf_Shdr *s; const char *str; unsigned i; - s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host16 (e->e_shstrndx) * grub_target_to_host16 (e->e_shentsize)); + s = get_shdr (arch, e, get_shstrndx (arch, e, module_size), module_size); str = (char *) e + grub_target_to_host (s->sh_offset); - for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); - i < grub_target_to_host16 (e->e_shnum); - i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) - if (strcmp (str + grub_target_to_host32 (s->sh_name), name) == 0) - return s; + for (i = 0; i < get_shnum (arch, e); i++) + { + s = get_shdr (arch, e, i, module_size); + + if (strcmp (str + grub_target_to_host32 (s->sh_name), name) == 0) + return s; + } return NULL; } static void check_license (const char * const filename, - const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) + const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, size_t module_size) { - Elf_Shdr *s = find_section (arch, e, ".module_license"); + Elf_Shdr *s = find_section (arch, e, ".module_license", module_size); if (s && (strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3") == 0 || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3+") == 0 || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv2+") == 0)) @@ -163,20 +242,21 @@ check_license (const char * const filename, } static Elf_Sym * -get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word *size, Elf_Word *entsize) +get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word *size, Elf_Word *entsize, size_t module_size) { unsigned i; - Elf_Shdr *s, *sections; + Elf_Shdr *s; Elf_Sym *sym; - sections = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); - for (i = 0, s = sections; - i < grub_target_to_host16 (e->e_shnum); - i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) - if (grub_target_to_host32 (s->sh_type) == SHT_SYMTAB) - break; + for (i = 0; i < get_shnum (arch, e); i++) + { + s = get_shdr (arch, e, i, module_size); - if (i == grub_target_to_host16 (e->e_shnum)) + if (grub_target_to_host32 (s->sh_type) == SHT_SYMTAB) + break; + } + + if (i == get_shnum (arch, e)) return NULL; sym = (Elf_Sym *) ((char *) e + grub_target_to_host (s->sh_offset)); @@ -202,7 +282,7 @@ is_whitelisted (const char *modname, const char **whitelist) static void check_symbols (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *modname, - const char **whitelist_empty) + const char **whitelist_empty, size_t module_size) { Elf_Sym *sym; Elf_Word size, entsize; @@ -210,7 +290,7 @@ check_symbols (const struct grub_module_verifier_arch *arch, /* Module without symbol table and without .moddeps section is useless at boot time, so catch it early to prevent build errors */ - sym = get_symtab (arch, e, &size, &entsize); + sym = get_symtab (arch, e, &size, &entsize, module_size); if (!sym) { Elf_Shdr *s; @@ -222,7 +302,7 @@ check_symbols (const struct grub_module_verifier_arch *arch, if (is_whitelisted (modname, whitelist_empty)) return; - s = find_section (arch, e, ".moddeps"); + s = find_section (arch, e, ".moddeps", module_size); if (!s) grub_util_error ("%s: no symbol table and no .moddeps section", modname); @@ -277,13 +357,13 @@ is_symbol_local(Elf_Sym *sym) static void section_check_relocations (const char * const modname, const struct grub_module_verifier_arch *arch, void *ehdr, - Elf_Shdr *s, size_t target_seg_size) + Elf_Shdr *s, size_t target_seg_size, size_t module_size) { Elf_Rel *rel, *max; Elf_Sym *symtab; Elf_Word symtabsize, symtabentsize; - symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize); + symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize, module_size); if (!symtab) grub_util_error ("%s: relocation without symbol table", modname); @@ -359,30 +439,32 @@ section_check_relocations (const char * const modname, static void check_relocations (const char * const modname, - const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) + const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, size_t module_size) { Elf_Shdr *s; unsigned i; - for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); - i < grub_target_to_host16 (e->e_shnum); - i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) - if (grub_target_to_host32 (s->sh_type) == SHT_REL || grub_target_to_host32 (s->sh_type) == SHT_RELA) - { - Elf_Shdr *ts; + for (i = 0; i < get_shnum (arch, e); i++) + { + s = get_shdr (arch, e, i, module_size); - if (grub_target_to_host32 (s->sh_type) == SHT_REL && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_REL)) - grub_util_error ("%s: unsupported SHT_REL", modname); - if (grub_target_to_host32 (s->sh_type) == SHT_RELA && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_RELA)) - grub_util_error ("%s: unsupported SHT_RELA", modname); + if (grub_target_to_host32 (s->sh_type) == SHT_REL || grub_target_to_host32 (s->sh_type) == SHT_RELA) + { + Elf_Shdr *ts; - /* Find the target segment. */ - if (grub_target_to_host32 (s->sh_info) >= grub_target_to_host16 (e->e_shnum)) - grub_util_error ("%s: orphaned reloc section", modname); - ts = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host32 (s->sh_info) * grub_target_to_host16 (e->e_shentsize)); + if (grub_target_to_host32 (s->sh_type) == SHT_REL && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_REL)) + grub_util_error ("%s: unsupported SHT_REL", modname); + if (grub_target_to_host32 (s->sh_type) == SHT_RELA && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_RELA)) + grub_util_error ("%s: unsupported SHT_RELA", modname); - section_check_relocations (modname, arch, e, s, grub_target_to_host (ts->sh_size)); - } + /* Find the target segment. */ + if (grub_target_to_host32 (s->sh_info) >= get_shnum (arch, e)) + grub_util_error ("%s: orphaned reloc section", modname); + ts = get_shdr (arch, e, grub_target_to_host32 (s->sh_info), module_size); + + section_check_relocations (modname, arch, e, s, grub_target_to_host (ts->sh_size), module_size); + } + } } void @@ -418,22 +500,22 @@ SUFFIX(grub_module_verify) (const char * const filename, /* Make sure that every section is within the core. */ if (size < grub_target_to_host (e->e_shoff) - + (grub_uint32_t) grub_target_to_host16 (e->e_shentsize) * grub_target_to_host16(e->e_shnum)) + + (grub_uint32_t) grub_target_to_host16 (e->e_shentsize) * get_shnum (arch, e)) { grub_util_error ("%s: ELF sections outside core", filename); } - check_license (filename, arch, e); + check_license (filename, arch, e, size); Elf_Shdr *s; const char *modname; - s = find_section (arch, e, ".modname"); + s = find_section (arch, e, ".modname", size); if (!s) grub_util_error ("%s: no module name found", filename); modname = (const char *) e + grub_target_to_host (s->sh_offset); - check_symbols(arch, e, modname, whitelist_empty); - check_relocations(modname, arch, e); + check_symbols(arch, e, modname, whitelist_empty, size); + check_relocations(modname, arch, e, size); } diff --git a/util/grub-mount.c b/util/grub-mount.c index d7be2a427..bf4c8b891 100644 --- a/util/grub-mount.c +++ b/util/grub-mount.c @@ -16,7 +16,6 @@ * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ -#define FUSE_USE_VERSION 26 #include #include #include @@ -34,7 +33,7 @@ #include #include #include -#include +#include #include #include @@ -146,12 +145,18 @@ fuse_getattr_find_file (const char *cur_filename, return 0; } +#if FUSE_USE_VERSION < 30 static int fuse_getattr (const char *path, struct stat *st) +#else +static int +fuse_getattr (const char *path, struct stat *st, + struct fuse_file_info *fi __attribute__ ((unused))) +#endif { struct fuse_getattr_ctx ctx; char *pathname, *path2; - + if (path[0] == '/' && path[1] == 0) { st->st_dev = 0; @@ -170,7 +175,7 @@ fuse_getattr (const char *path, struct stat *st) ctx.file_exists = 0; pathname = xstrdup (path); - + /* Remove trailing '/'. */ while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') pathname[grub_strlen (pathname) - 1] = 0; @@ -193,6 +198,7 @@ fuse_getattr (const char *path, struct stat *st) (fs->fs_dir) (dev, path2, fuse_getattr_find_file, &ctx); grub_free (path2); + free (pathname); if (!ctx.file_exists) { grub_errno = GRUB_ERR_NONE; @@ -231,7 +237,7 @@ fuse_getattr (const char *path, struct stat *st) } static int -fuse_opendir (const char *path, struct fuse_file_info *fi) +fuse_opendir (const char *path, struct fuse_file_info *fi) { return 0; } @@ -240,9 +246,12 @@ fuse_opendir (const char *path, struct fuse_file_info *fi) static grub_file_t files[65536]; static int first_fd = 1; -static int -fuse_open (const char *path, struct fuse_file_info *fi __attribute__ ((unused))) +static int +fuse_open (const char *path, struct fuse_file_info *fi) { + if ((fi->flags & O_ACCMODE) != O_RDONLY) + return -EROFS; + grub_file_t file; file = grub_file_open (path, GRUB_FILE_TYPE_MOUNT); if (! file) @@ -252,9 +261,9 @@ fuse_open (const char *path, struct fuse_file_info *fi __attribute__ ((unused))) files[first_fd++] = file; grub_errno = GRUB_ERR_NONE; return 0; -} +} -static int +static int fuse_read (const char *path, char *buf, size_t sz, off_t off, struct fuse_file_info *fi) { @@ -265,7 +274,7 @@ fuse_read (const char *path, char *buf, size_t sz, off_t off, return -EINVAL; file->offset = off; - + size = grub_file_read (file, buf, sz); if (size < 0) return translate_error (); @@ -274,9 +283,9 @@ fuse_read (const char *path, char *buf, size_t sz, off_t off, grub_errno = GRUB_ERR_NONE; return size; } -} +} -static int +static int fuse_release (const char *path, struct fuse_file_info *fi) { grub_file_close (files[fi->fh]); @@ -330,13 +339,24 @@ fuse_readdir_call_fill (const char *filename, st.st_blocks = (st.st_size + 511) >> 9; st.st_atime = st.st_mtime = st.st_ctime = info->mtimeset ? info->mtime : 0; +#if FUSE_USE_VERSION < 30 ctx->fill (ctx->buf, filename, &st, 0); +#else + ctx->fill (ctx->buf, filename, &st, 0, 0); +#endif return 0; } -static int +#if FUSE_USE_VERSION < 30 +static int fuse_readdir (const char *path, void *buf, fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi) +#else +static int +fuse_readdir (const char *path, void *buf, + fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi, + enum fuse_readdir_flags flags __attribute__ ((unused))) +#endif { struct fuse_readdir_ctx ctx = { .path = path, @@ -346,7 +366,7 @@ fuse_readdir (const char *path, void *buf, char *pathname; pathname = xstrdup (path); - + /* Remove trailing '/'. */ while (pathname [0] && pathname[1] && pathname[grub_strlen (pathname) - 1] == '/') @@ -448,7 +468,7 @@ fuse_init (void) return grub_errno; } -static struct argp_option options[] = { +static struct argp_option options[] = { {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2}, {"debug", 'd', N_("STRING"), 0, N_("Set debug environment variable."), 2}, {"crypto", 'C', NULL, 0, N_("Mount crypto devices."), 2}, @@ -467,7 +487,7 @@ print_version (FILE *stream, struct argp_state *state) } void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; -static error_t +static error_t argp_parser (int key, char *arg, struct argp_state *state) { switch (key) @@ -479,7 +499,7 @@ argp_parser (int key, char *arg, struct argp_state *state) case 'K': if (strcmp (arg, "prompt") == 0) { - char buf[1024]; + char buf[1024]; grub_printf ("%s", _("Enter ZFS password: ")); if (grub_password_get (buf, 1023)) { @@ -543,6 +563,8 @@ argp_parser (int key, char *arg, struct argp_state *state) images = xrealloc (images, (num_disks + 1) * sizeof (images[0])); images[num_disks] = grub_canonicalize_file_name (arg); + if (images[num_disks] == NULL) + grub_util_error (_("cannot find `%s': %s"), arg, strerror (errno)); num_disks++; return 0; @@ -550,7 +572,7 @@ argp_parser (int key, char *arg, struct argp_state *state) struct argp argp = { options, argp_parser, N_("IMAGE1 [IMAGE2 ...] MOUNTPOINT"), - N_("Debug tool for filesystem driver."), + N_("Debug tool for filesystem driver."), NULL, NULL, NULL }; @@ -570,7 +592,7 @@ main (int argc, char *argv[]) fuse_argc++; argp_parse (&argp, argc, argv, 0, 0, 0); - + if (num_disks < 2) grub_util_error ("%s", _("need an image and mountpoint")); fuse_args = xrealloc (fuse_args, (fuse_argc + 2) * sizeof (fuse_args[0])); diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c index 0d4084a10..11331294f 100644 --- a/util/grub-pe2elf.c +++ b/util/grub-pe2elf.c @@ -100,9 +100,9 @@ write_section_data (FILE* fp, const char *name, char *image, char *pe_strtab = (image + pe_chdr->symtab_offset + pe_chdr->num_symbols * sizeof (struct grub_pe32_symbol)); - section_map = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (int)); + section_map = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (int)); section_map[0] = 0; - shdr = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (shdr[0])); + shdr = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (shdr[0])); idx = 1; idx_reloc = pe_chdr->num_sections + 1; @@ -233,7 +233,7 @@ write_reloc_section (FILE* fp, const char *name, char *image, pe_sec = pe_shdr + shdr[i].sh_link; pe_rel = (struct grub_pe32_reloc *) (image + pe_sec->relocations_offset); - rel = (elf_reloc_t *) xmalloc (pe_sec->num_relocations * sizeof (elf_reloc_t)); + rel = (elf_reloc_t *) xcalloc (pe_sec->num_relocations, sizeof (elf_reloc_t)); num_rels = 0; modified = 0; @@ -365,12 +365,10 @@ write_symbol_table (FILE* fp, const char *name, char *image, pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset); pe_strtab = (char *) (pe_symtab + pe_chdr->num_symbols); - symtab = (Elf_Sym *) xmalloc ((pe_chdr->num_symbols + 1) * - sizeof (Elf_Sym)); - memset (symtab, 0, (pe_chdr->num_symbols + 1) * sizeof (Elf_Sym)); + symtab = (Elf_Sym *) xcalloc (pe_chdr->num_symbols + 1, sizeof (Elf_Sym)); num_syms = 1; - symtab_map = (int *) xmalloc (pe_chdr->num_symbols * sizeof (int)); + symtab_map = (int *) xcalloc (pe_chdr->num_symbols, sizeof (int)); for (i = 0; i < (int) pe_chdr->num_symbols; i += pe_symtab->num_aux + 1, pe_symtab += pe_symtab->num_aux + 1) diff --git a/util/grub-probe.c b/util/grub-probe.c index 81d27eead..65c1ca3f8 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -133,7 +133,7 @@ get_targets_string (void) } static int -print_gpt_guid (grub_gpt_part_guid_t guid) +print_gpt_guid (grub_guid_t guid) { guid.data1 = grub_le_to_cpu32 (guid.data1); guid.data2 = grub_le_to_cpu16 (guid.data2); @@ -361,8 +361,8 @@ probe (const char *path, char **device_names, char delim) grub_util_pull_device (*curdev); ndev++; } - - drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); + + drives_names = xcalloc (ndev + 1, sizeof (drives_names[0])); for (curdev = device_names, curdrive = drives_names; *curdev; curdev++, curdrive++) @@ -398,7 +398,7 @@ probe (const char *path, char **device_names, char delim) if (! dev || !dev->disk) grub_util_error ("%s", grub_errmsg); - dsize = grub_disk_get_size (dev->disk); + dsize = grub_disk_native_sectors (dev->disk); for (addr = 0; addr < dsize; addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE) { @@ -433,7 +433,7 @@ probe (const char *path, char **device_names, char delim) dev = grub_device_open (drives_names[0]); if (! dev) grub_util_error ("%s", grub_errmsg); - + fs = grub_fs_probe (dev); if (! fs) grub_util_error ("%s", grub_errmsg); @@ -543,7 +543,7 @@ probe (const char *path, char **device_names, char delim) else printf ("\n"); } - + else if ((print == PRINT_COMPATIBILITY_HINT || print == PRINT_BIOS_HINT || print == PRINT_IEEE1275_HINT || print == PRINT_BAREMETAL_HINT || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT) @@ -732,7 +732,8 @@ static struct argp_option options[] = { {"device-map", 'm', N_("FILE"), 0, N_("use FILE as the device map [default=%s]"), 0}, {"target", 't', N_("TARGET"), 0, 0, 0}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, + {"verbose", 'v', 0, 0, + N_("print verbose messages (pass twice to enable debug printing)."), 0}, {0, '0', 0, 0, N_("separate items in output using ASCII NUL characters"), 0}, { 0, 0, 0, 0, 0, 0 } }; diff --git a/util/grub-protect.c b/util/grub-protect.c new file mode 100644 index 000000000..40d4a3fc5 --- /dev/null +++ b/util/grub-protect.c @@ -0,0 +1,1638 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2022 Microsoft Corporation + * 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 +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#include +#pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wmissing-declarations" + +#include "progname.h" + +/* Unprintable option keys for argp */ +typedef enum protect_opt +{ + /* General */ + PROTECT_OPT_ACTION = 'a', + PROTECT_OPT_PROTECTOR = 'p', + /* TPM2 */ + PROTECT_OPT_TPM2_DEVICE = 0x100, + PROTECT_OPT_TPM2_PCRS, + PROTECT_OPT_TPM2_ASYMMETRIC, + PROTECT_OPT_TPM2_BANK, + PROTECT_OPT_TPM2_SRK, + PROTECT_OPT_TPM2_KEYFILE, + PROTECT_OPT_TPM2_OUTFILE, + PROTECT_OPT_TPM2_EVICT, + PROTECT_OPT_TPM2_TPM2KEY, + PROTECT_OPT_TPM2_NVINDEX, +} protect_opt_t; + +/* Option flags to keep track of specified arguments */ +typedef enum protect_arg +{ + /* General */ + PROTECT_ARG_ACTION = 1 << 0, + PROTECT_ARG_PROTECTOR = 1 << 1, + /* TPM2 */ + PROTECT_ARG_TPM2_DEVICE = 1 << 2, + PROTECT_ARG_TPM2_PCRS = 1 << 3, + PROTECT_ARG_TPM2_ASYMMETRIC = 1 << 4, + PROTECT_ARG_TPM2_BANK = 1 << 5, + PROTECT_ARG_TPM2_SRK = 1 << 6, + PROTECT_ARG_TPM2_KEYFILE = 1 << 7, + PROTECT_ARG_TPM2_OUTFILE = 1 << 8, + PROTECT_ARG_TPM2_EVICT = 1 << 9, + PROTECT_ARG_TPM2_TPM2KEY = 1 << 10, + PROTECT_ARG_TPM2_NVINDEX = 1 << 11 +} protect_arg_t; + +typedef enum protect_protector +{ + PROTECT_TYPE_ERROR, + PROTECT_TYPE_TPM2 +} protect_protector_t; + +typedef enum protect_action +{ + PROTECT_ACTION_ERROR, + PROTECT_ACTION_ADD, + PROTECT_ACTION_REMOVE +} protect_action_t; + +typedef struct protect_args +{ + protect_arg_t args; + protect_action_t action; + protect_protector_t protector; + + const char *tpm2_device; + grub_uint8_t tpm2_pcrs[TPM_MAX_PCRS]; + grub_uint8_t tpm2_pcr_count; + grub_srk_type_t srk_type; + TPM_ALG_ID_t tpm2_bank; + TPM_HANDLE_t tpm2_srk; + const char *tpm2_keyfile; + const char *tpm2_outfile; + bool tpm2_evict; + bool tpm2_tpm2key; + TPM_HANDLE_t tpm2_nvindex; +} protect_args_t; + +static struct argp_option protect_options[] = + { + /* Top-level options */ + { + .name = "action", + .key = 'a', + .arg = "add|remove", + .flags = 0, + .doc = + N_("Add or remove a key protector to or from a key."), + .group = 0 + }, + { + .name = "protector", + .key = 'p', + .arg = "tpm2", + .flags = 0, + .doc = + N_("Set key protector to use (only tpm2 is currently supported)."), + .group = 0 + }, + /* TPM2 key protector options */ + { + .name = "tpm2-device", + .key = PROTECT_OPT_TPM2_DEVICE, + .arg = "FILE", + .flags = 0, + .doc = + N_("Set the path to the TPM2 device. (default: /dev/tpm0)"), + .group = 0 + }, + { + .name = "tpm2-pcrs", + .key = PROTECT_OPT_TPM2_PCRS, + .arg = "0[,1]...", + .flags = 0, + .doc = + N_("Set a comma-separated list of PCRs used to authorize key release " + "e.g., '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: 7)"), + .group = 0 + }, + { + .name = "tpm2-bank", + .key = PROTECT_OPT_TPM2_BANK, + .arg = "ALG", + .flags = 0, + .doc = + N_("Set the bank of PCRs used to authorize key release: " + "SHA1, SHA256, SHA384, or SHA512. (default: SHA256)"), + .group = 0 + }, + { + .name = "tpm2-keyfile", + .key = PROTECT_OPT_TPM2_KEYFILE, + .arg = "FILE", + .flags = 0, + .doc = + N_("Set the path to a file that contains the cleartext key to protect."), + .group = 0 + }, + { + .name = "tpm2-outfile", + .key = PROTECT_OPT_TPM2_OUTFILE, + .arg = "FILE", + .flags = 0, + .doc = + N_("Set the path to the file that will contain the key after sealing " + "(must be accessible to GRUB during boot)."), + .group = 0 + }, + { + .name = "tpm2-srk", + .key = PROTECT_OPT_TPM2_SRK, + .arg = "NUM", + .flags = 0, + .doc = + N_("Set the SRK handle if the SRK is to be made persistent."), + .group = 0 + }, + { + .name = "tpm2-asymmetric", + .key = PROTECT_OPT_TPM2_ASYMMETRIC, + .arg = "TYPE", + .flags = 0, + .doc = + N_("Set the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)." + "(default: ECC)"), + .group = 0 + }, + { + .name = "tpm2-evict", + .key = PROTECT_OPT_TPM2_EVICT, + .arg = NULL, + .flags = 0, + .doc = + N_("Evict a previously persisted SRK from the TPM, if any."), + .group = 0 + }, + { + .name = "tpm2key", + .key = PROTECT_OPT_TPM2_TPM2KEY, + .arg = NULL, + .flags = 0, + .doc = + N_("Use TPM 2.0 Key File format."), + .group = 0 + }, + { + .name = "tpm2-nvindex", + .key = PROTECT_OPT_TPM2_NVINDEX, + .arg = "NUM", + .flags = 0, + .doc = + N_("Store the sealed key in a persistent or NV index handle."), + .group = 0 + }, + /* End of list */ + { 0, 0, 0, 0, 0, 0 } + }; + +static int protector_tpm2_fd = -1; + +static grub_err_t +protect_read_file (const char *filepath, void **buffer, size_t *buffer_size) +{ + grub_err_t err; + FILE *f; + long len; + void *buf; + + f = fopen (filepath, "rb"); + if (f == NULL) + { + fprintf (stderr, N_("Could not open file: %s\n"), filepath); + return GRUB_ERR_FILE_NOT_FOUND; + } + + if (fseek (f, 0, SEEK_END)) + { + fprintf (stderr, N_("Could not seek file: %s\n"), filepath); + err = GRUB_ERR_FILE_READ_ERROR; + goto exit1; + } + + len = ftell (f); + if (len <= 0) + { + fprintf (stderr, N_("Could not get file length: %s\n"), filepath); + err = GRUB_ERR_FILE_READ_ERROR; + goto exit1; + } + + rewind (f); + + buf = grub_malloc (len); + if (buf == NULL) + { + fprintf (stderr, N_("Could not allocate memory for file: %s\n"), filepath); + err = GRUB_ERR_OUT_OF_MEMORY; + goto exit1; + } + + if (fread (buf, len, 1, f) != 1) + { + fprintf (stderr, N_("Could not read file: %s\n"), filepath); + err = GRUB_ERR_FILE_READ_ERROR; + goto exit2; + } + + *buffer = buf; + *buffer_size = len; + + buf = NULL; + err = GRUB_ERR_NONE; + + exit2: + grub_free (buf); + + exit1: + fclose (f); + + return err; +} + +static grub_err_t +protect_write_file (const char *filepath, void *buffer, size_t buffer_size) +{ + grub_err_t err; + FILE *f; + + f = fopen (filepath, "wb"); + if (f == NULL) + return GRUB_ERR_FILE_NOT_FOUND; + + if (fwrite (buffer, buffer_size, 1, f) != 1) + { + err = GRUB_ERR_WRITE_ERROR; + goto exit; + } + + err = GRUB_ERR_NONE; + + exit: + fclose (f); + + return err; +} + +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 (write (protector_tpm2_fd, input, input_size) != input_size) + { + fprintf (stderr, N_("Could not send TPM command.\n")); + return GRUB_ERR_BAD_DEVICE; + } + + if (read (protector_tpm2_fd, output, output_size) < sizeof (TPM_RESPONSE_HEADER_t)) + { + fprintf (stderr, N_("Could not get TPM response.\n")); + return GRUB_ERR_BAD_DEVICE; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_open_device (const char *dev_node) +{ + if (protector_tpm2_fd != -1) + return GRUB_ERR_NONE; + + protector_tpm2_fd = open (dev_node, O_RDWR); + if (protector_tpm2_fd == -1) + { + fprintf (stderr, N_("Could not open TPM device (%s).\n"), strerror (errno)); + return GRUB_ERR_FILE_NOT_FOUND; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_close_device (void) +{ + int err; + + if (protector_tpm2_fd == -1) + return GRUB_ERR_NONE; + + err = close (protector_tpm2_fd); + if (err != GRUB_ERR_NONE) + { + fprintf (stderr, N_("Could not close TPM device (%s).\n"), strerror (errno)); + return GRUB_ERR_IO; + } + + protector_tpm2_fd = -1; + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_get_policy_digest (protect_args_t *args, TPM2B_DIGEST_t *digest) +{ + TPM_RC_t rc; + TPML_PCR_SELECTION_t pcr_sel = { + .count = 1, + .pcrSelections = { + { + .hash = args->tpm2_bank, + .sizeOfSelect = 3, + .pcrSelect = {0} + }, + } + }; + TPML_PCR_SELECTION_t pcr_sel_out = {0}; + TPML_DIGEST_t pcr_values = {0}; + TPM2B_DIGEST_t pcr_digest = {0}; + grub_size_t pcr_digest_len; + TPM2B_MAX_BUFFER_t pcr_concat = {0}; + grub_size_t pcr_concat_len; + grub_uint8_t *pcr_cursor; + TPM2B_NONCE_t nonce = {0}; + TPM2B_ENCRYPTED_SECRET_t salt = {0}; + TPMT_SYM_DEF_t symmetric = {0}; + TPMI_SH_AUTH_SESSION_t session = 0; + TPM2B_DIGEST_t policy_digest = {0}; + grub_uint8_t i; + grub_err_t err; + + /* PCR Read */ + for (i = 0; i < args->tpm2_pcr_count; i++) + TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], args->tpm2_pcrs[i]); + + rc = grub_tpm2_pcr_read (NULL, &pcr_sel, NULL, &pcr_sel_out, &pcr_values, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to read PCRs (TPM2_PCR_Read: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + if ((pcr_sel_out.count != pcr_sel.count) || + (pcr_sel.pcrSelections[0].sizeOfSelect != + pcr_sel_out.pcrSelections[0].sizeOfSelect)) + { + fprintf (stderr, N_("Could not read all the specified PCRs.\n")); + return GRUB_ERR_BAD_DEVICE; + } + + /* Compute PCR Digest */ + switch (args->tpm2_bank) + { + case TPM_ALG_SHA1: + pcr_digest_len = TPM_SHA1_DIGEST_SIZE; + break; + case TPM_ALG_SHA256: + pcr_digest_len = TPM_SHA256_DIGEST_SIZE; + break; + case TPM_ALG_SHA384: + pcr_digest_len = TPM_SHA384_DIGEST_SIZE; + break; + case TPM_ALG_SHA512: + pcr_digest_len = TPM_SHA512_DIGEST_SIZE; + break; + default: + return GRUB_ERR_BAD_ARGUMENT; + } + + pcr_concat_len = pcr_digest_len * args->tpm2_pcr_count; + if (pcr_concat_len > TPM_MAX_DIGEST_BUFFER) + { + fprintf (stderr, N_("PCR concatenation buffer not big enough.\n")); + return GRUB_ERR_OUT_OF_RANGE; + } + + pcr_cursor = pcr_concat.buffer; + for (i = 0; i < args->tpm2_pcr_count; i++) + { + if (pcr_values.digests[i].size != pcr_digest_len) + { + fprintf (stderr, + N_("Bad PCR value size: expected %llu bytes but got %u bytes.\n"), + (long long unsigned int)pcr_digest_len, pcr_values.digests[i].size); + return GRUB_ERR_BAD_ARGUMENT; + } + + grub_memcpy (pcr_cursor, pcr_values.digests[i].buffer, pcr_digest_len); + pcr_cursor += pcr_digest_len; + } + pcr_concat.size = pcr_concat_len; + + rc = grub_tpm2_hash (NULL, &pcr_concat, args->tpm2_bank, TPM_RH_NULL, &pcr_digest, NULL, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to generate PCR digest (TPM2_Hash: 0x%x)\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + /* Start Trial Session */ + nonce.size = TPM_SHA256_DIGEST_SIZE; + symmetric.algorithm = TPM_ALG_NULL; + + rc = grub_tpm2_startauthsession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonce, &salt, + TPM_SE_TRIAL, &symmetric, TPM_ALG_SHA256, + &session, NULL, 0); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to start trial policy session (TPM2_StartAuthSession: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + /* PCR Policy */ + rc = grub_tpm2_policypcr (session, NULL, &pcr_digest, &pcr_sel, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to submit PCR policy (TPM2_PolicyPCR: 0x%x).\n", rc); + err = GRUB_ERR_BAD_DEVICE; + goto error; + } + + /* Retrieve Policy Digest */ + rc = grub_tpm2_policygetdigest (session, NULL, &policy_digest, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).\n", rc); + err = GRUB_ERR_BAD_DEVICE; + goto error; + } + + /* Epilogue */ + *digest = policy_digest; + err = GRUB_ERR_NONE; + + error: + grub_tpm2_flushcontext (session); + + return err; +} + +static grub_err_t +protect_tpm2_get_srk (protect_args_t *args, TPM_HANDLE_t *srk) +{ + TPM_RC_t rc; + TPM2B_PUBLIC_t public; + 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 srkHandle; + + if (args->tpm2_srk != 0) + { + /* Find SRK */ + rc = grub_tpm2_readpublic (args->tpm2_srk, NULL, &public); + if (rc == TPM_RC_SUCCESS) + { + printf ("Read SRK from 0x%x\n", args->tpm2_srk); + *srk = args->tpm2_srk; + return GRUB_ERR_NONE; + } + + /* The handle exists but its public area could not be read. */ + if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE) + { + fprintf (stderr, "Failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 0x%x).\n", args->tpm2_srk, rc); + return GRUB_ERR_BAD_DEVICE; + } + } + + /* Create SRK */ + authCommand.sessionHandle = TPM_RS_PW; + inPublic.publicArea.type = args->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; + + switch (args->srk_type.type) + { + case 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 = args->srk_type.detail.rsa_bits; + inPublic.publicArea.parameters.rsaDetail.exponent = 0; + break; + + case 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 = args->srk_type.detail.ecc_curve; + inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; + break; + + default: + return GRUB_ERR_BAD_ARGUMENT; + } + + rc = grub_tpm2_createprimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic, + &outsideInfo, &creationPcr, &srkHandle, &outPublic, + &creationData, &creationHash, &creationTicket, + &srkName, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to create SRK (TPM2_CreatePrimary: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + /* Persist SRK */ + if (args->tpm2_srk != 0) + { + rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, srkHandle, &authCommand, args->tpm2_srk, NULL); + if (rc == TPM_RC_SUCCESS) + { + grub_tpm2_flushcontext (srkHandle); + srkHandle = args->tpm2_srk; + } + else + fprintf (stderr, + "Warning: Failed to persist SRK (0x%x) (TPM2_EvictControl: 0x%x).\n" + "Continuing anyway...\n", args->tpm2_srk, rc); + } + + /* Epilogue */ + *srk = srkHandle; + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_seal (TPM2B_DIGEST_t *policyDigest, TPM_HANDLE_t srk, + grub_uint8_t *clearText, grub_size_t clearTextLength, + tpm2_sealed_key_t *sealed_key) +{ + TPM_RC_t rc; + 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 pcr_sel = {0}; + TPM2B_PRIVATE_t outPrivate = {0}; + TPM2B_PUBLIC_t outPublic = {0}; + + /* Seal Data */ + authCommand.sessionHandle = TPM_RS_PW; + + inSensitive.sensitive.data.size = clearTextLength; + memcpy(inSensitive.sensitive.data.buffer, clearText, clearTextLength); + + inPublic.publicArea.type = TPM_ALG_KEYEDHASH; + inPublic.publicArea.nameAlg = TPM_ALG_SHA256; + inPublic.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_NULL; + inPublic.publicArea.authPolicy = *policyDigest; + + rc = grub_tpm2_create (srk, &authCommand, &inSensitive, &inPublic, &outsideInfo, + &pcr_sel, &outPrivate, &outPublic, NULL, NULL, NULL, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to seal key (TPM2_Create: 0x%x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + /* Epilogue */ + sealed_key->public = outPublic; + sealed_key->private = outPrivate; + + return GRUB_ERR_NONE; +} + +extern asn1_static_node tpm2key_asn1_tab[]; + +/* id-sealedkey OID defined in TPM 2.0 Key Files Spec */ +#define TPM2KEY_SEALED_KEY_OID "2.23.133.10.1.5" + +static grub_err_t +protect_tpm2_export_tpm2key (const protect_args_t *args, tpm2_sealed_key_t *sealed_key, + void **der_buf, int *der_buf_size) +{ + const char *sealed_key_oid = TPM2KEY_SEALED_KEY_OID; + asn1_node asn1_def = NULL; + asn1_node tpm2key = NULL; + grub_uint32_t parent; + grub_uint32_t cmd_code; + struct grub_tpm2_buffer pol_buf; + TPML_PCR_SELECTION_t pcr_sel = { + .count = 1, + .pcrSelections = { + { + .hash = args->tpm2_bank, + .sizeOfSelect = 3, + .pcrSelect = {0} + }, + } + }; + struct grub_tpm2_buffer pub_buf; + struct grub_tpm2_buffer priv_buf; + int i; + int ret; + grub_err_t err; + + if (der_buf == NULL) + return GRUB_ERR_BAD_ARGUMENT; + + for (i = 0; i < args->tpm2_pcr_count; i++) + TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], args->tpm2_pcrs[i]); + + /* + * Prepare the parameters for TPM_CC_PolicyPCR: + * empty pcrDigest and the user selected PCRs + */ + grub_tpm2_buffer_init (&pol_buf); + grub_tpm2_buffer_pack_u16 (&pol_buf, 0); + grub_Tss2_MU_TPML_PCR_SELECTION_Marshal (&pol_buf, &pcr_sel); + + grub_tpm2_buffer_init (&pub_buf); + grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&pub_buf, &sealed_key->public); + grub_tpm2_buffer_init (&priv_buf); + grub_Tss2_MU_TPM2B_Marshal (&priv_buf, sealed_key->private.size, + sealed_key->private.buffer); + if (pub_buf.error != 0 || priv_buf.error != 0) + return GRUB_ERR_BAD_ARGUMENT; + + ret = asn1_array2tree (tpm2key_asn1_tab, &asn1_def, NULL); + if (ret != ASN1_SUCCESS) + return GRUB_ERR_BAD_ARGUMENT; + + ret = asn1_create_element (asn1_def, "TPM2KEY.TPMKey" , &tpm2key); + if (ret != ASN1_SUCCESS) + return GRUB_ERR_BAD_ARGUMENT; + + /* Set 'type' to "sealed key" */ + ret = asn1_write_value (tpm2key, "type", sealed_key_oid, 1); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'type': 0x%u\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Set 'emptyAuth' to TRUE */ + ret = asn1_write_value (tpm2key, "emptyAuth", "TRUE", 1); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'emptyAuth': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Set 'policy' */ + ret = asn1_write_value (tpm2key, "policy", "NEW", 1); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'policy': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + cmd_code = grub_cpu_to_be32 (TPM_CC_PolicyPCR); + ret = asn1_write_value (tpm2key, "policy.?LAST.CommandCode", &cmd_code, + sizeof (cmd_code)); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'policy CommandCode': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + ret = asn1_write_value (tpm2key, "policy.?LAST.CommandPolicy", &pol_buf.data, + pol_buf.size); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'policy CommandPolicy': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Remove 'secret' */ + ret = asn1_write_value (tpm2key, "secret", NULL, 0); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to remove 'secret': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Remove 'authPolicy' */ + ret = asn1_write_value (tpm2key, "authPolicy", NULL, 0); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to remove 'authPolicy': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Remove 'description' */ + ret = asn1_write_value (tpm2key, "description", NULL, 0); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to remove 'description': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* + * Use the SRK handle as the parent handle if specified + * Otherwise, Use TPM_RH_OWNER as the default parent handle + */ + if (args->tpm2_srk != 0) + parent = grub_cpu_to_be32 (args->tpm2_srk); + else + parent = grub_cpu_to_be32 (TPM_RH_OWNER); + ret = asn1_write_value (tpm2key, "parent", &parent, sizeof (parent)); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'parent': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* + * Set 'rsaParent' to TRUE if the RSA SRK is specified and the SRK + * handle is not persistent. Otherwise, remove 'rsaParent'. + */ + if (args->tpm2_srk == 0 && args->srk_type.type == TPM_ALG_RSA) + ret = asn1_write_value (tpm2key, "rsaParent", "TRUE", 1); + else + ret = asn1_write_value (tpm2key, "rsaParent", NULL, 0); + + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'rsaParent': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Set the pubkey */ + ret = asn1_write_value (tpm2key, "pubkey", pub_buf.data, pub_buf.size); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'pubkey': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Set the privkey */ + ret = asn1_write_value (tpm2key, "privkey", priv_buf.data, priv_buf.size); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "Failed to set 'privkey': 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + /* Create the DER binary */ + *der_buf_size = 0; + ret = asn1_der_coding (tpm2key, "", NULL, der_buf_size, NULL); + if (ret != ASN1_MEM_ERROR) + { + fprintf (stderr, "Failed to get DER size: 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + *der_buf = grub_malloc (*der_buf_size); + if (*der_buf == NULL) + { + fprintf (stderr, "Failed to allocate memory for DER encoding\n"); + err = GRUB_ERR_OUT_OF_MEMORY; + goto error; + } + + ret = asn1_der_coding (tpm2key, "", *der_buf, der_buf_size, NULL); + if (ret != ASN1_SUCCESS) + { + fprintf (stderr, "DER coding error: 0x%x\n", ret); + err = GRUB_ERR_BAD_ARGUMENT; + goto error; + } + + error: + if (tpm2key) + asn1_delete_structure (&tpm2key); + + return err; +} + +static grub_err_t +protect_tpm2_export_raw (tpm2_sealed_key_t *sealed_key, void **out_buf, int *out_buf_size) +{ + struct grub_tpm2_buffer buf; + + grub_tpm2_buffer_init (&buf); + grub_Tss2_MU_TPM2B_PUBLIC_Marshal (&buf, &sealed_key->public); + grub_Tss2_MU_TPM2B_Marshal (&buf, sealed_key->private.size, + sealed_key->private.buffer); + if (buf.error != 0) + return GRUB_ERR_BAD_ARGUMENT; + + *out_buf_size = buf.size; + *out_buf = grub_malloc (buf.size); + + if (*out_buf == NULL) + { + fprintf (stderr, N_("Could not allocate memory for the raw format key.\n")); + return GRUB_ERR_OUT_OF_MEMORY; + } + + grub_memcpy (*out_buf, buf.data, buf.size); + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_export_persistent (protect_args_t *args, + TPM_HANDLE_t srk_handle, + tpm2_sealed_key_t *sealed_key) +{ + TPMS_AUTH_COMMAND_t authCmd = {0}; + TPM2B_NAME_t name = {0}; + TPM_HANDLE_t sealed_handle; + TPM_RC_t rc; + grub_err_t err = GRUB_ERR_NONE; + + /* 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 (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to load sealed key (TPM2_Load: %x).\n", rc); + return GRUB_ERR_BAD_DEVICE; + } + + /* Make the sealed key object persistent */ + authCmd.sessionHandle = TPM_RS_PW; + rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, sealed_handle, &authCmd, args->tpm2_nvindex, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to make sealed key persistent with handle 0x%x (TPM2_EvictControl: 0x%x).\n", args->tpm2_nvindex, rc); + err = GRUB_ERR_BAD_DEVICE; + goto exit; + } + + exit: + grub_tpm2_flushcontext (sealed_handle); + + return err; +} + +static grub_err_t +protect_tpm2_export_nvindex (protect_args_t *args, void *data, int data_size) +{ + TPMS_AUTH_COMMAND_t authCmd = {0}; + TPM2B_NV_PUBLIC_t pub_info = {0}; + TPM2B_MAX_NV_BUFFER_t nv_data = {0}; + TPM_RC_t rc; + + if (data_size > TPM_MAX_NV_BUFFER_SIZE || data_size < 0) + { + fprintf (stderr, N_("Invalid tpm2key size for TPM NV buffer\n")); + return GRUB_ERR_OUT_OF_RANGE; + } + + pub_info.nvPublic.nvIndex = args->tpm2_nvindex; + pub_info.nvPublic.nameAlg = TPM_ALG_SHA256; + pub_info.nvPublic.attributes = TPMA_NV_OWNERWRITE | TPMA_NV_OWNERREAD; + pub_info.nvPublic.dataSize = (grub_uint16_t) data_size; + + authCmd.sessionHandle = TPM_RS_PW; + rc = grub_tpm2_nv_definespace (TPM_RH_OWNER, &authCmd, NULL, &pub_info); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to define NV space for 0x%x (TPM2_NV_DefineSpace: 0x%x)\n", args->tpm2_nvindex, rc); + return GRUB_ERR_BAD_DEVICE; + } + + authCmd.sessionHandle = TPM_RS_PW; + grub_memcpy (nv_data.buffer, data, data_size); + nv_data.size = (grub_uint16_t) data_size; + + rc = grub_tpm2_nv_write (TPM_RH_OWNER, args->tpm2_nvindex, &authCmd, &nv_data, 0); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to write data into 0x%x (TPM2_NV_Write: 0x%x)\n", args->tpm2_nvindex, rc); + return GRUB_ERR_BAD_DEVICE; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_add (protect_args_t *args) +{ + grub_err_t err; + grub_uint8_t *key = NULL; + grub_size_t key_size; + TPM_HANDLE_t srk; + TPM2B_DIGEST_t policy_digest; + void *out_buf = NULL; + int out_buf_size; + tpm2_sealed_key_t sealed_key; + + err = protect_tpm2_open_device (args->tpm2_device); + if (err != GRUB_ERR_NONE) + return err; + + err = protect_read_file (args->tpm2_keyfile, (void **)&key, &key_size); + if (err != GRUB_ERR_NONE) + goto exit1; + + if (key_size > TPM_MAX_SYM_DATA) + { + fprintf (stderr, N_("Input key size larger than %u bytes.\n"), TPM_MAX_SYM_DATA); + err = GRUB_ERR_OUT_OF_RANGE; + goto exit2; + } + + err = protect_tpm2_get_srk (args, &srk); + if (err != GRUB_ERR_NONE) + goto exit2; + + err = protect_tpm2_get_policy_digest (args, &policy_digest); + if (err != GRUB_ERR_NONE) + goto exit3; + + err = protect_tpm2_seal (&policy_digest, srk, key, key_size, &sealed_key); + if (err != GRUB_ERR_NONE) + goto exit3; + + if (args->tpm2_tpm2key == true) + { + err = protect_tpm2_export_tpm2key (args, &sealed_key, &out_buf, &out_buf_size); + if (err != GRUB_ERR_NONE) + { + fprintf (stderr, N_("Could not export to TPM 2.0 Key File format\n")); + goto exit3; + } + } + else + { + err = protect_tpm2_export_raw (&sealed_key, &out_buf, &out_buf_size); + if (err != GRUB_ERR_NONE) + { + fprintf (stderr, N_("Could not export to the raw format\n")); + goto exit3; + } + } + + if (args->tpm2_outfile != NULL) + { + err = protect_write_file (args->tpm2_outfile, out_buf, out_buf_size); + if (err != GRUB_ERR_NONE) + { + fprintf (stderr, N_("Could not write key file (%s).\n"), strerror (errno)); + goto exit3; + } + } + + if (TPM_HT_IS_NVINDEX (args->tpm2_nvindex) == true) + { + err = protect_tpm2_export_nvindex (args, out_buf, out_buf_size); + if (err != GRUB_ERR_NONE) + goto exit3; + } + else if (TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == true) + { + err = protect_tpm2_export_persistent (args, srk, &sealed_key); + if (err != GRUB_ERR_NONE) + goto exit3; + } + + exit3: + grub_tpm2_flushcontext (srk); + grub_free (out_buf); + + exit2: + grub_free (key); + + exit1: + protect_tpm2_close_device (); + + return err; +} + +static grub_err_t +protect_tpm2_evict (TPM_HANDLE_t handle) +{ + TPM_RC_t rc; + TPM2B_PUBLIC_t public; + TPMS_AUTH_COMMAND_t authCmd = {0}; + + /* Find the persistent handle */ + rc = grub_tpm2_readpublic (handle, NULL, &public); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Handle 0x%x not found.\n", handle); + return GRUB_ERR_BAD_ARGUMENT; + } + + /* Evict the persistent handle */ + authCmd.sessionHandle = TPM_RS_PW; + rc = grub_tpm2_evictcontrol (TPM_RH_OWNER, handle, &authCmd, handle, NULL); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to evict handle 0x%x (TPM2_EvictControl: 0x%x).\n", handle, rc); + return GRUB_ERR_BAD_DEVICE; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_nv_undefine (TPM_HANDLE_t handle) +{ + TPM_RC_t rc; + TPM2B_NV_PUBLIC_t nv_public; + TPMS_AUTH_COMMAND_t authCmd = {0}; + TPM2B_NAME_t nv_name; + + /* Find the nvindex handle */ + rc = grub_tpm2_nv_readpublic (handle, NULL, &nv_public, &nv_name); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Handle 0x%x not found.\n", handle); + return GRUB_ERR_BAD_ARGUMENT; + } + + /* Undefine the nvindex handle */ + authCmd.sessionHandle = TPM_RS_PW; + rc = grub_tpm2_nv_undefinespace (TPM_RH_OWNER, handle, &authCmd); + if (rc != TPM_RC_SUCCESS) + { + fprintf (stderr, "Failed to undefine handle 0x%x (TPM2_NV_UndefineSpace: 0x%x).\n", handle, rc); + return GRUB_ERR_BAD_DEVICE; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_tpm2_remove (protect_args_t *args) +{ + grub_err_t err; + + if (args->tpm2_evict == false) + { + printf ("--tpm2-evict not specified, nothing to do.\n"); + return GRUB_ERR_NONE; + } + + err = protect_tpm2_open_device (args->tpm2_device); + if (err != GRUB_ERR_NONE) + return err; + + if (args->tpm2_srk != 0) + { + err = protect_tpm2_evict (args->tpm2_srk); + if (err != GRUB_ERR_NONE) + goto exit; + } + + if (args->tpm2_nvindex != 0) + { + if (TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == true) + { + err = protect_tpm2_evict (args->tpm2_nvindex); + if (err != GRUB_ERR_NONE) + goto exit; + } + else if (TPM_HT_IS_NVINDEX (args->tpm2_nvindex) == true) + { + err = protect_tpm2_nv_undefine (args->tpm2_nvindex); + if (err != GRUB_ERR_NONE) + goto exit; + } + else + { + fprintf (stderr, "Unsupported handle 0x%x\n", args->tpm2_nvindex); + err = GRUB_ERR_BAD_ARGUMENT; + goto exit; + } + } + + err = GRUB_ERR_NONE; + + exit: + protect_tpm2_close_device (); + + return err; +} + +static grub_err_t +protect_tpm2_run (protect_args_t *args) +{ + switch (args->action) + { + case PROTECT_ACTION_ADD: + return protect_tpm2_add (args); + + case PROTECT_ACTION_REMOVE: + return protect_tpm2_remove (args); + + default: + return GRUB_ERR_BAD_ARGUMENT; + } +} + +static grub_err_t +protect_tpm2_args_verify (protect_args_t *args) +{ + if (args->tpm2_device == NULL) + args->tpm2_device = "/dev/tpm0"; + + switch (args->action) + { + case PROTECT_ACTION_ADD: + if (args->args & PROTECT_ARG_TPM2_EVICT) + { + fprintf (stderr, N_("--tpm2-evict is invalid when --action is 'add'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_keyfile == NULL) + { + fprintf (stderr, N_("--tpm2-keyfile must be specified.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_outfile == NULL && args->tpm2_nvindex == 0) + { + fprintf (stderr, N_("--tpm2-outfile or --tpm2-nvindex must be specified.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_nvindex != 0) + { + if (args->tpm2_tpm2key == true && TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == true) + { + fprintf (stderr, N_("Persistent handle does not support TPM 2.0 Key File format.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (TPM_HT_IS_PERSISTENT (args->tpm2_nvindex) == false && TPM_HT_IS_NVINDEX (args->tpm2_nvindex) == false) + { + fprintf (stderr, N_("--tpm2-nvindex must be a persistent or NV index handle.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_nvindex == args->tpm2_srk) + { + fprintf (stderr, N_("--tpm2-nvindex and --tpm2-srk must be different.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + } + + if (args->tpm2_srk != 0 && TPM_HT_IS_PERSISTENT(args->tpm2_srk) == false) + { + fprintf (stderr, N_("--tpm2-srk must be a persistent handle, e.g. 0x81000000.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_pcr_count == 0) + { + args->tpm2_pcrs[0] = 7; + args->tpm2_pcr_count = 1; + } + + if (args->srk_type.type == TPM_ALG_ERROR) + { + args->srk_type.type = TPM_ALG_ECC; + args->srk_type.detail.ecc_curve = TPM_ECC_NIST_P256; + } + + if (args->tpm2_bank == TPM_ALG_ERROR) + args->tpm2_bank = TPM_ALG_SHA256; + + break; + + case PROTECT_ACTION_REMOVE: + if (args->args & PROTECT_ARG_TPM2_ASYMMETRIC) + { + fprintf (stderr, N_("--tpm2-asymmetric is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->args & PROTECT_ARG_TPM2_BANK) + { + fprintf (stderr, N_("--tpm2-bank is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->args & PROTECT_ARG_TPM2_KEYFILE) + { + fprintf (stderr, N_("--tpm2-keyfile is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->args & PROTECT_ARG_TPM2_OUTFILE) + { + fprintf (stderr, N_("--tpm2-outfile is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->args & PROTECT_ARG_TPM2_PCRS) + { + fprintf (stderr, N_("--tpm2-pcrs is invalid when --action is 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + if (args->tpm2_srk == 0 && args->tpm2_nvindex == 0) + { + fprintf (stderr, N_("missing --tpm2-srk or --tpm2-nvindex for --action 'remove'.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + break; + + default: + fprintf (stderr, N_("The TPM2 key protector only supports the following actions: add, remove.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + return GRUB_ERR_NONE; +} + +static error_t +protect_argp_parser (int key, char *arg, struct argp_state *state) +{ + grub_err_t err; + protect_args_t *args = state->input; + + switch (key) + { + case PROTECT_OPT_ACTION: + if (args->args & PROTECT_ARG_ACTION) + { + fprintf (stderr, N_("--action|-a can only be specified once.\n")); + return EINVAL; + } + + if (grub_strcmp (arg, "add") == 0) + args->action = PROTECT_ACTION_ADD; + else if (grub_strcmp (arg, "remove") == 0) + args->action = PROTECT_ACTION_REMOVE; + else + { + fprintf (stderr, N_("'%s' is not a valid action.\n"), arg); + return EINVAL; + } + + args->args |= PROTECT_ARG_ACTION; + break; + + case PROTECT_OPT_PROTECTOR: + if (args->args & PROTECT_ARG_PROTECTOR) + { + fprintf (stderr, N_("--protector|-p can only be specified once.\n")); + return EINVAL; + } + + if (grub_strcmp (arg, "tpm2") == 0) + args->protector = PROTECT_TYPE_TPM2; + else + { + fprintf (stderr, N_("'%s' is not a valid protector.\n"), arg); + return EINVAL; + } + + args->args |= PROTECT_ARG_PROTECTOR; + break; + + case PROTECT_OPT_TPM2_DEVICE: + if (args->args & PROTECT_ARG_TPM2_DEVICE) + { + fprintf (stderr, N_("--tpm2-device can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_device = xstrdup (arg); + args->args |= PROTECT_ARG_TPM2_DEVICE; + break; + + case PROTECT_OPT_TPM2_PCRS: + if (args->args & PROTECT_ARG_TPM2_PCRS) + { + fprintf (stderr, N_("--tpm2-pcrs can only be specified once.\n")); + return EINVAL; + } + + err = grub_tpm2_protector_parse_pcrs (arg, args->tpm2_pcrs, + &args->tpm2_pcr_count); + if (err != GRUB_ERR_NONE) + { + if (grub_errno != GRUB_ERR_NONE) + grub_print_error (); + return EINVAL; + } + + args->args |= PROTECT_ARG_TPM2_PCRS; + break; + + case PROTECT_OPT_TPM2_SRK: + if (args->args & PROTECT_ARG_TPM2_SRK) + { + fprintf (stderr, N_("--tpm2-srk can only be specified once.\n")); + return EINVAL; + } + + err = grub_tpm2_protector_parse_tpm_handle (arg, &args->tpm2_srk); + if (err != GRUB_ERR_NONE) + { + if (grub_errno != GRUB_ERR_NONE) + grub_print_error (); + return EINVAL; + } + + args->args |= PROTECT_ARG_TPM2_SRK; + break; + + case PROTECT_OPT_TPM2_ASYMMETRIC: + if (args->args & PROTECT_ARG_TPM2_ASYMMETRIC) + { + fprintf (stderr, N_("--tpm2-asymmetric can only be specified once.\n")); + return EINVAL; + } + + err = grub_tpm2_protector_parse_asymmetric (arg, &args->srk_type); + if (err != GRUB_ERR_NONE) + { + if (grub_errno != GRUB_ERR_NONE) + grub_print_error (); + return EINVAL; + } + + args->args |= PROTECT_ARG_TPM2_ASYMMETRIC; + break; + + case PROTECT_OPT_TPM2_BANK: + if (args->args & PROTECT_ARG_TPM2_BANK) + { + fprintf (stderr, N_("--tpm2-bank can only be specified once.\n")); + return EINVAL; + } + + err = grub_tpm2_protector_parse_bank (arg, &args->tpm2_bank); + if (err != GRUB_ERR_NONE) + { + if (grub_errno != GRUB_ERR_NONE) + grub_print_error (); + return EINVAL; + } + + args->args |= PROTECT_ARG_TPM2_BANK; + break; + + case PROTECT_OPT_TPM2_KEYFILE: + if (args->args & PROTECT_ARG_TPM2_KEYFILE) + { + fprintf (stderr, N_("--tpm2-keyfile can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_keyfile = xstrdup(arg); + args->args |= PROTECT_ARG_TPM2_KEYFILE; + break; + + case PROTECT_OPT_TPM2_OUTFILE: + if (args->args & PROTECT_ARG_TPM2_OUTFILE) + { + fprintf (stderr, N_("--tpm2-outfile can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_outfile = xstrdup(arg); + args->args |= PROTECT_ARG_TPM2_OUTFILE; + break; + + case PROTECT_OPT_TPM2_EVICT: + if (args->args & PROTECT_ARG_TPM2_EVICT) + { + fprintf (stderr, N_("--tpm2-evict can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_evict = true; + args->args |= PROTECT_ARG_TPM2_EVICT; + break; + + case PROTECT_OPT_TPM2_TPM2KEY: + if (args->args & PROTECT_ARG_TPM2_TPM2KEY) + { + fprintf (stderr, N_("--tpm2-tpm2key can only be specified once.\n")); + return EINVAL; + } + + args->tpm2_tpm2key = true; + args->args |= PROTECT_ARG_TPM2_TPM2KEY; + break; + + case PROTECT_OPT_TPM2_NVINDEX: + if (args->args & PROTECT_ARG_TPM2_NVINDEX) + { + fprintf (stderr, N_("--tpm2-nvindex can only be specified once.\n")); + return EINVAL; + } + + err = grub_tpm2_protector_parse_tpm_handle (arg, &args->tpm2_nvindex); + if (err != GRUB_ERR_NONE) + { + if (grub_errno != GRUB_ERR_NONE) + grub_print_error (); + return EINVAL; + } + + args->args |= PROTECT_ARG_TPM2_NVINDEX; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +static grub_err_t +protect_args_verify (protect_args_t *args) +{ + if (args->action == PROTECT_ACTION_ERROR) + { + fprintf (stderr, N_("--action is mandatory.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + /* + * At the moment, the only configurable key protector is the TPM2 one, so it + * is the only key protector supported by this tool. + */ + if (args->protector != PROTECT_TYPE_TPM2) + { + fprintf (stderr, N_("--protector is mandatory and only 'tpm2' is currently supported.\n")); + return GRUB_ERR_BAD_ARGUMENT; + } + + switch (args->protector) + { + case PROTECT_TYPE_TPM2: + return protect_tpm2_args_verify (args); + default: + return GRUB_ERR_BAD_ARGUMENT; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +protect_dispatch (protect_args_t *args) +{ + switch (args->protector) + { + case PROTECT_TYPE_TPM2: + return protect_tpm2_run (args); + default: + return GRUB_ERR_BAD_ARGUMENT; + } +} + +static void +protect_init (int *argc, char **argv[]) +{ + grub_util_host_init (argc, argv); + + grub_util_biosdisk_init (NULL); + + grub_init_all (); + + grub_lvm_fini (); + grub_mdraid09_fini (); + grub_mdraid1x_fini (); + grub_diskfilter_fini (); + grub_diskfilter_init (); + grub_mdraid09_init (); + grub_mdraid1x_init (); + grub_lvm_init (); +} + +static void +protect_fini (void) +{ + grub_fini_all (); + grub_util_biosdisk_fini (); +} + +static struct argp protect_argp = +{ + .options = protect_options, + .parser = protect_argp_parser, + .args_doc = NULL, + .doc = + N_("Protect a cleartext key using a GRUB key protector that can retrieve " + "the key during boot to unlock fully-encrypted disks automatically."), + .children = NULL, + .help_filter = NULL, + .argp_domain = NULL +}; + +int +main (int argc, char *argv[]) +{ + grub_err_t err; + protect_args_t args = {0}; + + if (argp_parse (&protect_argp, argc, argv, 0, 0, &args) != 0) + { + fprintf (stderr, N_("Could not parse arguments.\n")); + return EXIT_FAILURE; + } + + protect_init (&argc, &argv); + + err = protect_args_verify (&args); + if (err != GRUB_ERR_NONE) + goto exit; + + err = protect_dispatch (&args); + + exit: + protect_fini (); + + if (err != GRUB_ERR_NONE) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 801b3df4a..21d63f0a1 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -184,7 +184,7 @@ main (int argc, char *argv[]) { input = 0; get_config_line (&input, 0, &ctx); - if (! input) + if (! input) break; found_input = 1; diff --git a/util/grub-setup.c b/util/grub-setup.c index 42b98ad3c..1783224dd 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -315,7 +315,7 @@ main (int argc, char *argv[]) arguments.core_file ? : DEFAULT_CORE_FILE, dest_dev, arguments.force, arguments.fs_probe, arguments.allow_floppy, - arguments.add_rs_codes); + arguments.add_rs_codes, 0); /* Free resources. */ grub_fini_all (); diff --git a/util/grub-syslinux2cfg.c b/util/grub-syslinux2cfg.c index 85fa0da14..f90a61a4a 100644 --- a/util/grub-syslinux2cfg.c +++ b/util/grub-syslinux2cfg.c @@ -180,7 +180,7 @@ main (int argc, char *argv[]) { grub_util_error (_("cannot open `%s': %s"), arguments.input, strerror (errno)); - } + } inpfull = xasprintf ("(host)/%s", t); free (t); @@ -190,7 +190,7 @@ main (int argc, char *argv[]) { grub_util_error (_("cannot open `%s': %s"), arguments.root, strerror (errno)); - } + } rootfull = xasprintf ("(host)/%s", t); free (t); @@ -211,7 +211,7 @@ main (int argc, char *argv[]) { grub_util_error (_("cannot open `%s': %s"), arguments.root, strerror (errno)); - } + } cwdfull = xasprintf ("(host)/%s", t); free (t); @@ -227,7 +227,7 @@ main (int argc, char *argv[]) if (!f) grub_util_error (_("cannot open `%s': %s"), arguments.output, strerror (errno)); - fwrite (res, 1, strlen (res), f); + fwrite (res, 1, strlen (res), f); fclose (f); } else diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 93a90233e..f86b69bad 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -191,7 +191,7 @@ EOF EOF # Gettext variables and module -if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "x" ]; then +if [ "x${grub_lang}" != "xC" ] && [ "x${LANG}" != "xPOSIX" ] && [ "x${LANG}" != "x" ]; then cat << EOF set locale_dir=\$prefix/locale set lang=${grub_lang} @@ -275,7 +275,7 @@ EOF prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"` cat << EOF insmod $reader -background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"` +background_image -m stretch "`make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`" EOF fi fi diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 59a9a48a2..f9c394ecb 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -68,12 +68,37 @@ for i in /hurd/${hurd_fs}.static /hurd/exec ; do fi done +if test -e '/hurd/pci-arbiter.static' ; then + pci_arbiter=true +else + pci_arbiter=false +fi + +if test -e '/hurd/acpi.static' ; then + acpi=true +else + acpi=false +fi + +if test -e '/hurd/rumpdisk.static' ; then + rumpdisk=true +else + rumpdisk=false +fi + if ${at_least_one} ; then : ; else # no hurd here, aborting silently exit 0 fi -if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else +if test -e '/lib/ld.so.1' ; then + LD_SO=/lib/ld.so.1 +fi +if test -e '/lib/ld-x86-64.so.1' ; then + LD_SO=/lib/ld-x86-64.so.1 +fi + +if ${all_of_them} && test -n "$LD_SO" ; then : ; else gettext "Some Hurd stuff found, but not enough to boot." >&2 echo >&2 exit 1 @@ -116,9 +141,11 @@ EOF else opts= fi + device=device:${GRUB_DEVICE#/dev/} + device=$(echo "$device" | sed -e 's/^device:\(.*[0-9]\+\)s\([0-9]\+\)$/part:\2:device:\1'/) sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' - multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} $opts ${GRUB_CMDLINE_GNUMACH} + multiboot ${kernel} root=$device $opts ${GRUB_CMDLINE_GNUMACH} EOF if [ x$type != xrecovery ] ; then @@ -132,15 +159,65 @@ EOF opts="--readonly" fi + host_ports="--host-priv-port='\${host-port}' --device-master-port='\${device-port}'" + resume_task="'\$(task-resume)'" + sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' +EOF + + if [ "$pci_arbiter" = true ] ; then + if [ "$acpi" = true ] ; then + next_task='${acpi-task}' + elif [ "$rumpdisk" = true ] ; then + next_task='${disk-task}' + else + next_task='${fs-task}' + fi + sed "s/^/$submenu_indentation/" << EOF + module /hurd/pci-arbiter.static pci-arbiter \\ + $host_ports \\ + --next-task='$next_task' \\ + '\$(pci-task=task-create)' $resume_task +EOF + host_ports="" + resume_task="" + fi + + if [ "$acpi" = true ] ; then + if [ "$rumpdisk" = true ] ; then + next_task='${disk-task}' + else + next_task='${fs-task}' + fi + sed "s/^/$submenu_indentation/" << EOF + module /hurd/acpi.static acpi \\ + $host_ports \\ + --next-task='$next_task' \\ + '\$(acpi-task=task-create)' $resume_task +EOF + host_ports="" + resume_task="" + fi + + if [ "$rumpdisk" = true ] ; then + sed "s/^/$submenu_indentation/" << EOF + module /hurd/rumpdisk.static rumpdisk \\ + $host_ports \\ + --next-task='\${fs-task}' \\ + '\$(disk-task=task-create)' $resume_task +EOF + host_ports="" + resume_task="" + fi + + sed "s/^/$submenu_indentation/" << EOF module /hurd/${hurd_fs}.static ${hurd_fs} $opts \\ --multiboot-command-line='\${kernel-command-line}' \\ - --host-priv-port='\${host-port}' \\ - --device-master-port='\${device-port}' \\ + $host_ports \\ --exec-server-task='\${exec-task}' -T typed '\${root}' \\ - '\$(task-create)' '\$(task-resume)' - module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' + '\$(fs-task=task-create)' $resume_task + module $LD_SO exec /hurd/exec '\$(exec-task=task-create)' } EOF @@ -151,12 +228,30 @@ title_correction_code= # Extra indentation to add to menu entries in a submenu. We're not in a submenu # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). submenu_indentation="" + +# Perform a reverse version sort on the entire kernels list. +# Temporarily replace the '.old' suffix by ' 1' and append ' 2' for all +# other files to order the '.old' files after their non-old counterpart +# in reverse-sorted order. + +reverse_sorted_kernels=$(echo ${kernels} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') + +if [ "x$GRUB_TOP_LEVEL" != x ]; then + reverse_sorted_kernels=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_kernels}) +fi + is_top_level=true -while [ "x$kernels" != "x" ] ; do - kernel=`version_find_latest $kernels` +for kernel in ${reverse_sorted_kernels}; do + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then hurd_entry "$kernel" simple submenu_indentation="$grub_tab" @@ -167,8 +262,6 @@ while [ "x$kernels" != "x" ] ; do hurd_entry "$kernel" advanced hurd_entry "$kernel" recovery - - kernels=`echo $kernels | tr ' ' '\n' | fgrep -vx "$kernel" | tr '\n' ' '` done # If at least one kernel was found, then we need to diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 9d8e8fd85..83e9636e8 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -157,10 +157,20 @@ title_correction_code= # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). submenu_indentation="" +# Perform a reverse version sort on the entire list. +# Temporarily replace the '.old' suffix by ' 1' and append ' 2' for all +# other files to order the '.old' files after their non-old counterpart +# in reverse-sorted order. + +reverse_sorted_list=$(echo ${list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') + +if [ "x$GRUB_TOP_LEVEL" != x ]; then + reverse_sorted_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_list}) +fi + is_top_level=true -while [ "x$list" != "x" ] ; do - kfreebsd=`version_find_latest $list` +for kfreebsd in ${reverse_sorted_list}; do gettext_printf "Found kernel of FreeBSD: %s\n" "$kfreebsd" >&2 basename=`basename $kfreebsd` dirname=`dirname $kfreebsd` @@ -214,7 +224,15 @@ while [ "x$list" != "x" ] ; do module_dir_rel=$(make_system_path_relative_to_its_root $module_dir) fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then kfreebsd_entry "${OS}" "${version}" simple submenu_indentation="$grub_tab" @@ -230,8 +248,6 @@ while [ "x$list" != "x" ] ; do if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then kfreebsd_entry "${OS}" "${version}" recovery "-s" fi - - list=`echo $list | tr ' ' '\n' | fgrep -vx "$kfreebsd" | tr '\n' ' '` done # If at least one kernel was found, then we need to diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 4532266be..cc393be7e 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -43,9 +43,11 @@ case ${GRUB_DEVICE} in ;; esac +: ${GRUB_CMDLINE_LINUX_RECOVERY:=single} + # Default to disabling partition uuid support to maintian compatibility with # older kernels. -GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true} +: ${GRUB_DISABLE_LINUX_PARTUUID=true} # btrfs may reside on multiple devices. We cannot pass them as value of root= parameter # and mounting btrfs requires user space scanning, so force UUID in this case. @@ -191,9 +193,19 @@ title_correction_code= # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). submenu_indentation="" +# Perform a reverse version sort on the entire list. +# Temporarily replace the '.old' suffix by ' 1' and append ' 2' for all +# other files to order the '.old' files after their non-old counterpart +# in reverse-sorted order. + +reverse_sorted_list=$(echo $list | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') + +if [ "x$GRUB_TOP_LEVEL" != x ]; then + reverse_sorted_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_list}) +fi + is_top_level=true -while [ "x$list" != "x" ] ; do - linux=`version_find_latest $list` +for linux in ${reverse_sorted_list}; do gettext_printf "Found linux image: %s\n" "$linux" >&2 basename=`basename $linux` dirname=`dirname $linux` @@ -211,8 +223,10 @@ while [ "x$list" != "x" ] ; do done initrd_real= - for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \ - "initrd-${version}" "initramfs-${version}.img" \ + for i in "initrd.img-${version}" "initrd-${version}.img" \ + "initrd-${alt_version}.img.old" "initrd-${version}.gz" \ + "initrd-${alt_version}.gz.old" "initrd-${version}" \ + "initramfs-${version}.img" "initramfs-${alt_version}.img.old" \ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ "initrd-${alt_version}" "initramfs-${alt_version}.img" \ "initramfs-genkernel-${version}" \ @@ -261,7 +275,15 @@ while [ "x$list" != "x" ] ; do fi fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then linux_entry "${OS}" "${version}" simple \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" @@ -279,10 +301,8 @@ while [ "x$list" != "x" ] ; do "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" recovery \ - "single ${GRUB_CMDLINE_LINUX}" + "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}" fi - - list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '` done # If at least one kernel was found, then we need to diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index 874f59969..3154e9e15 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -146,8 +146,14 @@ pattern="^ELF[^,]*executable.*statically linked" # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). submenu_indentation="" +list="/netbsd $(ls -t /netbsd?* 2>/dev/null)" + +if [ "x$GRUB_TOP_LEVEL" != x ]; then + list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${list}) +fi + is_top_level=true -for k in /netbsd $(ls -t /netbsd?* 2>/dev/null) ; do +for k in ${list}; do if ! grub_file_is_not_garbage "$k" ; then continue fi @@ -157,7 +163,15 @@ for k in /netbsd $(ls -t /netbsd?* 2>/dev/null) ; do gettext_printf "Found NetBSD kernel: %s\n" "$k" >&2 - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then netbsd_entry "knetbsd" "$k" simple "${GRUB_CMDLINE_NETBSD_DEFAULT}" submenu_indentation="$grub_tab" diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 96179ea61..94dd8be13 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -43,9 +43,11 @@ case ${GRUB_DEVICE} in ;; esac +: ${GRUB_CMDLINE_LINUX_RECOVERY:=single} + # Default to disabling partition uuid support to maintian compatibility with # older kernels. -GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true} +: ${GRUB_DISABLE_LINUX_PARTUUID=true} # btrfs may reside on multiple devices. We cannot pass them as value of root= parameter # and mounting btrfs requires user space scanning, so force UUID in this case. @@ -88,24 +90,42 @@ esac title_correction_code= linux_entry () +{ + linux_entry_xsm "$@" false + linux_entry_xsm "$@" true +} +linux_entry_xsm () { os="$1" version="$2" - xen_version="$3" + entry_xen_version="$3" type="$4" args="$5" xen_args="$6" + xsm="$7" + # If user wants to enable XSM support, make sure there's + # corresponding policy file. + xenpolicy= + if ${xsm} ; then + xenpolicy="xenpolicy-$entry_xen_version" + if test ! -e "${xen_dirname}/${xenpolicy}" ; then + return + fi + xen_args="$xen_args flask=enforcing" + entry_xen_version="$(gettext_printf "%s (XSM enabled)" "$entry_xen_version")" + # entry_xen_version is used for messages only; actual file is xen_basename + fi if [ -z "$boot_device_id" ]; then boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" fi if [ x$type != xsimple ] ; then if [ x$type = xrecovery ] ; then - title="$(gettext_printf "%s, with Xen %s and Linux %s (recovery mode)" "${os}" "${xen_version}" "${version}")" + title="$(gettext_printf "%s, with Xen %s and Linux %s (recovery mode)" "${os}" "${entry_xen_version}" "${version}")" else - title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${xen_version}" "${version}")" + title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${entry_xen_version}" "${version}")" fi replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" - if [ x"Xen ${xen_version}>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then + if [ x"Xen ${entry_xen_version}>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" @@ -123,7 +143,7 @@ linux_entry () prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)" fi printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" - xmessage="$(gettext_printf "Loading Xen %s ..." ${xen_version})" + xmessage="$(gettext_printf "Loading Xen %s ..." ${entry_xen_version})" lmessage="$(gettext_printf "Loading Linux %s ..." ${version})" sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$xmessage" | grub_quote)' @@ -141,11 +161,18 @@ EOF message="$(gettext_printf "Loading initial ramdisk ...")" initrd_path= for i in ${initrd}; do - initrd_path="${initrd_path} ${rel_dirname}/${i}" - done - sed "s/^/$submenu_indentation/" << EOF + initrd_path="${rel_dirname}/${i}" + sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' ${module_loader} --nounzip $(echo $initrd_path) +EOF + done + fi + if test -n "${xenpolicy}" ; then + message="$(gettext_printf "Loading XSM policy ...")" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' + ${module_loader} ${rel_dirname}/${xenpolicy} EOF fi sed "s/^/$submenu_indentation/" << EOF @@ -173,10 +200,14 @@ if [ "x${linux_list}" = "x" ] ; then exit 0 fi -file_is_not_sym () { +file_is_not_xen_garbage () { case "$1" in */xen-syms-*) return 1;; + */xenpolicy-*) + return 1;; + */*.config) + return 1;; *) return 0;; esac @@ -184,7 +215,7 @@ file_is_not_sym () { xen_list= for i in /boot/xen*; do - if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" ; then xen_list="$xen_list $i" ; fi + if grub_file_is_not_garbage "$i" && file_is_not_xen_garbage "$i" ; then xen_list="$xen_list $i" ; fi done prepare_boot_cache= boot_device_id= @@ -205,11 +236,24 @@ esac # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). submenu_indentation="" +# Perform a reverse version sort on the entire xen_list and linux_list. +# Temporarily replace the '.old' suffix by ' 1' and append ' 2' for all +# other files to order the '.old' files after their non-old counterpart +# in reverse-sorted order. + +reverse_sorted_xen_list=$(echo ${xen_list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') +reverse_sorted_linux_list=$(echo ${linux_list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') + +if [ "x$GRUB_TOP_LEVEL_XEN" != x ]; then + reverse_sorted_xen_list=$(grub_move_to_front "$GRUB_TOP_LEVEL_XEN" ${reverse_sorted_xen_list}) +fi +if [ "x$GRUB_TOP_LEVEL" != x ]; then + reverse_sorted_linux_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_linux_list}) +fi + is_top_level=true -while [ "x${xen_list}" != "x" ] ; do - list="${linux_list}" - current_xen=`version_find_latest $xen_list` +for current_xen in ${reverse_sorted_xen_list}; do xen_basename=`basename ${current_xen}` xen_dirname=`dirname ${current_xen}` rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname` @@ -241,8 +285,7 @@ while [ "x${xen_list}" != "x" ] ; do fi done - while [ "x$list" != "x" ] ; do - linux=`version_find_latest $list` + for linux in ${reverse_sorted_linux_list}; do gettext_printf "Found linux image: %s\n" "$linux" >&2 basename=`basename $linux` dirname=`dirname $linux` @@ -252,8 +295,10 @@ while [ "x${xen_list}" != "x" ] ; do linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" initrd_real= - for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \ - "initrd-${version}" "initramfs-${version}.img" \ + for i in "initrd.img-${version}" "initrd-${version}.img" \ + "initrd-${alt_version}.img.old" "initrd-${version}.gz" \ + "initrd-${alt_version}.gz.old" "initrd-${version}" \ + "initramfs-${version}.img" "initramfs-${alt_version}.img.old" \ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \ "initrd-${alt_version}" "initramfs-${alt_version}.img" \ "initramfs-genkernel-${version}" \ @@ -268,7 +313,10 @@ while [ "x${xen_list}" != "x" ] ; do initrd= if test -n "${initrd_early}" || test -n "${initrd_real}"; then - initrd="${initrd_early} ${initrd_real}" + # Xen assumes the real initrd is the first module after the kernel. + # Additional (later) initrds can also be used for microcode update, + # with Xen option 'ucode= (non-default anyway). + initrd="${initrd_real} ${initrd_early}" initrd_display= for i in ${initrd}; do @@ -288,7 +336,15 @@ while [ "x${xen_list}" != "x" ] ; do fi fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then linux_entry "${OS}" "${version}" "${xen_version}" simple \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" @@ -307,15 +363,12 @@ while [ "x${xen_list}" != "x" ] ; do "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then linux_entry "${OS}" "${version}" "${xen_version}" recovery \ - "single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}" + "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}" fi - - list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '` done if [ x"$is_top_level" != xtrue ]; then echo ' }' fi - xen_list=`echo $xen_list | tr ' ' '\n' | fgrep -vx "$current_xen" | tr '\n' ' '` done # If at least one kernel was found, then we need to diff --git a/util/grub.d/25_bli.in b/util/grub.d/25_bli.in new file mode 100644 index 000000000..26e27a019 --- /dev/null +++ b/util/grub.d/25_bli.in @@ -0,0 +1,24 @@ +#! /bin/sh +set -e + +# grub-mkconfig helper script. +# 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 . + +cat << EOF +if [ "\$grub_platform" = "efi" ]; then + insmod bli +fi +EOF diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 515a68c7a..5d8d75292 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -27,14 +27,17 @@ export TEXTDOMAINDIR="@localedir@" . "$pkgdatadir/grub-mkconfig_lib" if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then + grub_warn "$(gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.")" exit 0 fi -if [ -z "`which os-prober 2> /dev/null`" ] || [ -z "`which linux-boot-prober 2> /dev/null`" ] ; then +if ! command -v os-prober > /dev/null || ! command -v linux-boot-prober > /dev/null ; then # missing os-prober and/or linux-boot-prober exit 0 fi +grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIts output will be used to detect bootable binaries on them and create new boot entries.")" + OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" if [ -z "${OSPROBED}" ] ; then # empty os-prober output, nothing doing @@ -110,19 +113,30 @@ EOF used_osprober_linux_ids= +if [ "x$GRUB_TOP_LEVEL_OS_PROBER" != x ]; then + OSPROBED=$(grub_move_to_front "$GRUB_TOP_LEVEL_OS_PROBER" ${OSPROBED}) +fi + +case "$GRUB_OS_PROBER_SKIP_LIST" in *@/[dD][eE][vV]/*) + grub_warn "$(gettext_printf "GRUB_OS_PROBER_SKIP_LIST contains deprecated @/dev/* notation. The @/dev/* suffix is ignored.")" +esac + for OS in ${OSPROBED} ; do DEVICE="`echo ${OS} | cut -d ':' -f 1`" LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`" BOOT="`echo ${OS} | cut -d ':' -f 4`" - if UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`"; then - EXPUUID="$UUID" + unset UUID + if [ -n "${GRUB_OS_PROBER_SKIP_LIST}" ] && UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`"; then + SPACE='[[:space:],;]' # regex matching spaces and common separators - if [ x"${DEVICE#*@}" != x ] ; then - EXPUUID="${EXPUUID}@${DEVICE#*@}" + if [ x"${DEVICE##*@*}" = x ] ; then + EXPUUID="$UUID@${DEVICE#*@}" + else + EXPUUID="$UUID(@/dev/.*)?" fi - if [ "x${GRUB_OS_PROBER_SKIP_LIST}" != "x" ] && [ "x`echo ${GRUB_OS_PROBER_SKIP_LIST} | grep -i -e '\b'${EXPUUID}'\b'`" != "x" ] ; then + if printf %s " ${GRUB_OS_PROBER_SKIP_LIST} " | grep -Eqie "${SPACE}${EXPUUID}${SPACE}" ; then echo "Skipped ${LONGNAME} on ${DEVICE} by user request." >&2 continue fi @@ -148,6 +162,8 @@ for OS in ${OSPROBED} ; do onstr="$(gettext_printf "(on %s)" "${DEVICE}")" cat << EOF +# This menu entry is supported only on PC BIOS platforms. +if [ "\$grub_platform" = "pc" ]; then menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' $CLASS --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' { EOF save_default_entry | grub_add_tab @@ -172,6 +188,7 @@ EOF cat <. + +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR="@localedir@" + +. "$pkgdatadir/grub-mkconfig_lib" + +LABEL="UEFI Firmware Settings" + +gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2 + +cat << EOF +if [ "\$grub_platform" = "efi" ]; then + fwsetup --is-supported + if [ "\$?" = 0 ]; then + menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' { + fwsetup + } + fi +fi +EOF diff --git a/util/grub.d/41_custom.in b/util/grub.d/41_custom.in index fcc21a987..a08363da1 100644 --- a/util/grub.d/41_custom.in +++ b/util/grub.d/41_custom.in @@ -3,7 +3,7 @@ cat < sizeof (section->name)) + grub_util_error (_("section name %s length is bigger than %lu"), + name, (unsigned long) sizeof (section->name)); + + memcpy (section->name, name, len); + + section->virtual_address = grub_host_to_target32 (*vma); + section->virtual_size = grub_host_to_target32 (vsz); + (*vma) = ALIGN_UP (*vma + vsz, valign); + + section->raw_data_offset = grub_host_to_target32 (*rda); + section->raw_data_size = grub_host_to_target32 (rsz); + (*rda) = ALIGN_UP (*rda + rsz, GRUB_PE32_FILE_ALIGNMENT); + + section->characteristics = grub_host_to_target32 (characteristics); + + return section + 1; +} + +/* + * tmp_ is just here so the compiler knows we'll never derefernce a NULL. + * It should get fully optimized away. + */ +#define PE_OHDR(o32, o64, field) (*( \ +{ \ + __typeof__((o64)->field) tmp_; \ + __typeof__((o64)->field) *ret_ = &tmp_; \ + if (o32) \ + ret_ = (void *)(&((o32)->field)); \ + else if (o64) \ + ret_ = (void *)(&((o64)->field)); \ + ret_; \ +})) + 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_path) + int note, grub_compression_t comp, const char *dtb_path, + const char *sbat_path, int disable_shim_lock, + int disable_cli) { char *kernel_img, *core_img; size_t total_module_size, core_size; size_t memdisk_size = 0, config_size = 0; - size_t prefix_size = 0, dtb_size = 0; + size_t prefix_size = 0, dtb_size = 0, sbat_size = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p; @@ -878,6 +943,15 @@ grub_install_generate_image (const char *dir, const char *prefix, total_module_size += dtb_size + sizeof (struct grub_module_header); } + if (sbat_path != NULL && (image_target->id != IMAGE_EFI && image_target->id != IMAGE_PPC)) + grub_util_error (_("SBAT data can be added only to EFI or powerpc-ieee1275 images")); + + if (disable_shim_lock) + total_module_size += sizeof (struct grub_module_header); + + if (disable_cli) + total_module_size += sizeof (struct grub_module_header); + if (config_path) { config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1); @@ -1014,6 +1088,26 @@ grub_install_generate_image (const char *dir, const char *prefix, offset += dtb_size; } + if (disable_shim_lock) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_SHIM_LOCK); + header->size = grub_host_to_target32 (sizeof (*header)); + offset += sizeof (*header); + } + + if (disable_cli) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_CLI); + header->size = grub_host_to_target32 (sizeof (*header)); + offset += sizeof (*header); + } + if (config_path) { struct grub_module_header *header; @@ -1050,7 +1144,7 @@ grub_install_generate_image (const char *dir, const char *prefix, grub_util_info ("the core size is 0x%" GRUB_HOST_PRIxLONG_LONG, (unsigned long long) core_size); - if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) && image_target->total_module_size != TARGET_NO_FIELD) *((grub_uint32_t *) (core_img + image_target->total_module_size)) = grub_host_to_target32 (total_module_size); @@ -1076,7 +1170,7 @@ grub_install_generate_image (const char *dir, const char *prefix, default: grub_util_error (_("unknown compression %d"), comp); } - + decompress_path = grub_util_get_path (dir, name); decompress_size = grub_util_get_image_size (decompress_path); decompress_img = grub_util_read_image (decompress_path); @@ -1176,11 +1270,11 @@ grub_install_generate_image (const char *dir, const char *prefix, char *pxeboot_path, *pxeboot_img; size_t pxeboot_size; grub_uint32_t *ptr; - + pxeboot_path = grub_util_get_path (dir, "pxeboot.img"); pxeboot_size = grub_util_get_image_size (pxeboot_path); pxeboot_img = grub_util_read_image (pxeboot_path); - + grub_util_write_image (pxeboot_img, pxeboot_size, out, outname); free (pxeboot_img); @@ -1203,11 +1297,11 @@ grub_install_generate_image (const char *dir, const char *prefix, { char *eltorito_path, *eltorito_img; size_t eltorito_size; - + eltorito_path = grub_util_get_path (dir, "cdboot.img"); eltorito_size = grub_util_get_image_size (eltorito_path); eltorito_img = grub_util_read_image (eltorito_path); - + grub_util_write_image (eltorito_img, eltorito_size, out, outname); free (eltorito_img); @@ -1242,33 +1336,35 @@ grub_install_generate_image (const char *dir, const char *prefix, break; case IMAGE_EFI: { - void *pe_img; - grub_uint8_t *header; - void *sections; - size_t pe_size; + char *pe_img, *pe_sbat, *header; + struct grub_pe32_section_table *section; + size_t n_sections = 4; + size_t scn_size; + grub_uint32_t vma, raw_data; + size_t pe_size, header_size; struct grub_pe32_coff_header *c; - struct grub_pe32_section_table *text_section, *data_section; - struct grub_pe32_section_table *mods_section, *reloc_section; static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size; - int reloc_addr; + struct grub_pe32_optional_header *o32 = NULL; + struct grub_pe64_optional_header *o64 = NULL; if (image_target->voidp_sizeof == 4) header_size = EFI32_HEADER_SIZE; else header_size = EFI64_HEADER_SIZE; - reloc_addr = ALIGN_UP (header_size + core_size, - GRUB_PE32_FILE_ALIGNMENT); + vma = raw_data = header_size; - pe_size = ALIGN_UP (reloc_addr + layout.reloc_size, - GRUB_PE32_FILE_ALIGNMENT); - pe_img = xmalloc (reloc_addr + layout.reloc_size); - memset (pe_img, 0, header_size); - memcpy ((char *) pe_img + header_size, core_img, core_size); - memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size)); - memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size); - header = pe_img; + if (sbat_path != NULL) + { + sbat_size = ALIGN_ADDR (grub_util_get_image_size (sbat_path)); + sbat_size = ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT); + } + + pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) + + ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT) + sbat_size; + header = pe_img = xcalloc (1, pe_size); + + memcpy (pe_img + raw_data, core_img, core_size); /* The magic. */ memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); @@ -1280,7 +1376,10 @@ grub_install_generate_image (const char *dir, const char *prefix, + GRUB_PE32_SIGNATURE_SIZE); c->machine = grub_host_to_target16 (image_target->pe_target); - c->num_sections = grub_host_to_target16 (4); + if (sbat_path != NULL) + n_sections++; + + c->num_sections = grub_host_to_target16 (n_sections); c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP); c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE | GRUB_PE32_LINE_NUMS_STRIPPED @@ -1293,137 +1392,121 @@ grub_install_generate_image (const char *dir, const char *prefix, /* The PE Optional header. */ if (image_target->voidp_sizeof == 4) { - struct grub_pe32_optional_header *o; - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); - o = (struct grub_pe32_optional_header *) - (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header)); - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (layout.exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size - - header_size); - o->bss_size = grub_cpu_to_le32 (layout.bss_size); - o->entry_addr = grub_cpu_to_le32 (layout.start_address); - o->code_base = grub_cpu_to_le32 (header_size); + o32 = (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o32->data_base = grub_host_to_target32 (header_size + layout.exec_size); - o->data_base = grub_host_to_target32 (header_size + layout.exec_size); - - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (image_target->section_align); - o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); - - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); - - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size); - sections = o + 1; + section = (struct grub_pe32_section_table *)(o32 + 1); } else { - struct grub_pe64_optional_header *o; - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); + o64 = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); - o = (struct grub_pe64_optional_header *) - (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header)); - o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); - o->code_size = grub_host_to_target32 (layout.exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size - - header_size); - o->bss_size = grub_cpu_to_le32 (layout.bss_size); - o->entry_addr = grub_cpu_to_le32 (layout.start_address); - o->code_base = grub_cpu_to_le32 (header_size); - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (image_target->section_align); - o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); - - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target64 (0x10000); - o->stack_commit_size = grub_host_to_target64 (0x10000); - o->heap_reserve_size = grub_host_to_target64 (0x10000); - o->heap_commit_size = grub_host_to_target64 (0x10000); - - o->num_data_directories - = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size); - sections = o + 1; + section = (struct grub_pe32_section_table *)(o64 + 1); } - /* The sections. */ - text_section = sections; - strcpy (text_section->name, ".text"); - text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size); - text_section->virtual_address = grub_cpu_to_le32 (header_size); - text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size); - text_section->raw_data_offset = grub_cpu_to_le32 (header_size); - text_section->characteristics = grub_cpu_to_le32_compile_time ( - GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ); - data_section = text_section + 1; - strcpy (data_section->name, ".data"); - data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size); - data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size); - data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size); - data_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.exec_size); - data_section->characteristics - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - -#if 0 - bss_section = data_section + 1; - strcpy (bss_section->name, ".bss"); - bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size); - bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size); - bss_section->raw_data_size = 0; - bss_section->raw_data_offset = 0; - bss_section->characteristics - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES - | GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | 0x80); +#if __GNUC__ >= 12 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdangling-pointer" #endif - - mods_section = data_section + 1; - strcpy (mods_section->name, "mods"); - mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size); - mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size); - mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size); - mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.kernel_size); - mods_section->characteristics - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); + PE_OHDR (o32, o64, dll_characteristics) = grub_host_to_target16 (GRUB_PE32_NX_COMPAT); + PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size); + PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address); + PE_OHDR (o32, o64, image_base) = 0; + PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size); + PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align); + PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); + PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + PE_OHDR (o32, o64, stack_reserve_size) = grub_host_to_target32 (0x10000); + PE_OHDR (o32, o64, stack_commit_size) = grub_host_to_target32 (0x10000); + PE_OHDR (o32, o64, heap_reserve_size) = grub_host_to_target32 (0x10000); + PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000); + + PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + /* The sections. */ + PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma); + PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size); +#if __GNUC__ >= 12 +#pragma GCC diagnostic pop +#endif + section = init_pe_section (image_target, section, ".text", + &vma, layout.exec_size, + image_target->section_align, + &raw_data, layout.exec_size, + GRUB_PE32_SCN_CNT_CODE | + GRUB_PE32_SCN_MEM_EXECUTE | + GRUB_PE32_SCN_MEM_READ); + + scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT); +#if __GNUC__ >= 12 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdangling-pointer" +#endif + /* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */ + PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + sbat_size + + ALIGN_UP (total_module_size, + GRUB_PE32_FILE_ALIGNMENT)); +#if __GNUC__ >= 12 +#pragma GCC diagnostic pop +#endif + + section = init_pe_section (image_target, section, ".data", + &vma, scn_size, image_target->section_align, + &raw_data, scn_size, + GRUB_PE32_SCN_CNT_INITIALIZED_DATA | + GRUB_PE32_SCN_MEM_READ | + GRUB_PE32_SCN_MEM_WRITE); + + scn_size = pe_size - layout.reloc_size - sbat_size - raw_data; + section = init_pe_section (image_target, section, "mods", + &vma, scn_size, image_target->section_align, + &raw_data, scn_size, + GRUB_PE32_SCN_CNT_INITIALIZED_DATA | + GRUB_PE32_SCN_MEM_READ | + GRUB_PE32_SCN_MEM_WRITE); + + if (sbat_path != NULL) + { + pe_sbat = pe_img + raw_data; + grub_util_load_image (sbat_path, pe_sbat); + + section = init_pe_section (image_target, section, ".sbat", + &vma, sbat_size, + image_target->section_align, + &raw_data, sbat_size, + GRUB_PE32_SCN_CNT_INITIALIZED_DATA | + GRUB_PE32_SCN_MEM_READ); + } + + scn_size = layout.reloc_size; +#if __GNUC__ >= 12 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdangling-pointer" +#endif + PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma); + PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size); +#if __GNUC__ >= 12 +#pragma GCC diagnostic pop +#endif + memcpy (pe_img + raw_data, layout.reloc_section, scn_size); + init_pe_section (image_target, section, ".reloc", + &vma, scn_size, image_target->section_align, + &raw_data, scn_size, + GRUB_PE32_SCN_CNT_INITIALIZED_DATA | + GRUB_PE32_SCN_MEM_DISCARDABLE | + GRUB_PE32_SCN_MEM_READ); - reloc_section = mods_section + 1; - strcpy (reloc_section->name, ".reloc"); - reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size); - reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size); - reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size); - reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); - reloc_section->characteristics - = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); free (core_img); core_img = pe_img; core_size = pe_size; @@ -1523,7 +1606,7 @@ grub_install_generate_image (const char *dir, const char *prefix, size_t boot_size; /* fwstart.img is the only part which can't be tested by using *-elf target. Check it against the checksum. */ - const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] = + const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] = { 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a, 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5, @@ -1534,8 +1617,8 @@ grub_install_generate_image (const char *dir, const char *prefix, 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7, 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25 }; - const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] = - { + const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] = + { 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62, 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c, 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d, @@ -1547,7 +1630,7 @@ grub_install_generate_image (const char *dir, const char *prefix, }; const grub_uint8_t *fwstart_good_hash; grub_uint8_t fwstart_hash[512 / 8]; - + if (image_target->id == IMAGE_FULOONG2F_FLASH) { fwstart_good_hash = fuloong2f_fwstart_good_hash; @@ -1576,7 +1659,7 @@ grub_install_generate_image (const char *dir, const char *prefix, rom_size = 512 * 1024; rom_img = xmalloc (rom_size); - memset (rom_img, 0, rom_size); + memset (rom_img, 0, rom_size); memcpy (rom_img, boot_img, boot_size); @@ -1602,7 +1685,7 @@ grub_install_generate_image (const char *dir, const char *prefix, rom_size = 512 * 1024; rom_img = xmalloc (rom_size); - memset (rom_img, 0, rom_size); + memset (rom_img, 0, rom_size); memcpy (rom_img, core_img, core_size); @@ -1708,7 +1791,7 @@ grub_install_generate_image (const char *dir, const char *prefix, head->entry = grub_host_to_target32 (target_addr); head->text_start = grub_host_to_target32 (target_addr); head->data_start = grub_host_to_target32 (target_addr + program_size); - grub_memcpy (section->name, ".text", sizeof (".text") - 1); + grub_memcpy (section->name, ".text", sizeof (".text") - 1); section->vaddr = grub_host_to_target32 (target_addr); section->size = grub_host_to_target32 (program_size); section->file_offset = grub_host_to_target32 (sizeof (*head) + sizeof (*section)); @@ -1731,6 +1814,14 @@ grub_install_generate_image (const char *dir, const char *prefix, case IMAGE_I386_IEEE1275: { grub_uint64_t target_addr; + char *sbat = NULL; + if (sbat_path != NULL) + { + sbat_size = grub_util_get_image_size (sbat_path); + sbat = xmalloc (sbat_size); + grub_util_load_image (sbat_path, sbat); + layout.sbat_size = sbat_size; + } if (image_target->id == IMAGE_LOONGSON_ELF) { if (comp == GRUB_COMPRESSION_NONE) @@ -1742,10 +1833,10 @@ grub_install_generate_image (const char *dir, const char *prefix, else target_addr = image_target->link_addr; if (image_target->voidp_sizeof == 4) - grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size, + grub_mkimage_generate_elf32 (image_target, note, sbat, &core_img, &core_size, target_addr, &layout); else - grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size, + grub_mkimage_generate_elf64 (image_target, note, sbat, &core_img, &core_size, target_addr, &layout); } break; diff --git a/util/probe.c b/util/probe.c index fa7ca34d1..81d91cf59 100644 --- a/util/probe.c +++ b/util/probe.c @@ -36,8 +36,6 @@ #include #include #include -#include -#include #include @@ -169,4 +167,4 @@ grub_util_fprint_full_disk_name (FILE *f, else fprintf (f, "%s", dname); free (dname); -} +} diff --git a/util/render-label.c b/util/render-label.c index 91c080c9c..432a5c3d2 100644 --- a/util/render-label.c +++ b/util/render-label.c @@ -162,7 +162,7 @@ grub_util_render_label (const char *label_font, { grub_util_error (_("cannot open `%s': %s"), label_font, strerror (errno)); - } + } fontfull = xasprintf ("(host)/%s", t); free (t); @@ -173,7 +173,7 @@ grub_util_render_label (const char *label_font, { grub_util_error (_("cannot open `%s': %s"), label_font, grub_errmsg); - } + } width = grub_font_get_string_width (font, text) + 10; height = grub_font_get_height (font); diff --git a/util/resolve.c b/util/resolve.c index 3e887d2ff..b6e26312f 100644 --- a/util/resolve.c +++ b/util/resolve.c @@ -102,7 +102,7 @@ read_dep_list (FILE *fp) dep_list = dep; /* Add dependencies. */ - while (*p) + while (p < (buf + sizeof (buf)) && *p) { struct mod_list *mod; char *name; @@ -127,6 +127,9 @@ read_dep_list (FILE *fp) mod->next = dep->list; dep->list = mod; } + + if ((p - buf) == sizeof (buf)) + grub_util_error (_("line too long, length greater than %zu: module %s"), sizeof (buf), dep->name); } return dep_list; diff --git a/util/setup.c b/util/setup.c index 6f88f3cc4..87a889ff7 100644 --- a/util/setup.c +++ b/util/setup.c @@ -254,7 +254,8 @@ 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 __attribute__ ((unused))) /* unused on sparc64 */ + int add_rs_codes __attribute__ ((unused)), /* unused on sparc64 */ + int warn_small) { char *core_path; char *boot_img, *core_img, *boot_path; @@ -270,6 +271,9 @@ SETUP (const char *dir, #ifdef GRUB_SETUP_BIOS bl.current_segment = GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); +#endif +#ifdef GRUB_SETUP_SPARC64 + bl.gpt_offset = 0; #endif bl.last_length = 0; @@ -346,7 +350,7 @@ SETUP (const char *dir, root = drive; continue; } - grub_device_close (try_dev); + grub_device_close (try_dev); free (drive); } if (!root_dev) @@ -375,7 +379,7 @@ SETUP (const char *dir, tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE); if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img)) grub_util_error ("%s", grub_errmsg); - + boot_drive_check = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_DRIVE_CHECK); /* Copy the possible DOS BPB. */ @@ -527,7 +531,7 @@ SETUP (const char *dir, GRUB_EMBED_PCBIOS, §ors); else if (ctx.dest_partmap) err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, - GRUB_EMBED_PCBIOS, §ors); + GRUB_EMBED_PCBIOS, §ors, warn_small); else err = fs->fs_embed (dest_dev, &nsec, maxsec, GRUB_EMBED_PCBIOS, §ors); @@ -537,7 +541,7 @@ SETUP (const char *dir, N_("Your embedding area is unusually small. " "core.img won't fit in it.")); } - + if (err) { grub_util_warn ("%s", grub_errmsg); @@ -552,7 +556,7 @@ SETUP (const char *dir, while (bl.block->len) { grub_memset (bl.block, 0, sizeof (*bl.block)); - + bl.block--; if ((char *) bl.block <= core_img) @@ -613,7 +617,7 @@ SETUP (const char *dir, - sizeof (*bl.block)); #if GRUB_SETUP_BIOS grub_size_t no_rs_length; - no_rs_length = grub_target_to_host16 + no_rs_length = grub_target_to_host16 (grub_get_unaligned16 (core_img + GRUB_DISK_SECTOR_SIZE + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH)); @@ -730,7 +734,6 @@ unable_to_embed: #ifdef GRUB_SETUP_SPARC64 { grub_partition_t container = root_dev->disk->partition; - bl.gpt_offset = 0; if (grub_strstr (container->partmap->name, "gpt")) bl.gpt_offset = grub_partition_get_start (container); @@ -839,7 +842,7 @@ unable_to_embed: ptr += cur; len -= cur; bl.block--; - + if ((char *) bl.block <= core_img) grub_util_error ("%s", _("no terminator in the core image")); }