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 eca17bec9..524f2e6d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,249 +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 -aclocal.m4 -ahci_test -ascii.bitmaps -ascii.h -autom4te.cache -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 -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-sh -lib/libgcrypt-grub -libgrub_a_init.c +*.img *.log *.lst -lzocompress_test *.marker -Makefile *.mod -mod-*.c -missing -netboot_test *.o -*.a -ohci_test -partmap_test -pata_test *.pf2 *.pp -po/*.mo -po/grub.pot -po/POTFILES -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/gnulib/alloca.h -grub-core/gnulib/arg-nonnull.h -grub-core/gnulib/c++defs.h -grub-core/gnulib/charset.alias -grub-core/gnulib/configmake.h -grub-core/gnulib/float.h -grub-core/gnulib/getopt.h -grub-core/gnulib/langinfo.h -grub-core/gnulib/ref-add.sed -grub-core/gnulib/ref-del.sed -grub-core/gnulib/stdio.h -grub-core/gnulib/stdlib.h -grub-core/gnulib/string.h -grub-core/gnulib/strings.h -grub-core/gnulib/sys -grub-core/gnulib/unistd.h -grub-core/gnulib/warn-on-use.h -grub-core/gnulib/wchar.h -grub-core/gnulib/wctype.h -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 -grub-core/gnulib/locale.h -grub-core/gnulib/unitypes.h -grub-core/gnulib/uniwidth.h -build-aux/test-driver + +# +# 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 new file mode 100644 index 000000000..4bd05a30a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: GPL-3.0+ +# Originally Copyright Roger Meier +# Adapted for GRUB by Alexander Graf +# +# Build GRUB on Travis CI - https://www.travis-ci.org/ +# + +dist: xenial + +language: c + +addons: + apt: + packages: + - autopoint + - libsdl1.2-dev + - lzop + - ovmf + - python + - qemu-system + - unifont + +env: + global: + # Include all cross toolchain paths, so we can just call them later down. + - PATH=/tmp/qemu-install/bin:/tmp/grub/bin:/usr/bin:/bin:/tmp/cross/gcc-8.1.0-nolibc/aarch64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/arm-linux-gnueabi/bin:/tmp/cross/gcc-8.1.0-nolibc/ia64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/mips64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/powerpc64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv32-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/sparc64-linux/bin + +before_script: + # Install necessary toolchains based on $CROSS_TARGETS variable. + - mkdir /tmp/cross + # These give us binaries like /tmp/cross/gcc-8.1.0-nolibc/ia64-linux/bin/ia64-linux-gcc + - for i in $CROSS_TARGETS; do + ( cd /tmp/cross; wget -t 3 -O - https://mirrors.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-$i.tar.xz | tar xJ ); + done + +script: + # Comments must be outside the command strings below, or the Travis parser + # will get confused. + - ./bootstrap + + # Build all selected GRUB targets. + - for target in $GRUB_TARGETS; do + plat=${target#*-}; + arch=${target%-*}; + [ "$arch" = "arm64" ] && arch=aarch64-linux; + [ "$arch" = "arm" ] && arch=arm-linux-gnueabi; + [ "$arch" = "ia64" ] && arch=ia64-linux; + [ "$arch" = "mipsel" ] && arch=mips64-linux; + [ "$arch" = "powerpc" ] && arch=powerpc64-linux; + [ "$arch" = "riscv32" ] && arch=riscv32-linux; + [ "$arch" = "riscv64" ] && arch=riscv64-linux; + [ "$arch" = "sparc64" ] && arch=sparc64-linux; + echo "Building $target"; + mkdir obj-$target; + JOBS=`getconf _NPROCESSORS_ONLN 2> /dev/null || echo 1`; + [ "$JOBS" == 1 ] || JOBS=$(($JOBS + 1)); + ( cd obj-$target && ../configure --target=$arch --with-platform=$plat --prefix=/tmp/grub && make -j$JOBS && make -j$JOBS install ) &> log || ( cat log; false ); + done + + # Our test canary. + - echo -e "insmod echo\\ninsmod reboot\\necho hello world\\nreboot" > grub.cfg + + # Assemble images and possibly run them. + - for target in $GRUB_TARGETS; do grub-mkimage -c grub.cfg -p / -O $target -o grub-$target echo reboot normal; done + + # Run images we know how to run. + - if [[ "$GRUB_TARGETS" == *"x86_64-efi"* ]]; then qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -m 512 -no-reboot -nographic -net nic -net user,tftp=.,bootfile=grub-x86_64-efi | tee grub.log && grep "hello world" grub.log; fi + +matrix: + include: + # Each env setting here is a dedicated build. + - name: "x86_64" + env: + - GRUB_TARGETS="x86_64-efi x86_64-xen" + - name: "i386" + env: + - GRUB_TARGETS="i386-coreboot i386-efi i386-ieee1275 i386-multiboot i386-pc i386-qemu i386-xen i386-xen_pvh" + - name: "powerpc" + env: + - GRUB_TARGETS="powerpc-ieee1275" + - CROSS_TARGETS="powerpc64-linux" + - name: "sparc64" + env: + - GRUB_TARGETS="sparc64-ieee1275" + - CROSS_TARGETS="sparc64-linux" + - name: "ia64" + env: + - GRUB_TARGETS="ia64-efi" + - CROSS_TARGETS="ia64-linux" + - name: "mips" + env: + - GRUB_TARGETS="mips-arc mipsel-arc mipsel-qemu_mips mips-qemu_mips" + - CROSS_TARGETS="mips64-linux" + - name: "arm" + env: + - GRUB_TARGETS="arm-coreboot arm-efi arm-uboot" + - CROSS_TARGETS="arm-linux-gnueabi" + - name: "arm64" + env: + - GRUB_TARGETS="arm64-efi" + - CROSS_TARGETS="aarch64-linux" + - name: "riscv32" + env: + - GRUB_TARGETS="riscv32-efi" + - CROSS_TARGETS="riscv32-linux" + - name: "riscv64" + env: + - GRUB_TARGETS="riscv64-efi" + - CROSS_TARGETS="riscv64-linux" diff --git a/ABOUT-NLS b/ABOUT-NLS deleted file mode 100644 index 866b904ec..000000000 --- a/ABOUT-NLS +++ /dev/null @@ -1,223 +0,0 @@ -1 Notes on the Free Translation Project -*************************************** - -Free software is going international! The Free Translation Project is -a way to get maintainers of free software, translators, and users all -together, so that free software will gradually become able to speak many -languages. A few packages already provide translations for their -messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do _not_ -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work on translations can contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -1.1 Quick configuration advice -============================== - -If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias, message inheritance, automatic -charset conversion or plural form handling) as the implementation here. -It is also not possible to offer this additional functionality on top -of a `catgets' implementation. Future versions of GNU `gettext' will -very likely convey even more functionality. So it might be a good idea -to change to GNU `gettext' as soon as possible. - - So you need _not_ provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -1.2 INSTALL Matters -=================== - -Some packages are "localizable" when properly installed; the programs -they contain can be made to speak your own native language. Most such -packages use GNU `gettext'. Other packages have their own ways to -internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system already -provides the GNU `gettext' functions. If not, the included GNU -`gettext' library will be used. This library is wholly contained -within this package, usually in the `intl/' subdirectory, so prior -installation of the GNU `gettext' package is _not_ required. -Installers may use special options at configuration time for changing -the default behaviour. The commands: - - ./configure --with-included-gettext - ./configure --disable-nls - -will, respectively, bypass any pre-existing `gettext' to use the -internationalizing routines provided within this package, or else, -_totally_ disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might not be desirable. You should use -the more recent version of the GNU `gettext' library. I.e. if the file -`intl/VERSION' shows that the library which comes with this package is -more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - The configuration process will not test for the `catgets' function -and therefore it will not be used. The reason is that even an -emulation of `gettext' on top of `catgets' could not provide all the -extensions of the GNU `gettext' library. - - Internationalized packages usually have many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -1.3 Using This Package -====================== - -As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, -and `CC' is an ISO 3166 two-letter country code. For example, let's -suppose that you speak German and live in Germany. At the shell -prompt, merely execute `setenv LANG de_DE' (in `csh'), -`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). -This can be done from your `.login' or `.profile' file, once and for -all. - - You might think that the country code specification is redundant. -But in fact, some languages have dialects in different countries. For -example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The -country code serves to distinguish the dialects. - - The locale naming convention of `LL_CC', with `LL' denoting the -language and `CC' denoting the country, is the one use on systems based -on GNU libc. On other systems, some variations of this scheme are -used, such as `LL' or `LL_CC.ENCODING'. You can get the list of -locales supported by your system for your language by running the -command `locale -a | grep '^LL''. - - Not all programs have translations for all languages. By default, an -English message is shown in place of a nonexistent translation. If you -understand other languages, you can set up a priority list of languages. -This is done through a different environment variable, called -`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' -for the purpose of message handling, but you still need to have `LANG' -set to the primary language; this is required by other parts of the -system libraries. For example, some Swedish users who would rather -read translations in German than English for when Swedish is not -available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. - - Special advice for Norwegian users: The language code for Norwegian -bokma*l changed from `no' to `nb' recently (in 2003). During the -transition period, while some message catalogs for this language are -installed under `nb' and some older ones under `no', it's recommended -for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and -older translations are used. - - In the `LANGUAGE' environment variable, but not in the `LANG' -environment variable, `LL_CC' combinations can be abbreviated as `LL' -to denote the language's main dialect. For example, `de' is equivalent -to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' -(Portuguese as spoken in Portugal) in this context. - -1.4 Translating Teams -===================== - -For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list. The up-to-date list of -teams can be found at the Free Translation Project's homepage, -`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" -area. - - If you'd like to volunteer to _work_ at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is _not_ the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -_actively_ in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skills are praised more than -programming skills, here. - -1.5 Available Packages -====================== - -Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of October -2006. The matrix shows, in regard of each package, for which languages -PO files have been submitted to translation coordination, with a -translation percentage of at least 50%. - -# Matrix here is removed! - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If October 2006 seems to be old, you may fetch a more recent copy of -this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date -matrix with full percentage details can be found at -`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. - -1.6 Using `gettext' in new packages -=================================== - -If you are writing a freely available program and want to -internationalize it you are welcome to use GNU `gettext' in your -package. Of course you have to respect the GNU Library General Public -License which covers the use of the GNU `gettext' library. This means -in particular that even non-free programs can use `libintl' as a shared -library, whereas only free software can use `libintl' as a static -library or use modified versions of `libintl'. - - Once the sources are changed appropriately and the setup can handle -the use of `gettext' the only thing missing are the translations. The -Free Translation Project is also available for packages which are not -developed inside the GNU project. Therefore the information given above -applies also for every other Free Software Project. Contact -`translation@iro.umontreal.ca' to make the `.pot' files available to -the translation teams. - diff --git a/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 f3c20edc8..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,32 +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) @@ -48,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 or later +* 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.60 or later -* Automake 1.10.1 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 ==================== @@ -101,10 +139,10 @@ The simplest way to compile this package is: 2. Skip this and following step if you use release tarball and proceed to step 4. If you want translations type `./linguas.sh'. - 3. Type `./autogen.sh'. + 3. Type `./bootstrap'. - * autogen.sh uses python. By default invocation is "python" but can be - overriden by setting 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 @@ -117,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 @@ -158,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_FREETYPE=freetype-config --host=amd64-linux-gnu -CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" FREETYPE=amd64-linux-gnu-freetype-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_FREETYPE= for freetype-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. FREETYPE= for freetype-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. @@ -202,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 7795baeb6..43635d5ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects -Wno-portability DEPDIR = .deps-util -SUBDIRS = grub-core/gnulib . +SUBDIRS = grub-core/lib/gnulib . if COND_real_platform SUBDIRS += grub-core endif @@ -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 @@ -71,7 +80,7 @@ endif starfield_theme_files = $(srcdir)/themes/starfield/blob_w.png $(srcdir)/themes/starfield/boot_menu_c.png $(srcdir)/themes/starfield/boot_menu_e.png $(srcdir)/themes/starfield/boot_menu_ne.png $(srcdir)/themes/starfield/boot_menu_n.png $(srcdir)/themes/starfield/boot_menu_nw.png $(srcdir)/themes/starfield/boot_menu_se.png $(srcdir)/themes/starfield/boot_menu_s.png $(srcdir)/themes/starfield/boot_menu_sw.png $(srcdir)/themes/starfield/boot_menu_w.png $(srcdir)/themes/starfield/slider_c.png $(srcdir)/themes/starfield/slider_n.png $(srcdir)/themes/starfield/slider_s.png $(srcdir)/themes/starfield/starfield.png $(srcdir)/themes/starfield/terminal_box_c.png $(srcdir)/themes/starfield/terminal_box_e.png $(srcdir)/themes/starfield/terminal_box_ne.png $(srcdir)/themes/starfield/terminal_box_n.png $(srcdir)/themes/starfield/terminal_box_nw.png $(srcdir)/themes/starfield/terminal_box_se.png $(srcdir)/themes/starfield/terminal_box_s.png $(srcdir)/themes/starfield/terminal_box_sw.png $(srcdir)/themes/starfield/terminal_box_w.png $(srcdir)/themes/starfield/theme.txt $(srcdir)/themes/starfield/README $(srcdir)/themes/starfield/COPYING.CC-BY-SA-3.0 build-grub-mkfont$(BUILD_EXEEXT): util/grub-mkfont.c grub-core/unidata.c grub-core/kern/emu/misc.c util/misc.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-mkfont\" $^ $(build_freetype_cflags) $(build_freetype_libs) + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-mkfont\" $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) CLEANFILES += build-grub-mkfont$(BUILD_EXEEXT) garbage-gen$(BUILD_EXEEXT): util/garbage-gen.c @@ -80,11 +89,11 @@ CLEANFILES += garbage-gen$(BUILD_EXEEXT) EXTRA_DIST += util/garbage-gen.c build-grub-gen-asciih$(BUILD_EXEEXT): util/grub-gen-asciih.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror CLEANFILES += build-grub-gen-asciih$(BUILD_EXEEXT) build-grub-gen-widthspec$(BUILD_EXEEXT): util/grub-gen-widthspec.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror CLEANFILES += build-grub-gen-widthspec$(BUILD_EXEEXT) if COND_STARFIELD @@ -422,9 +431,10 @@ BOOTCHECK_TIMEOUT=180 bootcheck: $(BOOTCHECKS) if COND_i386_coreboot +FS_PAYLOAD_MODULES ?= $(shell cat grub-core/fs.lst) default_payload.elf: grub-mkstandalone grub-mkimage FORCE test -f $@ && rm $@ || true - pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(shell cat grub-core/fs.lst) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg + pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg endif endif @@ -472,10 +482,13 @@ 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 +# can predict its behaviour in tests. We have to pre-substitute this before +# calling config.status, as config.status offers no reliable way to hook in +# a command between setting ac_abs_top_srcdir and emitting output files. tests/syslinux/ubuntu10.04_grub.cfg: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg.in - (for x in tests/syslinux/ubuntu10.04_grub.cfg.in ; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- + simplified_abs_top_srcdir=`echo "$(abs_top_srcdir)" | sed 's,//,/,g; s,/\./,/,g; :loop; s,/[^/][^/]*/\.\.\(/\|$$\),\1,; t loop'`; \ + sed "s,@simplified_abs_top_srcdir@,$$simplified_abs_top_srcdir,g" $(srcdir)/tests/syslinux/ubuntu10.04_grub.cfg.in | $(top_builddir)/config.status --file=$@:- CLEANFILES += tests/syslinux/ubuntu10.04_grub.cfg diff --git a/Makefile.util.def b/Makefile.util.def index f9caccb97..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,8 +56,8 @@ library = { library = { name = libgrubmods.a; - cflags = '-fno-builtin -Wno-undef'; - cppflags = '-I$(top_srcdir)/grub-core/lib/minilzo -I$(srcdir)/grub-core/lib/xzembed -DMINILZO_HAVE_CONFIG_H'; + cflags = '-fno-builtin -Wno-undef -Wno-unused-but-set-variable'; + cppflags = '-I$(srcdir)/grub-core/lib/minilzo -I$(srcdir)/grub-core/lib/xzembed -I$(srcdir)/grub-core/lib/zstd -DMINILZO_HAVE_CONFIG_H'; common_nodist = grub_script.tab.c; common_nodist = grub_script.yy.c; @@ -96,9 +99,11 @@ 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; + common = grub-core/fs/f2fs.c; common = grub-core/fs/fshelp.c; common = grub-core/fs/hfs.c; common = grub-core/fs/hfsplus.c; @@ -138,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; @@ -160,10 +165,20 @@ 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; common = grub-core/lib/xzembed/xz_dec_stream.c; + common = grub-core/lib/zstd/debug.c; + common = grub-core/lib/zstd/entropy_common.c; + common = grub-core/lib/zstd/error_private.c; + common = grub-core/lib/zstd/fse_decompress.c; + common = grub-core/lib/zstd/huf_decompress.c; + common = grub-core/lib/zstd/module.c; + common = grub-core/lib/zstd/xxhash.c; + common = grub-core/lib/zstd/zstd_common.c; + common = grub-core/lib/zstd/zstd_decompress.c; }; program = { @@ -188,10 +203,35 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + 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 = { @@ -205,7 +245,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -220,7 +260,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -230,12 +270,23 @@ 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; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -251,7 +302,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -274,7 +325,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -287,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/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) -lfuse'; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) $(FUSE_LIBS)'; condition = COND_GRUB_MOUNT; }; @@ -302,14 +355,14 @@ program = { common = grub-core/kern/emu/argp_common.c; common = grub-core/osdep/init.c; - cflags = '$(freetype_cflags)'; + cflags = '$(FREETYPE_CFLAGS)'; cppflags = '-DGRUB_MKFONT=1'; ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(freetype_libs)'; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(FREETYPE_LIBS)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; condition = COND_GRUB_MKFONT; }; @@ -327,7 +380,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -349,7 +402,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = libgrubgcry.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cppflags = '-DGRUB_SETUP_FUNC=grub_util_bios_setup'; }; @@ -369,7 +422,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubkern.a; ldadd = libgrubgcry.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; cppflags = '-DGRUB_SETUP_FUNC=grub_util_sparc_setup'; }; @@ -385,7 +438,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -400,7 +453,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -415,7 +468,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -486,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; @@ -542,7 +607,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; condition = COND_HAVE_EXEC; @@ -589,7 +654,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -628,7 +693,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -664,7 +729,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -713,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; @@ -721,464 +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 = 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; @@ -1188,12 +1307,12 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { - testcase; + testcase = native; name = printf_test; common = tests/printf_unit_test.c; common = tests/lib/unit_test.c; @@ -1203,12 +1322,12 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { - testcase; + testcase = native; name = date_test; common = tests/date_unit_test.c; common = tests/lib/unit_test.c; @@ -1218,12 +1337,12 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; program = { - testcase; + testcase = native; name = priority_queue_unit_test; common = tests/priority_queue_unit_test.cc; common = tests/lib/unit_test.c; @@ -1234,13 +1353,13 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; condition = COND_HAVE_CXX; }; program = { - testcase; + testcase = native; name = cmp_test; common = tests/cmp_unit_test.c; common = tests/lib/unit_test.c; @@ -1250,7 +1369,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -1265,7 +1384,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -1283,7 +1402,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -1299,7 +1418,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -1317,7 +1436,7 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; @@ -1346,6 +1465,6 @@ program = { ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; + ldadd = grub-core/lib/gnulib/libgnu.a; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; diff --git a/NEWS b/NEWS index 2ebd54e78..310130962 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,55 @@ +New in 2.12: + +* GCC 13 support. +* clang 14 support. +* binutils 2.38 support. +* Unification of EFI Linux kernel loader across architectures. +* Transition to EFI Linux kernel stub loader for x86 architecture. +* Initial support for Boot Loader Interface. +* Support for dynamic GRUB runtime memory addition using firmware calls. +* PCI and MMIO UARTs support. +* SDL2 support. +* LoongArch support. +* TPM driver fixes. +* Many filesystems fixes. +* Many CVE and Coverity fixes. +* Debugging support improvements. +* Tests improvements. +* Documentation improvements. +* ...and tons of other fixes and cleanups... + +New in 2.06: + +* GCC 10 support. +* clang 10 support. +* SBAT support. +* LUKS2 support. +* Drop small MBR gap support. +* Xen Security Modules (XSM/FLASK) support. +* The lockdown mechanism similar to the Linux kernel one. +* Disable the os-prober by default. +* Many backports of GRUB distros specific patches. +* BootHole and BootHole2 fixes. +* ...and tons of other fixes and cleanups... + +New in 2.04: + +* GCC 8 and 9 support. +* Gnulib integration overhaul. +* RISC-V support. +* Xen PVH support. +* Native UEFI secure boot support. +* UEFI TPM driver. +* New IEEE 1275 obdisk driver. +* Btrfs RAID 5 and RIAD 6 support. +* PARTUUID support. +* VLAN support. +* Native DHCP support. +* Many ARM and ARM64 fixes. +* Many SPARC fixes. +* Many IEEE 1275 fixes. +* ...and tons of other fixes and cleanups... + New in 2.02: * New/improved filesystem and disk support: 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 7537561ad..ebd614792 100755 --- a/autogen.sh +++ b/autogen.sh @@ -2,13 +2,31 @@ set -e -# Set ${PYTHON} to plain 'python' if not set already -: ${PYTHON:=python} +if [ ! -e grub-core/lib/gnulib/stdlib.in.h ]; then + echo "Gnulib not yet bootstrapped; run ./bootstrap instead." >&2 + exit 1 +fi + +# 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' |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..." @@ -33,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. @@ -82,6 +133,17 @@ done echo "Saving timestamps..." echo timestamp > stamp-h.in -echo "Running autoreconf..." -autoreconf -vi +if [ -z "$FROM_BOOTSTRAP" ]; then + # Unaided autoreconf is likely to install older versions of many files + # than the ones provided by Gnulib, but in most cases this won't matter + # very much. This mode is provided so that you can run ./autogen.sh to + # regenerate the GRUB build system in an unpacked release tarball (perhaps + # after patching it), even on systems that don't have access to + # gnulib.git. + echo "Running autoreconf..." + cp -a INSTALL INSTALL.grub + autoreconf -vif + mv INSTALL.grub INSTALL +fi + exit 0 diff --git a/bootstrap b/bootstrap new file mode 100755 index 000000000..dc2238f4a --- /dev/null +++ b/bootstrap @@ -0,0 +1,1118 @@ +#! /bin/sh +# Print a version string. +scriptversion=2022-01-26.05; # UTC + +# Bootstrap this package from checked-out sources. + +# Copyright (C) 2003-2022 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Originally written by Paul Eggert. The canonical version of this +# script is maintained as build-aux/bootstrap in gnulib, however, to +# be useful to your project, you should place a copy of it under +# version control in the top-level directory of your project. The +# intent is that all customization can be done with a bootstrap.conf +# file also maintained in your version control; gnulib comes with a +# template build-aux/bootstrap.conf to get you started. + +# Please report bugs or propose patches to bug-gnulib@gnu.org. + +nl=' +' + +# Ensure file names are sorted consistently across platforms. +LC_ALL=C +export LC_ALL + +# Ensure that CDPATH is not set. Otherwise, the output from cd +# would cause trouble in at least one use below. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +local_gl_dir=gl + +# Honor $PERL, but work even if there is none. +PERL="${PERL-perl}" + +me=$0 + +default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git + +usage() { + cat <&2 +} + +# warn_ WORD1... +warn_ () +{ + # If IFS does not start with ' ', set it and emit the warning in a subshell. + case $IFS in + ' '*) warnf_ '%s\n' "$*";; + *) (IFS=' '; warn_ "$@");; + esac +} + +# die WORD1... +die() { warn_ "$@"; exit 1; } + +# Configuration. + +# Name of the Makefile.am +gnulib_mk=gnulib.mk + +# List of gnulib modules needed. +gnulib_modules= + +# Any gnulib files needed that are not in modules. +gnulib_files= + +: ${AUTOPOINT=autopoint} +: ${AUTORECONF=autoreconf} + +# A function to be called for each unrecognized option. Returns 0 if +# the option in $1 has been processed by the function. Returns 1 if +# the option has not been processed by the function. Override it via +# your own definition in bootstrap.conf + +bootstrap_option_hook() { return 1; } + +# A function to be called in order to print the --help information +# corresponding to user-defined command-line options. + +bootstrap_print_option_usage_hook() { :; } + +# A function to be called right after gnulib-tool is run. +# Override it via your own definition in bootstrap.conf. +bootstrap_post_import_hook() { :; } + +# A function to be called after everything else in this script. +# Override it via your own definition in bootstrap.conf. +bootstrap_epilogue() { :; } + +# The command to download all .po files for a specified domain into a +# specified directory. Fill in the first %s with the destination +# directory and the second with the domain name. +po_download_command_format=\ +"wget --mirror --level=1 -nd -nv -A.po -P '%s' \ + https://translationproject.org/latest/%s/" + +# Prefer a non-empty tarname (4th argument of AC_INIT if given), else +# fall back to the package name (1st argument with munging). +extract_package_name=' + /^AC_INIT(\[*/{ + s/// + /^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{ + s//\1/ + s/[],)].*// + p + q + } + s/[],)].*// + s/^GNU // + y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g + p + } +' +package=$(${AUTOCONF:-autoconf} --trace AC_INIT:\$4 configure.ac 2>/dev/null) +if test -z "$package"; then + package=$(sed -n "$extract_package_name" configure.ac) \ + || die 'cannot find package name in configure.ac' +fi +gnulib_name=lib$package + +build_aux=build-aux +source_base=lib +m4_base=m4 +doc_base=doc +tests_base=tests +gnulib_extra_files=" + build-aux/install-sh + build-aux/mdate-sh + build-aux/texinfo.tex + build-aux/depcomp + build-aux/config.guess + build-aux/config.sub + doc/INSTALL +" + +# Additional gnulib-tool options to use. Use "\newline" to break lines. +gnulib_tool_option_extras= + +# Other locale categories that need message catalogs. +EXTRA_LOCALE_CATEGORIES= + +# Additional xgettext options to use. Use "\\\newline" to break lines. +XGETTEXT_OPTIONS='\\\ + --flag=_:1:pass-c-format\\\ + --flag=N_:1:pass-c-format\\\ + --flag=error:3:c-format --flag=error_at_line:5:c-format\\\ +' + +# Package bug report address and copyright holder for gettext files +COPYRIGHT_HOLDER='Free Software Foundation, Inc.' +MSGID_BUGS_ADDRESS=bug-$package@gnu.org + +# Files we don't want to import. +excluded_files= + +# File that should exist in the top directory of a checked out hierarchy, +# but not in a distribution tarball. +checkout_only_file=README-hacking + +# Whether to use copies instead of symlinks. +copy=false + +# Set this to '.cvsignore .gitignore' in bootstrap.conf if you want +# those files to be generated in directories like lib/, m4/, and po/. +# Or set it to 'auto' to make this script select which to use based +# on which version control system (if any) is used in the source directory. +vc_ignore=auto + +# Set this to true in bootstrap.conf to enable --bootstrap-sync by +# default. +bootstrap_sync=false + +# Use git to update gnulib sources +use_git=true + +check_exists() { + if test "$1" = "--verbose"; then + ($2 --version /dev/null 2>&1 + if test $? -ge 126; then + # If not found, run with diagnostics as one may be + # presented with env variables to set to find the right version + ($2 --version /dev/null 2>&1 + fi + + test $? -lt 126 +} + +# find_tool ENVVAR NAMES... +# ------------------------- +# Search for a required program. Use the value of ENVVAR, if set, +# otherwise find the first of the NAMES that can be run. +# If found, set ENVVAR to the program name, die otherwise. +# +# FIXME: code duplication, see also gnu-web-doc-update. +find_tool () +{ + find_tool_envvar=$1 + shift + find_tool_names=$@ + eval "find_tool_res=\$$find_tool_envvar" + if test x"$find_tool_res" = x; then + for i; do + if check_exists $i; then + find_tool_res=$i + break + fi + done + fi + if test x"$find_tool_res" = x; then + warn_ "one of these is required: $find_tool_names;" + die "alternatively set $find_tool_envvar to a compatible tool" + fi + eval "$find_tool_envvar=\$find_tool_res" + eval "export $find_tool_envvar" +} + +# Strip blank and comment lines to leave significant entries. +gitignore_entries() { + sed '/^#/d; /^$/d' "$@" +} + +# If $STR is not already on a line by itself in $FILE, insert it at the start. +# Entries are inserted at the start of the ignore list to ensure existing +# entries starting with ! are not overridden. Such entries support +# whitelisting exceptions after a more generic blacklist pattern. +insert_if_absent() { + file=$1 + str=$2 + test -f $file || touch $file + test -r $file || die "Error: failed to read ignore file: $file" + duplicate_entries=$(gitignore_entries $file | sort | uniq -d) + if [ "$duplicate_entries" ] ; then + die "Error: Duplicate entries in $file: " $duplicate_entries + fi + linesold=$(gitignore_entries $file | wc -l) + linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l) + if [ $linesold != $linesnew ] ; then + { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \ + || die "insert_if_absent $file $str: failed" + fi +} + +# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with +# insert_if_absent. +insert_vc_ignore() { + vc_ignore_file="$1" + pattern="$2" + case $vc_ignore_file in + *.gitignore) + # A .gitignore entry that does not start with '/' applies + # recursively to subdirectories, so prepend '/' to every + # .gitignore entry. + pattern=$(echo "$pattern" | sed s,^,/,);; + esac + insert_if_absent "$vc_ignore_file" "$pattern" +} + +symlink_to_dir() +{ + src=$1/$2 + dst=${3-$2} + + test -f "$src" && { + + # If the destination directory doesn't exist, create it. + # This is required at least for "lib/uniwidth/cjk.h". + dst_dir=$(dirname "$dst") + if ! test -d "$dst_dir"; then + mkdir -p "$dst_dir" + + # If we've just created a directory like lib/uniwidth, + # tell version control system(s) it's ignorable. + # FIXME: for now, this does only one level + parent=$(dirname "$dst_dir") + for dot_ig in x $vc_ignore; do + test $dot_ig = x && continue + ig=$parent/$dot_ig + insert_vc_ignore $ig "${dst_dir##*/}" + done + fi + + if $copy; then + { + test ! -h "$dst" || { + echo "$me: rm -f $dst" && + rm -f "$dst" + } + } && + test -f "$dst" && + cmp -s "$src" "$dst" || { + echo "$me: cp -fp $src $dst" && + cp -fp "$src" "$dst" + } + else + # Leave any existing symlink alone, if it already points to the source, + # so that broken build tools that care about symlink times + # aren't confused into doing unnecessary builds. Conversely, if the + # existing symlink's timestamp is older than the source, make it afresh, + # so that broken tools aren't confused into skipping needed builds. See + # . + test -h "$dst" && + src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 && + dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 && + test "$src_i" = "$dst_i" && + both_ls=$(ls -dt "$src" "$dst") && + test "X$both_ls" = "X$dst$nl$src" || { + dot_dots= + case $src in + /*) ;; + *) + case /$dst/ in + *//* | */../* | */./* | /*/*/*/*/*/) + die "invalid symlink calculation: $src -> $dst";; + /*/*/*/*/) dot_dots=../../../;; + /*/*/*/) dot_dots=../../;; + /*/*/) dot_dots=../;; + esac;; + esac + + echo "$me: ln -fs $dot_dots$src $dst" && + ln -fs "$dot_dots$src" "$dst" + } + fi + } +} + +# Override the default configuration, if necessary. +# Make sure that bootstrap.conf is sourced from the current directory +# if we were invoked as "sh bootstrap". +case "$0" in + */*) test -r "$0.conf" && . "$0.conf" ;; + *) test -r "$0.conf" && . ./"$0.conf" ;; +esac + +if test "$vc_ignore" = auto; then + vc_ignore= + test -d .git && vc_ignore=.gitignore + test -d CVS && vc_ignore="$vc_ignore .cvsignore" +fi + +if test x"$gnulib_modules$gnulib_files$gnulib_extra_files" = x; then + use_gnulib=false +else + use_gnulib=true +fi + +# Translate configuration into internal form. + +# Parse options. + +for option +do + case $option in + --help) + usage + exit;; + --version) + set -e + echo "bootstrap $scriptversion" + echo "$copyright" + exit 0 + ;; + --gnulib-srcdir=*) + GNULIB_SRCDIR=${option#--gnulib-srcdir=};; + --skip-po) + SKIP_PO=t;; + --force) + checkout_only_file=;; + --copy) + copy=true;; + --bootstrap-sync) + bootstrap_sync=true;; + --no-bootstrap-sync) + bootstrap_sync=false;; + --no-git) + use_git=false;; + *) + bootstrap_option_hook $option || die "$option: unknown option";; + esac +done + +$use_git || test -d "$GNULIB_SRCDIR" \ + || die "Error: --no-git requires --gnulib-srcdir" + +if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then + die "Bootstrapping from a non-checked-out distribution is risky." +fi + +# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac. +found_aux_dir=no +grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \ + >/dev/null && found_aux_dir=yes +grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \ + >/dev/null && found_aux_dir=yes +test $found_aux_dir = yes \ + || die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it" + +# If $build_aux doesn't exist, create it now, otherwise some bits +# below will malfunction. If creating it, also mark it as ignored. +if test ! -d $build_aux; then + mkdir $build_aux + for dot_ig in x $vc_ignore; do + test $dot_ig = x && continue + insert_vc_ignore $dot_ig $build_aux + done +fi + +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +sort_ver() { # sort -V is not generally available + ver1="$1" + ver2="$2" + + # split on '.' and compare each component + i=1 + while : ; do + p1=$(echo "$ver1" | cut -d. -f$i) + p2=$(echo "$ver2" | cut -d. -f$i) + if [ ! "$p1" ]; then + echo "$1 $2" + break + elif [ ! "$p2" ]; then + echo "$2 $1" + break + elif [ ! "$p1" = "$p2" ]; then + if [ "$p1" -gt "$p2" ] 2>/dev/null; then # numeric comparison + echo "$2 $1" + elif [ "$p2" -gt "$p1" ] 2>/dev/null; then # numeric comparison + echo "$1 $2" + else # numeric, then lexicographic comparison + lp=$(printf "$p1\n$p2\n" | LANG=C sort -n | tail -n1) + if [ "$lp" = "$p2" ]; then + echo "$1 $2" + else + echo "$2 $1" + fi + fi + break + fi + i=$(($i+1)) + done +} + +get_version_sed=' +# Move version to start of line. +s/.*[v ]\([0-9]\)/\1/ + +# Skip lines that do not start with version. +/^[0-9]/!d + +# Remove characters after the version. +s/[^.a-z0-9-].*// + +# The first component must be digits only. +s/^\([0-9]*\)[a-z-].*/\1/ + +#the following essentially does s/5.005/5.5/ +s/\.0*\([1-9]\)/.\1/g +p +q' + +get_version() { + app=$1 + + $app --version >/dev/null 2>&1 || { $app --version; return 1; } + + $app --version 2>&1 | sed -n "$get_version_sed" +} + +check_versions() { + ret=0 + + while read app req_ver; do + # We only need libtoolize from the libtool package. + if test "$app" = libtool; then + app=libtoolize + fi + # Exempt git if --no-git is in effect. + if test "$app" = git; then + $use_git || continue + fi + # Honor $APP variables ($TAR, $AUTOCONF, etc.) + appvar=$(echo $app | LC_ALL=C tr '[a-z]-' '[A-Z]_') + test "$appvar" = TAR && appvar=AMTAR + case $appvar in + GZIP) ;; # Do not use $GZIP: it contains gzip options. + PERL::*) ;; # Keep perl modules as-is + *) eval "app=\${$appvar-$app}" ;; + esac + + # Handle the still-experimental Automake-NG programs specially. + # They remain named as the mainstream Automake programs ("automake", + # and "aclocal") to avoid gratuitous incompatibilities with + # pre-existing usages (by, say, autoreconf, or custom autogen.sh + # scripts), but correctly identify themselves (as being part of + # "GNU automake-ng") when asked their version. + case $app in + automake-ng|aclocal-ng) + app=${app%-ng} + ($app --version | grep '(GNU automake-ng)') >/dev/null 2>&1 || { + warn_ "Error: '$app' not found or not from Automake-NG" + ret=1 + continue + } ;; + # Another check is for perl modules. These can be written as + # e.g. perl::XML::XPath in case of XML::XPath module, etc. + perl::*) + # Extract module name + app="${app#perl::}" + if ! $PERL -m"$app" -e 'exit 0' >/dev/null 2>&1; then + warn_ "Error: perl module '$app' not found" + ret=1 + fi + continue + ;; + esac + if [ "$req_ver" = "-" ]; then + # Merely require app to exist; not all prereq apps are well-behaved + # so we have to rely on $? rather than get_version. + if ! check_exists --verbose $app; then + warn_ "Error: '$app' not found" + ret=1 + fi + else + # Require app to produce a new enough version string. + inst_ver=$(get_version $app) + if [ ! "$inst_ver" ]; then + warn_ "Error: '$app' not found" + ret=1 + else + latest_ver=$(sort_ver $req_ver $inst_ver | cut -d' ' -f2) + if [ ! "$latest_ver" = "$inst_ver" ]; then + warnf_ '%s\n' \ + "Error: '$app' version == $inst_ver is too old" \ + " '$app' version >= $req_ver is required" + ret=1 + fi + fi + fi + done + + return $ret +} + +print_versions() { + echo "Program Min_version" + echo "----------------------" + printf %s "$buildreq" + echo "----------------------" + # can't depend on column -t +} + +# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6. +# Also find the compatible sha1 utility on the BSDs +if test x"$SKIP_PO" = x; then + find_tool SHA1SUM sha1sum gsha1sum shasum sha1 +fi + +use_libtool=0 +# We'd like to use grep -E, to see if any of LT_INIT, +# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac, +# but that's not portable enough (e.g., for Solaris). +grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \ + && use_libtool=1 +grep '^[ ]*LT_INIT' configure.ac >/dev/null \ + && use_libtool=1 +if test $use_libtool = 1; then + find_tool LIBTOOLIZE glibtoolize libtoolize +fi + +# gnulib-tool requires at least automake and autoconf. +# If either is not listed, add it (with minimum version) as a prerequisite. +case $buildreq in + *automake*) ;; + *) buildreq="automake 1.9 +$buildreq" ;; +esac +case $buildreq in + *autoconf*) ;; + *) buildreq="autoconf 2.59 +$buildreq" ;; +esac + +# When we can deduce that gnulib-tool will require patch, +# and when patch is not already listed as a prerequisite, add it, too. +if test -d "$local_gl_dir" \ + && ! find "$local_gl_dir" -name '*.diff' -exec false {} +; then + case $buildreq in + *patch*) ;; + *) buildreq="patch - +$buildreq" ;; + esac +fi + +if ! printf "$buildreq" | check_versions; then + echo >&2 + if test -f README-prereq; then + die "See README-prereq for how to get the prerequisite programs" + else + die "Please install the prerequisite programs" + fi +fi + +# Warn the user if autom4te appears to be broken; this causes known +# issues with at least gettext 0.18.3. +probe=$(echo 'm4_quote([hi])' | autom4te -l M4sugar -t 'm4_quote:$%' -) +if test "x$probe" != xhi; then + warn_ "WARNING: your autom4te wrapper eats stdin;" + warn_ "if bootstrap fails, consider upgrading your autotools" +fi + +echo "$0: Bootstrapping from checked-out $package sources..." + +# See if we can use gnulib's git-merge-changelog merge driver. +if $use_git && test -d .git && check_exists git; then + if git config merge.merge-changelog.driver >/dev/null ; then + : + elif check_exists git-merge-changelog; then + echo "$0: initializing git-merge-changelog driver" + git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' + git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' + else + echo "$0: consider installing git-merge-changelog from gnulib" + fi +fi + + +cleanup_gnulib() { + status=$? + rm -fr "$gnulib_path" + exit $status +} + +git_modules_config () { + test -f .gitmodules && git config --file .gitmodules "$@" +} + +if $use_gnulib; then + if $use_git; then + gnulib_path=$(git_modules_config submodule.gnulib.path) + test -z "$gnulib_path" && gnulib_path=gnulib + fi + + # Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a + # submodule, for use in the rest of the script. + + case ${GNULIB_SRCDIR--} in + -) + # Note that $use_git is necessarily true in this case. + if git_modules_config submodule.gnulib.url >/dev/null; then + echo "$0: getting gnulib files..." + git submodule init -- "$gnulib_path" || exit $? + git submodule update -- "$gnulib_path" || exit $? + + elif [ ! -d "$gnulib_path" ]; then + echo "$0: getting gnulib files..." + + trap cleanup_gnulib 1 2 13 15 + + shallow= + if test -z "$GNULIB_REVISION"; then + git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' + git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \ + || cleanup_gnulib + else + git fetch -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' + mkdir -p "$gnulib_path" + # Only want a shallow checkout of $GNULIB_REVISION, but git does not + # support cloning by commit hash. So attempt a shallow fetch by commit + # hash to minimize the amount of data downloaded and changes needed to + # be processed, which can drastically reduce download and processing + # time for checkout. If the fetch by commit fails, a shallow fetch can + # not be performed because we do not know what the depth of the commit + # is without fetching all commits. So fallback to fetching all commits. + git -C "$gnulib_path" init + git -C "$gnulib_path" remote add origin ${GNULIB_URL:-$default_gnulib_url} + git -C "$gnulib_path" fetch $shallow origin "$GNULIB_REVISION" \ + || git -C "$gnulib_path" fetch origin \ + || cleanup_gnulib + git -C "$gnulib_path" reset --hard FETCH_HEAD + fi + + trap - 1 2 13 15 + fi + GNULIB_SRCDIR=$gnulib_path + ;; + *) + # Use GNULIB_SRCDIR directly or as a reference. + if $use_git && test -d "$GNULIB_SRCDIR"/.git && \ + git_modules_config submodule.gnulib.url >/dev/null; then + echo "$0: getting gnulib files..." + if git submodule -h|grep -- --reference > /dev/null; then + # Prefer the one-liner available in git 1.6.4 or newer. + git submodule update --init --reference "$GNULIB_SRCDIR" \ + "$gnulib_path" || exit $? + else + # This fallback allows at least git 1.5.5. + if test -f "$gnulib_path"/gnulib-tool; then + # Since file already exists, assume submodule init already complete. + git submodule update -- "$gnulib_path" || exit $? + else + # Older git can't clone into an empty directory. + rmdir "$gnulib_path" 2>/dev/null + git clone --reference "$GNULIB_SRCDIR" \ + "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \ + && git submodule init -- "$gnulib_path" \ + && git submodule update -- "$gnulib_path" \ + || exit $? + fi + fi + GNULIB_SRCDIR=$gnulib_path + fi + ;; + esac + + if test -d "$GNULIB_SRCDIR"/.git && test -n "$GNULIB_REVISION" \ + && ! git_modules_config submodule.gnulib.url >/dev/null; then + (cd "$GNULIB_SRCDIR" && git checkout "$GNULIB_REVISION") || cleanup_gnulib + fi + + # $GNULIB_SRCDIR now points to the version of gnulib to use, and + # we no longer need to use git or $gnulib_path below here. + + if $bootstrap_sync; then + cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || { + echo "$0: updating bootstrap and restarting..." + case $(sh -c 'echo "$1"' -- a) in + a) ignored=--;; + *) ignored=ignored;; + esac + exec sh -c \ + 'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \ + $ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \ + "$0" "$@" --no-bootstrap-sync + } + fi + + gnulib_tool=$GNULIB_SRCDIR/gnulib-tool + <$gnulib_tool || exit $? +fi + +# Get translations. + +download_po_files() { + subdir=$1 + domain=$2 + echo "$me: getting translations into $subdir for $domain..." + cmd=$(printf "$po_download_command_format" "$subdir" "$domain") + eval "$cmd" +} + +# Mirror .po files to $po_dir/.reference and copy only the new +# or modified ones into $po_dir. Also update $po_dir/LINGUAS. +# Note po files that exist locally only are left in $po_dir but will +# not be included in LINGUAS and hence will not be distributed. +update_po_files() { + # Directory containing primary .po files. + # Overwrite them only when we're sure a .po file is new. + po_dir=$1 + domain=$2 + + # Mirror *.po files into this dir. + # Usually contains *.s1 checksum files. + ref_po_dir="$po_dir/.reference" + + test -d $ref_po_dir || mkdir $ref_po_dir || return + download_po_files $ref_po_dir $domain \ + && ls "$ref_po_dir"/*.po 2>/dev/null | + sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return + + langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g') + test "$langs" = '*' && langs=x + for po in $langs; do + case $po in x) continue;; esac + new_po="$ref_po_dir/$po.po" + cksum_file="$ref_po_dir/$po.s1" + if ! test -f "$cksum_file" || + ! test -f "$po_dir/$po.po" || + ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then + echo "$me: updated $po_dir/$po.po..." + cp "$new_po" "$po_dir/$po.po" \ + && $SHA1SUM < "$new_po" > "$cksum_file" || return + fi + done +} + +case $SKIP_PO in +'') + if test -d po; then + update_po_files po $package || exit + fi + + if test -d runtime-po; then + update_po_files runtime-po $package-runtime || exit + fi;; +esac + +version_controlled_file() { + parent=$1 + file=$2 + if test -d .git; then + git rm -n "$file" > /dev/null 2>&1 + elif test -d .svn; then + svn log -r HEAD "$file" > /dev/null 2>&1 + elif test -d CVS; then + grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null | + grep '^/[^/]*/[0-9]' > /dev/null + else + warn_ "no version control for $file?" + false + fi +} + +# NOTE: we have to be careful to run both autopoint and libtoolize +# before gnulib-tool, since gnulib-tool is likely to provide newer +# versions of files "installed" by these two programs. +# Then, *after* gnulib-tool (see below), we have to be careful to +# run autoreconf in such a way that it does not run either of these +# two just-pre-run programs. + +# Import from gettext. +with_gettext=yes +grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \ + with_gettext=no + +if test $with_gettext = yes || test $use_libtool = 1; then + + tempbase=.bootstrap$$ + trap "rm -f $tempbase.0 $tempbase.1" 1 2 13 15 + + > $tempbase.0 > $tempbase.1 && + find . ! -type d -print | sort > $tempbase.0 || exit + + if test $with_gettext = yes; then + # Released autopoint has the tendency to install macros that have been + # obsoleted in current gnulib, so run this before gnulib-tool. + echo "$0: $AUTOPOINT --force" + $AUTOPOINT --force || exit + fi + + # Autoreconf runs aclocal before libtoolize, which causes spurious + # warnings if the initial aclocal is confused by the libtoolized + # (or worse out-of-date) macro directory. + # libtoolize 1.9b added the --install option; but we support back + # to libtoolize 1.5.22, where the install action was default. + if test $use_libtool = 1; then + install= + case $($LIBTOOLIZE --help) in + *--install*) install=--install ;; + esac + echo "running: $LIBTOOLIZE $install --copy" + $LIBTOOLIZE $install --copy + fi + + find . ! -type d -print | sort >$tempbase.1 + old_IFS=$IFS + IFS=$nl + for file in $(comm -13 $tempbase.0 $tempbase.1); do + IFS=$old_IFS + parent=${file%/*} + version_controlled_file "$parent" "$file" || { + for dot_ig in x $vc_ignore; do + test $dot_ig = x && continue + ig=$parent/$dot_ig + insert_vc_ignore "$ig" "${file##*/}" + done + } + done + IFS=$old_IFS + + rm -f $tempbase.0 $tempbase.1 + trap - 1 2 13 15 +fi + +# Import from gnulib. + +if $use_gnulib; then + gnulib_tool_options="\ + --no-changelog\ + --aux-dir=$build_aux\ + --doc-base=$doc_base\ + --lib=$gnulib_name\ + --m4-base=$m4_base/\ + --source-base=$source_base/\ + --tests-base=$tests_base\ + --local-dir=$local_gl_dir\ + $gnulib_tool_option_extras\ + " + if test $use_libtool = 1; then + case "$gnulib_tool_options " in + *' --libtool '*) ;; + *) gnulib_tool_options="$gnulib_tool_options --libtool" ;; + esac + fi + echo "$0: $gnulib_tool $gnulib_tool_options --import ..." + $gnulib_tool $gnulib_tool_options --import $gnulib_modules \ + || die "gnulib-tool failed" + + for file in $gnulib_files; do + symlink_to_dir "$GNULIB_SRCDIR" $file \ + || die "failed to symlink $file" + done +fi + +bootstrap_post_import_hook \ + || die "bootstrap_post_import_hook failed" + +# Don't proceed if there are uninitialized submodules. In particular, +# the next step will remove dangling links, which might be links into +# uninitialized submodules. +# +# Uninitialized submodules are listed with an initial dash. +if $use_git && git submodule | grep '^-' >/dev/null; then + die "some git submodules are not initialized. " \ + "Run 'git submodule update --init' and bootstrap again." +fi + +# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some +# gnulib-populated directories. Such .m4 files would cause aclocal to fail. +# The following requires GNU find 4.2.3 or newer. Considering the usual +# portability constraints of this script, that may seem a very demanding +# requirement, but it should be ok. Ignore any failure, which is fine, +# since this is only a convenience to help developers avoid the relatively +# unusual case in which a symlinked-to .m4 file is git-removed from gnulib +# between successive runs of this script. +find "$m4_base" "$source_base" \ + -depth \( -name '*.m4' -o -name '*.[ch]' \) \ + -type l -xtype l -delete > /dev/null 2>&1 + +# Invoke autoreconf with --force --install to ensure upgrades of tools +# such as ylwrap. +AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS" + +# Some systems (RHEL 5) are using ancient autotools, for which the +# --no-recursive option had not been invented. Detect that lack and +# omit the option when it's not supported. FIXME in 2017: remove this +# hack when RHEL 5 autotools are updated, or when they become irrelevant. +case $($AUTORECONF --help) in + *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";; +esac + +# Tell autoreconf not to invoke autopoint or libtoolize; they were run above. +echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS" +AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \ + || die "autoreconf failed" + +# Get some extra files from gnulib, overriding existing files. +for file in $gnulib_extra_files; do + case $file in + */INSTALL) dst=INSTALL;; + build-aux/*) dst=$build_aux/${file#build-aux/};; + *) dst=$file;; + esac + symlink_to_dir "$GNULIB_SRCDIR" $file $dst \ + || die "failed to symlink $file" +done + +if test $with_gettext = yes; then + # Create gettext configuration. + echo "$0: Creating po/Makevars from po/Makevars.template ..." + rm -f po/Makevars + sed ' + /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/ + /^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/ + /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'| + /^XGETTEXT_OPTIONS *=/{ + s/$/ \\/ + a\ + '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+} + } + ' po/Makevars.template >po/Makevars \ + || die 'cannot generate po/Makevars' + + # If the 'gettext' module is in use, grab the latest Makefile.in.in. + # If only the 'gettext-h' module is in use, assume autopoint already + # put the correct version of this file into place. + case $gnulib_modules in + *gettext-h*) ;; + *gettext*) + cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \ + || die "cannot create po/Makefile.in.in" + ;; + esac + + if test -d runtime-po; then + # Similarly for runtime-po/Makevars, but not quite the same. + rm -f runtime-po/Makevars + sed ' + /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/ + /^subdir *=.*/s/=.*/= runtime-po/ + /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/ + /^XGETTEXT_OPTIONS *=/{ + s/$/ \\/ + a\ + '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+} + } + ' po/Makevars.template >runtime-po/Makevars \ + || die 'cannot generate runtime-po/Makevars' + + # Copy identical files from po to runtime-po. + (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po) + fi +fi + +bootstrap_epilogue + +echo "$0: done. Now you can run './configure'." + +# Local Variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/bootstrap.conf b/bootstrap.conf new file mode 100644 index 000000000..7a7813d28 --- /dev/null +++ b/bootstrap.conf @@ -0,0 +1,103 @@ +# Bootstrap configuration. + +# Copyright (C) 2006-2022 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +GNULIB_REVISION=9f48fb992a3d7e96610c4ce8be969cff2d61a01b + +# gnulib modules used by this package. +# mbswidth is used by fix-width.diff's changes to argp rather than directly. +gnulib_modules=" + argp + base64 + error + fnmatch + getdelim + getline + gettext-h + gitlog-to-changelog + mbswidth + progname + realloc-gnu + regex + save-cwd + stdbool +" + +gnulib_tool_option_extras="\ + --no-conditional-dependencies \ + --no-vc-files \ +" + +gnulib_name=libgnu +source_base=grub-core/lib/gnulib +gnulib_extra_files=" + build-aux/install-sh + build-aux/mdate-sh + build-aux/texinfo.tex + build-aux/depcomp + build-aux/config.guess + build-aux/config.sub +" + +# Additional xgettext options to use. Use "\\\newline" to break lines. +XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ + --from-code=UTF-8\\\ +' + +checkout_only_file= +copy=true +vc_ignore= + +SKIP_PO=t + +# Build prerequisites +buildreq="\ +autoconf 2.64 +automake 1.14 +gettext - +git 1.5.5 +patch - +tar - +" + +# bootstrap doesn't give us a reasonable way to stop Automake from +# overwriting this, so we just copy our version aside and put it back later. +cp -a INSTALL INSTALL.grub + +bootstrap_post_import_hook () { + set -e + + # Instead of patching our gnulib and therefore maintaining a fork, submit + # changes to gnulib and update the hash above when they've merged. Do not + # add new patches here. + 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 +} + +bootstrap_epilogue () { + mv INSTALL.grub INSTALL +} diff --git a/build-aux/config.rpath b/build-aux/config.rpath deleted file mode 100755 index c38b914d6..000000000 --- a/build-aux/config.rpath +++ /dev/null @@ -1,690 +0,0 @@ -#! /bin/sh -# Output a system dependent set of variables, describing how to set the -# run time search path of shared libraries in an executable. -# -# Copyright 1996-2013 Free Software Foundation, Inc. -# Taken from GNU libtool, 2001 -# Originally by Gordon Matzigkeit , 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld -# should be set by the caller. -# -# The set of defined variables is at the end of this script. - -# Known limitations: -# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer -# than 256 bytes, otherwise the compiler driver will dump core. The only -# known workaround is to choose shorter directory names for the build -# directory and/or the installation directory. - -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a -shrext=.so - -host="$1" -host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - -# Code taken from libtool.m4's _LT_CC_BASENAME. - -for cc_temp in $CC""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` - -# Code taken from libtool.m4's _LT_COMPILER_PIC. - -wl= -if test "$GCC" = yes; then - wl='-Wl,' -else - case "$host_os" in - aix*) - wl='-Wl,' - ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) - ;; - hpux9* | hpux10* | hpux11*) - wl='-Wl,' - ;; - irix5* | irix6* | nonstopux*) - wl='-Wl,' - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - ecc*) - wl='-Wl,' - ;; - icc* | ifort*) - wl='-Wl,' - ;; - lf95*) - wl='-Wl,' - ;; - nagfor*) - wl='-Wl,-Wl,,' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - wl='-Wl,' - ;; - ccc*) - wl='-Wl,' - ;; - xl* | bgxl* | bgf* | mpixl*) - wl='-Wl,' - ;; - como) - wl='-lopt=' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) - wl= - ;; - *Sun\ C*) - wl='-Wl,' - ;; - esac - ;; - esac - ;; - newsos6) - ;; - *nto* | *qnx*) - ;; - osf3* | osf4* | osf5*) - wl='-Wl,' - ;; - rdos*) - ;; - solaris*) - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - wl='-Qoption ld ' - ;; - *) - wl='-Wl,' - ;; - esac - ;; - sunos4*) - wl='-Qoption ld ' - ;; - sysv4 | sysv4.2uw2* | sysv4.3*) - wl='-Wl,' - ;; - sysv4*MP*) - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - wl='-Wl,' - ;; - unicos*) - wl='-Wl,' - ;; - uts4*) - ;; - esac -fi - -# Code taken from libtool.m4's _LT_LINKER_SHLIBS. - -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no - -case "$host_os" in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - # Unlike libtool, we use -rpath here, not --rpath, since the documented - # option of GNU ld is called -rpath, not --rpath. - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - case "$host_os" in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - fi - ;; - amigaos*) - case "$host_cpu" in - powerpc) - ;; - m68k) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - cygwin* | mingw* | pw32* | cegcc*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - haiku*) - ;; - interix[3-9]*) - hardcode_direct=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - netbsd*) - ;; - solaris*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - ;; - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' - else - ld_shlibs=no - fi - ;; - esac - ;; - sunos4*) - hardcode_direct=yes - ;; - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - esac - if test "$ld_shlibs" = no; then - hardcode_libdir_flag_spec= - fi -else - case "$host_os" in - aix3*) - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - else - aix_use_runtimelinking=no - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - fi - hardcode_direct=yes - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - fi - # Begin _LT_AC_SYS_LIBPATH_AIX. - echo 'int main () { return 0; }' > conftest.c - ${CC} ${LDFLAGS} conftest.c -o conftest - aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - fi - if test -z "$aix_libpath"; then - aix_libpath="/usr/lib:/lib" - fi - rm -f conftest.c conftest - # End _LT_AC_SYS_LIBPATH_AIX. - if test "$aix_use_runtimelinking" = yes; then - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - else - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - fi - fi - ;; - amigaos*) - case "$host_cpu" in - powerpc) - ;; - m68k) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - bsdi[45]*) - ;; - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - libext=lib - ;; - darwin* | rhapsody*) - hardcode_direct=no - if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then - : - else - ld_shlibs=no - fi - ;; - dgux*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - freebsd2.2*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - freebsd2*) - hardcode_direct=yes - hardcode_minus_L=yes - ;; - freebsd* | dragonfly*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - hpux9*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - hpux10*) - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - hpux11*) - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - ;; - *) - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - irix5* | irix6* | nonstopux*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - netbsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - newsos6) - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - *nto* | *qnx*) - ;; - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - osf3*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - osf4* | osf5*) - if test "$GCC" = yes; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - # Both cc and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - solaris*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - sunos4*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - ;; - sysv4) - case $host_vendor in - sni) - hardcode_direct=yes # is this really true??? - ;; - siemens) - hardcode_direct=no - ;; - motorola) - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - ;; - sysv4.3*) - ;; - sysv4*MP*) - if test -d /usr/nec; then - ld_shlibs=yes - fi - ;; - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - ;; - sysv5* | sco3.2v5* | sco5v6*) - hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' - hardcode_libdir_separator=':' - ;; - uts4*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - *) - ld_shlibs=no - ;; - esac -fi - -# Check dynamic linker characteristics -# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. -# Unlike libtool.m4, here we don't care about _all_ names of the library, but -# only about the one the linker finds when passed -lNAME. This is the last -# element of library_names_spec in libtool.m4, or possibly two of them if the -# linker has special search rules. -library_names_spec= # the last element of library_names_spec in libtool.m4 -libname_spec='lib$name' -case "$host_os" in - aix3*) - library_names_spec='$libname.a' - ;; - aix[4-9]*) - library_names_spec='$libname$shrext' - ;; - amigaos*) - case "$host_cpu" in - powerpc*) - library_names_spec='$libname$shrext' ;; - m68k) - library_names_spec='$libname.a' ;; - esac - ;; - beos*) - library_names_spec='$libname$shrext' - ;; - bsdi[45]*) - library_names_spec='$libname$shrext' - ;; - cygwin* | mingw* | pw32* | cegcc*) - shrext=.dll - library_names_spec='$libname.dll.a $libname.lib' - ;; - darwin* | rhapsody*) - shrext=.dylib - library_names_spec='$libname$shrext' - ;; - dgux*) - library_names_spec='$libname$shrext' - ;; - freebsd* | dragonfly*) - case "$host_os" in - freebsd[123]*) - library_names_spec='$libname$shrext$versuffix' ;; - *) - library_names_spec='$libname$shrext' ;; - esac - ;; - gnu*) - library_names_spec='$libname$shrext' - ;; - haiku*) - library_names_spec='$libname$shrext' - ;; - hpux9* | hpux10* | hpux11*) - case $host_cpu in - ia64*) - shrext=.so - ;; - hppa*64*) - shrext=.sl - ;; - *) - shrext=.sl - ;; - esac - library_names_spec='$libname$shrext' - ;; - interix[3-9]*) - library_names_spec='$libname$shrext' - ;; - irix5* | irix6* | nonstopux*) - library_names_spec='$libname$shrext' - case "$host_os" in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; - *) libsuff= shlibsuff= ;; - esac - ;; - esac - ;; - linux*oldld* | linux*aout* | linux*coff*) - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - library_names_spec='$libname$shrext' - ;; - knetbsd*-gnu) - library_names_spec='$libname$shrext' - ;; - netbsd*) - library_names_spec='$libname$shrext' - ;; - newsos6) - library_names_spec='$libname$shrext' - ;; - *nto* | *qnx*) - library_names_spec='$libname$shrext' - ;; - openbsd*) - library_names_spec='$libname$shrext$versuffix' - ;; - os2*) - libname_spec='$name' - shrext=.dll - library_names_spec='$libname.a' - ;; - osf3* | osf4* | osf5*) - library_names_spec='$libname$shrext' - ;; - rdos*) - ;; - solaris*) - library_names_spec='$libname$shrext' - ;; - sunos4*) - library_names_spec='$libname$shrext$versuffix' - ;; - sysv4 | sysv4.3*) - library_names_spec='$libname$shrext' - ;; - sysv4*MP*) - library_names_spec='$libname$shrext' - ;; - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - library_names_spec='$libname$shrext' - ;; - tpf*) - library_names_spec='$libname$shrext' - ;; - uts4*) - library_names_spec='$libname$shrext' - ;; -esac - -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' -escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` -shlibext=`echo "$shrext" | sed -e 's,^\.,,'` -escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` - -LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. - -# Written by Jim Meyering - -use strict; -use warnings; -use Getopt::Long; -use POSIX qw(strftime); - -(my $ME = $0) =~ s|.*/||; - -# use File::Coda; # http://meyering.net/code/Coda/ -END { - defined fileno STDOUT or return; - close STDOUT and return; - warn "$ME: failed to close standard output: $!\n"; - $? ||= 1; -} - -sub usage ($) -{ - my ($exit_code) = @_; - my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); - if ($exit_code != 0) - { - print $STREAM "Try '$ME --help' for more information.\n"; - } - else - { - print $STREAM < ChangeLog - $ME -- -n 5 foo > last-5-commits-to-branch-foo - -SPECIAL SYNTAX: - -The following types of strings are interpreted specially when they appear -at the beginning of a log message line. They are not copied to the output. - - Copyright-paperwork-exempt: Yes - Append the "(tiny change)" notation to the usual "date name email" - ChangeLog header to mark a change that does not require a copyright - assignment. - Co-authored-by: Joe User - List the specified name and email address on a second - ChangeLog header, denoting a co-author. - Signed-off-by: Joe User - These lines are simply elided. - -In a FILE specified via --amend, comment lines (starting with "#") are ignored. -FILE must consist of pairs where SHA is a 40-byte SHA1 (alone on -a line) referring to a commit in the current project, and CODE refers to one -or more consecutive lines of Perl code. Pairs must be separated by one or -more blank line. - -Here is sample input for use with --amend=FILE, from coreutils: - -3a169f4c5d9159283548178668d2fae6fced3030 -# fix typo in title: -s/all tile types/all file types/ - -1379ed974f1fa39b12e2ffab18b3f7a607082202 -# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself. -# Change the author to be Paul. Note the escaped "@": -s,Jim .*>,Paul Eggert , - -EOF - } - exit $exit_code; -} - -# If the string $S is a well-behaved file name, simply return it. -# If it contains white space, quotes, etc., quote it, and return the new string. -sub shell_quote($) -{ - my ($s) = @_; - if ($s =~ m![^\w+/.,-]!) - { - # Convert each single quote to '\'' - $s =~ s/\'/\'\\\'\'/g; - # Then single quote the string. - $s = "'$s'"; - } - return $s; -} - -sub quoted_cmd(@) -{ - return join (' ', map {shell_quote $_} @_); -} - -# Parse file F. -# Comment lines (starting with "#") are ignored. -# F must consist of pairs where SHA is a 40-byte SHA1 -# (alone on a line) referring to a commit in the current project, and -# CODE refers to one or more consecutive lines of Perl code. -# Pairs must be separated by one or more blank line. -sub parse_amend_file($) -{ - my ($f) = @_; - - open F, '<', $f - or die "$ME: $f: failed to open for reading: $!\n"; - - my $fail; - my $h = {}; - my $in_code = 0; - my $sha; - while (defined (my $line = )) - { - $line =~ /^\#/ - and next; - chomp $line; - $line eq '' - and $in_code = 0, next; - - if (!$in_code) - { - $line =~ /^([0-9a-fA-F]{40})$/ - or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"), - $fail = 1, next; - $sha = lc $1; - $in_code = 1; - exists $h->{$sha} - and (warn "$ME: $f:$.: duplicate SHA1\n"), - $fail = 1, next; - } - else - { - $h->{$sha} ||= ''; - $h->{$sha} .= "$line\n"; - } - } - close F; - - $fail - and exit 1; - - return $h; -} - -# git_dir_option $SRCDIR -# -# From $SRCDIR, the --git-dir option to pass to git (none if $SRCDIR -# is undef). Return as a list (0 or 1 element). -sub git_dir_option($) -{ - my ($srcdir) = @_; - my @res = (); - if (defined $srcdir) - { - my $qdir = shell_quote $srcdir; - my $cmd = "cd $qdir && git rev-parse --show-toplevel"; - my $qcmd = shell_quote $cmd; - my $git_dir = qx($cmd); - defined $git_dir - or die "$ME: cannot run $qcmd: $!\n"; - $? == 0 - or die "$ME: $qcmd had unexpected exit code or signal ($?)\n"; - chomp $git_dir; - push @res, "--git-dir=$git_dir/.git"; - } - @res; -} - -{ - my $since_date; - my $format_string = '%s%n%b%n'; - my $amend_file; - my $append_dot = 0; - my $cluster = 1; - my $strip_tab = 0; - my $strip_cherry_pick = 0; - my $srcdir; - GetOptions - ( - help => sub { usage 0 }, - version => sub { print "$ME version $VERSION\n"; exit }, - 'since=s' => \$since_date, - 'format=s' => \$format_string, - 'amend=s' => \$amend_file, - 'append-dot' => \$append_dot, - 'cluster!' => \$cluster, - 'strip-tab' => \$strip_tab, - 'strip-cherry-pick' => \$strip_cherry_pick, - 'srcdir=s' => \$srcdir, - ) or usage 1; - - defined $since_date - and unshift @ARGV, "--since=$since_date"; - - # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/) - # that makes a correction in the log or attribution of that commit. - my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {}; - - my @cmd = ('git', - git_dir_option $srcdir, - qw(log --log-size), - '--pretty=format:%H:%ct %an <%ae>%n%n'.$format_string, @ARGV); - open PIPE, '-|', @cmd - or die ("$ME: failed to run '". quoted_cmd (@cmd) ."': $!\n" - . "(Is your Git too old? Version 1.5.1 or later is required.)\n"); - - my $prev_multi_paragraph; - my $prev_date_line = ''; - my @prev_coauthors = (); - while (1) - { - defined (my $in = ) - or last; - $in =~ /^log size (\d+)$/ - or die "$ME:$.: Invalid line (expected log size):\n$in"; - my $log_nbytes = $1; - - my $log; - my $n_read = read PIPE, $log, $log_nbytes; - $n_read == $log_nbytes - or die "$ME:$.: unexpected EOF\n"; - - # Extract leading hash. - my ($sha, $rest) = split ':', $log, 2; - defined $sha - or die "$ME:$.: malformed log entry\n"; - $sha =~ /^[0-9a-fA-F]{40}$/ - or die "$ME:$.: invalid SHA1: $sha\n"; - - # If this commit's log requires any transformation, do it now. - my $code = $amend_code->{$sha}; - if (defined $code) - { - eval 'use Safe'; - my $s = new Safe; - # Put the unpreprocessed entry into "$_". - $_ = $rest; - - # Let $code operate on it, safely. - my $r = $s->reval("$code") - or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n"; - - # Note that we've used this entry. - delete $amend_code->{$sha}; - - # Update $rest upon success. - $rest = $_; - } - - # Remove lines inserted by "git cherry-pick". - if ($strip_cherry_pick) - { - $rest =~ s/^\s*Conflicts:\n.*//sm; - $rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m; - } - - my @line = split "\n", $rest; - my $author_line = shift @line; - defined $author_line - or die "$ME:$.: unexpected EOF\n"; - $author_line =~ /^(\d+) (.*>)$/ - or die "$ME:$.: Invalid line " - . "(expected date/author/email):\n$author_line\n"; - - # Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog - # `(tiny change)' annotation. - my $tiny = (grep (/^Copyright-paperwork-exempt:\s+[Yy]es$/, @line) - ? ' (tiny change)' : ''); - - my $date_line = sprintf "%s %s$tiny\n", - strftime ("%F", localtime ($1)), $2; - - my @coauthors = grep /^Co-authored-by:.*$/, @line; - # Omit meta-data lines we've already interpreted. - @line = grep !/^(?:Signed-off-by:[ ].*>$ - |Co-authored-by:[ ] - |Copyright-paperwork-exempt:[ ] - )/x, @line; - - # Remove leading and trailing blank lines. - if (@line) - { - while ($line[0] =~ /^\s*$/) { shift @line; } - while ($line[$#line] =~ /^\s*$/) { pop @line; } - } - - # Record whether there are two or more paragraphs. - my $multi_paragraph = grep /^\s*$/, @line; - - # Format 'Co-authored-by: A U Thor ' lines in - # standard multi-author ChangeLog format. - for (@coauthors) - { - s/^Co-authored-by:\s*/\t /; - s/\s*/ - or warn "$ME: warning: missing email address for " - . substr ($_, 5) . "\n"; - } - - # If clustering of commit messages has been disabled, if this header - # would be different from the previous date/name/email/coauthors header, - # or if this or the previous entry consists of two or more paragraphs, - # then print the header. - if ( ! $cluster - || $date_line ne $prev_date_line - || "@coauthors" ne "@prev_coauthors" - || $multi_paragraph - || $prev_multi_paragraph) - { - $prev_date_line eq '' - or print "\n"; - print $date_line; - @coauthors - and print join ("\n", @coauthors), "\n"; - } - $prev_date_line = $date_line; - @prev_coauthors = @coauthors; - $prev_multi_paragraph = $multi_paragraph; - - # If there were any lines - if (@line == 0) - { - warn "$ME: warning: empty commit message:\n $date_line\n"; - } - else - { - if ($append_dot) - { - # If the first line of the message has enough room, then - if (length $line[0] < 72) - { - # append a dot if there is no other punctuation or blank - # at the end. - $line[0] =~ /[[:punct:]\s]$/ - or $line[0] .= '.'; - } - } - - # Remove one additional leading TAB from each line. - $strip_tab - and map { s/^\t// } @line; - - # Prefix each non-empty line with a TAB. - @line = map { length $_ ? "\t$_" : '' } @line; - - print "\n", join ("\n", @line), "\n"; - } - - defined ($in = ) - or last; - $in ne "\n" - and die "$ME:$.: unexpected line:\n$in"; - } - - close PIPE - or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; - # FIXME-someday: include $PROCESS_STATUS in the diagnostic - - # Complain about any unused entry in the --amend=F specified file. - my $fail = 0; - foreach my $sha (keys %$amend_code) - { - warn "$ME:$amend_file: unused entry: $sha\n"; - $fail = 1; - } - - exit $fail; -} - -# Local Variables: -# mode: perl -# indent-tabs-mode: nil -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "my $VERSION = '" -# time-stamp-format: "%:y-%02m-%02d %02H:%02M" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "'; # UTC" -# End: diff --git a/build-aux/snippet/_Noreturn.h b/build-aux/snippet/_Noreturn.h deleted file mode 100644 index c44ad89b7..000000000 --- a/build-aux/snippet/_Noreturn.h +++ /dev/null @@ -1,10 +0,0 @@ -#if !defined _Noreturn && __STDC_VERSION__ < 201112 -# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ - || 0x5110 <= __SUNPRO_C) -# define _Noreturn __attribute__ ((__noreturn__)) -# elif 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn -# endif -#endif diff --git a/build-aux/snippet/arg-nonnull.h b/build-aux/snippet/arg-nonnull.h deleted file mode 100644 index 8ea2a4747..000000000 --- a/build-aux/snippet/arg-nonnull.h +++ /dev/null @@ -1,26 +0,0 @@ -/* A C macro for declaring that specific arguments must not be NULL. - Copyright (C) 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools - that the values passed as arguments n, ..., m must be non-NULL pointers. - n = 1 stands for the first argument, n = 2 for the second argument etc. */ -#ifndef _GL_ARG_NONNULL -# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 -# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) -# else -# define _GL_ARG_NONNULL(params) -# endif -#endif diff --git a/build-aux/snippet/c++defs.h b/build-aux/snippet/c++defs.h deleted file mode 100644 index b35b933cd..000000000 --- a/build-aux/snippet/c++defs.h +++ /dev/null @@ -1,271 +0,0 @@ -/* C++ compatible function declaration macros. - Copyright (C) 2010-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _GL_CXXDEFS_H -#define _GL_CXXDEFS_H - -/* The three most frequent use cases of these macros are: - - * For providing a substitute for a function that is missing on some - platforms, but is declared and works fine on the platforms on which - it exists: - - #if @GNULIB_FOO@ - # if !@HAVE_FOO@ - _GL_FUNCDECL_SYS (foo, ...); - # endif - _GL_CXXALIAS_SYS (foo, ...); - _GL_CXXALIASWARN (foo); - #elif defined GNULIB_POSIXCHECK - ... - #endif - - * For providing a replacement for a function that exists on all platforms, - but is broken/insufficient and needs to be replaced on some platforms: - - #if @GNULIB_FOO@ - # if @REPLACE_FOO@ - # if !(defined __cplusplus && defined GNULIB_NAMESPACE) - # undef foo - # define foo rpl_foo - # endif - _GL_FUNCDECL_RPL (foo, ...); - _GL_CXXALIAS_RPL (foo, ...); - # else - _GL_CXXALIAS_SYS (foo, ...); - # endif - _GL_CXXALIASWARN (foo); - #elif defined GNULIB_POSIXCHECK - ... - #endif - - * For providing a replacement for a function that exists on some platforms - but is broken/insufficient and needs to be replaced on some of them and - is additionally either missing or undeclared on some other platforms: - - #if @GNULIB_FOO@ - # if @REPLACE_FOO@ - # if !(defined __cplusplus && defined GNULIB_NAMESPACE) - # undef foo - # define foo rpl_foo - # endif - _GL_FUNCDECL_RPL (foo, ...); - _GL_CXXALIAS_RPL (foo, ...); - # else - # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ - _GL_FUNCDECL_SYS (foo, ...); - # endif - _GL_CXXALIAS_SYS (foo, ...); - # endif - _GL_CXXALIASWARN (foo); - #elif defined GNULIB_POSIXCHECK - ... - #endif -*/ - -/* _GL_EXTERN_C declaration; - performs the declaration with C linkage. */ -#if defined __cplusplus -# define _GL_EXTERN_C extern "C" -#else -# define _GL_EXTERN_C extern -#endif - -/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); - declares a replacement function, named rpl_func, with the given prototype, - consisting of return type, parameters, and attributes. - Example: - _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) - _GL_ARG_NONNULL ((1))); - */ -#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ - _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) -#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ - _GL_EXTERN_C rettype rpl_func parameters_and_attributes - -/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); - declares the system function, named func, with the given prototype, - consisting of return type, parameters, and attributes. - Example: - _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) - _GL_ARG_NONNULL ((1))); - */ -#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ - _GL_EXTERN_C rettype func parameters_and_attributes - -/* _GL_CXXALIAS_RPL (func, rettype, parameters); - declares a C++ alias called GNULIB_NAMESPACE::func - that redirects to rpl_func, if GNULIB_NAMESPACE is defined. - Example: - _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); - */ -#define _GL_CXXALIAS_RPL(func,rettype,parameters) \ - _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - rettype (*const func) parameters = ::rpl_func; \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); - is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); - except that the C function rpl_func may have a slightly different - declaration. A cast is used to silence the "invalid conversion" error - that would otherwise occur. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - rettype (*const func) parameters = \ - reinterpret_cast(::rpl_func); \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_SYS (func, rettype, parameters); - declares a C++ alias called GNULIB_NAMESPACE::func - that redirects to the system provided function func, if GNULIB_NAMESPACE - is defined. - Example: - _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); - */ -#if defined __cplusplus && defined GNULIB_NAMESPACE - /* If we were to write - rettype (*const func) parameters = ::func; - like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls - better (remove an indirection through a 'static' pointer variable), - but then the _GL_CXXALIASWARN macro below would cause a warning not only - for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */ -# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - static rettype (*func) parameters = ::func; \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); - is like _GL_CXXALIAS_SYS (func, rettype, parameters); - except that the C function func may have a slightly different declaration. - A cast is used to silence the "invalid conversion" error that would - otherwise occur. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ - namespace GNULIB_NAMESPACE \ - { \ - static rettype (*func) parameters = \ - reinterpret_cast(::func); \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); - is like _GL_CXXALIAS_SYS (func, rettype, parameters); - except that the C function is picked among a set of overloaded functions, - namely the one with rettype2 and parameters2. Two consecutive casts - are used to silence the "cannot find a match" and "invalid conversion" - errors that would otherwise occur. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE - /* The outer cast must be a reinterpret_cast. - The inner cast: When the function is defined as a set of overloaded - functions, it works as a static_cast<>, choosing the designated variant. - When the function is defined as a single variant, it works as a - reinterpret_cast<>. The parenthesized cast syntax works both ways. */ -# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ - namespace GNULIB_NAMESPACE \ - { \ - static rettype (*func) parameters = \ - reinterpret_cast( \ - (rettype2(*)parameters2)(::func)); \ - } \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#else -# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIASWARN (func); - causes a warning to be emitted when ::func is used but not when - GNULIB_NAMESPACE::func is used. func must be defined without overloaded - variants. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIASWARN(func) \ - _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) -# define _GL_CXXALIASWARN_1(func,namespace) \ - _GL_CXXALIASWARN_2 (func, namespace) -/* To work around GCC bug , - we enable the warning only when not optimizing. */ -# if !__OPTIMIZE__ -# define _GL_CXXALIASWARN_2(func,namespace) \ - _GL_WARN_ON_USE (func, \ - "The symbol ::" #func " refers to the system function. " \ - "Use " #namespace "::" #func " instead.") -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -# define _GL_CXXALIASWARN_2(func,namespace) \ - extern __typeof__ (func) func -# else -# define _GL_CXXALIASWARN_2(func,namespace) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -# endif -#else -# define _GL_CXXALIASWARN(func) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); - causes a warning to be emitted when the given overloaded variant of ::func - is used but not when GNULIB_NAMESPACE::func is used. */ -#if defined __cplusplus && defined GNULIB_NAMESPACE -# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ - _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ - GNULIB_NAMESPACE) -# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ - _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) -/* To work around GCC bug , - we enable the warning only when not optimizing. */ -# if !__OPTIMIZE__ -# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ - "The symbol ::" #func " refers to the system function. " \ - "Use " #namespace "::" #func " instead.") -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - extern __typeof__ (func) func -# else -# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -# endif -#else -# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ - _GL_EXTERN_C int _gl_cxxalias_dummy -#endif - -#endif /* _GL_CXXDEFS_H */ diff --git a/build-aux/snippet/warn-on-use.h b/build-aux/snippet/warn-on-use.h deleted file mode 100644 index 1736a1bd7..000000000 --- a/build-aux/snippet/warn-on-use.h +++ /dev/null @@ -1,109 +0,0 @@ -/* A C macro for emitting warnings if a function is used. - Copyright (C) 2010-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* _GL_WARN_ON_USE (function, "literal string") issues a declaration - for FUNCTION which will then trigger a compiler warning containing - the text of "literal string" anywhere that function is called, if - supported by the compiler. If the compiler does not support this - feature, the macro expands to an unused extern declaration. - - This macro is useful for marking a function as a potential - portability trap, with the intent that "literal string" include - instructions on the replacement function that should be used - instead. However, one of the reasons that a function is a - portability trap is if it has the wrong signature. Declaring - FUNCTION with a different signature in C is a compilation error, so - this macro must use the same type as any existing declaration so - that programs that avoid the problematic FUNCTION do not fail to - compile merely because they included a header that poisoned the - function. But this implies that _GL_WARN_ON_USE is only safe to - use if FUNCTION is known to already have a declaration. Use of - this macro implies that there must not be any other macro hiding - the declaration of FUNCTION; but undefining FUNCTION first is part - of the poisoning process anyway (although for symbols that are - provided only via a macro, the result is a compilation error rather - than a warning containing "literal string"). Also note that in - C++, it is only safe to use if FUNCTION has no overloads. - - For an example, it is possible to poison 'getline' by: - - adding a call to gl_WARN_ON_USE_PREPARE([[#include ]], - [getline]) in configure.ac, which potentially defines - HAVE_RAW_DECL_GETLINE - - adding this code to a header that wraps the system : - #undef getline - #if HAVE_RAW_DECL_GETLINE - _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" - "not universally present; use the gnulib module getline"); - #endif - - It is not possible to directly poison global variables. But it is - possible to write a wrapper accessor function, and poison that - (less common usage, like &environ, will cause a compilation error - rather than issue the nice warning, but the end result of informing - the developer about their portability problem is still achieved): - #if HAVE_RAW_DECL_ENVIRON - static char ***rpl_environ (void) { return &environ; } - _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); - # undef environ - # define environ (*rpl_environ ()) - #endif - */ -#ifndef _GL_WARN_ON_USE - -# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) -/* A compiler attribute is available in gcc versions 4.3.0 and later. */ -# define _GL_WARN_ON_USE(function, message) \ -extern __typeof__ (function) function __attribute__ ((__warning__ (message))) -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -/* Verify the existence of the function. */ -# define _GL_WARN_ON_USE(function, message) \ -extern __typeof__ (function) function -# else /* Unsupported. */ -# define _GL_WARN_ON_USE(function, message) \ -_GL_WARN_EXTERN_C int _gl_warn_on_use -# endif -#endif - -/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") - is like _GL_WARN_ON_USE (function, "string"), except that the function is - declared with the given prototype, consisting of return type, parameters, - and attributes. - This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does - not work in this case. */ -#ifndef _GL_WARN_ON_USE_CXX -# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes \ - __attribute__ ((__warning__ (msg))) -# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING -/* Verify the existence of the function. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes -# else /* Unsupported. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -_GL_WARN_EXTERN_C int _gl_warn_on_use -# endif -#endif - -/* _GL_WARN_EXTERN_C declaration; - performs the declaration with C linkage. */ -#ifndef _GL_WARN_EXTERN_C -# if defined __cplusplus -# define _GL_WARN_EXTERN_C extern "C" -# else -# define _GL_WARN_EXTERN_C extern -# endif -#endif diff --git a/conf/Makefile.common b/conf/Makefile.common index 11296b550..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,8 +75,8 @@ 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 -CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib +CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-error=attributes +CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib CFLAGS_POSIX = -fno-builtin CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap @@ -84,11 +94,15 @@ CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)' CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_lockdown(...)=COMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd_lockdown(...)=EXTCOMMAND_LOCKDOWN_LIST_MARKER(__VA_ARGS__)' CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)' +CPPFLAGS_FDT_LIST := '-Dgrub_fdtbus_register(...)=FDT_DRIVER_LIST_MARKER(__VA_ARGS__)' CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \ $(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \ - $(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST) + $(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST) \ + $(CPPFLAGS_FDT_LIST) # Define these variables to calm down automake @@ -97,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 = @@ -126,11 +142,11 @@ BUILT_SOURCES = .PRECIOUS: $(top_srcdir)/Makefile.util.am $(top_srcdir)/Makefile.util.am: $(top_srcdir)/gentpl.py $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def - python $^ > $@.new || (rm -f $@.new; exit 1) + $(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1) mv $@.new $@ .PRECIOUS: $(top_srcdir)/grub-core/Makefile.core.am $(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/gentpl.py $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def - if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./autogen.sh manually." >&2; exit 1; fi - python $^ > $@.new || (rm -f $@.new; exit 1) + if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./bootstrap manually." >&2; exit 1; fi + $(PYTHON) $^ > $@.new || (rm -f $@.new; exit 1) mv $@.new $@ diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index b16bd9253..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,10 +29,7 @@ EXTRA_DIST += grub-core/gensymlist.sh EXTRA_DIST += grub-core/genemuinit.sh EXTRA_DIST += grub-core/genemuinitheader.sh -EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff -EXTRA_DIST += grub-core/gnulib-fix-width.diff -EXTRA_DIST += grub-core/gnulib-no-abort.diff -EXTRA_DIST += grub-core/gnulib-no-gets.diff +EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch EXTRA_DIST += grub-core/lib/libgcrypt EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic @@ -111,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 acf94b056..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.02~rc2],[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 @@ -45,10 +53,14 @@ save_program_prefix="${program_prefix}" AC_CANONICAL_TARGET program_prefix="${save_program_prefix}" -AM_INIT_AUTOMAKE([1.10.1]) -AC_PREREQ(2.60) +AM_INIT_AUTOMAKE([1.11]) +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. +PKG_PROG_PKG_CONFIG # Program name transformations AC_ARG_PROGRAM @@ -64,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]) @@ -71,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" @@ -94,12 +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 - ;; + 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). @@ -123,6 +146,9 @@ 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 ;; *) AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities]) platform=none @@ -147,6 +173,7 @@ case "$target_cpu"-"$platform" in i386-efi) ;; x86_64-efi) ;; i386-xen) ;; + i386-xen_pvh) ;; x86_64-xen) ;; i386-pc) ;; i386-multiboot) ;; @@ -167,8 +194,12 @@ case "$target_cpu"-"$platform" in mipsel-fuloong) platform=loongson ;; mipsel-loongson) ;; arm-uboot) ;; + arm-coreboot) ;; arm-efi) ;; arm64-efi) ;; + loongarch64-efi) ;; + riscv32-efi) ;; + riscv64-efi) ;; *-emu) ;; *-none) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; @@ -203,7 +234,8 @@ case "$host_os" in esac case "$host_os" in - cygwin | windows* | mingw32*) have_exec=n ;; + cygwin) have_exec=y ;; + windows* | mingw32*) have_exec=n ;; aros*) have_exec=n ;; *) have_exec=y;; esac @@ -213,6 +245,7 @@ case "$platform" in multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;; efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;; xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;; + xen_pvh) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN_PVH=1" ;; ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;; uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;; qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;; @@ -220,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,`" @@ -275,7 +308,7 @@ fi AC_SUBST(bootdirname) AC_DEFINE_UNQUOTED(GRUB_BOOT_DIR_NAME, "$bootdirname", - [Default boot directory name]") + [Default boot directory name]) AC_ARG_WITH([grubdir], AS_HELP_STRING([--with-grubdir=DIR], @@ -306,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 @@ -335,16 +368,22 @@ gl_EARLY AC_PROG_CXX AM_PROG_CC_C_O AM_PROG_AS +AM_PATH_PYTHON([2.6]) # Must be GCC. 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 @@ -373,7 +412,10 @@ case "$host_os" in ;; *) AC_CHECK_SIZEOF(off_t) - test x"$ac_cv_sizeof_off_t" = x8 || AC_MSG_ERROR([Large file support is required]);; + if test x"$ac_cv_sizeof_off_t" != x8 ; then + AC_CHECK_SIZEOF(off64_t) + test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required]) + fi;; esac if test x$USE_NLS = xno; then @@ -387,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 @@ -456,6 +498,16 @@ case "$build_os" in esac AC_SUBST(BUILD_EXEEXT) +# In some build environments like termux /bin/sh is not a valid +# shebang. Use $SHELL instead if it's executable and /bin/sh isn't +BUILD_SHEBANG=/bin/sh +for she in /bin/sh "$SHELL"; do + if test -x "$she" ; then + BUILD_SHEBANG="$she" + fi +done +AC_SUBST(BUILD_SHEBANG) + # For gnulib. gl_INIT @@ -529,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" @@ -717,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 @@ -751,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([[]], [[]])], @@ -763,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 @@ -794,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) @@ -806,11 +950,34 @@ if test x"$platform" != xemu ; then AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], []) fi + if test "x$target_cpu" = xriscv32; then + CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], []) + # ISA spec version 20191213 factored out extensions Zicsr and Zifencei + CFLAGS="$TARGET_CFLAGS -march=rv32imac_zicsr_zifencei -mabi=ilp32 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv32imac_zicsr_zifencei -mabi=ilp32"], []) + fi + if test "x$target_cpu" = xriscv64; then + CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], []) + # ISA spec version 20191213 factored out extensions Zicsr and Zifencei + CFLAGS="$TARGET_CFLAGS -march=rv64imac_zicsr_zifencei -mabi=lp64 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv64imac_zicsr_zifencei -mabi=lp64"], []) + fi if test "x$target_cpu" = xia64; then CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], []) fi + if test "x$target_cpu" = xsh4; then + CFLAGS="$TARGET_CFLAGS -m4-nofpu -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-m4-nofpu"], []) + fi for cand in "-msoft-float -Xclang -msoft-float -Xclang -no-implicit-float" \ "-Xclang -msoft-float -Xclang -no-implicit-float" \ "-Xclang -msoft-float" "-msoft-float"; do @@ -890,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 @@ -956,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" @@ -1034,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 @@ -1121,7 +1312,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC) LDFLAGS="$TARGET_LDFLAGS" -if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then +if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then # Use large model to support 4G memory AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [ CFLAGS="$TARGET_CFLAGS -mcmodel=large" @@ -1131,7 +1322,7 @@ if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then ]) if test "x$grub_cv_cc_mcmodel" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" - elif test "$target_cpu" = sparc64; then + elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany" fi fi @@ -1155,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 @@ -1185,12 +1377,12 @@ if test "x$target_cpu" = xarm; then fi AC_CACHE_CHECK([whether option -Qn works], grub_cv_target_cc_qn, [ - CFLAGS="$TARGET_CFLAGS -Qn -Werror" + CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments -Werror" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [grub_cv_target_cc_qn=yes], [grub_cv_target_cc_qn=no])]) if test "x$grub_cv_target_cc_qn" = xyes; then - TARGET_CFLAGS="$TARGET_CFLAGS -Qn" + TARGET_CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments" fi # @@ -1208,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 @@ -1242,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" @@ -1294,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 @@ -1325,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 @@ -1352,7 +1586,7 @@ AC_SUBST(TARGET_NMFLAGS_DEFINED_ONLY) if test "$platform" != emu; then AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [ SAVED_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" + CPPFLAGS="$TARGET_CPPFLAGS -nostdlib -nostdinc -isystem `$TARGET_CC -print-file-name=include`" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include int va_arg_func (int fixed, va_list args);]], [[]])], @@ -1361,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], [ @@ -1392,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], @@ -1418,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)])]) @@ -1427,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], @@ -1493,42 +1759,36 @@ if test x"$enable_grub_mkfont" = xno ; then grub_mkfont_excuse="explicitly disabled" fi -if test x"$grub_mkfont_excuse" = x ; then - # Check for freetype libraries. - AC_CHECK_TOOLS([FREETYPE], [freetype-config]) - if test "x$FREETYPE" = x ; then - grub_mkfont_excuse=["need freetype2 library"] - fi -fi - unset ac_cv_header_ft2build_h if test x"$grub_mkfont_excuse" = x ; then # Check for freetype libraries. - freetype_cflags=`$FREETYPE --cflags` - freetype_libs=`$FREETYPE --libs` - SAVED_CPPFLAGS="$CPPFLAGS" - SAVED_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $freetype_cflags" - LIBS="$LIBS $freetype_libs" - AC_CHECK_HEADERS([ft2build.h], [], - [grub_mkfont_excuse=["need freetype2 headers"]]) - AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], [grub_mkfont_excuse=["freetype2 library unusable"]]) - CPPFLAGS="$SAVED_CPPFLAGS" - LIBS="$SAVED_LIBS" + PKG_CHECK_MODULES([FREETYPE], [freetype2], [ + SAVED_CPPFLAGS="$CPPFLAGS" + SAVED_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS" + LIBS="$LIBS $FREETYPE_LIBS" + AC_CHECK_HEADERS([ft2build.h], [], + [grub_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], + [grub_mkfont_excuse=["freetype2 library unusable"]]) + CPPFLAGS="$SAVED_CPPFLAGS" + LIBS="$SAVED_LIBS" + ], [grub_mkfont_excuse=["need freetype2 library"]]) + if test x"$grub_mkfont_excuse" = x && test x"$host_kernel" = xnetbsd ; then + FREETYPE_LIBS="$FREETYPE_LIBS -Wl,-R,/usr/pkg/lib" ; + fi 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]) -AC_SUBST([freetype_cflags]) -AC_SUBST([freetype_libs]) SAVED_CC="$CC" SAVED_CPP="$CPP" @@ -1539,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 @@ -1558,25 +1818,26 @@ AC_SUBST([BUILD_WORDS_BIGENDIAN]) if test x"$grub_build_mkfont_excuse" = x ; then # Check for freetype libraries. - AC_CHECK_PROGS([BUILD_FREETYPE], [freetype-config]) - if test "x$BUILD_FREETYPE" = x ; then - grub_build_mkfont_excuse=["need freetype2 library"] + SAVED_PKG_CONFIG="$PKG_CONFIG" + test -z "$BUILD_PKG_CONFIG" || PKG_CONFIG="$BUILD_PKG_CONFIG" + PKG_CHECK_MODULES([BUILD_FREETYPE], [freetype2], [ + SAVED_CPPFLAGS_2="$CPPFLAGS" + SAVED_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $BUILD_FREETYPE_CFLAGS" + LIBS="$LIBS $BUILD_FREETYPE_LIBS" + AC_CHECK_HEADERS([ft2build.h], [], + [grub_build_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], + [grub_build_mkfont_excuse=["freetype2 library unusable"]]) + LIBS="$SAVED_LIBS" + CPPFLAGS="$SAVED_CPPFLAGS_2" + ], [grub_build_mkfont_excuse=["need freetype2 library"]]) + if test x"$grub_build_mkfont_excuse" = x ; then + case x"$build_os" in + xnetbsd*) BUILD_FREETYPE_LIBS="$BUILD_FREETYPE_LIBS -Wl,-R,/usr/pkg/lib" ;; + esac fi -fi - -if test x"$grub_build_mkfont_excuse" = x ; then - # Check for freetype libraries. - build_freetype_cflags=`$BUILD_FREETYPE --cflags` - build_freetype_libs=`$BUILD_FREETYPE --libs` - SAVED_CPPFLAGS_2="$CPPFLAGS" - SAVED_LIBS="$LIBS" - CPPFLAGS="$CPPFLAGS $build_freetype_cflags" - LIBS="$LIBS $build_freetype_libs" - AC_CHECK_HEADERS([ft2build.h], [], - [grub_build_mkfont_excuse=["need freetype2 headers"]]) - AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], [grub_build_mkfont_excuse=["freetype2 library unusable"]]) - LIBS="$SAVED_LIBS" - CPPFLAGS="$SAVED_CPPFLAGS_2" + PKG_CONFIG="$SAVED_PKG_CONFIG" fi if test x"$enable_build_grub_mkfont" = xyes && test x"$grub_build_mkfont_excuse" != x ; then @@ -1595,9 +1856,6 @@ if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || tes fi fi -AC_SUBST([build_freetype_cflags]) -AC_SUBST([build_freetype_libs]) - CC="$SAVED_CC" CPP="$SAVED_CPP" CFLAGS="$SAVED_CFLAGS" @@ -1605,8 +1863,6 @@ CPPFLAGS="$SAVED_CPPFLAGS" LDFLAGS="$SAVED_LDFLAGS" -DJVU_FONT_SOURCE= - starfield_excuse= AC_ARG_ENABLE([grub-themes], @@ -1620,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 @@ -1641,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= @@ -1684,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 @@ -1798,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 @@ -1809,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]) @@ -1837,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" @@ -1884,30 +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_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_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_x86_64_xen], [test x$target_cpu = xx86_64 -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_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_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_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]) @@ -1918,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 @@ -1939,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}" @@ -1982,7 +2295,7 @@ fi AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([grub-core/Makefile]) -AC_CONFIG_FILES([grub-core/gnulib/Makefile]) +AC_CONFIG_FILES([grub-core/lib/gnulib/Makefile]) AC_CONFIG_FILES([po/Makefile.in]) AC_CONFIG_FILES([docs/Makefile]) AC_CONFIG_FILES([util/bash-completion.d/Makefile]) @@ -1995,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 @@ -2043,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 @@ -2070,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 a9f4de631..f4367f895 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -77,6 +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:: @@ -84,6 +87,8 @@ This edition documents version @value{VERSION}. * Video Subsystem:: * PFF2 Font File Format:: * Graphical Menu Software Design:: +* Verifiers framework:: +* Lockdown framework:: * Copying This Manual:: Copying This Manual * Index:: @end menu @@ -92,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 @@ -181,38 +186,44 @@ If a macro is global, its name must be prefixed with GRUB_ and must consist of o @section Comments All comments shall be C-style comments, of the form @samp{/* @dots{} */}. - -Comments shall be placed only on a line by themselves. They shall not be placed together with code, variable declarations, or other non-comment entities. A comment should be placed immediately preceding the entity it describes. +A comment can be placed immediately preceding the entity it describes or it +can be placed together with code, variable declarations, or other non-comment +entities. However, it is recommended to not mix various forms especially in +types/structs descriptions. Acceptable: @example -/* The page # that is the front buffer. */ +/* The page # that is the front buffer. */ int displayed_page; -/* The page # that is the back buffer. */ -int render_page; @end example -Unacceptable: @example -int displayed_page; /* The page # that is the front buffer. */ -int render_page; /* The page # that is the back buffer. */ +int render_page; /* The page # that is the back buffer. */ @end example @node Multi-Line Comments @section Multi-Line Comments -Comments spanning multiple lines shall be formatted with all lines after the first aligned with the first line. - -Asterisk characters should not be repeated a the start of each subsequent line. +Comments spanning multiple lines shall be formatted with all lines after the +first aligned with the first line. Asterisk characters should be repeated at +the start of each subsequent line. Acceptable: @example -/* This is a comment - which spans multiple lines. - It is long. */ +/* + * This is a comment + * which spans multiple lines. + * It is long. + */ @end example Unacceptable: +@example +/* This is a comment + which spans multiple lines. + It is long. */ +@end example + @example /* * This is a comment @@ -220,7 +231,16 @@ Unacceptable: * It is long. */ @end example -The opening @samp{/*} and closing @samp{*/} should be placed together on a line with text. +@example +/* This is a comment + * which spans multiple lines. + * It is long. + */ +@end example + +In particular first unacceptable form makes comment difficult to distinguish +from the code itself. Especially if it contains the code snippets and/or is +long. So, its usage is disallowed. @node Finding your way around @chapter Finding your way around @@ -327,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 @@ -442,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: @@ -465,6 +485,380 @@ If your intention is to just get started, please do not submit a inclusion request. Instead, please subscribe to the mailing list, and communicate first (e.g. sending a patch, asking a question, commenting on another message...). +@node Setting up and running test suite +@chapter Setting up and running test suite + +GRUB is basically a tiny operating system with read support for many file +systems and which has been ported to a variety of architectures. As such, its +test suite has quite a few dependencies required to fully run the suite. +These dependencies are currently documented in the +@uref{https://git.savannah.gnu.org/cgit/grub.git/tree/INSTALL, INSTALL} +file in the source repository. Once installed, the test suite can be started +by running the @command{make check} command from the GRUB build directory. + +@node Updating External Code +@chapter Updating external code + +GRUB includes some code from other projects, and it is sometimes necessary +to update it. + +@menu +* Gnulib:: +* jsmn:: +* minilzo:: +* libtasn1:: +@end menu + +@node Gnulib +@section Gnulib + +Gnulib is a source code library that provides basic functionality to +programs and libraries. Many software packages make use of Gnulib +to avoid reinventing the portability wheel. + +GRUB imports Gnulib using its @command{bootstrap} utility, identifying a +particular Git commit in @file{bootstrap.conf}. To upgrade to a new Gnulib +commit, set @code{GNULIB_REVISION} in @file{bootstrap.conf} to the new commit +ID, then run @kbd{./bootstrap} and whatever else you need to make sure it +works. Check for changes to Gnulib's @file{NEWS} file between the old and new +commits; in some cases it will be necessary to adjust GRUB to match. You may +also need to update the patches in @file{grub-core/lib/gnulib-patches/}. + +To add a new Gnulib module or remove one that is no longer needed, change +@code{gnulib_modules} in @file{bootstrap.conf}. Again, run @kbd{./bootstrap} +and whatever else you need to make sure it works. + +Bootstrapping from an older distribution containing gettext version < 0.18.3, +will require a patch similar to this to be applied first before running the +@command{./bootstrap} utility: + +@example +diff --git a/bootstrap.conf b/bootstrap.conf +index 988dda0..a3193a9 100644 +--- a/bootstrap.conf ++++ b/bootstrap.conf +@@ -67,7 +67,7 @@ SKIP_PO=t +buildreq="\ +autoconf 2.63 +automake 1.11 +-gettext 0.18.3 ++gettext 0.17 +git 1.5.5 +tar - +" +diff --git a/configure.ac b/configure.ac +index 08b518f..99f5b36 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -362,7 +362,7 @@ AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no) + +AC_GNU_SOURCE +AM_GNU_GETTEXT([external]) +-AM_GNU_GETTEXT_VERSION([0.18.3]) ++AM_GNU_GETTEXT_VERSION([0.17]) +AC_SYS_LARGEFILE + +# Identify characteristics of the host architecture. + +@end example + +It will also be necessary to adjust the patches in +@file{po/gettext-patches/} to apply to an older version of gettext. + +@node jsmn +@section jsmn + +jsmn is a minimalistic JSON parser which is implemented in a single header file +@file{jsmn.h}. To import a different version of the jsmn parser, you may simply +download the @file{jsmn.h} header from the desired tag or commit to the target +directory: + +@example +curl -L https://raw.githubusercontent.com/zserge/jsmn/v1.1.0/jsmn.h \ + -o grub-core/lib/json/jsmn.h +@end example + +@node minilzo +@section minilzo + +miniLZO is a very lightweight subset of the LZO library intended for easy +inclusion in other projects. It is generated automatically from the LZO +source code and contains the most important LZO functions. + +To upgrade to a new version of the miniLZO library, download the release +tarball and copy the files into the target directory: + +@example +curl -L -O https://www.oberhumer.com/opensource/lzo/download/minilzo-2.10.tar.gz +tar -zxf minilzo-2.10.tar.gz +rm minilzo-2.10/testmini.c +rm -r grub-core/lib/minilzo/* +cp minilzo-2.10/*.[hc] grub-core/lib/minilzo +rm -r minilzo-2.10* +@end example + +@node libtasn1 +@section libtasn1 + +libtasn1 is a library providing Abstract Syntax Notation One (ASN.1, as +specified by the X.680 ITU-T recommendation) parsing and structures management, +and Distinguished Encoding Rules (DER, as per X.690) encoding and decoding +functions. + +To upgrade to a new version of the libtasn1 library, download the release +tarball and copy the files into the target directory: + +@example +curl -L -O https://ftp.gnu.org/gnu/libtasn1/libtasn1-4.19.0.tar.gz +tar xvzf libtasn1-4.19.0.tar.gz +rm -rf grub-core/lib/libtasn1 +mkdir -p grub-core/lib/libtasn1/lib +mkdir -p grub-core/lib/libtasn1/tests +cp libtasn1-4.19.0/@{README.md,COPYING@} grub-core/lib/libtasn1 +cp libtasn1-4.19.0/lib/@{coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h@} grub-core/lib/libtasn1/lib +cp libtasn1-4.19.0/lib/includes/libtasn1.h grub-core/lib/libtasn1 +cp libtasn1-4.19.0/tests/@{CVE-2018-1000654-1_asn1_tab.h,CVE-2018-1000654-2_asn1_tab.h,CVE-2018-1000654.c,object-id-decoding.c,object-id-encoding.c,octet-string.c,reproducers.c,Test_overflow.c,Test_simple.c,Test_strings.c@} grub-core/lib/libtasn1/tests +rm -rf libtasn1-4.19.0* +@end example + +After upgrading the library, it may be necessary to apply the patches in +@file{grub-core/lib/libtasn1-patches/} to adjust the code to be compatible with +GRUB. These patches were needed to use the current version of libtasn1. The +existing patches may not apply cleanly, apply at all, or even be needed for a +newer version of the library, and other patches may be needed due to changes in +the newer version. If existing patches need to be refreshed to apply cleanly, +please include updated patches as part of the a patch set sent to the list. +If new patches are needed or existing patches are not needed, also please send +additions or removals as part of any patch set upgrading libtasn1. + +@node Debugging +@chapter Debugging + +GRUB2 can be difficult to debug because it runs on the bare-metal and thus +does not have the debugging facilities normally provided by an operating +system. This chapter aims to provide useful information on some ways to +debug GRUB2 for some architectures. It by no means intends to be exhaustive. +The focus will be one x86_64 and i386 architectures. Luckily for some issues +virtual machines have made the ability to debug GRUB2 much easier, and this +chapter will focus debugging via the QEMU virtual machine. We will not be +going over debugging of the userland tools (eg. grub-install), there are +many tutorials on debugging programs in userland. + +You will need GDB and the QEMU binaries for your system, on Debian these +can be installed with the @samp{gdb} and @samp{qemu-system-x86} packages. +Also it is assumed that you have already successfully compiled GRUB2 from +source for the target specified in the section below and have some +familiarity with GDB. When GRUB2 is built it will create many different +binaries. The ones of concern will be in the @file{grub-core} +directory of the GRUB2 build dir. To aide in debugging we will want the +debugging symbols generated during the build because these symbols are not +kept in the binaries which get installed to the boot location. The build +process outputs two sets of binaries, one without symbols which gets executed +at boot, and another set of ELF images with debugging symbols. The built +images with debugging symbols will have a @file{.image} suffix, and the ones +without a @file{.img} suffix. Similarly, loadable modules with debugging +symbols will have a @file{.module} suffix, and ones without a @file{.mod} +suffix. In the case of the kernel the binary with symbols is named +@file{kernel.exec}. + +In the following sections, information will be provided on debugging on +various targets using @command{gdb} and the @samp{gdb_grub} GDB script. + +@menu +* i386-pc:: +* x86_64-efi:: +@end menu + +@node i386-pc +@section i386-pc + +The i386-pc target is a good place to start when first debugging GRUB2 +because in some respects it's easier than EFI platforms. The reason being +that the initial load address is always known in advance. To start +debugging GRUB2 first QEMU must be started in GDB stub mode. The following +command is a simple illustration: + +@example +qemu-system-i386 -drive file=disk.img,format=raw \ + -device virtio-scsi-pci,id=scsi0 -S -s +@end example + +This will start a QEMU instance booting from @file{disk.img}. It will pause +at start waiting for a GDB instance to attach to it. You should change +@file{disk.img} to something more appropriate. A block device can be used, +but you may need to run QEMU as a privileged user. + +To connect to this QEMU instance with GDB, the @code{target remote} GDB +command must be used. We also need to load a binary image, preferably with +symbols. This can be done using the GDB command @code{file kernel.exec}, if +GDB is started from the @file{grub-core} directory in the GRUB2 build +directory. GRUB2 developers have made this more simple by including a GDB +script which does much of the setup. This file is at @file{grub-core/gdb_grub} +in the build directory and is also installed via @command{make install}. +When using a pre-built GRUB, the distribution may have a package which installs +this GDB script along with debug symbol binaries, such as Debian's +@samp{grub-pc-dbg} package. The GDB script is intended to be used +like so, assuming that @samp{/path/to/script} is the path to the directory +containing the gdb_grub script and debug symbol files: + +@example +cd $(dirname /path/to/script/gdb_grub) +gdb -x gdb_grub +@end example + +Once GDB has been started with the @file{gdb_grub} script it will +automatically connect to the QEMU instance. You can then do things you +normally would in GDB like set a break point on @var{grub_main}. + +Setting breakpoints in modules is trickier since they haven't been loaded +yet and are loaded at addresses determined at runtime. The module could be +loaded to different addresses in different QEMU instances. The debug symbols +in the modules @file{.module} binary, thus are always wrong, and GDB needs +to be told where to load the symbols to. But this must happen at runtime +after GRUB2 has determined where the module will get loaded. Luckily the +@file{gdb_grub} script takes care of this with the @command{runtime_load_module} +command, which configures GDB to watch for GRUB2 module loading and when +it does add the module symbols with the appropriate offset. + +@node x86_64-efi +@section x86_64-efi + +Using GDB to debug GRUB2 for the x86_64-efi target has some similarities with +the i386-pc target. Please read and familiarize yourself with the @ref{i386-pc} +section when reading this one. Extra care must be used to run QEMU such that it +boots a UEFI firmware. This usually involves either using the @samp{-bios} +option with a UEFI firmware blob (eg. @file{OVMF.fd}) or loading the firmware +via pflash. This document will not go further into how to do this as there are +ample resource on the web. + +Like all EFI implementations, on x86_64-efi the (U)EFI firmware that loads +the GRUB2 EFI application determines at runtime where the application will +be loaded. This means that we do not know where to tell GDB to load the +symbols for the GRUB2 core until the (U)EFI firmware determines it. There are +two good ways of figuring this out when running in QEMU: use a @ref{OVMF debug log, +debug build of OVMF} and check the debug log, or have GRUB2 say where it is +loaded. Neither of these are ideal because they both generally give the +information after GRUB2 is already running, which makes debugging early boot +infeasible. Technically, the first method does give the load address before +GRUB2 is run, but without debugging the EFI firmware with symbols, the author +currently does not know how to cause the OVMF firmware to pause at that point +to use the load address before GRUB2 is run. + +Even after getting the application load address, the loading of core symbols +is complicated by the fact that the debugging symbols for the kernel are in +an ELF binary named @file{kernel.exec} while what is in memory are sections +for the PE32+ EFI binary. When @command{grub-mkimage} creates the PE32+ +binary it condenses several segments from the ELF kernel binary into one +.data section in the PE32+ binary. This must be taken into account to +properly load the other non-text sections. Otherwise, GDB will work as +expected when breaking on functions, but, for instance, global variables +will point to the wrong address in memory and thus give incorrect values +(which can be difficult to debug). + +Calculating the correct offsets for sections is taken care of automatically +when loading the kernel symbols via the user-defined GDB command +@command{dynamic_load_kernel_exec_symbols}, which takes one argument, the +address where the text section is loaded as determined by one of the methods +above. Alternatively, the command @command{dynamic_load_symbols} with the text +section address as an agrument can be called to load the kernel symbols and set +up loading the module symbols as they are loaded at runtime. + +In the author's experience, when debugging with QEMU and OVMF, to have +debugging symbols loaded at the start of GRUB2 execution the GRUB2 EFI +application must be run via QEMU at least once prior in order to get the +load address. Two methods for obtaining the load address are described in +two subsections below. Generally speaking, the load address does not change +between QEMU runs. There are exceptions to this, namely that different +GRUB2 EFI applications can be run at different addresses. Also, it has been +observed that after running the EFI application for the first time, the +second run will sometimes have a different load address, but subsequent +runs of the same EFI application will have the same load address as the +second run. And it's a near certainty that if the GRUB EFI binary has changed, +eg. been recompiled, the load address will also be different. + +This ability to predict what the load address will be allows one to assume +the load address on subsequent runs and thus load the symbols before GRUB2 +starts. The following command illustrates this, assuming that QEMU is +running and waiting for a debugger connection and the current working +directory is where @file{gdb_grub} resides: + +@example +gdb -x gdb_grub -ex 'dynamic_load_symbols @var{address of .text section}' +@end example + +If you load the symbols in this manner and, after continuing execution, do +not see output showing the module symbols loading, then it is very likely +that the load address was incorrect. + +Another thing to be aware of is how the loading of the GRUB image by the +firmware affects previously set software breakpoints. On x86 platforms, +software breakpoints are implemented by GDB by writing a special processor +instruction at the location of the desired breakpoint. This special instruction +when executed will stop the program execution and hand control to the +debugger, GDB. GDB will first save the instruction bytes that are +overwritten at the breakpoint and will put them back when the breakpoint +is hit. If GRUB is being run for the first time in QEMU, the firmware will +be loading the GRUB image into memory where every byte is already set to 0. +This means that if a breakpoint is set before GRUB is loaded, GDB will save +the 0-byte(s) where the the special instruction will go. Then when the firmware +loads the GRUB image and because it is unaware of the debugger, it will +write the GRUB image to memory, overwriting anything that was there previously --- +notably in this case the instruction that implements the software breakpoint. +This will be confusing for the person using GDB because GDB will show the +breakpoint as set, but the brekapoint will never be hit. Furthermore, GDB +then becomes confused, such that even deleting an recreating the breakpoint +will not create usable breakpoints. The @file{gdb_grub} script takes care of +this by saving the breakpoints just before they are overwritten, and then +restores them at the start of GRUB execution. So breakpoints for GRUB can be +set before GRUB is loaded, but be mindful of this effect if you are confused +as to why breakpoints are not getting hit. + +Also note, that hardware breakpoints do not suffer this problem. They are +implemented by having the breakpoint address in special debug registers on +the CPU. So they can always be set freely without regard to whether GRUB has +been loaded or not. The reason that hardware breakpoints aren't always used +is because there are a limited number of them, usually around 4 on various +CPUs, and specifically exactly 4 for x86 CPUs. The @file{gdb_grub} script goes +out of its way to avoid using hardware breakpoints internally and uses them as +briefly as possible when needed, thus allowing the user to have a maximal +number at their disposal. + +@menu +* OVMF debug log:: +* Using the gdbinfo command:: +@end menu + +@node OVMF debug log +@subsection OVMF debug log + +In order to get the GRUB2 load address from OVMF, first, a debug build +of OVMF must be obtained (@uref{https://github.com/retrage/edk2-nightly/raw/master/bin/DEBUGX64_OVMF.fd, +here is one} which is not officially recommended). OVMF will output debug +messages to a special serial device, which we must add to QEMU. The following +QEMU command will run the debug OVMF and write the debug messages to a +file named @file{debug.log}. It is assumed that @file{disk.img} is a disk +image or block device that is set up to boot GRUB2 EFI. + +@example +qemu-system-x86_64 -bios /path/to/debug/OVMF.fd \ + -drive file=disk.img,format=raw \ + -device virtio-scsi-pci,id=scsi0 \ + -debugcon file:debug.log -global isa-debugcon.iobase=0x402 +@end example + +If GRUB2 was started by the (U)EFI firmware, then in the @file{debug.log} +file one of the last lines should be a log message like: +@samp{Loading driver at 0x00006AEE000 EntryPoint=0x00006AEE756}. This +means that the GRUB2 EFI application was loaded at @samp{0x00006AEE000} and +its .text section is at @samp{0x00006AEE756}. + +@node Using the gdbinfo command +@subsection Using the gdbinfo command + +On EFI platforms the command @command{gdbinfo} will output a string that +is to be run in a GDB session running with the @file{gdb_grub} GDB script. + + @node Porting @chapter Porting @@ -642,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 @@ -671,7 +1065,7 @@ is already present and you'll need to make it follow the existant code paths for your platform adding adjustments if necessary. When done compile: @example -./autogen.sh +./bootstrap ./configure --target=$cpu --with-platform=$platform TARGET_CC=.. OBJCOPY=... STRIP=... make > /dev/null @end example @@ -688,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). @@ -702,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 @@ -916,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. @@ -957,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 @@ -1651,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. @@ -1772,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. @@ -1918,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 @@ -1949,6 +2346,89 @@ the graphics mode that was in use before @code{grub_video_setup()} was called might fix some of the problems. +@node Verifiers framework +@chapter Verifiers framework + +To register your own verifier call @samp{grub_verifier_register} with a structure +pointing to your functions. + +The interface is inspired by the hash interface with @samp{init}/@samp{write}/@samp{fini}. + +There are essentially 2 ways of using it, hashing and whole-file verification. + +With the hashing approach: +During @samp{init} you decide whether you want to check the given file and init context. +In @samp{write} you update your hashing state. +In @samp{fini} you check that the hash matches the expected value/passes some check/... + +With whole-file verification: +During @samp{init} you decide whether you want to check the given file and init context. +In @samp{write} you verify the file and return an error if it fails. +You don't have @samp{fini}. + +Additional @samp{verify_string} receives various strings like kernel parameters +to verify. Returning no error means successful verification and an error stops +the current action. + +Detailed description of the API: + +Every time a file is opened your @samp{init} function is called with file descriptor +and file type. Your function can have the following outcomes: + +@itemize + +@item returning no error and setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_DEFER_AUTH}. +In this case verification is deferred to other active verifiers. Verification +fails if nobody cares or selected verifier fails. + +@item returning no error and setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION}. +In this case your verifier will not be called anymore and it is assumed to have +skipped verification. + +@item returning no error and not setting @samp{*flags} to @samp{GRUB_VERIFY_FLAGS_SKIP_VERIFICATION} +In this case verification is done as described in the following section. + +@item returning an error. Then opening of the file will fail due to failed verification. + +@end itemize + +In the third case your @samp{write} will be called with chunks of the file. If +you need the whole file in a single chunk then during @samp{init} set the bit +@samp{GRUB_VERIFY_FLAGS_SINGLE_CHUNK} in @samp{*flags}. During @samp{init} you +may set @samp{*context} if you need additional context. At every iteration you +may return an error and the file will be considered as having failed the +verification. If you return no error then verification continues. + +Optionally at the end of the file @samp{fini}, if it exists, is called with just +the context. If you return no error during any of @samp{init}, @samp{write} and +@samp{fini} then the file is considered as having succeded verification. + +@node Lockdown framework +@chapter Lockdown framework + +The GRUB can be locked down, which is a restricted mode where some operations +are not allowed. For instance, some commands cannot be used when the GRUB is +locked down. + +The function +@code{grub_lockdown()} is used to lockdown GRUB and the function +@code{grub_is_lockdown()} function can be used to check whether lockdown is +enabled or not. When enabled, the function returns @samp{GRUB_LOCKDOWN_ENABLED} +and @samp{GRUB_LOCKDOWN_DISABLED} when is not enabled. + +The following functions can be used to register the commands that can only be +used when lockdown is disabled: + +@itemize + +@item @code{grub_cmd_lockdown()} registers command which should not run when the +GRUB is in lockdown mode. + +@item @code{grub_cmd_lockdown()} registers extended command which should not run +when the GRUB is in lockdown mode. + +@end itemize + @node Copying This Manual @appendix Copying This Manual diff --git a/docs/grub.texi b/docs/grub.texi index e935af33e..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,14 +353,18 @@ 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{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{exFAT}, @dfn{HFS}, -@dfn{HFS+}, @dfn{ISO9660} (including Joliet, Rock-ridge and multi-chunk files), +@dfn{EROFS} (only uncompressed support for now), +@dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, +@dfn{exFAT}, @dfn{F2FS}, @dfn{HFS}, @dfn{HFS+}, +@dfn{ISO9660} (including Joliet, Rock-ridge and multi-chunk files), @dfn{JFS}, @dfn{Minix fs} (versions 1, 2 and 3), @dfn{nilfs2}, @dfn{NTFS} (including compression), @dfn{ReiserFS}, @dfn{ROMFS}, @dfn{Amiga Smart FileSystem (SFS)}, @dfn{Squash4}, @dfn{tar}, @dfn{UDF}, @dfn{BSD UFS/UFS2}, @dfn{XFS}, and @dfn{ZFS} (including lzjb, gzip, zle, mirror, stripe, raidz1/2/3 and encryption in AES-CCM and AES-GCM). @xref{Filesystem}, for more information. +Note: Only a subset of filesystems are supported in lockdown mode (such +as when secure boot is enabled, @pxref{Lockdown} for more information). @item Support automatic decompression Can decompress files which were compressed by @command{gzip} or @@ -694,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: @@ -828,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. @@ -893,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 @@ -900,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 @@ -936,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 @@ -974,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 @@ -1092,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 @@ -1213,10 +1263,11 @@ GRUB is configured using @file{grub.cfg}, usually located under need to write the whole thing by hand. @menu -* Simple configuration:: Recommended for most users -* 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 +* Simple configuration:: Recommended for most users +* Root Identification Heuristics:: Summary on how the root file system is identified. +* Shell-like scripting:: For power users and developers +* Multi-boot manual config:: For non-standard multi-OS scenarios +* Embedded configuration:: Embedding a configuration file into GRUB @end menu @@ -1307,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 @@ -1380,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 @@ -1398,6 +1456,35 @@ 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}. +This is for loading things like CPU microcode, firmware, ACPI tables, crypto +keys, and so on. These early images will be loaded in the order declared, +and all will be loaded before the actual functional initrd image. + +@samp{GRUB_EARLY_INITRD_LINUX_STOCK} is for your distribution to declare +images that are provided by the distribution. It should not be modified +without understanding the consequences. They will be loaded first. + +@samp{GRUB_EARLY_INITRD_LINUX_CUSTOM} is for your custom created images. + +The default stock images are as follows, though they may be overridden by +your distribution: +@example +intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode.cpio +@end example + @item GRUB_DISABLE_LINUX_UUID Normally, @command{grub-mkconfig} will generate menu entries that use universally-unique identifiers (UUIDs) to identify the root filesystem to @@ -1405,10 +1492,30 @@ the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is usually more reliable, but in some cases it may not be appropriate. To disable the use of UUIDs, set this option to @samp{true}. +@item GRUB_DISABLE_LINUX_PARTUUID +If @command{grub-mkconfig} cannot identify the root filesystem via its +universally-unique indentifier (UUID), @command{grub-mkconfig} can use the UUID +of the partition containing the filesystem to identify the root filesystem to +the Linux kernel via a @samp{root=PARTUUID=...} kernel parameter. This is not +as reliable as using the filesystem UUID, but is more reliable than using the +Linux device names. When @samp{GRUB_DISABLE_LINUX_PARTUUID} is set to +@samp{false}, the Linux kernel version must be 2.6.37 (3.10 for systems using +the MSDOS partition scheme) or newer. This option defaults to @samp{true}. To +enable the use of partition UUIDs, set this option to @samp{false}. + @item GRUB_DISABLE_RECOVERY If this option is set to @samp{true}, disable the generation of recovery mode menu entries. +@item GRUB_DISABLE_UUID +Normally, @command{grub-mkconfig} will generate menu entries that use +universally-unique identifiers (UUIDs) to identify various filesystems to +search for files. This is usually more reliable, but in some cases it may +not be appropriate. To disable this use of UUIDs, set this option to +@samp{true}. Setting this option to @samp{true}, will also set the options +@samp{GRUB_DISABLE_LINUX_UUID} and @samp{GRUB_DISABLE_LINUX_PARTUUID} to +@samp{true}, unless they have been explicitly set to @samp{false}. + @item GRUB_VIDEO_BACKEND If graphical video support is required, either because the @samp{gfxterm} graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set, @@ -1430,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. @@ -1449,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 @@ -1497,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 @@ -1536,6 +1650,54 @@ 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 Identification Heuristics +@section Root Identification Heuristics +If the target operating system uses the Linux kernel, @command{grub-mkconfig} +attempts to identify the root file system via a heuristic algoirthm. This +algorithm selects the identification method of the root file system by +considering three factors. The first is if an initrd for the target operating +system is also present. The second is @samp{GRUB_DISABLE_LINUX_UUID} and if set +to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file +system by its UUID. The third is @samp{GRUB_DISABLE_LINUX_PARTUUID} and if set +to @samp{true}, prevents @command{grub-mkconfig} from identifying the root file +system via the UUID of its enclosing partition. If the variables are assigned +any other value, that value is considered equivalent to @samp{false}. The +variables are also considered to be set to @samp{false} if they are not set. + +When booting, the Linux kernel will delegate the task of mounting the root +filesystem to the initrd. Most initrd images determine the root file system by +checking the Linux kernel's command-line for the @samp{root} key and use its +value as the identification method of the root file system. To improve the +reliability of booting, most initrd images also allow the root file system to be +identified by its UUID. Because of this behavior, the @command{grub-mkconfig} +command will set @samp{root} to @samp{root=UUID=...} to provide the initrd with +the filesystem UUID of the root file system. + +If no initrd is detected or @samp{GRUB_DISABLE_LINUX_UUID} is set to @samp{true} +then @command{grub-command} will identify the root filesystem by setting the +kernel command-line variable @samp{root} to @samp{root=PARTUUID=...} unless +@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true}. If +@samp{GRUB_DISABLE_LINUX_PARTUUID} is also set to @samp{true}, +@command{grub-command} will identify by its Linux device name. + +The following table summarizes the behavior of the @command{grub-mkconfig} +command. + +@multitable {detected} {GRUB_DISABLE_LINUX_PARTUUID} {GRUB_DISABLE_LINUX_UUID} {Linux Root} +@headitem Initrd detected @tab GRUB_DISABLE_LINUX_PARTUUID Set To @tab GRUB_DISABLE_LINUX_UUID Set To @tab Linux Root ID Method +@item false @tab false @tab false @tab part UUID +@item false @tab false @tab true @tab part UUID +@item false @tab true @tab false @tab dev name +@item false @tab true @tab true @tab dev name +@item true @tab false @tab false @tab fs UUID +@item true @tab false @tab true @tab part UUID +@item true @tab true @tab false @tab fs UUID +@item true @tab true @tab true @tab dev name +@end multitable + +Remember, @samp{GRUB_DISABLE_LINUX_PARTUUID} and @samp{GRUB_DISABLE_LINUX_UUID} +are also considered to be set to @samp{true} and @samp{false}, respectively, +when they are unset. @node Shell-like scripting @section Writing full configuration files directly @@ -1654,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 @@ -1733,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, @@ -2407,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. @@ -2427,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. @@ -2467,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 @@ -2497,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 @@ -2512,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 @@ -2771,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 @@ -2834,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. @@ -2866,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 @@ -2910,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: @@ -2994,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 @@ -3046,6 +3288,7 @@ These variables have special meaning to GRUB. * color_normal:: * config_directory:: * config_file:: +* cryptodisk_passphrase_tries:: * debug:: * default:: * fallback:: @@ -3057,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:: @@ -3074,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 @@ -3205,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. @@ -3365,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 @@ -3394,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 @@ -3483,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 @@ -3514,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 @@ -3556,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 @@ -3582,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. @@ -3601,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: @@ -3688,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. @@ -3707,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 @@ -3764,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. @@ -3781,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} @@ -3803,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 @@ -3812,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 @@ -3849,9 +6470,10 @@ 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 * regexp:: Test if regular expression matches string @@ -3864,20 +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 -* xen_hypervisor:: Load xen hypervisor binary -* xen_linux:: Load dom0 kernel for xen hypervisor -* xen_initrd:: Load dom0 initrd for dom0 kernel -* xen_xsm:: Load xen security module for xen hypervisor +* wrmsr:: Write values to model-specific registers @end menu @@ -3907,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 @@ -3950,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 @@ -3967,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 @@ -4001,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 @@ -4056,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] @@ -4071,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 @@ -4111,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 @@ -4141,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 @@ -4189,6 +6880,8 @@ For example: @example drivemap -s (hd0) (hd1) @end example + +NOTE: Only available on i386-pc. @end deffn @@ -4235,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 @@ -4262,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 @@ -4297,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 @@ -4341,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 @@ -4387,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 @@ -4495,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: @@ -4504,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 @@ -4567,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. @@ -4645,7 +7476,7 @@ range 0-0xFF (prefix with @samp{0x} to enter it in hexadecimal). When enabled, this hides the selected partition by setting the @dfn{hidden} bit in its partition type code; when disabled, unhides the selected partition by clearing this bit. This is useful only when booting DOS or -Wwindows and multiple primary FAT partitions exist in one disk. See also +Windows and multiple primary FAT partitions exist in one disk. See also @ref{DOS/Windows}. @end table @end deffn @@ -4670,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 @@ -4692,29 +7594,40 @@ 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. + +The option @option{--part-uuid} is currently only implemented for MSDOS and GPT formatted disks. @end deffn -@node pxe_unload -@subsection pxe_unload +@node rdmsr +@subsection rdmsr -@deffn Command pxe_unload -Unload the PXE environment (@pxref{Network}). +@deffn Command: rdmsr 0xADDR [-v VARNAME] +Read a model-specific register at address 0xADDR. If the parameter +@option{-v} is used and an environment variable @var{VARNAME} is +given, set that environment variable to the value that was read. -This command is only available on PC BIOS systems. +Please note that on SMP systems, reading from a MSR that has a +scope per hardware thread, implies that the value that is returned +only applies to the particular cpu/core/thread that runs the command. + +Also, if you specify a reserved or unimplemented MSR address, it will +cause a general protection exception (which is not currently being handled) +and the system will reboot. @end deffn @node read @subsection read -@deffn Command read [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 @@ -4773,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 @@ -4807,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, @@ -4944,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 @@ -4980,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 @@ -5068,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 @@ -5102,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 @@ -5146,50 +8218,36 @@ successfully. If validation fails, it is set to a non-zero value. List available video modes. If resolution is given, show only matching modes. @end deffn -@node xen_hypervisor -@subsection xen_hypervisor +@node wrmsr +@subsection wrmsr -@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. +@deffn Command: wrmsr 0xADDR 0xVALUE +Write a 0xVALUE to a model-specific register at address 0xADDR. + +Please note that on SMP systems, writing to a MSR that has a scope +per hardware thread, implies that the value that is written +only applies to the particular cpu/core/thread that runs the command. + +Also, if you specify a reserved or unimplemented MSR address, it will +cause a general protection exception (which is not currently being handled) +and the system will reboot. + +Note: The command is not allowed when lockdown is enforced (@pxref{Lockdown}). + This is done to prevent subverting various security mechanisms. @end deffn -@node xen_linux -@subsection xen_linux - -@deffn Command xen_linux file [arguments] -Load a dom0 kernel image for xen hypervisor at the booting process of xen. -The rest of the line is passed verbatim as the module command line. -@end deffn - -@node xen_initrd -@subsection xen_initrd - -@deffn Command xen_initrd file -Load a initrd image for dom0 kernel at the booting process of xen. -@end deffn - -@node xen_xsm -@subsection xen_xsm - -@deffn Command xen_xsm file -Load a xen security module for xen hypervisor at the booting process of xen. -See @uref{http://wiki.xen.org/wiki/XSM} for more detail. -@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 @@ -5197,6 +8255,7 @@ See @uref{http://wiki.xen.org/wiki/XSM} for more detail. * 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 @@ -5236,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 @@ -5264,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 @@ -5355,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 @@ -5367,8 +8560,8 @@ 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), -RockRidge part of ISO9660, nilfs2, UFS1, UFS2 and ZFS are assumed +minix2, minix3, ROMFS, ReiserFS, XFS, EROFS, ext2, ext3, ext4, FAT (short names), +F2FS, RockRidge part of ISO9660, nilfs2, UFS1, UFS2 and ZFS are assumed to be UTF-8. This might be false on systems configured with legacy charset but as long as the charset used is superset of ASCII you should be able to access ASCII-named files. And it's recommended to configure your system to use @@ -5445,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. @@ -5459,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. @@ -5477,6 +8670,11 @@ environment variables and commands are listed in the same order. @menu * Authentication and authorisation:: Users and access control * Using digital signatures:: Booting digitally signed code +* UEFI secure boot and shim:: Booting digitally signed PE files +* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation +* Measured Boot:: Measuring boot components +* Lockdown:: Lockdown when booting on a secure setup +* TPM2 key protector:: Managing disk key with TPM2 key protector @end menu @node Authentication and authorisation @@ -5508,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 @@ -5568,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 @@ -5639,6 +8834,535 @@ or BIOS) configuration to cause the machine to boot from a different (attacker-controlled) device. GRUB is at best only one link in a secure boot chain. +@node UEFI secure boot and shim +@section UEFI secure boot and shim support + +The GRUB works with UEFI secure boot and the shim. This functionality is +provided by the shim_lock verifier. It is built into the @file{core.img} and is +registered if the UEFI secure boot is enabled. The @samp{shim_lock} variable is +set to @samp{y} when shim_lock verifier is registered. If it is desired to use +UEFI secure boot without shim, one can disable shim_lock by disabling shim +verification with MokSbState UEFI variable or by building grub image with +@samp{--disable-shim-lock} option. + +All GRUB modules not stored in the @file{core.img}, OS kernels, ACPI tables, +Device Trees, etc. have to be signed, e.g, using PGP. Additionally, the commands +that can be used to subvert the UEFI secure boot mechanism, such as @command{iorw} +and @command{memrw} will not be available when the UEFI secure boot is enabled. +This is done for security reasons and are enforced by the GRUB Lockdown mechanism +(@pxref{Lockdown}). + +@node Secure Boot Advanced Targeting +@section Embedded information for generation number based revocation + +The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the revocation +of components in the boot path by using generation numbers embedded into the EFI +binaries. The SBAT metadata is located in an .sbat data section that has set of +UTF-8 strings as comma-separated values (CSV). See +@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details. + +To add a data section containing the SBAT information into the binary, the +@option{--sbat} option of @command{grub-mkimage} command should be used. The content +of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section into +the generated EFI binary. The CSV file can be stored anywhere on the file system. + +@example +grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efinet tftp +@end example + +@node Measured Boot +@section Measuring boot components + +If the tpm module is loaded and the platform has a Trusted Platform Module +installed, GRUB will log each command executed and each file loaded into the +TPM event log and extend the PCR values in the TPM correspondingly. All events +will be logged into the PCR described below with a type of EV_IPL and an +event description as described below. + +@multitable @columnfractions 0.3 0.1 0.6 +@headitem Event type @tab PCR @tab Description +@item Command +@tab 8 +@tab All executed commands (including those from configuration files) will be +logged and measured as entered with a prefix of ``grub_cmd: `` +@item Kernel command line +@tab 8 +@tab Any command line passed to a kernel will be logged and measured as entered +with a prefix of ``kernel_cmdline: '' +@item Module command line +@tab 8 +@tab Any command line passed to a kernel module will be logged and measured as +entered with a prefix of ``module_cmdline: `` +@item Files +@tab 9 +@tab Any file read by GRUB will be logged and measured with a descriptive text +corresponding to the filename. +@end multitable + +GRUB will not measure its own @file{core.img} - it is expected that firmware +will carry this out. GRUB will also not perform any measurements until the +tpm module is loaded. As such it is recommended that the tpm module be built +into @file{core.img} in order to avoid a potential gap in measurement between +@file{core.img} being loaded and the tpm module being loaded. + +Measured boot is currently only supported on EFI and IBM IEEE1275 PowerPC +platforms. + +@node Lockdown +@section Lockdown when booting on a secure setup + +The GRUB can be locked down when booted on a secure boot environment, for example +if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will +be restricted and some operations/commands cannot be executed. This also includes +limiting which filesystems are supported to those thought to be more robust and +widely used within GRUB. + +The filesystems currently allowed in lockdown mode include: +@itemize @bullet +@item BtrFS +@item cpio +@item exFAT +@item Enhanced Read-Only File System (EROFS) +@item Linux ext2/ext3/ext4 +@item F2FS +@item DOS FAT12/FAT16/FAT32 +@item HFS+ +@item ISO9660 +@item Squash4 +@item tar +@item XFS +@item ZFS +@end itemize + +The filesystems currently not allowed in lockdown mode include: +@itemize @bullet +@item Amiga Fast FileSystem (AFFS) +@item AtheOS File System (AFS) +@item Bee File System (BFS) +@item Coreboot File System (CBFS) +@item Hierarchical File System (HFS) +@item Journaled File System (JFS) +@item Minix filesystem +@item New Implementation of Log filesystem (nilfs2) +@item Windows New Technology File System (NTFS) +@item ReiserFS +@item Read-Only Memory File System (ROMFS) +@item Amiga Smart File System (SFS) +@item Universal Disk Format (UDF) +@item Unix File System (UFS) +@end itemize + +The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. +Otherwise it does not exist. + +@node TPM2 key protector +@section TPM2 key protector in GRUB + +TPM2 key protector extends measured boot to unlock the encrypted partition +without user intervention. It uses the TPM Storage Root Key (SRK) to seal +the disk key with a given set of PCR values. If the system state matches, +i.e. PCR values match the sealed PCR set, TPM2 key protector unseals the +disk key for @command{cryptomount} (@pxref{cryptomount}) to unlock the +encrypted partition. In case the unsealed key fails to unlock the +partition, @command{cryptomount} falls back to the passphrase prompt. + +Please note that TPM2 key protector uses the SRK in the owner hierarchy +@emph{without} authorization. If the owner hierarchy is password-protected, +TPM2 key protector may fail to unseal the key due to the absence of the +password. For the systems that already enable the password protection for the +owner hierarchy, the following command removes the password protection with +the existing password. + +@example +# @kbd{tpm2_changeauth -c owner -p password} +@end example + +There are two supported modes to store the sealed key, SRK and NV index. +The details will be addressed in later sections. + +TPM2 key protector is currently only supported on EFI and EMU platforms. + +@subsection TPM PCR usage + +Since TPM2 key protector relies on PCRs to check the system state, it is +important to decide which PCRs to seal the key with. The following table +lists uses of PCRs and the measured objects on EFI platforms. + +@multitable @columnfractions 0.1 0.2 0.7 +@headitem PCR @tab Used by @tab Measured Objects +@item 0 +@tab Firmware +@tab Core system firmware executable code +@item 1 +@tab Firmware +@tab Core system firmware data/host platform configuration; typically +contains serial and model numbers +@item 2 +@tab Firmware +@tab Extended or pluggable executable code; includes option ROMs on +pluggable hardware +@item 3 +@tab Firmware +@tab Extended or pluggable firmware data; includes information about +pluggable hardware +@item 4 +@tab Firmware +@tab Boot loader and additional drivers; binaries and extensions loaded +by the boot loader +@item 5 +@tab Firmware +@tab GPT/Partition table +@item 7 +@tab Firmware +@tab SecureBoot state +@item 8 +@tab GRUB +@tab Commands and kernel command line +@item 9 +@tab GRUB +@tab All files read (including kernel image) +@item 9 +@tab Linux Kernel +@tab All passed initrds (when the new LOAD_FILE2 initrd protocol is used) +@item 10 +@tab Linux Kernel +@tab Protection of the IMA measurement log +@item 14 +@tab shim +@tab “MOK” certificates and hashes +@end multitable + +PCR 0, 2, 4, and 7 can be used to check the integrity of the firmware code +and bootloaders. PCR 8 and 9 are useful to check the file and data processed +by GRUB. PCRs 10, 11, 12, 13, and 15 are controlled by the operating system, +so those PCRs are usually still in the initial state when GRUB is running. + +In general, it is nice to include PCR 0, 2, 4, and 7 to ensure the integrity +of the firmware and bootloaders. For PCR 8 and 9, a sophisticated tool is +required to examine the GRUB configuration files and the files to be loaded +to calculate the correct PCR values. + +Please note that PCRs are sensitive to any change, so an update of a component +could invalidate the sealed key, due to the so-called PCR brittleness. For the +bootloader update, PCR 4 may be affected. This can be mitigated by extracting +the events from the TPM event log and predict the value with the updated +bootloader binary. On the other hand, it is difficult to predict PCR 0~7 after +a firmware update since the content of the code and the order of drivers may +not follow the TPM event log from the previous firmware version, so it is +necessary to reboot the system to update the measurement results of PCR 0~7 +and seal or sign the sealed key again. + +Reference: @url{https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/, Linux TPM PCR Registry} + +@subsection Setting up the extra disk key + +Instead of using the existing password, it is recommended to seal a new +random disk key and use the existing password for recovery. + +Here are the sample commands to create a 128 random bytes key file and +enroll the key into the target partition (sda2). + +@example +# @kbd{dd if=/dev/urandom of=luks.key bs=1 count=128} +# @kbd{cryptsetup luksAddKey /dev/sda2 luks.key --pbkdf=pbkdf2 --hash=sha512} +@end example + +@subsection SRK mode + +To unlock the partition with SRK mode, assume that the sealed key is in +@file{(hd0,gpt1)/efi/grub/sealed.tpm}, the following GRUB commands +unseal the disk key with SRK mode and supply it to @command{cryptomount}. + +@example +grub> @kbd{tpm2_key_protector_init -T (hd0,gpt1)/efi/grub/sealed.tpm} +grub> @kbd{cryptomount -u -P tpm2} +@end example + +There are two programs to create the sealed key for SRK mode: @command{grub-protect} +and @command{pcr-oracle} (@url{https://github.com/okirch/pcr-oracle}). + +The following sample command uses @command{grub-protect} to seal the random +key, @file{luks.key}, with PCR 0, 2, 4 and 7 in TPM 2.0 Key File format. + +@example +@group +# @kbd{grub-protect --action=add \ + --protector=tpm2 \ + --tpm2-pcrs=0,2,4,7 \ + --tpm2key \ + --tpm2-keyfile=luks.key \ + --tpm2-outfile=/boot/efi/efi/grub/sealed.tpm} +@end group +@end example + +@command{grub-protect} only seals the key with the current PCR values. +Therefore, when a boot component, such as shim or GRUB, is updated, it is +necessary to reboot the system to update the measurement results and seal +the key again. That means the random disk key has to be stored in cleartext +for the next key sealing. Besides this, the measurement result of some PCRs +may differ between boot time and OS runtime. For example, PCR 9 measures the +files loaded by GRUB including the Linux kernel and initrd. To unlock the disk +containing the kernel and initrd, the key has to be sealed with PCR 9 value +before loading the kernel and initrd. However, PCR 9 changes after GRUB +loading the kernel and initrd, so PCR 9 at OS runtime cannot be used directly +for key sealing. + +To solve these problems, @command{pcr-oracle} takes a different approach. It +reads the TPM eventlog and predicts the PCR values. Besides, +@command{pcr-oracle} also supports ``authorized policy'' which allows the +PCR policy to be updated with a valid signature, so that the user only seals +the random disk key once. If at some later time the PCR values change due to +an update of the system firmware, bootloader, or config file, the user just +needs to update the signature of the PCR policy. + +To seal the key with the authorized policy, the first thing is to generate +the RSA policy key, @file{policy-key.pem}, and the authorized policy file, +@file{authorized.policy}. In this example, PCR 0, 2, 4, 7 and 9 are chosen +for key sealing. + +@example +@group +# @kbd{pcr-oracle --rsa-generate-key \ + --private-key policy-key.pem \ + --auth authorized.policy \ + create-authorized-policy 0,2,4,7,9} +@end group +@end example + +Then, we seal the random disk key, @file{luks.key}, with the authorized +policy file and save the sealed key in @file{sealed.key}. + +@example +@group +# @kbd{pcr-oracle --key-format tpm2.0 \ + --auth authorized.policy \ + --input luks.key \ + --output sealed.key \ + seal-secret} +@end group +@end example + +Since we now have the sealed key, we can remove the random disk key file +@file{luks.key}. + +The last step is to sign the predicted PCR policy and save the final key +file, @file{sealed.tpm}. + +@example +@group +# @kbd{pcr-oracle --key-format tpm2.0 \ + --private-key policy-key.pem \ + --from eventlog \ + --stop-event "grub-file=grub.cfg" \ + --after \ + --input sealed.key \ + --output /boot/efi/efi/grub/sealed.tpm \ + sign 0,2,4,7,9} +@end group +@end example + +Here we also set a stop event for the prediction. With +@kbd{--stop-event grub-file=grub.cfg --after}, @command{pcr-oracle} stops +the calculation of PCR values right after GRUB loads @file{grub.cfg}. + +When/After the shim or GRUB are updated, it only requires to run the last +@command{pcr-oracle} command to update the predicted PCR policy. + +@subsection NV index mode + +Instead of storing the sealed key in a file, NV index mode uses the TPM +non-volatile memory to store the sealed key and could be useful when accessing +the file is not possible. + +However, the Linux root user must be careful who she/he gives access to the +TPM (tss group) since those users will also be able to modify the NV index +that's holding the key. + +There are two types of TPM handles supported by NV index mode: persistent +handle and NV index handle. + +@subsubsection Persistent handle + +The range of persistent handles is from @kbd{0x81000000} to @kbd{0x81FFFFFF}. +The persistent handle is designed to make TPM objects persistent through +power cycles, and only TPM objects, such as RSA or EC keys, are accepted. +Thus, only the raw format is supported by persistent handles. The following +shows the @command{grub-protect} command to seal the disk key @file{luks.key} +into the persistent handle @kbd{0x81000000} with the PCRs @kbd{0,2,4,7}. + +@example +@group +# @kbd{grub-protect \ + --protector=tpm2 \ + --action=add \ + --tpm2-bank=sha256 \ + --tpm2-pcrs=0,2,4,7 \ + --tpm2-keyfile=luks.key \ + --tpm2-nvindex=0x81000000} +@end group +@end example + +To unseal the key, we have to specify the mode @kbd{nv}, the persistent handle +@kbd{0x81000000}, and the PCRs @kbd{0,2,4,7} for the @command{tpm2_key_protector_init} +command. + +@example +grub> @kbd{tpm2_key_protector_init --mode=nv --nvindex=0x81000000 --pcrs=0,2,4,7} +grub> @kbd{cryptomount -u --protector tpm2} +@end example + +If the key in the persistent handle becomes unwanted, the following +@command{grub-protect} command removes the specified persistent handle +@kbd{0x81000000}. + +@example +@group +# @kbd{grub-protect \ + --protector=tpm2 \ + --action=remove \ + --tpm2-evict \ + --tpm2-nvindex=0x81000000} +@end group +@end example + +@subsubsection NV index handle + +The range of NV index handles is from @kbd{0x1000000} to @kbd{0x1FFFFFF}. +Unlike the persistent handle, the NV index handle allows user-defined data, +so it can easily support both the TPM 2.0 Key File format as well as the raw +format. + +The following @kbd{grub-protect} command seals the disk key @file{luks.key} +into the NV index handle @kbd{0x1000000} with the PCRs @kbd{0,2,4,7} while +using the TPM 2.0 Key File format. + +@example +@group +# @kbd{grub-protect \ + --protector=tpm2 \ + --action=add \ + --tpm2key \ + --tpm2-bank=sha256 \ + --tpm2-pcrs=0,2,4,7 \ + --tpm2-keyfile=luks.key \ + --tpm2-nvindex=0x1000000} +@end group +@end example + +Furthermore, it is also possible to insert an existing key file, +@file{sealed.tpm}, into a specific NV index handle using the following +tpm2-tools (@url{https://github.com/tpm2-software/tpm2-tools}) commands. + +@example +@group +# @kbd{tpm2_nvdefine -C o \ + -a "ownerread|ownerwrite" \ + -s $(stat -c %s sealed.tpm) \ + 0x1000000} +@end group +# @kbd{tpm2_nvwrite -C o -i sealed.tpm 0x1000000} +@end example + +When unsealing the key in TPM 2.0 Key File format, only the mode @kbd{nv} +and the NV index handle @kbd{0x1000000} have to be specified for the +@command{tpm2_key_protector_init} command. + +@example +grub> @kbd{tpm2_key_protector_init --mode=nv --nvindex=0x1000000} +grub> @kbd{cryptomount -u --protector tpm2} +@end example + +The following @command{grub-protect} command allows to remove the specified +NV index handle @kbd{0x1000000}. + +@example +@group +# @kbd{grub-protect \ + --protector=tpm2 \ + --action=remove \ + --tpm2-evict \ + --tpm2-nvindex=0x1000000} +@end group +@end example + +@subsection Setting up software TPM for EMU platform + +In order to test TPM2 key protector and TPM2 Software Stack (TSS2), it is +useful to set up a software TPM (swtpm) instance and run the commands on the +EMU platform. + +Here are the commands to start a swtpm instance which provides a character +device interface. To store the TPM states, the directory, @file{swtpm-state}, +is created before the @command{swtpm} command. All the messages are stored +in @file{swtpm.log} including the name of the character device. + +@example +# @kbd{mkdir swtpm-state} +@group +# @kbd{swtpm chardev --vtpm-proxy --tpmstate dir=swtpm-state \ + --tpm2 --ctrl type=unixio,path="swtpm-state/ctrl" \ + --flags startup-clear --daemon > swtpm.log} +@end group +@end example + +Then, we extract the name of the character device from @file{swtpm.log} and +save it to the variable, @samp{tpm2dev}. + +@example +# @kbd{tpm2dev=$(grep "New TPM device" swtpm.log | cut -d' ' -f 4)} +@end example + +Now we can start @kbd{grub-emu} with @kbd{--tpm-device $tpm2dev} to interact +with the swtpm instance. + +@example +# @kbd{grub-emu --tpm-device $tpm2dev} +@end example + +On the host, the tpm2-tools commands can interact with the swtpm instance by +setting @samp{TPM2TOOLS_TCTI}. + +@example +# @kbd{export TPM2TOOLS_TCTI="device:$tpm2dev"} +@end example + +When the test is done, use @kbd{swtpm_ioctl} to send the shutdown +command through the swtpm control channel. + +@example +# @kbd{swtpm_ioctl -s --unix swtpm-state/ctrl} +@end example + +@subsection Command line and menuentry editor protection + +The TPM key protector provides full disk encryption support on servers or +virtual machine images, meanwhile keeping the boot process unattended. This +prevents service disruptions by eliminating the need for manual password input +during startup, improving system uptime and continuity. It is achieved by TPM, +which verifies the integrity of boot components by checking cryptographic +hashes against securely stored values, to confirm the disks are unlocked in a +trusted state. + +However, for users to access the system interactively, some form of +authentication is still required, as the disks are not unlocked by an +authorized user. This raised concerns about using an unprotected +@samp{command-line interface} (@pxref{Command-line interface}), as anyone could +execute commands to access decrypted data. To address this issue, the LUKS +password is used to ensure that only authorized users are granted access to the +interface. Additionally, the @samp{menu entry editor} (@pxref{Menu entry +editor}) is also safeguarded by the LUKS password, as modifying a boot entry is +effectively the same as altering the @file{grub.cfg} file read from encrypted +files. + +It is worth mentioning that the built-in password support, as described in +@samp{Authentication and Authorization in GRUB} (@pxref{Authentication and +authorisation}), can also be used to protect the command-line interface from +unauthorized access. However, it is not recommended to rely on this approach as +it is an optional step. Setting it up requires additional manual intervention, +which increases the risk of password leakage during the process. Moreover, the +superuser list must be well maintained, and the password used cannot be +synchronized with LUKS key rotation. + @node Platform limitations @chapter Platform limitations @@ -5646,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. @@ -5655,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. @@ -5664,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. @@ -5680,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. @@ -5694,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. @@ -5711,6 +9445,8 @@ to install to is specified, UUID is used instead as well. @item USB @tab yes @tab yes @tab yes @tab yes @item chainloader @tab local @tab yes @tab yes @tab no @item cpuid @tab partial @tab partial @tab partial @tab partial +@item rdmsr @tab partial @tab partial @tab partial @tab partial +@item wrmsr @tab partial @tab partial @tab partial @tab partial @item hints @tab guess @tab guess @tab guess @tab guess @item PCI @tab yes @tab yes @tab yes @tab yes @item badram @tab yes @tab yes @tab yes @tab yes @@ -5730,6 +9466,8 @@ to install to is specified, UUID is used instead as well. @item USB @tab yes @tab yes @tab yes @tab no @item chainloader @tab local @tab local @tab no @tab local @item cpuid @tab partial @tab partial @tab partial @tab no +@item rdmsr @tab partial @tab partial @tab partial @tab no +@item wrmsr @tab partial @tab partial @tab partial @tab no @item hints @tab guess @tab guess @tab good @tab guess @item PCI @tab yes @tab yes @tab yes @tab no @item badram @tab yes @tab yes @tab no @tab yes @@ -5749,6 +9487,8 @@ to install to is specified, UUID is used instead as well. @item USB @tab yes @tab no @tab no @tab no @item chainloader @tab yes @tab no @tab no @tab no @item cpuid @tab no @tab no @tab no @tab no +@item rdmsr @tab no @tab no @tab no @tab no +@item wrmsr @tab no @tab no @tab no @tab no @item hints @tab good @tab good @tab good @tab no @item PCI @tab yes @tab no @tab no @tab no @item badram @tab yes (*) @tab no @tab no @tab no @@ -5768,6 +9508,8 @@ to install to is specified, UUID is used instead as well. @item USB @tab N/A @tab yes @tab no @item chainloader @tab yes @tab no @tab yes @item cpuid @tab no @tab no @tab yes +@item rdmsr @tab no @tab no @tab yes +@item wrmsr @tab no @tab no @tab yes @item hints @tab guess @tab no @tab no @item PCI @tab no @tab no @tab no @item badram @tab yes (*) @tab no @tab no @@ -5809,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 @@ -5968,6 +9710,7 @@ Required files are: @menu * GRUB only offers a rescue shell:: +* Firmware stalls instead of booting GRUB:: @end menu @@ -6038,8 +9781,36 @@ support has not yet been added to GRUB. @end itemize +@node Firmware stalls instead of booting GRUB +@section Firmware stalls instead of booting GRUB + +The EFI implementation of some older MacBook laptops stalls when it gets +presented a grub-mkrescue ISO image for x86_64-efi target on an USB stick. +Affected are models of year 2010 or earlier. Workaround is to zeroize the +bytes 446 to 461 of the EFI partition, where mformat has put a partition table +entry which claims partition start at block 0. This change will not hamper +bootability on other machines. + + +@node User-space utilities +@chapter User-space utilities + +@menu +* Invoking grub-install:: How to use the GRUB installer +* Invoking grub-mkconfig:: Generate a GRUB configuration file +* Invoking grub-mkpasswd-pbkdf2:: + Generate GRUB password hashes +* Invoking grub-mkrelpath:: Make system path relative to its root +* Invoking grub-mkrescue:: Make a GRUB rescue image +* Invoking grub-mount:: Mount a file system using GRUB +* Invoking grub-probe:: Probe device information for GRUB +* Invoking grub-protect:: Protect a disk key with a key protector +* Invoking grub-script-check:: Check GRUB script file for syntax errors +@end menu + + @node Invoking grub-install -@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 @@ -6105,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}). @@ -6131,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}). @@ -6159,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 @@ -6186,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}). @@ -6244,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 @@ -6331,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. @@ -6416,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 f08bcc404..d8c6965d8 100644 --- a/gentpl.py +++ b/gentpl.py @@ -28,30 +28,36 @@ import re GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275", "x86_64_efi", - "i386_xen", "x86_64_xen", + "i386_xen", "x86_64_xen", "i386_xen_pvh", "mips_loongson", "sparc64_ieee1275", "powerpc_ieee1275", "mips_arc", "ia64_efi", - "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi" ] + "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", + "arm_coreboot", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] GROUPS = {} GROUPS["common"] = GRUB_PLATFORMS[:] # Groups based on CPU -GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] -GROUPS["x86_64"] = [ "x86_64_efi" ] -GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] -GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] -GROUPS["sparc64"] = [ "sparc64_ieee1275" ] -GROUPS["powerpc"] = [ "powerpc_ieee1275" ] -GROUPS["arm"] = [ "arm_uboot", "arm_efi" ] -GROUPS["arm64"] = [ "arm64_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" ] +GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", + "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] GROUPS["uboot"] = [ "arm_uboot" ] GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] +GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ] # emu is a special case so many core functionality isn't needed on this platform GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") @@ -61,24 +67,24 @@ GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips", "sparc64_ieee1275", "powerpc_ieee1275"] GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi"); GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] -GROUPS["usb"] = GROUPS["pci"] +GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"] # If gfxterm is main output console integrate it into kernel -GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot" ] +GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ] GROUPS["videomodules"] = GRUB_PLATFORMS[:]; for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) # Similar for terminfo -GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"]; +GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"]; GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) # Flattened Device Trees (FDT) -GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi" ] +GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] # Needs software helpers for division # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h -GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] +GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"] GROUPS["no_softdiv"] = GRUB_PLATFORMS[:] for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i) @@ -563,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): @@ -624,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") @@ -650,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): @@ -692,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): @@ -761,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 """) @@ -812,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: @@ -854,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 04e9395fd..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 @@ -101,7 +106,20 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h endif +if COND_i386_xen_pvh +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h +endif + if COND_i386_efi +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h @@ -111,8 +129,9 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h endif if COND_i386_coreboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h @@ -122,6 +141,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h endif if COND_i386_multiboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h endif @@ -132,7 +152,9 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h endif if COND_i386_ieee1275 +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/alloc.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h @@ -140,6 +162,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h endif if COND_i386_xen +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h @@ -158,6 +181,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h endif if COND_x86_64_efi +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h @@ -218,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 @@ -239,8 +264,21 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h endif +if COND_arm_coreboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h +endif + if COND_arm_efi -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/efi/loader.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h @@ -253,6 +291,24 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h endif +if COND_loongarch64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_riscv32_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_riscv64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + if COND_emu KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h @@ -260,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 @@ -278,7 +338,7 @@ BUILT_SOURCES += symlist.h symlist.c: symlist.h gensymlist.sh $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1) - cat symlist.p | /bin/sh $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1) + cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1) rm -f symlist.p CLEANFILES += symlist.c BUILT_SOURCES += symlist.c @@ -332,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 @@ -358,6 +420,16 @@ terminal.lst: $(MARKER_FILES) platform_DATA += terminal.lst CLEANFILES += terminal.lst +fdt.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ + -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += fdt.lst +CLEANFILES += fdt.lst + parttool.lst: $(MARKER_FILES) (for pp in $^; do \ b=`basename $$pp .marker`; \ @@ -383,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 @@ -394,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 2dfa22a92..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,36 +49,54 @@ 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'; + loongarch64_efi_cflags = '-fshort-wchar'; + loongarch64_efi_ldflags = '-Wl,-r'; + loongarch64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; + + riscv32_efi_cflags = '-fshort-wchar'; + riscv32_efi_ldflags = '-Wl,-r'; + riscv32_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; + + riscv64_efi_cflags = '-fshort-wchar'; + riscv64_efi_ldflags = '-Wl,-r'; + riscv64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; + i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; i386_coreboot_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_coreboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; + i386_coreboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; i386_multiboot_ldflags = '$(TARGET_IMG_LDFLAGS)'; - i386_multiboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200'; + i386_multiboot_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000'; i386_ieee1275_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_ieee1275_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x10000'; i386_xen_ldflags = '$(TARGET_IMG_LDFLAGS)'; i386_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0'; x86_64_xen_ldflags = '$(TARGET_IMG_LDFLAGS)'; x86_64_xen_ldflags = '$(TARGET_IMG_BASE_LDOPT),0'; + i386_xen_pvh_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000'; mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; @@ -90,14 +108,17 @@ 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'; + arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; i386_pc_startup = kern/i386/pc/startup.S; i386_efi_startup = kern/i386/efi/startup.S; x86_64_efi_startup = kern/x86_64/efi/startup.S; i386_xen_startup = kern/i386/xen/startup.S; x86_64_xen_startup = kern/x86_64/xen/startup.S; + i386_xen_pvh_startup = kern/i386/xen/startup_pvh.S; i386_qemu_startup = kern/i386/qemu/startup.S; i386_ieee1275_startup = kern/i386/ieee1275/startup.S; i386_coreboot_startup = kern/i386/coreboot/startup.S; @@ -105,10 +126,15 @@ kernel = { mips_startup = kern/mips/startup.S; sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; - arm_uboot_startup = kern/arm/uboot/startup.S; + arm_uboot_startup = kern/arm/startup.S; + arm_coreboot_startup = kern/arm/startup.S; arm_efi_startup = kern/arm/efi/startup.S; arm64_efi_startup = kern/arm64/efi/startup.S; + loongarch64_efi_startup = kern/loongarch64/efi/startup.S; + riscv32_efi_startup = kern/riscv/efi/startup.S; + riscv64_efi_startup = kern/riscv/efi/startup.S; + common = kern/buffer.c; common = kern/command.c; common = kern/corecmd.c; common = kern/device.c; @@ -126,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; @@ -149,6 +176,21 @@ kernel = { uboot = kern/uboot/init.c; uboot = kern/uboot/hw.c; uboot = term/uboot/console.c; + arm_uboot = kern/arm/uboot/init.c; + arm_uboot = kern/arm/uboot/uboot.S; + + arm_coreboot = kern/arm/coreboot/init.c; + arm_coreboot = kern/arm/coreboot/timer.c; + arm_coreboot = kern/arm/coreboot/coreboot.S; + arm_coreboot = lib/fdt.c; + arm_coreboot = bus/fdt.c; + arm_coreboot = term/ps2.c; + arm_coreboot = term/arm/pl050.c; + arm_coreboot = term/arm/cros.c; + arm_coreboot = term/arm/cros_ec.c; + arm_coreboot = bus/spi/rk3288_spi.c; + arm_coreboot = commands/keylayouts.c; + arm_coreboot = kern/arm/coreboot/dma.c; terminfoinkernel = term/terminfo.c; terminfoinkernel = term/tparm.c; @@ -159,20 +201,24 @@ kernel = { i386 = kern/i386/dl.c; i386_xen = kern/i386/dl.c; + i386_xen_pvh = kern/i386/dl.c; i386_coreboot = kern/i386/coreboot/init.c; i386_multiboot = kern/i386/coreboot/init.c; i386_qemu = kern/i386/qemu/init.c; i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c; - i386_coreboot = video/i386/coreboot/cbfb.c; + coreboot = video/coreboot/cbfb.c; efi = disk/efi/efidisk.c; efi = kern/efi/efi.c; + efi = kern/efi/debug.c; efi = kern/efi/init.c; efi = kern/efi/mm.c; efi = term/efi/console.c; efi = kern/acpi.c; efi = kern/efi/acpi.c; + efi = kern/efi/sb.c; + efi = kern/lockdown.c; i386_coreboot = kern/i386/pc/acpi.c; i386_multiboot = kern/i386/pc/acpi.c; i386_coreboot = kern/acpi.c; @@ -191,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; @@ -204,6 +249,14 @@ kernel = { xen = disk/xen/xendisk.c; xen = commands/boot.c; + i386_xen_pvh = commands/boot.c; + i386_xen_pvh = disk/xen/xendisk.c; + i386_xen_pvh = kern/i386/tsc.c; + i386_xen_pvh = kern/i386/xen/tsc.c; + i386_xen_pvh = kern/i386/xen/pvh.c; + i386_xen_pvh = kern/xen/init.c; + i386_xen_pvh = term/xen/console.c; + ia64_efi = kern/ia64/efi/startup.S; ia64_efi = kern/ia64/efi/init.c; ia64_efi = kern/ia64/dl.c; @@ -211,12 +264,20 @@ kernel = { ia64_efi = kern/ia64/cache.c; arm_efi = kern/arm/efi/init.c; - arm_efi = kern/arm/efi/misc.c; arm_efi = kern/efi/fdt.c; arm64_efi = kern/arm64/efi/init.c; arm64_efi = kern/efi/fdt.c; + loongarch64_efi = kern/loongarch64/efi/init.c; + loongarch64_efi = kern/efi/fdt.c; + + riscv32_efi = kern/riscv/efi/init.c; + riscv32_efi = kern/efi/fdt.c; + + riscv64_efi = kern/riscv/efi/init.c; + riscv64_efi = kern/efi/fdt.c; + i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/mmap.c; i386_pc = term/i386/pc/console.c; @@ -225,8 +286,10 @@ kernel = { i386_qemu = kern/vga_init.c; i386_qemu = kern/i386/qemu/mmap.c; - i386_coreboot = kern/i386/coreboot/mmap.c; + coreboot = kern/coreboot/mmap.c; i386_coreboot = kern/i386/coreboot/cbtable.c; + coreboot = kern/coreboot/cbtable.c; + arm_coreboot = kern/arm/coreboot/cbtable.c; i386_multiboot = kern/i386/multiboot_mmap.c; @@ -238,6 +301,7 @@ kernel = { mips_qemu_mips = term/ns8250.c; mips_qemu_mips = term/serial.c; mips_qemu_mips = term/at_keyboard.c; + mips_qemu_mips = term/ps2.c; mips_qemu_mips = commands/boot.c; mips_qemu_mips = commands/keylayouts.c; mips_qemu_mips = term/i386/pc/vga_text.c; @@ -253,6 +317,7 @@ kernel = { mips_loongson = bus/pci.c; mips_loongson = kern/mips/loongson/init.c; mips_loongson = term/at_keyboard.c; + mips_loongson = term/ps2.c; mips_loongson = commands/boot.c; mips_loongson = term/serial.c; mips_loongson = video/sm712.c; @@ -270,6 +335,7 @@ kernel = { sparc64_ieee1275 = kern/sparc64/cache.S; sparc64_ieee1275 = kern/sparc64/dl.c; sparc64_ieee1275 = kern/sparc64/ieee1275/ieee1275.c; + sparc64_ieee1275 = disk/ieee1275/obdisk.c; arm = kern/arm/dl.c; arm = kern/arm/dl_helper.c; @@ -284,6 +350,19 @@ 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; + + riscv64 = kern/riscv/cache.c; + riscv64 = kern/riscv/cache_flush.S; + riscv64 = kern/riscv/dl.c; + emu = disk/host.c; emu = kern/emu/cache_s.S; emu = kern/emu/hostdisk.c; @@ -339,7 +418,7 @@ program = { ldadd = 'kernel.exec$(EXEEXT)'; ldadd = '$(MODULE_FILES)'; - ldadd = '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; }; @@ -351,7 +430,7 @@ program = { emu_nodist = symlist.c; ldadd = 'kernel.exec$(EXEEXT)'; - ldadd = '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; }; @@ -369,8 +448,14 @@ image = { i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_BOOT_MACHINE_LINK_ADDR)'; i386_qemu_ccasflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; - sparc64_ieee1275_objcopyflags = '-O a.out-sunos-big'; - sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000'; + /* The entry point for a.out binaries on sparc64 starts + at 0x4000. Since we are writing the 32 bytes long a.out + header in the assembly code ourselves, we need to tell + the linker to adjust the start of the text segment to + 0x4000 - 0x20 = 0x3fe0. + */ + sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; + sparc64_ieee1275_objcopyflags = '-O binary'; objcopyflags = '-O binary'; enable = i386_pc; @@ -399,8 +484,10 @@ image = { i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S; - sparc64_ieee1275_objcopyflags = '-O a.out-sunos-big'; - sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000'; + + /* See comment for sparc64_ieee1275_ldflags above. */ + sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x3fe0'; + sparc64_ieee1275_objcopyflags = '-O binary'; sparc64_ieee1275_cppflags = '-DCDBOOT=1'; objcopyflags = '-O binary'; @@ -449,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; @@ -467,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'; @@ -574,7 +661,10 @@ module = { module = { name = ehci; common = bus/usb/ehci.c; + arm_coreboot = bus/usb/ehci-fdt.c; + pci = bus/usb/ehci-pci.c; enable = pci; + enable = arm_coreboot; }; module = { @@ -624,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 = { @@ -641,6 +735,7 @@ module = { module = { name = cbtable; common = kern/i386/coreboot/cbtable.c; + common = kern/coreboot/cbtable.c; enable = i386_pc; enable = i386_efi; enable = i386_qemu; @@ -671,7 +766,10 @@ module = { name = regexp; common = commands/regexp.c; common = commands/wildcard.c; - common = gnulib/regex.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)'; }; @@ -736,6 +834,12 @@ module = { enable = efi; }; +module = { + name = efitextmode; + efi = commands/efi/efitextmode.c; + enable = efi; +}; + module = { name = blocklist; common = commands/blocklist.c; @@ -754,6 +858,10 @@ module = { enable = arm_efi; enable = arm64_efi; enable = arm_uboot; + enable = arm_coreboot; + enable = loongarch64_efi; + enable = riscv32_efi; + enable = riscv64_efi; }; module = { @@ -775,6 +883,7 @@ module = { name = cpuid; common = commands/i386/cpuid.c; enable = x86; + enable = i386_xen_pvh; enable = i386_xen; enable = x86_64_xen; }; @@ -834,27 +943,27 @@ module = { i386_coreboot = lib/i386/halt.c; i386_qemu = lib/i386/halt.c; xen = lib/xen/halt.c; + i386_xen_pvh = lib/xen/halt.c; efi = lib/efi/halt.c; ieee1275 = lib/ieee1275/halt.c; emu = lib/emu/halt.c; - uboot = lib/uboot/halt.c; + uboot = lib/dummy/halt.c; + arm_coreboot = lib/dummy/halt.c; }; module = { name = reboot; i386 = lib/i386/reboot.c; i386 = lib/i386/reboot_trampoline.S; - ia64_efi = lib/efi/reboot.c; - x86_64_efi = lib/efi/reboot.c; - arm_efi = lib/efi/reboot.c; - arm64_efi = lib/efi/reboot.c; powerpc_ieee1275 = lib/ieee1275/reboot.c; sparc64_ieee1275 = lib/ieee1275/reboot.c; mips_arc = lib/mips/arc/reboot.c; mips_loongson = lib/mips/loongson/reboot.c; mips_qemu_mips = lib/mips/qemu_mips/reboot.c; xen = lib/xen/reboot.c; + i386_xen_pvh = lib/xen/reboot.c; uboot = lib/uboot/reboot.c; + arm_coreboot = lib/dummy/reboot.c; common = commands/reboot.c; }; @@ -864,8 +973,8 @@ module = { }; module = { - name = verify; - common = commands/verify.c; + name = pgp; + common = commands/pgp.c; cflags = '$(CFLAGS_POSIX)'; cppflags = '-I$(srcdir)/lib/posix_wrap'; }; @@ -873,7 +982,6 @@ module = { module = { name = hdparm; common = commands/hdparm.c; - common = lib/hexdump.c; enable = pci; enable = mips_qemu_mips; }; @@ -1015,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; @@ -1028,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; @@ -1079,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 = { @@ -1130,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; @@ -1237,12 +1394,27 @@ module = { common = fs/bfs.c; }; +module = { + name = zstd; + common = lib/zstd/debug.c; + common = lib/zstd/entropy_common.c; + common = lib/zstd/error_private.c; + common = lib/zstd/fse_decompress.c; + common = lib/zstd/huf_decompress.c; + common = lib/zstd/module.c; + common = lib/zstd/xxhash.c; + common = lib/zstd/zstd_common.c; + common = lib/zstd/zstd_decompress.c; + cflags = '$(CFLAGS_POSIX) -Wno-undef'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/zstd'; +}; + module = { name = btrfs; common = fs/btrfs.c; common = lib/crc.c; cflags = '$(CFLAGS_POSIX) -Wno-undef'; - cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -DMINILZO_HAVE_CONFIG_H'; + cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/minilzo -I$(srcdir)/lib/zstd -DMINILZO_HAVE_CONFIG_H'; }; module = { @@ -1275,6 +1447,11 @@ module = { common = fs/odc.c; }; +module = { + name = erofs; + common = fs/erofs.c; +}; + module = { name = ext2; common = fs/ext2.c; @@ -1290,6 +1467,11 @@ module = { common = fs/exfat.c; }; +module = { + name = f2fs; + common = fs/f2fs.c; +}; + module = { name = fshelp; common = fs/fshelp.c; @@ -1424,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 = { @@ -1517,12 +1700,18 @@ module = { x86 = lib/i386/relocator16.S; x86 = lib/i386/relocator32.S; x86 = lib/i386/relocator64.S; + i386_xen_pvh = lib/i386/relocator16.S; + i386_xen_pvh = lib/i386/relocator32.S; + i386_xen_pvh = lib/i386/relocator64.S; i386 = lib/i386/relocator_asm.S; + i386_xen_pvh = lib/i386/relocator_asm.S; x86_64 = lib/x86_64/relocator_asm.S; i386_xen = lib/i386/relocator_asm.S; x86_64_xen = lib/x86_64/relocator_asm.S; x86 = lib/i386/relocator.c; x86 = lib/i386/relocator_common_c.c; + i386_xen_pvh = lib/i386/relocator.c; + i386_xen_pvh = lib/i386/relocator_common_c.c; ieee1275 = lib/ieee1275/relocator.c; efi = lib/efi/relocator.c; mips = lib/mips/relocator_asm.S; @@ -1541,22 +1730,25 @@ module = { enable = mips; enable = powerpc; enable = x86; + enable = i386_xen_pvh; enable = xen; }; module = { name = datetime; + common = lib/datetime.c; cmos = lib/cmos_datetime.c; efi = lib/efi/datetime.c; - uboot = lib/uboot/datetime.c; + uboot = lib/dummy/datetime.c; + arm_coreboot = lib/dummy/datetime.c; sparc64_ieee1275 = lib/ieee1275/datetime.c; powerpc_ieee1275 = lib/ieee1275/datetime.c; sparc64_ieee1275 = lib/ieee1275/cmos.c; powerpc_ieee1275 = lib/ieee1275/cmos.c; xen = lib/xen/datetime.c; + i386_xen_pvh = lib/xen/datetime.c; mips_arc = lib/arc/datetime.c; - enable = noemu; }; module = { @@ -1571,6 +1763,8 @@ module = { extra_dist = lib/ia64/longjmp.S; extra_dist = lib/arm/setjmp.S; extra_dist = lib/arm64/setjmp.S; + extra_dist = lib/riscv/setjmp.S; + extra_dist = lib/loongarch64/setjmp.S; }; module = { @@ -1601,8 +1795,6 @@ module = { module = { name = linux16; common = loader/i386/pc/linux.c; - common = loader/linux.c; - common = lib/cmdline.c; enable = x86; }; @@ -1637,24 +1829,24 @@ module = { cppflags = "-DGRUB_USE_MULTIBOOT2"; common = loader/multiboot.c; - common = lib/cmdline.c; common = loader/multiboot_mbi2.c; enable = x86; + enable = i386_xen_pvh; enable = mips; }; module = { name = multiboot; common = loader/multiboot.c; - common = lib/cmdline.c; x86 = loader/i386/multiboot_mbi.c; + i386_xen_pvh = loader/i386/multiboot_mbi.c; extra_dist = loader/multiboot_elfxx.c; enable = x86; + enable = i386_xen_pvh; }; module = { name = xen_boot; - common = lib/cmdline.c; arm64 = loader/arm64/xen_boot.c; enable = arm64; }; @@ -1662,22 +1854,31 @@ module = { module = { name = linux; x86 = loader/i386/linux.c; + i386_xen_pvh = loader/i386/linux.c; xen = loader/i386/xen.c; i386_pc = lib/i386/pc/vesa_modes_table.c; + i386_xen_pvh = lib/i386/pc/vesa_modes_table.c; mips = loader/mips/linux.c; powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; ia64_efi = loader/ia64/efi/linux.c; - arm = loader/arm/linux.c; - arm64 = loader/arm64/linux.c; + arm_coreboot = loader/arm/linux.c; + arm_efi = loader/efi/linux.c; + arm_uboot = loader/arm/linux.c; + arm64 = loader/efi/linux.c; + loongarch64 = loader/efi/linux.c; + riscv32 = loader/efi/linux.c; + riscv64 = loader/efi/linux.c; + i386_efi = loader/efi/linux.c; + x86_64_efi = loader/efi/linux.c; + emu = loader/emu/linux.c; common = loader/linux.c; common = lib/cmdline.c; - enable = noemu; }; module = { name = fdt; - arm64 = loader/arm64/fdt.c; + efi = loader/efi/fdt.c; common = lib/fdt.c; enable = fdt; }; @@ -1749,6 +1950,8 @@ module = { common = mmap/mmap.c; x86 = mmap/i386/uppermem.c; x86 = mmap/i386/mmap.c; + i386_xen_pvh = mmap/i386/uppermem.c; + i386_xen_pvh = mmap/i386/mmap.c; i386_pc = mmap/i386/pc/mmap.c; i386_pc = mmap/i386/pc/mmap_helper.S; @@ -1758,9 +1961,13 @@ module = { mips = mmap/mips/uppermem.c; enable = x86; + enable = i386_xen_pvh; enable = ia64_efi; enable = arm_efi; enable = arm64_efi; + enable = loongarch64_efi; + enable = riscv32_efi; + enable = riscv64_efi; enable = mips; }; @@ -1773,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; @@ -1802,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)'; }; @@ -1869,6 +2075,7 @@ module = { module = { name = at_keyboard; common = term/at_keyboard.c; + common = term/ps2.c; enable = x86; }; @@ -1887,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; @@ -1961,6 +2170,11 @@ module = { common = tests/example_functional_test.c; }; +module = { + name = strtoull_test; + common = tests/strtoull_test.c; +}; + module = { name = setjmp_test; common = tests/setjmp_test.c; @@ -1991,6 +2205,7 @@ module = { name = legacy_password_test; common = tests/legacy_password_test.c; enable = i386_pc; + enable = i386_xen_pvh; enable = i386_efi; enable = x86_64_efi; enable = emu; @@ -2125,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; @@ -2189,6 +2412,7 @@ module = { xen = lib/i386/pc/vesa_modes_table.c; enable = i386_pc; + enable = i386_xen_pvh; enable = i386_efi; enable = x86_64_efi; enable = emu; @@ -2232,10 +2456,12 @@ module = { module = { name = backtrace; x86 = lib/i386/backtrace.c; + i386_xen_pvh = lib/i386/backtrace.c; i386_xen = lib/i386/backtrace.c; x86_64_xen = lib/i386/backtrace.c; common = lib/backtrace.c; enable = x86; + enable = i386_xen_pvh; enable = i386_xen; enable = x86_64_xen; }; @@ -2334,6 +2560,41 @@ module = { common = commands/testspeed.c; }; +module = { + name = tpm; + common = commands/tpm.c; + efi = commands/efi/tpm.c; + enable = efi; +}; + +module = { + name = tss2; + common = lib/tss2/buffer.c; + common = lib/tss2/tss2_mu.c; + common = lib/tss2/tpm2_cmd.c; + common = lib/tss2/tss2.c; + efi = lib/efi/tcg2.c; + emu = lib/tss2/tcg2_emu.c; + powerpc_ieee1275 = lib/ieee1275/tcg2.c; + enable = efi; + enable = emu; + enable = powerpc_ieee1275; + cppflags = '-I$(srcdir)/lib/tss2'; +}; + +module = { + name = tpm2_key_protector; + common = commands/tpm2_key_protector/args.c; + common = commands/tpm2_key_protector/module.c; + common = commands/tpm2_key_protector/tpm2key.c; + common = commands/tpm2_key_protector/tpm2key_asn1_tab.c; + /* The plaform support of tpm2_key_protector depends on the tcg2 implementation in tss2. */ + enable = efi; + enable = emu; + enable = powerpc_ieee1275; + cppflags = '-I$(srcdir)/lib/tss2 -I$(srcdir)/lib/libtasn1-grub'; +}; + module = { name = tr; common = commands/tr.c; @@ -2355,3 +2616,56 @@ module = { common = loader/i386/xen_file64.c; extra_dist = loader/i386/xen_fileXX.c; }; +module = { + name = rdmsr; + common = commands/i386/rdmsr.c; + enable = x86; +}; +module = { + name = wrmsr; + common = commands/i386/wrmsr.c; + enable = x86; +}; + +module = { + name = memtools; + common = commands/memtools.c; + condition = COND_MM_DEBUG; +}; + +module = { + name = bli; + efi = commands/bli.c; + enable = efi; + depends = part_gpt; +}; + +module = { + name = asn1; + common = lib/libtasn1-grub/lib/decoding.c; + common = lib/libtasn1-grub/lib/coding.c; + common = lib/libtasn1-grub/lib/element.c; + common = lib/libtasn1-grub/lib/structure.c; + common = lib/libtasn1-grub/lib/parser_aux.c; + common = lib/libtasn1-grub/lib/gstr.c; + common = lib/libtasn1-grub/lib/errors.c; + common = lib/libtasn1_wrap/wrap.c; + cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; + /* -Wno-type-limits comes from configure.ac of libtasn1 */ + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/lib/libtasn1-grub/lib -Wno-type-limits'; +}; + +module = { + name = asn1_test; + common = tests/asn1/tests/CVE-2018-1000654.c; + common = tests/asn1/tests/object-id-decoding.c; + common = tests/asn1/tests/object-id-encoding.c; + common = tests/asn1/tests/octet-string.c; + common = tests/asn1/tests/reproducers.c; + common = tests/asn1/tests/Test_overflow.c; + common = tests/asn1/tests/Test_simple.c; + common = tests/asn1/tests/Test_strings.c; + common = tests/asn1/asn1_test.c; + cflags = '-Wno-uninitialized'; + cppflags = '-I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/tests/asn1/'; +}; diff --git a/grub-core/boot/i386/pc/diskboot.S b/grub-core/boot/i386/pc/diskboot.S index 1ee4cf5b2..c1addc0df 100644 --- a/grub-core/boot/i386/pc/diskboot.S +++ b/grub-core/boot/i386/pc/diskboot.S @@ -37,8 +37,8 @@ start: _start: /* - * _start is loaded at 0x2000 and is jumped to with - * CS:IP 0:0x2000 in kernel. + * _start is loaded at 0x8000 and is jumped to with + * CS:IP 0:0x8000 in kernel. */ /* diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S index 8bce7985c..28974821e 100644 --- a/grub-core/boot/i386/pc/startup_raw.S +++ b/grub-core/boot/i386/pc/startup_raw.S @@ -118,7 +118,16 @@ LOCAL (codestart): #include "../../../kern/i386/realmode.S" +/* + * + * This is a workaround for clang adding a section containing only .addrsig + * Since clang itself is unable to assemble this pseudo-opcode, just replace + * it with .text + * + */ +#define addrsig text #include +#undef addrsig .text diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S index 586efb401..ff8a79d3b 100644 --- a/grub-core/boot/sparc64/ieee1275/boot.S +++ b/grub-core/boot/sparc64/ieee1275/boot.S @@ -21,6 +21,24 @@ .text .align 4 + /* + * We're writing the a.out header ourselves as newer + * upstream versions of binutils no longer support + * the a.out format on sparc64. + * + * The boot loader fits into 512 bytes with 32 bytes + * used for the a.out header, hence the text segment + * size is 512 - 32. There is no data segment and no + * code relocation, thus those fields remain zero. + */ + .word 0x1030107 /* Magic number. */ + .word 512 - GRUB_BOOT_AOUT_HEADER_SIZE /* Size of text segment. */ + .word 0 /* Size of initialized data. */ + .word 0 /* Size of uninitialized data. */ + .word 0 /* Size of symbol table || checksum. */ + .word _start /* Entry point. */ + .word 0 /* Size of text relocation. */ + .word 0 /* Size of data relocation. */ .globl _start _start: /* OF CIF entry point arrives in %o4 */ @@ -30,7 +48,7 @@ pic_base: #ifndef CDBOOT /* The offsets to these locations are defined by the - * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h, + * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc64/ieee1275/boot.h, * and grub-setup uses this to patch these next three values as needed. * * The boot_path will be the OF device path of the partition where the @@ -40,10 +58,14 @@ pic_base: * * After loading in that block we will execute it by jumping to the * load address plus the size of the prepended A.OUT header (32 bytes). + * + * Since this assembly code includes the 32 bytes long a.out header, + * we need to move the actual code entry point forward by the size + * of the a.out header, i.e. += GRUB_BOOT_AOUT_HEADER_SIZE. */ - .org GRUB_BOOT_MACHINE_BOOT_DEVPATH + .org GRUB_BOOT_MACHINE_BOOT_DEVPATH + GRUB_BOOT_AOUT_HEADER_SIZE boot_path: - .org GRUB_BOOT_MACHINE_KERNEL_BYTE + .org GRUB_BOOT_MACHINE_KERNEL_BYTE + GRUB_BOOT_AOUT_HEADER_SIZE boot_path_end: kernel_byte: .xword (2 << 9) kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR @@ -52,7 +74,7 @@ kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR #define boot_path_end (_start + 1024) #include - .org 8 + .org 8 + GRUB_BOOT_AOUT_HEADER_SIZE kernel_byte: .xword (2 << 9) kernel_size: .word 512 kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS @@ -69,6 +91,10 @@ prom_seek_name: .asciz "seek" prom_read_name: .asciz "read" prom_exit_name: .asciz "exit" grub_name: .asciz "GRUB " +#ifdef CDBOOT +prom_close_name: .asciz "close" +#endif + #define GRUB_NAME_LEN 5 .align 4 @@ -213,6 +239,12 @@ bootpath_known: call prom_call_3_1_o1 #ifdef CDBOOT LDUW_ABS(kernel_size, 0x00, %o3) + + GET_ABS(prom_close_name, %o0) + mov 1, %g1 + mov 0, %o5 + call prom_call + mov BOOTDEV_REG, %o1 #else mov 512, %o3 #endif 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/fdt.c b/grub-core/bus/fdt.c new file mode 100644 index 000000000..135da497b --- /dev/null +++ b/grub-core/bus/fdt.c @@ -0,0 +1,256 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +static const void *dtb; +static grub_size_t root_address_cells, root_size_cells; +/* Pointer to this symbol signals invalid mapping. */ +char grub_fdtbus_invalid_mapping[1]; + +struct grub_fdtbus_dev *devs; +struct grub_fdtbus_driver *drivers; + +int +grub_fdtbus_is_compatible (const char *compat_string, + const struct grub_fdtbus_dev *dev) +{ + grub_size_t compatible_size; + const char *compatible = grub_fdt_get_prop (dtb, dev->node, "compatible", + &compatible_size); + if (!compatible) + return 0; + const char *compatible_end = compatible + compatible_size; + while (compatible < compatible_end) + { + if (grub_strcmp (compat_string, compatible) == 0) + return 1; + compatible += grub_strlen (compatible) + 1; + } + return 0; +} + +static void +fdtbus_scan (struct grub_fdtbus_dev *parent) +{ + int node; + for (node = grub_fdt_first_node (dtb, parent ? parent->node : 0); node >= 0; + node = grub_fdt_next_node (dtb, node)) + { + struct grub_fdtbus_dev *dev; + struct grub_fdtbus_driver *driver; + dev = grub_zalloc (sizeof (*dev)); + if (!dev) + { + grub_print_error (); + return; + } + dev->node = node; + dev->next = devs; + dev->parent = parent; + devs = dev; + FOR_LIST_ELEMENTS(driver, drivers) + if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev)) + { + grub_dprintf ("fdtbus", "Attaching %s\n", driver->compatible); + if (driver->attach (dev) == GRUB_ERR_NONE) + { + grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible); + dev->driver = driver; + break; + } + grub_print_error (); + } + fdtbus_scan (dev); + } +} + +void +grub_fdtbus_register (struct grub_fdtbus_driver *driver) +{ + struct grub_fdtbus_dev *dev; + grub_dprintf ("fdtbus", "Registering %s\n", driver->compatible); + grub_list_push (GRUB_AS_LIST_P (&drivers), + GRUB_AS_LIST (driver)); + for (dev = devs; dev; dev = dev->next) + if (!dev->driver && grub_fdtbus_is_compatible (driver->compatible, dev)) + { + grub_dprintf ("fdtbus", "Attaching %s (%p)\n", driver->compatible, dev); + if (driver->attach (dev) == GRUB_ERR_NONE) + { + grub_dprintf ("fdtbus", "Attached %s\n", driver->compatible); + dev->driver = driver; + } + grub_print_error (); + } +} + +void +grub_fdtbus_unregister (struct grub_fdtbus_driver *driver) +{ + grub_list_remove (GRUB_AS_LIST (driver)); + struct grub_fdtbus_dev *dev; + for (dev = devs; dev; dev = dev->next) + if (dev->driver == driver) + { + if (driver->detach) + driver->detach(dev); + dev->driver = 0; + } +} + +void +grub_fdtbus_init (const void *dtb_in, grub_size_t size) +{ + if (!dtb_in || grub_fdt_check_header (dtb_in, size) < 0) + grub_fatal ("invalid FDT"); + dtb = dtb_in; + const grub_uint32_t *prop = grub_fdt_get_prop (dtb, 0, "#address-cells", 0); + if (prop) + root_address_cells = grub_be_to_cpu32 (*prop); + else + root_address_cells = 1; + + prop = grub_fdt_get_prop (dtb, 0, "#size-cells", 0); + if (prop) + root_size_cells = grub_be_to_cpu32 (*prop); + else + root_size_cells = 1; + + fdtbus_scan (0); +} + +static int +get_address_cells (const struct grub_fdtbus_dev *dev) +{ + const grub_uint32_t *prop; + if (!dev) + return root_address_cells; + prop = grub_fdt_get_prop (dtb, dev->node, "#address-cells", 0); + if (prop) + return grub_be_to_cpu32 (*prop); + return 1; +} + +static int +get_size_cells (const struct grub_fdtbus_dev *dev) +{ + const grub_uint32_t *prop; + if (!dev) + return root_size_cells; + prop = grub_fdt_get_prop (dtb, dev->node, "#size-cells", 0); + if (prop) + return grub_be_to_cpu32 (*prop); + return 1; +} + +static grub_uint64_t +get64 (const grub_uint32_t *reg, grub_size_t cells) +{ + grub_uint64_t val = 0; + if (cells >= 1) + val = grub_be_to_cpu32 (reg[cells - 1]); + if (cells >= 2) + val |= ((grub_uint64_t) grub_be_to_cpu32 (reg[cells - 2])) << 32; + return val; +} + +static volatile void * +translate (const struct grub_fdtbus_dev *dev, const grub_uint32_t *reg) +{ + volatile void *ret; + const grub_uint32_t *ranges; + grub_size_t ranges_size, cells_per_mapping; + grub_size_t parent_address_cells, child_address_cells, child_size_cells; + grub_size_t nmappings, i; + if (dev == 0) + { + grub_uint64_t val; + val = get64 (reg, root_address_cells); + if (sizeof (void *) == 4 && (val >> 32)) + return grub_fdtbus_invalid_mapping; + return (void *) (grub_addr_t) val; + } + ranges = grub_fdt_get_prop (dtb, dev->node, "ranges", &ranges_size); + if (!ranges) + return grub_fdtbus_invalid_mapping; + if (ranges_size == 0) + return translate (dev->parent, reg); + parent_address_cells = get_address_cells (dev->parent); + child_address_cells = get_address_cells (dev); + child_size_cells = get_size_cells (dev); + cells_per_mapping = parent_address_cells + child_address_cells + child_size_cells; + nmappings = ranges_size / 4 / cells_per_mapping; + for (i = 0; i < nmappings; i++) + { + const grub_uint32_t *child_addr = &ranges[i * cells_per_mapping]; + const grub_uint32_t *parent_addr = child_addr + child_address_cells; + grub_uint64_t child_size = get64 (parent_addr + parent_address_cells, child_size_cells); + + if (child_address_cells > 2 && grub_memcmp (reg, child_addr, (child_address_cells - 2) * 4) != 0) + continue; + if (get64 (reg, child_address_cells) < get64 (child_addr, child_address_cells)) + continue; + + grub_uint64_t offset = get64 (reg, child_address_cells) - get64 (child_addr, child_address_cells); + if (offset >= child_size) + continue; + + ret = translate (dev->parent, parent_addr); + if (grub_fdtbus_is_mapping_valid (ret)) + ret = (volatile char *) ret + offset; + return ret; + } + return grub_fdtbus_invalid_mapping; +} + +volatile void * +grub_fdtbus_map_reg (const struct grub_fdtbus_dev *dev, int regno, grub_size_t *size) +{ + grub_size_t address_cells, size_cells; + address_cells = get_address_cells (dev->parent); + size_cells = get_size_cells (dev->parent); + const grub_uint32_t *reg = grub_fdt_get_prop (dtb, dev->node, "reg", 0); + if (size && size_cells) + *size = reg[(address_cells + size_cells) * regno + address_cells]; + if (size && !size_cells) + *size = 0; + return translate (dev->parent, reg + (address_cells + size_cells) * regno); +} + +const char * +grub_fdtbus_get_name (const struct grub_fdtbus_dev *dev) +{ + return grub_fdt_get_nodename (dtb, dev->node); +} + +const void * +grub_fdtbus_get_prop (const struct grub_fdtbus_dev *dev, + const char *name, + grub_uint32_t *len) +{ + return grub_fdt_get_prop (dtb, dev->node, name, len); +} + +const void * +grub_fdtbus_get_fdt (void) +{ + return dtb; +} diff --git a/grub-core/bus/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/spi/rk3288_spi.c b/grub-core/bus/spi/rk3288_spi.c new file mode 100644 index 000000000..aacb79ffe --- /dev/null +++ b/grub-core/bus/spi/rk3288_spi.c @@ -0,0 +1,103 @@ +/* + * GRUB -- GRand Unified Bootloader + * + * Copyright (C) 2012 Google Inc. + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * This is based on depthcharge code. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +spi_send (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz) +{ + const grub_uint8_t *ptr = data, *end = ptr + sz; + volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); + spi[2] = 0; + spi[1] = sz - 1; + spi[0] = ((1 << 18) | spi[0]) & ~(1 << 19); + spi[2] = 1; + while (ptr < end) + { + while (spi[9] & 2); + spi[256] = *ptr++; + } + while (spi[9] & 1); + return GRUB_ERR_NONE; +} + +static grub_err_t +spi_receive (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz) +{ + grub_uint8_t *ptr = data, *end = ptr + sz; + volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); + spi[2] = 0; + spi[1] = sz - 1; + spi[0] = ((1 << 19) | spi[0]) & ~(1 << 18); + spi[2] = 1; + while (ptr < end) + { + while (spi[9] & 8); + *ptr++ = spi[512]; + } + while (spi[9] & 1); + return GRUB_ERR_NONE; +} + +static grub_err_t +spi_start (const struct grub_fdtbus_dev *dev) +{ + volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); + spi[3] = 1; + return GRUB_ERR_NONE; +} + +static void +spi_stop (const struct grub_fdtbus_dev *dev) +{ + volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0); + spi[3] = 0; +} + +static grub_err_t +spi_attach(const struct grub_fdtbus_dev *dev) +{ + if (!grub_fdtbus_is_mapping_valid (grub_fdtbus_map_reg (dev, 0, 0))) + return GRUB_ERR_IO; + + return GRUB_ERR_NONE; +} + +static struct grub_fdtbus_driver spi = +{ + .compatible = "rockchip,rk3288-spi", + .attach = spi_attach, + .send = spi_send, + .receive = spi_receive, + .start = spi_start, + .stop = spi_stop, +}; + +void +grub_rk3288_spi_init (void) +{ + grub_fdtbus_register (&spi); +} diff --git a/grub-core/bus/usb/ehci-fdt.c b/grub-core/bus/usb/ehci-fdt.c new file mode 100644 index 000000000..29b50bdd5 --- /dev/null +++ b/grub-core/bus/usb/ehci-fdt.c @@ -0,0 +1,45 @@ +/* ehci.c - EHCI Support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +ehci_attach(const struct grub_fdtbus_dev *dev) +{ + grub_dprintf ("ehci", "Found generic-ehci\n"); + + grub_ehci_init_device (grub_fdtbus_map_reg (dev, 0, 0)); + return 0; +} + +struct grub_fdtbus_driver ehci = +{ + .compatible = "generic-ehci", + .attach = ehci_attach +}; + +void +grub_ehci_pci_scan (void) +{ + grub_fdtbus_register (&ehci); +} diff --git a/grub-core/bus/usb/ehci-pci.c b/grub-core/bus/usb/ehci-pci.c new file mode 100644 index 000000000..aa04988fd --- /dev/null +++ b/grub-core/bus/usb/ehci-pci.c @@ -0,0 +1,208 @@ +/* ehci.c - EHCI Support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_EHCI_PCI_SBRN_REG 0x60 +#define GRUB_EHCI_ADDR_MEM_MASK (~0xff) + +/* USBLEGSUP bits and related OS OWNED byte offset */ +enum +{ + GRUB_EHCI_BIOS_OWNED = (1 << 16), + GRUB_EHCI_OS_OWNED = (1 << 24) +}; + +/* PCI iteration function... */ +static int +grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) +{ + volatile grub_uint32_t *regs; + grub_uint32_t base, base_h; + grub_uint32_t eecp_offset; + grub_uint32_t usblegsup = 0; + grub_uint64_t maxtime; + grub_uint32_t interf; + grub_uint32_t subclass; + grub_uint32_t class; + grub_uint8_t release; + grub_uint32_t class_code; + + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n"); + + if (pciid == GRUB_CS5536_PCIID) + { + grub_uint64_t basereg; + + basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE); + if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) + { + /* Shouldn't happen. */ + grub_dprintf ("ehci", "No EHCI address is assigned\n"); + return 0; + } + base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); + basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg); + } + else + { + grub_pci_address_t addr; + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class_code = grub_pci_read (addr) >> 8; + interf = class_code & 0xFF; + subclass = (class_code >> 8) & 0xFF; + class = class_code >> 16; + + /* If this is not an EHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03 || interf != 0x20) + return 0; + + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n"); + + /* Check Serial Bus Release Number */ + addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG); + release = grub_pci_read_byte (addr); + if (release != 0x20) + { + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n", + release); + return 0; + } + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n"); + + /* Determine EHCI EHCC registers base address. */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + base = grub_pci_read (addr); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); + base_h = grub_pci_read (addr); + /* Stop if registers are mapped above 4G - GRUB does not currently + * work with registers mapped above 4G */ + if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32) + && (base_h != 0)) + { + grub_dprintf ("ehci", + "EHCI grub_ehci_pci_iter: registers above 4G are not supported\n"); + return 0; + } + base &= GRUB_PCI_ADDR_MEM_MASK; + if (!base) + { + grub_dprintf ("ehci", + "EHCI: EHCI is not mapped\n"); + return 0; + } + + /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */ + addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write_word(addr, + GRUB_PCI_COMMAND_MEM_ENABLED + | GRUB_PCI_COMMAND_BUS_MASTER + | grub_pci_read_word(addr)); + + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n"); + } + + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n", + (base & GRUB_EHCI_ADDR_MEM_MASK)); + + regs = grub_pci_device_map_range (dev, + (base & GRUB_EHCI_ADDR_MEM_MASK), + 0x100); + + /* Is there EECP ? */ + eecp_offset = (grub_le_to_cpu32 (regs[2]) >> 8) & 0xff; + + /* Determine and change ownership. */ + /* EECP offset valid in HCCPARAMS */ + /* Ownership can be changed via EECP only */ + if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40) + { + grub_pci_address_t pciaddr_eecp; + pciaddr_eecp = grub_pci_make_address (dev, eecp_offset); + + usblegsup = grub_pci_read (pciaddr_eecp); + if (usblegsup & GRUB_EHCI_BIOS_OWNED) + { + grub_boot_time ("Taking ownership of EHCI controller"); + grub_dprintf ("ehci", + "EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n"); + /* Ownership change - set OS_OWNED bit */ + grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED); + /* Ensure PCI register is written */ + grub_pci_read (pciaddr_eecp); + + /* Wait for finish of ownership change, EHCI specification + * doesn't say how long it can take... */ + maxtime = grub_get_time_ms () + 1000; + while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED) + && (grub_get_time_ms () < maxtime)); + if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED) + { + grub_dprintf ("ehci", + "EHCI grub_ehci_pci_iter: EHCI change ownership timeout"); + /* Change ownership in "hard way" - reset BIOS ownership */ + grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED); + /* Ensure PCI register is written */ + grub_pci_read (pciaddr_eecp); + } + } + else if (usblegsup & GRUB_EHCI_OS_OWNED) + /* XXX: What to do in this case - nothing ? Can it happen ? */ + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n"); + else + { + grub_dprintf ("ehci", + "EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n"); + /* XXX: What to do in this case ? Can it happen ? + * Is code below correct ? */ + /* Ownership change - set OS_OWNED bit */ + grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED); + /* Ensure PCI register is written */ + grub_pci_read (pciaddr_eecp); + } + + /* Disable SMI, just to be sure. */ + pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4); + grub_pci_write (pciaddr_eecp, 0); + /* Ensure PCI register is written */ + grub_pci_read (pciaddr_eecp); + } + + grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n"); + + grub_ehci_init_device (regs); + return 0; +} + +void +grub_ehci_pci_scan (void) +{ + grub_pci_iterate (grub_ehci_pci_iter, NULL); +} diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c index 5f4297bb2..2db07c7c0 100644 --- a/grub-core/bus/usb/ehci.c +++ b/grub-core/bus/usb/ehci.c @@ -22,13 +22,10 @@ #include #include #include -#include -#include -#include #include #include -#include #include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -39,8 +36,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); * - is not supporting interrupt transfers */ -#define GRUB_EHCI_PCI_SBRN_REG 0x60 - /* Capability registers offsets */ enum { @@ -54,7 +49,6 @@ enum #define GRUB_EHCI_EECP_MASK (0xff << 8) #define GRUB_EHCI_EECP_SHIFT 8 -#define GRUB_EHCI_ADDR_MEM_MASK (~0xff) #define GRUB_EHCI_POINTER_MASK (~0x1f) /* Capability register SPARAMS bits */ @@ -85,13 +79,6 @@ enum #define GRUB_EHCI_QH_EMPTY 1 -/* USBLEGSUP bits and related OS OWNED byte offset */ -enum -{ - GRUB_EHCI_BIOS_OWNED = (1 << 16), - GRUB_EHCI_OS_OWNED = (1 << 24) -}; - /* Operational registers offsets */ enum { @@ -231,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 { @@ -455,9 +442,10 @@ grub_ehci_reset (struct grub_ehci *e) sync_all_caches (e); + grub_dprintf ("ehci", "reset\n"); + grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, - GRUB_EHCI_CMD_HC_RESET - | grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); + GRUB_EHCI_CMD_HC_RESET); /* Ensure command is written */ grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND); /* XXX: How long time could take reset of HC ? */ @@ -473,116 +461,24 @@ grub_ehci_reset (struct grub_ehci *e) } /* PCI iteration function... */ -static int -grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, - void *data __attribute__ ((unused))) +void +grub_ehci_init_device (volatile void *regs) { - grub_uint8_t release; - grub_uint32_t class_code; - grub_uint32_t interf; - grub_uint32_t subclass; - grub_uint32_t class; - grub_uint32_t base, base_h; struct grub_ehci *e; - grub_uint32_t eecp_offset; grub_uint32_t fp; int i; - grub_uint32_t usblegsup = 0; - grub_uint64_t maxtime; grub_uint32_t n_ports; grub_uint8_t caplen; - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: begin\n"); - - if (pciid == GRUB_CS5536_PCIID) - { - grub_uint64_t basereg; - - basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE); - if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) - { - /* Shouldn't happen. */ - grub_dprintf ("ehci", "No EHCI address is assigned\n"); - return 0; - } - base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); - basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; - basereg &= ~GRUB_CS5536_MSR_USB_BASE_SMI_ENABLE; - grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_EHCI_BASE, basereg); - } - else - { - grub_pci_address_t addr; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class_code = grub_pci_read (addr) >> 8; - interf = class_code & 0xFF; - subclass = (class_code >> 8) & 0xFF; - class = class_code >> 16; - - /* If this is not an EHCI controller, just return. */ - if (class != 0x0c || subclass != 0x03 || interf != 0x20) - return 0; - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: class OK\n"); - - /* Check Serial Bus Release Number */ - addr = grub_pci_make_address (dev, GRUB_EHCI_PCI_SBRN_REG); - release = grub_pci_read_byte (addr); - if (release != 0x20) - { - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: Wrong SBRN: %0x\n", - release); - return 0; - } - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: bus rev. num. OK\n"); - - /* Determine EHCI EHCC registers base address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); - base_h = grub_pci_read (addr); - /* Stop if registers are mapped above 4G - GRUB does not currently - * work with registers mapped above 4G */ - if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32) - && (base_h != 0)) - { - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: registers above 4G are not supported\n"); - return 0; - } - base &= GRUB_PCI_ADDR_MEM_MASK; - if (!base) - { - grub_dprintf ("ehci", - "EHCI: EHCI is not mapped\n"); - return 0; - } - - /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); - grub_pci_write_word(addr, - GRUB_PCI_COMMAND_MEM_ENABLED - | GRUB_PCI_COMMAND_BUS_MASTER - | grub_pci_read_word(addr)); - - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n"); - } - /* Allocate memory for the controller and fill basic values. */ e = grub_zalloc (sizeof (*e)); if (!e) - return 1; + return; e->framelist_chunk = NULL; e->td_chunk = NULL; e->qh_chunk = NULL; - e->iobase_ehcc = grub_pci_device_map_range (dev, - (base & GRUB_EHCI_ADDR_MEM_MASK), - 0x100); + e->iobase_ehcc = regs; - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: iobase of EHCC: %08x\n", - (base & GRUB_EHCI_ADDR_MEM_MASK)); grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CAPLEN: %02x\n", grub_ehci_ehcc_read8 (e, GRUB_EHCI_EHCC_CAPLEN)); grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: VERSION: %04x\n", @@ -598,18 +494,18 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, if (caplen & (sizeof (grub_uint32_t) - 1)) { grub_dprintf ("ehci", "Unaligned caplen\n"); - return 0; + return; } 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 grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n", - (base & GRUB_EHCI_ADDR_MEM_MASK) + caplen); + "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llxx\n", + (unsigned long long) (grub_addr_t) e->iobase_ehcc + caplen); grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n", grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n", @@ -625,10 +521,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n", grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG)); - /* Is there EECP ? */ - eecp_offset = (grub_ehci_ehcc_read32 (e, GRUB_EHCI_EHCC_CPARAMS) - & GRUB_EHCI_EECP_MASK) >> GRUB_EHCI_EECP_SHIFT; - /* Check format of data structures requested by EHCI */ /* XXX: In fact it is not used at any place, it is prepared for future * This implementation uses 32-bits pointers only */ @@ -732,65 +624,6 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: QH/TD init. OK\n"); - /* Determine and change ownership. */ - /* EECP offset valid in HCCPARAMS */ - /* Ownership can be changed via EECP only */ - if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40) - { - grub_pci_address_t pciaddr_eecp; - pciaddr_eecp = grub_pci_make_address (dev, eecp_offset); - - usblegsup = grub_pci_read (pciaddr_eecp); - if (usblegsup & GRUB_EHCI_BIOS_OWNED) - { - grub_boot_time ("Taking ownership of EHCI controller"); - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n"); - /* Ownership change - set OS_OWNED bit */ - grub_pci_write (pciaddr_eecp, usblegsup | GRUB_EHCI_OS_OWNED); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - - /* Wait for finish of ownership change, EHCI specification - * doesn't say how long it can take... */ - maxtime = grub_get_time_ms () + 1000; - while ((grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED) - && (grub_get_time_ms () < maxtime)); - if (grub_pci_read (pciaddr_eecp) & GRUB_EHCI_BIOS_OWNED) - { - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: EHCI change ownership timeout"); - /* Change ownership in "hard way" - reset BIOS ownership */ - grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - } - } - else if (usblegsup & GRUB_EHCI_OS_OWNED) - /* XXX: What to do in this case - nothing ? Can it happen ? */ - grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: EHCI owned by: OS\n"); - else - { - grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: EHCI owned by: NONE\n"); - /* XXX: What to do in this case ? Can it happen ? - * Is code below correct ? */ - /* Ownership change - set OS_OWNED bit */ - grub_pci_write (pciaddr_eecp, GRUB_EHCI_OS_OWNED); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - } - - /* Disable SMI, just to be sure. */ - pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4); - grub_pci_write (pciaddr_eecp, 0); - /* Ensure PCI register is written */ - grub_pci_read (pciaddr_eecp); - - } - - grub_dprintf ("ehci", "inithw: EHCI grub_ehci_pci_iter: ownership OK\n"); - /* Now we can setup EHCI (maybe...) */ /* Check if EHCI is halted and halt it if not */ @@ -863,8 +696,8 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: OK at all\n"); grub_dprintf ("ehci", - "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08x\n", - (base & GRUB_EHCI_ADDR_MEM_MASK)); + "EHCI grub_ehci_pci_iter: iobase of oper. regs: %08llx\n", + (unsigned long long) (grub_addr_t) regs); grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: COMMAND: %08x\n", grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: STATUS: %08x\n", @@ -880,7 +713,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: CONFIG_FLAG: %08x\n", grub_ehci_oper_read32 (e, GRUB_EHCI_CONFIG_FLAG)); - return 0; + return; fail: if (e) @@ -894,7 +727,7 @@ fail: } grub_free (e); - return 0; + return; } static int @@ -1036,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); @@ -1891,12 +1724,6 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed) } } -static void -grub_ehci_inithw (void) -{ - grub_pci_iterate (grub_ehci_pci_iter, NULL); -} - static grub_err_t grub_ehci_restore_hw (void) { @@ -1986,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) @@ -1997,7 +1824,7 @@ GRUB_MOD_INIT (ehci) grub_stop_disk_firmware (); grub_boot_time ("Initing EHCI hardware"); - grub_ehci_inithw (); + grub_ehci_pci_scan (); grub_boot_time ("Registering EHCI driver"); grub_usb_controller_dev_register (&usb_controller); grub_boot_time ("EHCI driver registered"); 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 9266e4931..c5680b33a 100644 --- a/grub-core/bus/usb/usbtrans.c +++ b/grub-core/bus/usb/usbtrans.c @@ -18,7 +18,7 @@ */ #include -#include +#include #include #include #include @@ -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 b5c2f27c1..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++) @@ -635,7 +665,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) grub_size_t size; char *buf; - file = grub_file_open (args[i]); + file = grub_file_open (args[i], GRUB_FILE_TYPE_ACPI_TABLE); if (! file) { free_tables (); @@ -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; - grub_efi_system_table->boot_services->install_configuration_table - (&acpi20, grub_acpi_get_rsdpv2 ()); - grub_efi_system_table->boot_services->install_configuration_table - (&acpi, grub_acpi_get_rsdpv1 ()); + grub_efi_system_table->boot_services->install_configuration_table (&acpi20, + grub_acpi_get_rsdpv2 ()); + grub_efi_system_table->boot_services->install_configuration_table (&acpi, + grub_acpi_get_rsdpv1 ()); } #endif @@ -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 d1a47b504..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 @@ -121,8 +123,8 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - grub_file_filter_disable_compression (); - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_PRINT_BLOCKLIST + | GRUB_FILE_TYPE_NO_DECOMPRESS); if (! file) return grub_errno; 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 88d904436..2b67c1c7f 100644 --- a/grub-core/commands/cat.c +++ b/grub-core/commands/cat.c @@ -56,7 +56,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_CAT); if (! file) return grub_errno; @@ -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 cc23ee67e..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]); - file2 = grub_file_open (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 132cadbc7..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); @@ -169,7 +151,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)), if (argc > 1) { - file = grub_file_open (argv[1]); + file = grub_file_open (argv[1], GRUB_FILE_TYPE_VBE_DUMP); if (! file) return grub_errno; @@ -183,7 +165,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_VBE_DUMP); if (! file) return grub_errno; @@ -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 d901c3892..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,10 +108,13 @@ 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); - if (status != GRUB_EFI_SUCCESS) + status = grub_efi_system_table->boot_services->protocols_per_handle (handle, + &protocols, + &num_protocols); + if (status != GRUB_EFI_SUCCESS) { grub_printf ("Unable to retrieve protocols\n"); + continue; + } for (j = 0; j < num_protocols; j++) { for (k = 0; k < ARRAY_SIZE (known_protocols); k++) @@ -120,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/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 new file mode 100644 index 000000000..cbac69866 --- /dev/null +++ b/grub-core/commands/efi/tpm.c @@ -0,0 +1,334 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + * + * EFI TPM support code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef TCG_PCR_EVENT grub_tpm_event_t; + +static grub_guid_t tpm_guid = EFI_TPM_GUID; +static grub_guid_t tpm2_guid = EFI_TPM2_GUID; +static grub_guid_t cc_measurement_guid = GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID; + +static grub_efi_handle_t *grub_tpm_handle; +static grub_uint8_t grub_tpm_version; + +static grub_int8_t tpm1_present = -1; +static grub_int8_t tpm2_present = -1; + +static grub_efi_boolean_t +grub_tpm1_present (grub_efi_tpm_protocol_t *tpm) +{ + grub_efi_status_t status; + TCG_EFI_BOOT_SERVICE_CAPABILITY caps; + grub_uint32_t flags; + grub_efi_physical_address_t eventlog, lastevent; + + if (tpm1_present != -1) + return (grub_efi_boolean_t) tpm1_present; + + caps.Size = (grub_uint8_t) sizeof (caps); + + status = tpm->status_check (tpm, &caps, &flags, &eventlog, &lastevent); + + if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag + || !caps.TPMPresentFlag) + tpm1_present = 0; + else + tpm1_present = 1; + + grub_dprintf ("tpm", "tpm1%s present\n", tpm1_present ? "" : " NOT"); + + return (grub_efi_boolean_t) tpm1_present; +} + +static grub_efi_boolean_t +grub_tpm2_present (grub_efi_tpm2_protocol_t *tpm) +{ + grub_efi_status_t status; + EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; + + caps.Size = (grub_uint8_t) sizeof (caps); + + if (tpm2_present != -1) + return (grub_efi_boolean_t) tpm2_present; + + status = tpm->get_capability (tpm, &caps); + + if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) + tpm2_present = 0; + else + tpm2_present = 1; + + grub_dprintf ("tpm", "tpm2%s present\n", tpm2_present ? "" : " NOT"); + + return (grub_efi_boolean_t) tpm2_present; +} + +static grub_efi_boolean_t +grub_tpm_handle_find (grub_efi_handle_t *tpm_handle, + grub_efi_uint8_t *protocol_version) +{ + grub_efi_handle_t *handles; + grub_efi_uintn_t num_handles; + + if (grub_tpm_handle != NULL) + { + *tpm_handle = grub_tpm_handle; + *protocol_version = grub_tpm_version; + return 1; + } + + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL, + &num_handles); + if (handles && num_handles > 0) + { + grub_tpm_handle = handles[0]; + *tpm_handle = handles[0]; + grub_tpm_version = 1; + *protocol_version = 1; + grub_dprintf ("tpm", "TPM handle Found, version: 1\n"); + return 1; + } + + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, + &num_handles); + if (handles && num_handles > 0) + { + grub_tpm_handle = handles[0]; + *tpm_handle = handles[0]; + grub_tpm_version = 2; + *protocol_version = 2; + grub_dprintf ("tpm", "TPM handle Found, version: 2\n"); + return 1; + } + + return 0; +} + +static grub_err_t +grub_efi_log_event_status (grub_efi_status_t status) +{ + switch (status) + { + case GRUB_EFI_SUCCESS: + return GRUB_ERR_NONE; + case GRUB_EFI_DEVICE_ERROR: + return grub_error (GRUB_ERR_IO, N_("command failed")); + case GRUB_EFI_INVALID_PARAMETER: + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid parameter")); + case GRUB_EFI_BUFFER_TOO_SMALL: + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("output buffer too small")); + case GRUB_EFI_NOT_FOUND: + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); + default: + return grub_error (grub_is_tpm_fail_fatal () ? GRUB_ERR_UNKNOWN_DEVICE : GRUB_ERR_NONE, N_("unknown TPM error")); + } +} + +static grub_err_t +grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + grub_size_t size, grub_uint8_t pcr, + const char *description) +{ + grub_tpm_event_t *event; + grub_efi_status_t status; + grub_efi_tpm_protocol_t *tpm; + grub_efi_physical_address_t lastevent; + grub_uint32_t algorithm; + grub_uint32_t eventnum = 0; + + tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (!grub_tpm1_present (tpm)) + return 0; + + event = grub_zalloc (sizeof (*event) + grub_strlen (description) + 1); + if (!event) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + N_("cannot allocate TPM event buffer")); + + event->PCRIndex = pcr; + event->EventType = EV_IPL; + event->EventSize = grub_strlen (description) + 1; + grub_strcpy ((char *) event->Event, description); + + algorithm = TCG_ALG_SHA; + status = tpm->log_extend_event (tpm, (grub_addr_t) buf, (grub_uint64_t) size, + algorithm, event, &eventnum, &lastevent); + grub_free (event); + + return grub_efi_log_event_status (status); +} + +static grub_err_t +grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + grub_size_t size, grub_uint8_t pcr, + const char *description) +{ + EFI_TCG2_EVENT *event; + grub_efi_status_t status; + grub_efi_tpm2_protocol_t *tpm; + + tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (!grub_tpm2_present (tpm)) + return 0; + + event = + grub_zalloc (sizeof (EFI_TCG2_EVENT) + grub_strlen (description) + 1); + if (!event) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + N_("cannot allocate TPM event buffer")); + + event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); + event->Header.HeaderVersion = 1; + event->Header.PCRIndex = pcr; + event->Header.EventType = EV_IPL; + event->Size = + sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1; + grub_strcpy ((char *) event->Event, description); + + status = tpm->hash_log_extend_event (tpm, 0, (grub_addr_t) buf, + (grub_uint64_t) size, event); + grub_free (event); + + return grub_efi_log_event_status (status); +} + +static void +grub_cc_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + const char *description) +{ + grub_efi_cc_event_t *event; + grub_efi_status_t status; + grub_efi_cc_protocol_t *cc; + grub_efi_cc_mr_index_t mr; + + cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL); + if (cc == NULL) + return; + + status = cc->map_pcr_to_mr_index (cc, pcr, &mr); + if (status != GRUB_EFI_SUCCESS) + { + grub_efi_log_event_status (status); + return; + } + + event = grub_zalloc (sizeof (grub_efi_cc_event_t) + + grub_strlen (description) + 1); + if (event == NULL) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate CC event buffer")); + return; + } + + event->Header.HeaderSize = sizeof (grub_efi_cc_event_header_t); + event->Header.HeaderVersion = GRUB_EFI_CC_EVENT_HEADER_VERSION; + event->Header.MrIndex = mr; + event->Header.EventType = EV_IPL; + event->Size = sizeof (*event) + grub_strlen (description) + 1; + grub_strcpy ((char *) event->Event, description); + + status = cc->hash_log_extend_event (cc, 0, + (grub_efi_physical_address_t)(grub_addr_t) buf, + (grub_efi_uint64_t) size, event); + grub_free (event); + + if (status != GRUB_EFI_SUCCESS) + grub_efi_log_event_status (status); +} + +grub_err_t +grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + const char *description) +{ + grub_efi_handle_t tpm_handle; + grub_efi_uint8_t protocol_version; + + grub_cc_log_event(buf, size, pcr, description); + + if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) + return 0; + + grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", + pcr, size, description); + + if (protocol_version == 1) + return grub_tpm1_log_event (tpm_handle, buf, size, pcr, description); + else + return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description); +} + +int +grub_tpm_present (void) +{ + grub_efi_handle_t tpm_handle; + grub_efi_uint8_t protocol_version; + grub_efi_cc_protocol_t *cc; + + /* + * When confidential computing measurement protocol is enabled + * we assume the TPM is present. + */ + cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL); + if (cc != NULL) + return 1; + + if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) + return 0; + + if (protocol_version == 1) + { + grub_efi_tpm_protocol_t *tpm; + + tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (!tpm) + { + grub_dprintf ("tpm", "Cannot open TPM protocol\n"); + return 0; + } + return grub_tpm1_present (tpm); + } + else + { + grub_efi_tpm2_protocol_t *tpm; + + tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (!tpm) + { + grub_dprintf ("tpm", "Cannot open TPM protocol\n"); + return 0; + } + return grub_tpm2_present (tpm); + } +} diff --git a/grub-core/commands/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 12fba99e0..19602d757 100644 --- a/grub-core/commands/file.c +++ b/grub-core/commands/file.c @@ -25,8 +25,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -88,6 +90,10 @@ static const struct grub_arg_option options[] = { N_("Check if FILE is ARM64 EFI file"), 0, 0}, {"is-arm-efi", 0, 0, N_("Check if FILE is ARM EFI file"), 0, 0}, + {"is-riscv32-efi", 0, 0, + N_("Check if FILE is RISC-V 32bit EFI file"), 0, 0}, + {"is-riscv64-efi", 0, 0, + N_("Check if FILE is RISC-V 64bit EFI file"), 0, 0}, {"is-hibernated-hiberfil", 0, 0, N_("Check if FILE is hiberfil.sys in hibernated state"), 0, 0}, {"is-x86_64-xnu", 0, 0, @@ -128,6 +134,8 @@ enum IS_IA_EFI, IS_ARM64_EFI, IS_ARM_EFI, + IS_RISCV32_EFI, + IS_RISCV64_EFI, IS_HIBERNATED, IS_XNU64, IS_XNU32, @@ -163,7 +171,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) if (type == -1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no type specified"); - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL); if (!file) return grub_errno; switch (type) @@ -298,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; @@ -383,21 +393,19 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) } case IS_ARM_LINUX: { - grub_uint32_t sig, sig_pi; - if (grub_file_read (file, &sig_pi, 4) != 4) + struct linux_arch_kernel_header lh; + + if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) break; - /* Raspberry pi. */ - if (sig_pi == grub_cpu_to_le32_compile_time (0xea000006)) + /* Short forward branch in A32 state (for Raspberry pi kernels). */ + if (lh.code0 == grub_cpu_to_le32_compile_time (0xea000006)) { ret = 1; break; } - if (grub_file_seek (file, 0x24) == (grub_size_t) -1) - break; - if (grub_file_read (file, &sig, 4) != 4) - break; - if (sig == grub_cpu_to_le32_compile_time (0x016f2818)) + if (lh.magic == + grub_cpu_to_le32_compile_time (GRUB_LINUX_ARM_MAGIC_SIGNATURE)) { ret = 1; break; @@ -406,13 +414,24 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) } case IS_ARM64_LINUX: { - grub_uint32_t sig; + struct linux_arch_kernel_header lh; - if (grub_file_seek (file, 0x38) == (grub_size_t) -1) + if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) break; - if (grub_file_read (file, &sig, 4) != 4) - break; - if (sig == grub_cpu_to_le32_compile_time (0x644d5241)) + + /* + * 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; @@ -497,7 +516,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) case IS_X86_LINUX32: case IS_X86_LINUX: { - struct linux_kernel_header lh; + struct linux_i386_kernel_header lh; if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) break; if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) @@ -508,7 +527,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) /* FIXME: some really old kernels (< 1.3.73) will fail this. */ if (lh.header != - grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) + grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0200) break; @@ -521,7 +540,7 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and still not support 32-bit boot. */ if (lh.header != - grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) + grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0203) break; @@ -546,7 +565,8 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) case IS_XNU64: case IS_XNU32: { - macho = grub_macho_open (args[0], (type == IS_XNU64)); + macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL, + (type == IS_XNU64)); if (!macho) break; /* FIXME: more checks? */ @@ -570,6 +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_RISCV32_EFI: + case IS_RISCV64_EFI: { char signature[4]; grub_uint32_t pe_offset; @@ -615,7 +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_IA_EFI || type == IS_64_EFI || type == IS_ARM64_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_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 d18687351..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"}, @@ -113,10 +113,10 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) return grub_error (GRUB_ERR_BUG, "mdlen is too long"); - hashlist = grub_file_open (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,30 +128,37 @@ 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; - if (!uncompress) - grub_file_filter_disable_compression (); - file = grub_file_open (filename); + { + grub_free (buf); + return grub_errno; + } + file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); grub_free (filename); } else - { - if (!uncompress) - grub_file_filter_disable_compression (); - file = grub_file_open (p); - } + file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); if (!file) { grub_file_close (hashlist); @@ -185,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); } @@ -242,9 +249,9 @@ grub_cmd_hashsum (struct grub_extcmd_context *ctxt, grub_file_t file; grub_err_t err; unsigned j; - if (!uncompress) - grub_file_filter_disable_compression (); - file = grub_file_open (args[i]); + file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); if (!file) { if (!keep) diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c index f6b178eae..96f2336f3 100644 --- a/grub-core/commands/hdparm.c +++ b/grub-core/commands/hdparm.c @@ -328,11 +328,12 @@ grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) ata = ((struct grub_scsi *) disk->data)->data; break; } + /* FALLTHROUGH */ default: grub_disk_close (disk); return grub_error (GRUB_ERR_IO, "not an ATA device"); } - + /* Change settings. */ if (aam >= 0) @@ -435,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 4c884b3a1..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; @@ -90,7 +95,7 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args) { grub_file_t file; - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_HEXCAT); if (! file) return 0; 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 e72f38d6e..c44abb3fa 100644 --- a/grub-core/commands/i386/coreboot/cb_timestamps.c +++ b/grub-core/commands/i386/coreboot/cb_timestamps.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -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 e0a10596f..50b7b8750 100644 --- a/grub-core/commands/i386/coreboot/cbls.c +++ b/grub-core/commands/i386/coreboot/cbls.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); @@ -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 7712e2a36..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. @@ -93,7 +93,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), grub_uint32_t tempo; grub_file_t file; - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_AUDIO); if (! file) return grub_errno; @@ -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 new file mode 100644 index 000000000..2e42f6197 --- /dev/null +++ b/grub-core/commands/i386/rdmsr.c @@ -0,0 +1,91 @@ +/* rdmsr.c - Read CPU model-specific registers. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * Based on gcc/gcc/config/i386/driver-i386.c + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE("GPLv3+"); + +static grub_extcmd_t cmd_read; + +static const struct grub_arg_option options[] = +{ + {0, 'v', 0, N_("Save read value into variable VARNAME."), + N_("VARNAME"), ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + +static grub_err_t +grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) +{ + grub_err_t err; + grub_uint32_t addr; + grub_uint64_t value; + const char *ptr; + char buf[sizeof("1122334455667788")]; + + err = grub_cpu_is_msr_supported (); + + if (err != GRUB_ERR_NONE) + return grub_error (err, N_("RDMSR is unsupported")); + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + grub_errno = GRUB_ERR_NONE; + ptr = argv[0]; + addr = grub_strtoul (ptr, &ptr, 0); + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + if (*ptr != '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); + + value = grub_rdmsr (addr); + + if (ctxt->state[0].set) + { + grub_snprintf (buf, sizeof(buf), "%llx", (unsigned long long) value); + grub_env_set (ctxt->state[0].arg, buf); + } + else + grub_printf ("0x%llx\n", (unsigned long long) value); + + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT(rdmsr) +{ + cmd_read = grub_register_extcmd ("rdmsr", grub_cmd_msr_read, 0, N_("ADDR"), + N_("Read a CPU model specific register."), + options); +} + +GRUB_MOD_FINI(rdmsr) +{ + grub_unregister_extcmd (cmd_read); +} diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c new file mode 100644 index 000000000..7fbedaed9 --- /dev/null +++ b/grub-core/commands/i386/wrmsr.c @@ -0,0 +1,83 @@ +/* wrmsr.c - Write CPU model-specific registers. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * Based on gcc/gcc/config/i386/driver-i386.c + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE("GPLv3+"); + +static grub_command_t cmd_write; + +static grub_err_t +grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char **argv) +{ + grub_err_t err; + grub_uint32_t addr; + grub_uint64_t value; + const char *ptr; + + err = grub_cpu_is_msr_supported (); + + if (err != GRUB_ERR_NONE) + return grub_error (err, N_("WRMSR is unsupported")); + + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + + grub_errno = GRUB_ERR_NONE; + ptr = argv[0]; + addr = grub_strtoul (ptr, &ptr, 0); + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + if (*ptr != '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); + + ptr = argv[1]; + value = grub_strtoull (ptr, &ptr, 0); + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + if (*ptr != '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument")); + + grub_wrmsr (addr, value); + + return GRUB_ERR_NONE; +} + +GRUB_MOD_INIT(wrmsr) +{ + cmd_write = grub_register_command_lockdown ("wrmsr", grub_cmd_msr_write, N_("ADDR VALUE"), + N_("Write a value to a CPU model specific register.")); +} + +GRUB_MOD_FINI(wrmsr) +{ + grub_unregister_command (cmd_write); +} diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c 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 f4b773020..aa3ba34f2 100644 --- a/grub-core/commands/keylayouts.c +++ b/grub-core/commands/keylayouts.c @@ -35,19 +35,19 @@ 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', /* 0x20 */ '3', '4', '5', '6', '7', '8', '9', '0', - /* 0x28 */ '\n', '\e', '\b', '\t', ' ', '-', '=', '[', + /* 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,37 +77,37 @@ 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', '!', '@', /* 0x20 */ '#', '$', '%', '^', '&', '*', '(', ')', - /* 0x28 */ '\n' | GRUB_TERM_SHIFT, '\e' | GRUB_TERM_SHIFT, - /* 0x2a */ '\b' | GRUB_TERM_SHIFT, '\t' | GRUB_TERM_SHIFT, + /* 0x28 */ '\n' | GRUB_TERM_SHIFT, GRUB_TERM_ESC | GRUB_TERM_SHIFT, + /* 0x2a */ GRUB_TERM_BACKSPACE | GRUB_TERM_SHIFT, GRUB_TERM_TAB | GRUB_TERM_SHIFT, /* 0x2c */ ' ' | GRUB_TERM_SHIFT, '_', '+', '{', /* According to usage table 0x31 should be mapped to '/' but testing with real keyboard shows that 0x32 is remapped to '/'. - Map 0x31 to 0. + 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; @@ -220,7 +220,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), else filename = argv[0]; - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_KEYBOARD_LAYOUT); if (! file) goto fail; 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 b32f3c74c..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+"); @@ -55,7 +56,7 @@ legacy_file (const char *filename) if (!suffix) return grub_errno; - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG); if (! file) { grub_free (suffix); @@ -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 acd93d123..166445849 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -44,7 +44,8 @@ static const struct grub_arg_option options[] = PUBKEY filter (that insists upon properly signed files) as well. PUBKEY filter is restored before the function returns. */ static grub_file_t -open_envblk_file (char *filename, int untrusted) +open_envblk_file (char *filename, + enum grub_file_type type) { grub_file_t file; char *buf = 0; @@ -72,13 +73,7 @@ open_envblk_file (char *filename, int untrusted) grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG); } - /* The filters that are disabled will be re-enabled by the call to - grub_file_open() after this particular file is opened. */ - grub_file_filter_disable_compression (); - if (untrusted) - grub_file_filter_disable_pubkey (); - - file = grub_file_open (filename); + file = grub_file_open (filename, type); grub_free (buf); return file; @@ -171,7 +166,10 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) whitelist.list = args; /* state[0] is the -f flag; state[1] is the --skip-sig flag */ - file = open_envblk_file ((state[0].set) ? state[0].arg : 0, state[1].set); + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_LOADENV + | (state[1].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); if (! file) return grub_errno; @@ -206,7 +204,10 @@ grub_cmd_list_env (grub_extcmd_context_t ctxt, grub_file_t file; grub_envblk_t envblk; - file = open_envblk_file ((state[0].set) ? state[0].arg : 0, 0); + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_LOADENV + | (state[1].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); if (! file) return grub_errno; @@ -351,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; @@ -373,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 @@ -390,7 +393,8 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified"); file = open_envblk_file ((state[0].set) ? state[0].arg : 0, - 1 /* allow untrusted */); + GRUB_FILE_TYPE_SAVEENV + | GRUB_FILE_TYPE_SKIP_SIGNATURE); if (! file) return grub_errno; diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 0eaf83652..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); @@ -129,22 +136,21 @@ print_files_long (const char *filename, const struct grub_dirhook_info *info, /* XXX: For ext2fs symlinks are detected as files while they should be reported as directories. */ - grub_file_filter_disable_compression (); - file = grub_file_open (pathname); - if (! file) + file = grub_file_open (pathname, GRUB_FILE_TYPE_GET_SIZE + | GRUB_FILE_TYPE_NO_DECOMPRESS); + 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,55 +211,58 @@ 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; +#ifdef GRUB_MACHINE_IEEE1275 + /* + * Close device to prevent a double open in grub_normal_print_device_info(). + * Otherwise it may lead to hangs on some IEEE 1275 platforms. + */ + grub_device_close (dev); + dev = NULL; +#endif + grub_normal_print_device_info (device_name); } else if (fs) { struct grub_ls_list_files_ctx ctx = { .dirname = dirname, + .filename = NULL, .all = all, - .human = human + .human = human, + .longlist = longlist, + .print_dirhdr = dirhdr }; - if (longlist) - (fs->dir) (dev, path, print_files_long, &ctx); - else - (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); - grub_file_filter_disable_compression (); - file = grub_file_open (dirname); - 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) @@ -259,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 @@ -272,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 18efa1a84..3d761452a 100644 --- a/grub-core/commands/macbless.c +++ b/grub-core/commands/macbless.c @@ -159,12 +159,12 @@ grub_mac_bless_file (grub_device_t dev, const char *path_in, int intel) *tail = 0; ctx.dirname = tail + 1; - (fs->dir) (dev, *path == 0 ? "/" : path, find_inode, &ctx); + (fs->fs_dir) (dev, *path == 0 ? "/" : path, find_inode, &ctx); } else { ctx.dirname = path + 1; - (fs->dir) (dev, "/", find_inode, &ctx); + (fs->fs_dir) (dev, "/", find_inode, &ctx); } if (!ctx.found) { @@ -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 58d4dadf6..720e6d8ea 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -52,8 +52,8 @@ static struct int key; } hotkey_aliases[] = { - {"backspace", '\b'}, - {"tab", '\t'}, + {"backspace", GRUB_TERM_BACKSPACE}, + {"tab", GRUB_TERM_TAB}, {"delete", GRUB_TERM_KEY_DC}, {"insert", GRUB_TERM_KEY_INSERT}, {"f1", GRUB_TERM_KEY_F1}, @@ -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 a3a118241..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 */ @@ -43,7 +47,7 @@ grub_mini_cmd_cat (struct grub_command *cmd __attribute__ ((unused)), if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_CAT); if (! file) return grub_errno; @@ -137,8 +141,14 @@ grub_mini_cmd_rmmod (struct grub_command *cmd __attribute__ ((unused)), if (! mod) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such module"); - if (grub_dl_unref (mod) <= 0) - grub_dl_unload (mod); + if (grub_dl_is_persistent (mod)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload persistent module"); + + if (grub_dl_ref_count (mod) > 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "cannot unload referenced module"); + + grub_dl_unref (mod); + grub_dl_unload (mod); return 0; } @@ -161,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) @@ -181,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. */ } @@ -197,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 345f97c4d..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" @@ -66,6 +66,7 @@ get_uuid (const char *name, char **uuid, int getnative) /* Firmware disks. */ case GRUB_DISK_DEVICE_BIOSDISK_ID: case GRUB_DISK_DEVICE_OFDISK_ID: + case GRUB_DISK_DEVICE_OBDISK_ID: case GRUB_DISK_DEVICE_EFIDISK_ID: case GRUB_DISK_DEVICE_NAND_ID: case GRUB_DISK_DEVICE_ARCDISK_ID: @@ -79,6 +80,7 @@ get_uuid (const char *name, char **uuid, int getnative) case GRUB_DISK_DEVICE_XEN: if (getnative) break; + /* FALLTHROUGH */ /* Virtual disks. */ /* GRUB dynamically generated files. */ @@ -107,7 +109,7 @@ get_uuid (const char *name, char **uuid, int getnative) grub_device_close (dev); return grub_errno; } - if (!fs->uuid || fs->uuid (dev, uuid) || !*uuid) + if (!fs->fs_uuid || fs->fs_uuid (dev, uuid) || !*uuid) { grub_device_close (dev); @@ -193,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; @@ -241,7 +243,8 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)), if (! filename) goto fail; - file = grub_file_open (filename); + file = grub_file_open (filename, + GRUB_FILE_TYPE_GRUB_MODULE); grub_free (filename); if (! file) goto fail; diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c index 693e2cb42..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)); @@ -193,7 +199,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), { grub_file_t file; - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST); if (file) { char *buf = 0; @@ -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/verify.c b/grub-core/commands/pgp.c similarity index 69% rename from grub-core/commands/verify.c rename to grub-core/commands/pgp.c index 67cb1c785..5fadc33c4 100644 --- a/grub-core/commands/verify.c +++ b/grub-core/commands/pgp.c @@ -30,16 +30,10 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); -struct grub_verified -{ - grub_file_t file; - void *buf; -}; -typedef struct grub_verified *grub_verified_t; - enum { OPTION_SKIP_SIG = 0 @@ -80,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)) @@ -172,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" }, @@ -326,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)) { @@ -341,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)) { @@ -445,23 +439,27 @@ rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, return ret; } +struct grub_pubkey_context +{ + grub_file_t sig; + struct signature_v4_header v4; + grub_uint8_t v; + const gcry_md_spec_t *hash; + void *hash_context; +}; + static grub_err_t -grub_verify_signature_real (char *buf, grub_size_t size, - grub_file_t f, grub_file_t sig, - struct grub_public_key *pkey) +grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig) { grub_size_t len; - grub_uint8_t v; grub_uint8_t h; grub_uint8_t t; grub_uint8_t pk; - const gcry_md_spec_t *hash; - struct signature_v4_header v4; grub_err_t err; - grub_size_t i; - gcry_mpi_t mpis[10]; grub_uint8_t type = 0; + grub_memset (ctxt, 0, sizeof (*ctxt)); + err = read_packet_header (sig, &type, &len); if (err) return err; @@ -469,19 +467,19 @@ grub_verify_signature_real (char *buf, grub_size_t size, if (type != 0x2) return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v)) + if (grub_file_read (sig, &ctxt->v, sizeof (ctxt->v)) != sizeof (ctxt->v)) return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - if (v != 4) + if (ctxt->v != 4) return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4)) + if (grub_file_read (sig, &ctxt->v4, sizeof (ctxt->v4)) != sizeof (ctxt->v4)) return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - h = v4.hash; - t = v4.type; - pk = v4.pkeyalgo; - + 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")); @@ -491,183 +489,242 @@ grub_verify_signature_real (char *buf, grub_size_t size, if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL) return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - hash = grub_crypto_lookup_md_by_name (hashes[h]); - if (!hash) + ctxt->hash = grub_crypto_lookup_md_by_name (hashes[h]); + if (!ctxt->hash) return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]); grub_dprintf ("crypt", "alive\n"); - { - void *context = NULL; - unsigned char *hval; - grub_ssize_t rem = grub_be_to_cpu16 (v4.hashed_sub); - grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6); - grub_uint8_t s; - grub_uint16_t unhashed_sub; - grub_ssize_t r; - grub_uint8_t hash_start[2]; - gcry_mpi_t hmpi; - grub_uint64_t keyid = 0; - struct grub_public_subkey *sk; - grub_uint8_t *readbuf = NULL; + ctxt->hash_context = grub_zalloc (ctxt->hash->contextsize); + if (!ctxt->hash_context) + return grub_errno; - context = grub_zalloc (hash->contextsize); - readbuf = grub_zalloc (READBUF_SIZE); - if (!context || !readbuf) - goto fail; + ctxt->hash->init (ctxt->hash_context); + ctxt->sig = sig; - hash->init (context); - if (buf) - hash->write (context, buf, size); - else - while (1) - { - r = grub_file_read (f, readbuf, READBUF_SIZE); - if (r < 0) - goto fail; - if (r == 0) - break; - hash->write (context, readbuf, r); - } + return GRUB_ERR_NONE; +} - hash->write (context, &v, sizeof (v)); - hash->write (context, &v4, sizeof (v4)); - while (rem) - { - r = grub_file_read (sig, readbuf, - rem < READBUF_SIZE ? rem : READBUF_SIZE); - if (r < 0) - goto fail; - if (r == 0) - break; - hash->write (context, readbuf, r); - rem -= r; - } - hash->write (context, &v, sizeof (v)); - s = 0xff; - hash->write (context, &s, sizeof (s)); - hash->write (context, &headlen, sizeof (headlen)); - r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub)); - if (r != sizeof (unhashed_sub)) - goto fail; +static grub_err_t +grub_pubkey_write (void *ctxt_, void *buf, grub_size_t size) +{ + struct grub_pubkey_context *ctxt = ctxt_; + ctxt->hash->write (ctxt->hash_context, buf, size); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_verify_signature_real (struct grub_pubkey_context *ctxt, + struct grub_public_key *pkey) +{ + gcry_mpi_t mpis[10]; + grub_uint8_t pk = ctxt->v4.pkeyalgo; + grub_size_t i; + grub_uint8_t *readbuf = NULL; + unsigned char *hval; + grub_ssize_t rem = grub_be_to_cpu16 (ctxt->v4.hashed_sub); + grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6); + grub_uint8_t s; + grub_uint16_t unhashed_sub; + grub_ssize_t r; + grub_uint8_t hash_start[2]; + gcry_mpi_t hmpi; + grub_uint64_t keyid = 0; + struct grub_public_subkey *sk; + + readbuf = grub_malloc (READBUF_SIZE); + if (!readbuf) + goto fail; + + ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v)); + ctxt->hash->write (ctxt->hash_context, &ctxt->v4, sizeof (ctxt->v4)); + while (rem) { - grub_uint8_t *ptr; - grub_uint32_t l; - rem = grub_be_to_cpu16 (unhashed_sub); - if (rem > READBUF_SIZE) + r = grub_file_read (ctxt->sig, readbuf, + rem < READBUF_SIZE ? rem : READBUF_SIZE); + if (r < 0) goto fail; - r = grub_file_read (sig, readbuf, rem); - if (r != rem) + if (r == 0) + break; + ctxt->hash->write (ctxt->hash_context, readbuf, r); + rem -= r; + } + ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v)); + s = 0xff; + ctxt->hash->write (ctxt->hash_context, &s, sizeof (s)); + ctxt->hash->write (ctxt->hash_context, &headlen, sizeof (headlen)); + r = grub_file_read (ctxt->sig, &unhashed_sub, sizeof (unhashed_sub)); + if (r != sizeof (unhashed_sub)) + goto fail; + { + grub_uint8_t *ptr; + grub_uint32_t l; + rem = grub_be_to_cpu16 (unhashed_sub); + if (rem > READBUF_SIZE) + goto fail; + r = grub_file_read (ctxt->sig, readbuf, rem); + if (r != rem) + goto fail; + for (ptr = readbuf; ptr < readbuf + rem; ptr += l) + { + if (*ptr < 192) + l = *ptr++; + else if (*ptr < 255) + { + if (ptr + 1 >= readbuf + rem) + break; + l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192; + ptr += 2; + } + else + { + if (ptr + 5 >= readbuf + rem) + break; + l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1)); + ptr += 5; + } + if (*ptr == 0x10 && l >= 8) + keyid = grub_get_unaligned64 (ptr + 1); + } + } + + ctxt->hash->final (ctxt->hash_context); + + grub_dprintf ("crypt", "alive\n"); + + hval = ctxt->hash->read (ctxt->hash_context); + + if (grub_file_read (ctxt->sig, hash_start, sizeof (hash_start)) != sizeof (hash_start)) + goto fail; + if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0) + goto fail; + + grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (ctxt->sig)); + + for (i = 0; i < pkalgos[pk].nmpisig; i++) + { + grub_uint16_t l; + grub_size_t lb; + grub_dprintf ("crypt", "alive\n"); + if (grub_file_read (ctxt->sig, &l, sizeof (l)) != sizeof (l)) goto fail; - for (ptr = readbuf; ptr < readbuf + rem; ptr += l) - { - if (*ptr < 192) - l = *ptr++; - else if (*ptr < 255) - { - if (ptr + 1 >= readbuf + rem) - break; - l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192; - ptr += 2; - } - else - { - if (ptr + 5 >= readbuf + rem) - break; - l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1)); - ptr += 5; - } - if (*ptr == 0x10 && l >= 8) - keyid = grub_get_unaligned64 (ptr + 1); - } + grub_dprintf ("crypt", "alive\n"); + lb = (grub_be_to_cpu16 (l) + 7) / 8; + grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l)); + if (lb > READBUF_SIZE - sizeof (grub_uint16_t)) + goto fail; + grub_dprintf ("crypt", "alive\n"); + if (grub_file_read (ctxt->sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) + goto fail; + grub_dprintf ("crypt", "alive\n"); + grub_memcpy (readbuf, &l, sizeof (l)); + grub_dprintf ("crypt", "alive\n"); + + if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP, + readbuf, lb + sizeof (grub_uint16_t), 0)) + goto fail; + grub_dprintf ("crypt", "alive\n"); } - hash->final (context); - - grub_dprintf ("crypt", "alive\n"); - - hval = hash->read (context); - - if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start)) + if (pkey) + sk = grub_crypto_pk_locate_subkey (keyid, pkey); + else + sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid); + if (!sk) + { + /* TRANSLATORS: %08x is 32-bit key id. */ + grub_error (GRUB_ERR_BAD_SIGNATURE, + N_("public key %08" PRIxGRUB_UINT64_T " not found"), keyid); goto fail; - if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0) + } + + if (pkalgos[pk].pad (&hmpi, hval, ctxt->hash, sk)) + goto fail; + if (!*pkalgos[pk].algo) + { + grub_dl_load (pkalgos[pk].module); + grub_errno = GRUB_ERR_NONE; + } + + if (!*pkalgos[pk].algo) + { + grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"), + pkalgos[pk].module); goto fail; + } + if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0)) + goto fail; - grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig)); + grub_free (readbuf); - for (i = 0; i < pkalgos[pk].nmpisig; i++) - { - grub_uint16_t l; - grub_size_t lb; - grub_dprintf ("crypt", "alive\n"); - if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l)) - goto fail; - grub_dprintf ("crypt", "alive\n"); - lb = (grub_be_to_cpu16 (l) + 7) / 8; - grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l)); - if (lb > READBUF_SIZE - sizeof (grub_uint16_t)) - goto fail; - grub_dprintf ("crypt", "alive\n"); - if (grub_file_read (sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) - goto fail; - grub_dprintf ("crypt", "alive\n"); - grub_memcpy (readbuf, &l, sizeof (l)); - grub_dprintf ("crypt", "alive\n"); + return GRUB_ERR_NONE; - if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP, - readbuf, lb + sizeof (grub_uint16_t), 0)) - goto fail; - grub_dprintf ("crypt", "alive\n"); - } + fail: + grub_free (readbuf); + if (!grub_errno) + return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + return grub_errno; +} - if (pkey) - sk = grub_crypto_pk_locate_subkey (keyid, pkey); - else - sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid); - if (!sk) - { - /* TRANSLATORS: %08x is 32-bit key id. */ - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), - keyid); - goto fail; - } +static void +grub_pubkey_close_real (struct grub_pubkey_context *ctxt) +{ + if (ctxt->sig) + grub_file_close (ctxt->sig); + if (ctxt->hash_context) + grub_free (ctxt->hash_context); +} - if (pkalgos[pk].pad (&hmpi, hval, hash, sk)) - goto fail; - if (!*pkalgos[pk].algo) - { - grub_dl_load (pkalgos[pk].module); - grub_errno = GRUB_ERR_NONE; - } - - if (!*pkalgos[pk].algo) - { - grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"), - pkalgos[pk].module); - goto fail; - } - if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0)) - goto fail; - - grub_free (context); - grub_free (readbuf); - - return GRUB_ERR_NONE; - - fail: - grub_free (context); - grub_free (readbuf); - if (!grub_errno) - return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); - return grub_errno; - } +static void +grub_pubkey_close (void *ctxt) +{ + grub_pubkey_close_real (ctxt); + grub_free (ctxt); } grub_err_t -grub_verify_signature (grub_file_t f, grub_file_t sig, +grub_verify_signature (grub_file_t f, const char *fsig, struct grub_public_key *pkey) { - return grub_verify_signature_real (0, 0, f, sig, pkey); + grub_file_t sig; + grub_err_t err; + struct grub_pubkey_context ctxt; + grub_uint8_t *readbuf = NULL; + + sig = grub_file_open (fsig, + GRUB_FILE_TYPE_SIGNATURE + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (!sig) + return grub_errno; + + err = grub_verify_signature_init (&ctxt, sig); + if (err) + { + grub_file_close (sig); + return err; + } + + readbuf = grub_zalloc (READBUF_SIZE); + if (!readbuf) + goto fail; + + while (1) + { + grub_ssize_t r; + r = grub_file_read (f, readbuf, READBUF_SIZE); + if (r < 0) + goto fail; + if (r == 0) + break; + err = grub_pubkey_write (&ctxt, readbuf, r); + if (err) + return err; + } + + grub_verify_signature_real (&ctxt, pkey); + fail: + grub_pubkey_close_real (&ctxt); + return grub_errno; } static grub_err_t @@ -680,10 +737,12 @@ grub_cmd_trust (grub_extcmd_context_t ctxt, if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - grub_file_filter_disable_compression (); - if (ctxt->state[OPTION_SKIP_SIG].set) - grub_file_filter_disable_pubkey (); - pkf = grub_file_open (args[0]); + pkf = grub_file_open (args[0], + GRUB_FILE_TYPE_PUBLIC_KEY_TRUST + | GRUB_FILE_TYPE_NO_DECOMPRESS + | (ctxt->state[OPTION_SKIP_SIG].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE + : GRUB_FILE_TYPE_NONE)); if (!pkf) return grub_errno; pk = grub_load_public_key (pkf); @@ -757,7 +816,7 @@ static grub_err_t grub_cmd_verify_signature (grub_extcmd_context_t ctxt, int argc, char **args) { - grub_file_t f = NULL, sig = NULL; + grub_file_t f = NULL; grub_err_t err = GRUB_ERR_NONE; struct grub_public_key *pk = NULL; @@ -771,10 +830,12 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt, if (argc > 2) { grub_file_t pkf; - grub_file_filter_disable_compression (); - if (ctxt->state[OPTION_SKIP_SIG].set) - grub_file_filter_disable_pubkey (); - pkf = grub_file_open (args[2]); + pkf = grub_file_open (args[2], + GRUB_FILE_TYPE_PUBLIC_KEY + | GRUB_FILE_TYPE_NO_DECOMPRESS + | (ctxt->state[OPTION_SKIP_SIG].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE + : GRUB_FILE_TYPE_NONE)); if (!pkf) return grub_errno; pk = grub_load_public_key (pkf); @@ -786,26 +847,15 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt, grub_file_close (pkf); } - grub_file_filter_disable_all (); - f = grub_file_open (args[0]); + f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE); if (!f) { err = grub_errno; goto fail; } - grub_file_filter_disable_all (); - sig = grub_file_open (args[1]); - if (!sig) - { - err = grub_errno; - goto fail; - } - - err = grub_verify_signature (f, sig, pk); + err = grub_verify_signature (f, args[1], pk); fail: - if (sig) - grub_file_close (sig); if (f) grub_file_close (f); if (pk) @@ -815,135 +865,53 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt, static int sec = 0; -static void -verified_free (grub_verified_t verified) -{ - if (verified) - { - grub_free (verified->buf); - grub_free (verified); - } -} - -static grub_ssize_t -verified_read (struct grub_file *file, char *buf, grub_size_t len) -{ - grub_verified_t verified = file->data; - - grub_memcpy (buf, (char *) verified->buf + file->offset, len); - return len; -} - static grub_err_t -verified_close (struct grub_file *file) -{ - grub_verified_t verified = file->data; - - grub_file_close (verified->file); - verified_free (verified); - file->data = 0; - - /* device and name are freed by parent */ - file->device = 0; - file->name = 0; - - return grub_errno; -} - -struct grub_fs verified_fs = -{ - .name = "verified_read", - .read = verified_read, - .close = verified_close -}; - -static grub_file_t -grub_pubkey_open (grub_file_t io, const char *filename) +grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)), + void **context, enum grub_verify_flags *flags) { grub_file_t sig; char *fsuf, *ptr; grub_err_t err; - grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX]; - grub_file_t ret; - grub_verified_t verified; + struct grub_pubkey_context *ctxt; if (!sec) - return io; - if (io->device->disk && - (io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID - || io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID)) - return io; - fsuf = grub_malloc (grub_strlen (filename) + sizeof (".sig")); + { + *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; + return GRUB_ERR_NONE; + } + + fsuf = grub_malloc (grub_strlen (io->name) + sizeof (".sig")); if (!fsuf) - return NULL; - ptr = grub_stpcpy (fsuf, filename); + return grub_errno; + ptr = grub_stpcpy (fsuf, io->name); grub_memcpy (ptr, ".sig", sizeof (".sig")); - grub_memcpy (curfilt, grub_file_filters_enabled, - sizeof (curfilt)); - grub_file_filter_disable_all (); - sig = grub_file_open (fsuf); - grub_memcpy (grub_file_filters_enabled, curfilt, - sizeof (curfilt)); + sig = grub_file_open (fsuf, GRUB_FILE_TYPE_SIGNATURE); grub_free (fsuf); if (!sig) - return NULL; + return grub_errno; - ret = grub_malloc (sizeof (*ret)); - if (!ret) + ctxt = grub_malloc (sizeof (*ctxt)); + if (!ctxt) { grub_file_close (sig); - return NULL; + return grub_errno; } - *ret = *io; - - ret->fs = &verified_fs; - ret->not_easily_seekable = 0; - if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1)) - { - grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "big file signature isn't implemented yet"); - grub_file_close (sig); - grub_free (ret); - return NULL; - } - verified = grub_malloc (sizeof (*verified)); - if (!verified) - { - grub_file_close (sig); - grub_free (ret); - return NULL; - } - verified->buf = grub_malloc (ret->size); - if (!verified->buf) - { - grub_file_close (sig); - grub_free (verified); - grub_free (ret); - return NULL; - } - if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - filename); - grub_file_close (sig); - verified_free (verified); - grub_free (ret); - return NULL; - } - - err = grub_verify_signature_real (verified->buf, ret->size, 0, sig, NULL); - grub_file_close (sig); + err = grub_verify_signature_init (ctxt, sig); if (err) { - verified_free (verified); - grub_free (ret); - return NULL; + grub_free (ctxt); + grub_file_close (sig); + return err; } - verified->file = io; - ret->data = verified; - return ret; + *context = ctxt; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_pubkey_fini (void *ctxt) +{ + return grub_verify_signature_real (ctxt, NULL); } static char * @@ -954,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); @@ -963,17 +931,25 @@ 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", - .read = pseudo_read -}; + .fs_read = pseudo_read + }; +struct grub_file_verifier grub_pubkey_verifier = + { + .name = "pgp", + .init = grub_pubkey_init, + .fini = grub_pubkey_fini, + .write = grub_pubkey_write, + .close = grub_pubkey_close, + }; static grub_extcmd_t cmd, cmd_trust; static grub_command_t cmd_distrust, cmd_list; -GRUB_MOD_INIT(verify) +GRUB_MOD_INIT(pgp) { const char *val; struct grub_module_header *header; @@ -983,8 +959,6 @@ GRUB_MOD_INIT(verify) sec = 1; else sec = 0; - - grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY, grub_pubkey_open); grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec); grub_env_export ("check_signatures"); @@ -1030,11 +1004,15 @@ GRUB_MOD_INIT(verify) cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust, N_("PUBKEY_ID"), N_("Remove PUBKEY_ID from trusted keys.")); + + grub_verifier_register (&grub_pubkey_verifier); } -GRUB_MOD_FINI(verify) +GRUB_MOD_FINI(pgp) { - grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY); + grub_register_variable_hook ("check_signatures", NULL, NULL); + grub_env_unset ("check_signatures"); + grub_verifier_unregister (&grub_pubkey_verifier); grub_unregister_extcmd (cmd); grub_unregister_extcmd (cmd_trust); grub_unregister_command (cmd_list); diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index cf2793e1d..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) @@ -113,15 +173,24 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) if (state[4].set) { char *uuid; - if (! fs->uuid) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("%s does not support UUIDs"), fs->name); - err = fs->uuid (dev, &uuid); + if (! fs->fs_uuid) + { + grub_device_close (dev); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("%s does not support UUIDs"), fs->name); + } + err = fs->fs_uuid (dev, &uuid); if (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); @@ -134,17 +203,26 @@ grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) if (state[5].set) { char *label; - if (! fs->label) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("filesystem `%s' does not support labels"), - fs->name); - err = fs->label (dev, &label); + if (! fs->fs_label) + { + grub_device_close (dev); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("filesystem `%s' does not support labels"), + fs->name); + } + err = fs->fs_label (dev, &label); if (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 7dd32e445..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 @@ -81,8 +156,8 @@ iterate_device (const char *name, void *data) if (! buf) return 1; - grub_file_filter_disable_compression (); - file = grub_file_open (buf); + file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH + | GRUB_FILE_TYPE_NO_DECOMPRESS); if (file) { found = 1; @@ -103,9 +178,9 @@ iterate_device (const char *name, void *data) fs = grub_fs_probe (dev); #ifdef DO_SEARCH_FS_UUID -#define read_fn uuid +#define read_fn fs_uuid #else -#define read_fn label +#define read_fn fs_label #endif if (fs && fs->read_fn) @@ -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 5f06642f6..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); @@ -133,15 +136,15 @@ get_fileinfo (char *path, struct test_parse_ctx *ctx) /* Fetch writing time. */ ctx->file_info.mtimeset = 0; - if (fs->mtime) + if (fs->fs_mtime) { - if (! fs->mtime (dev, &ctx->file_info.mtime)) + if (! fs->fs_mtime (dev, &ctx->file_info.mtime)) ctx->file_info.mtimeset = 1; grub_errno = GRUB_ERR_NONE; } } else - (fs->dir) (dev, path, find_file, ctx); + (fs->fs_dir) (dev, path, find_file, ctx); grub_device_close (dev); grub_free (path); @@ -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, @@ -355,8 +358,8 @@ test_parse (char **args, int *argn, int argc) if (grub_strcmp (args[*argn], "-s") == 0) { grub_file_t file; - grub_file_filter_disable_compression (); - file = grub_file_open (args[*argn + 1]); + file = grub_file_open (args[*argn + 1], GRUB_FILE_TYPE_GET_SIZE + | GRUB_FILE_TYPE_NO_DECOMPRESS); update_val (file && (grub_file_size (file) != 0), &ctx); if (file) grub_file_close (file); @@ -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 cfab6763d..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 @@ -57,7 +59,7 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_TESTLOAD); if (! file) return grub_errno; diff --git a/grub-core/commands/testspeed.c b/grub-core/commands/testspeed.c index 042645f8d..c13a9b8d8 100644 --- a/grub-core/commands/testspeed.c +++ b/grub-core/commands/testspeed.c @@ -61,7 +61,7 @@ grub_cmd_testspeed (grub_extcmd_context_t ctxt, int argc, char **args) if (buffer == NULL) return grub_errno; - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_TESTLOAD); if (file == NULL) goto quit; diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c new file mode 100644 index 000000000..dde74ab83 --- /dev/null +++ b/grub-core/commands/tpm.c @@ -0,0 +1,125 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + * + * Core TPM support code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_err_t +grub_tpm_verify_init (grub_file_t io, + enum grub_file_type type __attribute__ ((unused)), + void **context, enum grub_verify_flags *flags) +{ + *context = io->name; + *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK; + + /* + * The loopback image is mapped as a disk allowing it to function like + * a block device. However, we measure files read from the block device + * not the device itself. For example, we don't measure block devices like + * hd0 disk directly. This process is crucial to prevent out-of-memory + * errors as loopback images are inherently large. + */ + if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_LOOPBACK) + *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_tpm_verify_write (void *context, void *buf, grub_size_t size) +{ + grub_err_t status = grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context); + + if (status == GRUB_ERR_NONE) + return GRUB_ERR_NONE; + + grub_dprintf ("tpm", "Measuring buffer failed: %d\n", status); + return grub_is_tpm_fail_fatal () ? status : GRUB_ERR_NONE; +} + +static grub_err_t +grub_tpm_verify_string (char *str, enum grub_verify_string_type type) +{ + const char *prefix = NULL; + char *description; + grub_err_t status; + + switch (type) + { + case GRUB_VERIFY_KERNEL_CMDLINE: + prefix = "kernel_cmdline: "; + break; + case GRUB_VERIFY_MODULE_CMDLINE: + prefix = "module_cmdline: "; + break; + case GRUB_VERIFY_COMMAND: + prefix = "grub_cmd: "; + break; + } + description = grub_malloc (grub_strlen (str) + grub_strlen (prefix) + 1); + if (!description) + return grub_errno; + grub_memcpy (description, prefix, grub_strlen (prefix)); + grub_memcpy (description + grub_strlen (prefix), str, + grub_strlen (str) + 1); + status = + grub_tpm_measure ((unsigned char *) str, grub_strlen (str), + GRUB_STRING_PCR, description); + grub_free (description); + if (status == GRUB_ERR_NONE) + return GRUB_ERR_NONE; + + grub_dprintf ("tpm", "Measuring string %s failed: %d\n", str, status); + return grub_is_tpm_fail_fatal () ? status : GRUB_ERR_NONE; +} + +struct grub_file_verifier grub_tpm_verifier = { + .name = "tpm", + .init = grub_tpm_verify_init, + .write = grub_tpm_verify_write, + .verify_string = grub_tpm_verify_string, +}; + +GRUB_MOD_INIT (tpm) +{ + /* + * Even though this now calls ibmvtpm's grub_tpm_present() from GRUB_MOD_INIT(), + * it does seem to call it late enough in the initialization sequence so + * that whatever discovered "device nodes" before this GRUB_MOD_INIT() is + * called, enables the ibmvtpm driver to see the device nodes. + */ + if (!grub_tpm_present()) + return; + grub_verifier_register (&grub_tpm_verifier); +} + +GRUB_MOD_FINI (tpm) +{ + if (!grub_tpm_present()) + return; + grub_verifier_unregister (&grub_tpm_verifier); +} diff --git a/grub-core/commands/tpm2_key_protector/args.c b/grub-core/commands/tpm2_key_protector/args.c 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/usbtest.c b/grub-core/commands/usbtest.c index 01cdca934..2c6d93fe6 100644 --- a/grub-core/commands/usbtest.c +++ b/grub-core/commands/usbtest.c @@ -63,6 +63,11 @@ static const char *usb_devspeed[] = "High" }; +#if __GNUC__ >= 9 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Waddress-of-packed-member" +#endif + static grub_usb_err_t grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, char **string) @@ -108,6 +113,10 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, return GRUB_USB_ERR_NONE; } +#if __GNUC__ >= 9 +#pragma GCC diagnostic pop +#endif + static void usb_print_str (const char *description, grub_usb_device_t dev, int idx) { 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 9b4e72766..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; } @@ -370,7 +396,7 @@ match_files (const char *prefix, const char *suffix, const char *end, else path = ctx.dir; - if (fs->dir (dev, path, match_files_iter, &ctx)) + if (fs->fs_dir (dev, path, match_files_iter, &ctx)) goto fail; grub_free (ctx.dir); @@ -418,7 +444,7 @@ check_file_iter (const char *name, const struct grub_dirhook_info *info, ctx->found = 1; return 1; } - + return 0; } @@ -452,7 +478,7 @@ check_file (const char *dir, const char *basename) else path = dir; - fs->dir (dev, path[0] ? path : "/", check_file_iter, &ctx); + fs->fs_dir (dev, path[0] ? path : "/", check_file_iter, &ctx); if (grub_errno == 0 && basename[0] == 0) ctx.found = 1; 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 494a1b773..f3c968195 100644 --- a/grub-core/disk/ahci.c +++ b/grub-core/disk/ahci.c @@ -82,6 +82,20 @@ enum grub_ahci_hba_port_command GRUB_AHCI_HBA_PORT_CMD_FR = 0x4000, }; +enum grub_ahci_hba_port_int_status + { + GRUB_AHCI_HBA_PORT_IS_IFS = (1UL << 27), + GRUB_AHCI_HBA_PORT_IS_HBDS = (1UL << 28), + GRUB_AHCI_HBA_PORT_IS_HBFS = (1UL << 29), + GRUB_AHCI_HBA_PORT_IS_TFES = (1UL << 30), + }; + +#define GRUB_AHCI_HBA_PORT_IS_FATAL_MASK ( \ + GRUB_AHCI_HBA_PORT_IS_IFS | \ + GRUB_AHCI_HBA_PORT_IS_HBDS | \ + GRUB_AHCI_HBA_PORT_IS_HBFS | \ + GRUB_AHCI_HBA_PORT_IS_TFES) + struct grub_ahci_hba { grub_uint32_t cap; @@ -136,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 @@ -443,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)); @@ -529,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); @@ -543,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); @@ -559,10 +572,10 @@ 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 () + 10000; + endtime = grub_get_time_ms () + 32000; while (grub_get_time_ms () < endtime) { @@ -688,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; @@ -729,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)); @@ -847,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) @@ -894,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; @@ -914,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; @@ -976,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], @@ -1024,9 +1036,10 @@ 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) + if (grub_get_time_ms () > endtime || + (dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK)) { grub_dprintf ("ahci", "AHCI status <%x %x %x %x>\n", dev->hba->ports[dev->port].command_issue, @@ -1034,7 +1047,10 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, dev->hba->ports[dev->port].intstatus, dev->hba->ports[dev->port].task_file_data); dev->hba->ports[dev->port].command_issue = 0; - err = grub_error (GRUB_ERR_IO, "AHCI transfer timed out"); + if (dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK) + err = grub_error (GRUB_ERR_IO, "AHCI transfer error"); + else + err = grub_error (GRUB_ERR_IO, "AHCI transfer timed out"); if (!reset) grub_ahci_reset_port (dev, 1); break; @@ -1076,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/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c index 0cc1993e5..c94039a3d 100644 --- a/grub-core/disk/arc/arcdisk.c +++ b/grub-core/disk/arc/arcdisk.c @@ -296,11 +296,11 @@ static struct grub_disk_dev grub_arcdisk_dev = { .name = "arcdisk", .id = GRUB_DISK_DEVICE_ARCDISK_ID, - .iterate = grub_arcdisk_iterate, - .open = grub_arcdisk_open, - .close = grub_arcdisk_close, - .read = grub_arcdisk_read, - .write = grub_arcdisk_write, + .disk_iterate = grub_arcdisk_iterate, + .disk_open = grub_arcdisk_open, + .disk_close = grub_arcdisk_close, + .disk_read = grub_arcdisk_read, + .disk_write = grub_arcdisk_write, .next = 0 }; diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c index 8ba4e5c50..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; @@ -510,11 +509,11 @@ static struct grub_disk_dev grub_atadisk_dev = { .name = "ATA", .id = GRUB_DISK_DEVICE_ATA_ID, - .iterate = grub_ata_iterate, - .open = grub_ata_open, - .close = grub_ata_close, - .read = grub_ata_read, - .write = grub_ata_write, + .disk_iterate = grub_ata_iterate, + .disk_open = grub_ata_open, + .disk_close = grub_ata_close, + .disk_read = grub_ata_read, + .disk_write = grub_ata_write, .next = 0 }; @@ -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 1e03a091c..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,24 +312,38 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, } break; case GRUB_CRYPTODISK_MODE_IV_PLAIN64: - iv[1] = grub_cpu_to_le32 (sector >> 32); 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) @@ -310,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; @@ -321,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; @@ -335,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) @@ -365,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); @@ -380,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; @@ -398,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 @@ -414,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) @@ -498,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 @@ -514,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 @@ -537,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++; @@ -592,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); @@ -605,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); } @@ -642,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); @@ -654,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"); @@ -711,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; @@ -731,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; } @@ -806,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) { @@ -819,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 @@ -863,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); @@ -873,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) @@ -903,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); @@ -916,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] == ')') @@ -986,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; @@ -996,31 +1612,33 @@ 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; } } static struct grub_disk_dev grub_cryptodisk_dev = { .name = "cryptodisk", .id = GRUB_DISK_DEVICE_CRYPTODISK_ID, - .iterate = grub_cryptodisk_iterate, - .open = grub_cryptodisk_open, - .close = grub_cryptodisk_close, - .read = grub_cryptodisk_read, - .write = grub_cryptodisk_write, + .disk_iterate = grub_cryptodisk_iterate, + .disk_open = grub_cryptodisk_open, + .disk_close = grub_cryptodisk_close, + .disk_read = grub_cryptodisk_read, + .disk_write = grub_cryptodisk_write, #ifdef GRUB_UTIL - .memberlist = grub_cryptodisk_memberlist, + .disk_memberlist = grub_cryptodisk_memberlist, #endif .next = 0 }; @@ -1038,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"); @@ -1096,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: @@ -1128,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", @@ -1140,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 6f901c0ad..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->iterate) - { - if ((p->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; @@ -311,9 +328,9 @@ grub_diskfilter_memberlist (grub_disk_t disk) for (pull = 0; pv && pull < GRUB_DISK_PULL_MAX; pull++) for (p = grub_disk_dev_list; pv && p; p = p->next) if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID - && p->iterate) + && p->disk_iterate) { - (p->iterate) (scan_disk_hook, NULL, pull); + (p->disk_iterate) (scan_disk_hook, NULL, pull); while (pv && pv->disk) pv = pv->next; } @@ -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,30 +1378,117 @@ 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", .id = GRUB_DISK_DEVICE_DISKFILTER_ID, - .iterate = grub_diskfilter_iterate, - .open = grub_diskfilter_open, - .close = grub_diskfilter_close, - .read = grub_diskfilter_read, - .write = grub_diskfilter_write, + .disk_iterate = grub_diskfilter_iterate, + .disk_open = grub_diskfilter_open, + .disk_close = grub_diskfilter_close, + .disk_read = grub_diskfilter_read, + .disk_write = grub_diskfilter_write, #ifdef GRUB_UTIL - .memberlist = grub_diskfilter_memberlist, - .raidname = grub_diskfilter_getname, + .disk_memberlist = grub_diskfilter_memberlist, + .disk_raidname = grub_diskfilter_getname, #endif .next = 0 }; +static grub_command_t cmd; + GRUB_MOD_INIT(diskfilter) { grub_disk_dev_register (&grub_diskfilter_dev); + cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck, + N_("[--quiet] DEVICE"), + N_("Check if a logical volume resides on encrypted disks.")); } GRUB_MOD_FINI(diskfilter) { grub_disk_dev_unregister (&grub_diskfilter_dev); + if (cmd != NULL) + grub_unregister_command (cmd); free_array (); } diff --git a/grub-core/disk/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 e66b35d87..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; @@ -129,6 +129,9 @@ find_parent_device (struct grub_efidisk_data *devices, return 0; ldp = grub_efi_find_last_device_path (dp); + if (! ldp) + return 0; + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ldp->length = sizeof (*ldp); @@ -159,6 +162,9 @@ is_child (struct grub_efidisk_data *child, return 0; ldp = grub_efi_find_last_device_path (dp); + if (! ldp) + return 0; + ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ldp->length = sizeof (*ldp); @@ -224,7 +230,7 @@ name_devices (struct grub_efidisk_data *devices) { case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE: is_hard_drive = 1; - /* Fall through by intention. */ + /* Intentionally fall through. */ case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE: { struct grub_efidisk_data *parent, *parent2; @@ -313,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, @@ -329,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; @@ -517,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); @@ -547,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)) @@ -564,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)) { @@ -627,11 +643,11 @@ static struct grub_disk_dev grub_efidisk_dev = { .name = "efidisk", .id = GRUB_DISK_DEVICE_EFIDISK_ID, - .iterate = grub_efidisk_iterate, - .open = grub_efidisk_open, - .close = grub_efidisk_close, - .read = grub_efidisk_read, - .write = grub_efidisk_write, + .disk_iterate = grub_efidisk_iterate, + .disk_open = grub_efidisk_open, + .disk_close = grub_efidisk_close, + .disk_read = grub_efidisk_read, + .disk_write = grub_efidisk_write, .next = 0 }; @@ -701,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) @@ -830,6 +846,9 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) { grub_efi_device_path_t *dup_ldp; dup_ldp = grub_efi_find_last_device_path (dup_dp); + if (! dup_ldp) + break; + if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE || GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))) @@ -858,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 76ef1afb8..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 @@ -84,11 +84,11 @@ static struct grub_disk_dev grub_host_dev = /* The only important line in this file :-) */ .name = "host", .id = GRUB_DISK_DEVICE_HOST_ID, - .iterate = grub_host_iterate, - .open = grub_host_open, - .close = grub_host_close, - .read = grub_host_read, - .write = grub_host_write, + .disk_iterate = grub_host_iterate, + .disk_open = grub_host_open, + .disk_close = grub_host_close, + .disk_read = grub_host_read, + .disk_write = grub_host_write, .next = 0 }; diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index f0aadd111..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); @@ -637,11 +636,11 @@ static struct grub_disk_dev grub_biosdisk_dev = { .name = "biosdisk", .id = GRUB_DISK_DEVICE_BIOSDISK_ID, - .iterate = grub_biosdisk_iterate, - .open = grub_biosdisk_open, - .close = grub_biosdisk_close, - .read = grub_biosdisk_read, - .write = grub_biosdisk_write, + .disk_iterate = grub_biosdisk_iterate, + .disk_open = grub_biosdisk_open, + .disk_close = grub_biosdisk_close, + .disk_read = grub_biosdisk_read, + .disk_write = grub_biosdisk_write, .next = 0 }; @@ -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/nand.c b/grub-core/disk/ieee1275/nand.c index feffa8c4c..bcf3a06f4 100644 --- a/grub-core/disk/ieee1275/nand.c +++ b/grub-core/disk/ieee1275/nand.c @@ -223,11 +223,11 @@ static struct grub_disk_dev grub_nand_dev = { .name = "nand", .id = GRUB_DISK_DEVICE_NAND_ID, - .iterate = grub_nand_iterate, - .open = grub_nand_open, - .close = grub_nand_close, - .read = grub_nand_read, - .write = grub_nand_write, + .disk_iterate = grub_nand_iterate, + .disk_open = grub_nand_open, + .disk_close = grub_nand_close, + .disk_read = grub_nand_read, + .disk_write = grub_nand_write, .next = 0 }; diff --git a/grub-core/disk/ieee1275/obdisk.c b/grub-core/disk/ieee1275/obdisk.c new file mode 100644 index 000000000..fcc39e0a2 --- /dev/null +++ b/grub-core/disk/ieee1275/obdisk.c @@ -0,0 +1,1109 @@ +/* obdisk.c - Open Boot disk access. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IEEE1275_DEV "ieee1275/" +#define IEEE1275_DISK_ALIAS "/disk@" + +struct disk_dev +{ + struct disk_dev *next; + struct disk_dev **prev; + char *name; + char *raw_name; + char *grub_devpath; + char *grub_alias_devpath; + grub_ieee1275_ihandle_t ihandle; + grub_uint32_t block_size; + grub_uint64_t num_blocks; + unsigned int log_sector_size; + grub_uint32_t opened; + grub_uint32_t valid; + grub_uint32_t boot_dev; +}; + +struct parent_dev +{ + struct parent_dev *next; + struct parent_dev **prev; + char *name; + char *type; + grub_ieee1275_ihandle_t ihandle; + grub_uint32_t address_cells; +}; + +static struct grub_scsi_test_unit_ready tur = +{ + .opcode = grub_scsi_cmd_test_unit_ready, + .lun = 0, + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, + .control = 0, +}; + +static int disks_enumerated; +static struct disk_dev *disk_devs; +static struct parent_dev *parent_devs; + +static const char *block_blacklist[] = { + /* Requires additional work in grub before being able to be used. */ + "/iscsi-hba", + /* This block device should never be used by grub. */ + "/reboot-memory@0", + 0 +}; + +#define STRCMP(a, b) ((a) && (b) && (grub_strcmp (a, b) == 0)) + +static char * +strip_ob_partition (char *path) +{ + char *sptr; + + sptr = grub_strstr (path, ":"); + + if (sptr != NULL) + *sptr = '\0'; + + return path; +} + +static void +escape_commas (const char *src, char *dest) +{ + const char *iptr; + + for (iptr = src; *iptr; ) + { + if (*iptr == ',') + *dest++ ='\\'; + + *dest++ = *iptr++; + } + + *dest = '\0'; +} + +static int +count_commas (const char *src) +{ + int count = 0; + + for ( ; *src; src++) + if (*src == ',') + count++; + + return count; +} + + +static char * +decode_grub_devname (const char *name) +{ + char *devpath; + char *p, c; + grub_size_t sz; + + if (grub_add (grub_strlen (name), 1, &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device name")); + return NULL; + } + + devpath = grub_malloc (sz); + if (devpath == NULL) + return NULL; + + /* Un-escape commas. */ + p = devpath; + while ((c = *name++) != '\0') + { + if (c == '\\' && *name == ',') + { + *p++ = ','; + name++; + } + else + *p++ = c; + } + + *p++ = '\0'; + + return devpath; +} + +static char * +encode_grub_devname (const char *path) +{ + char *encoding, *optr; + grub_size_t sz; + + if (path == NULL) + return NULL; + + if (grub_add (sizeof (IEEE1275_DEV) + 1, count_commas (path), &sz) || + grub_add (sz, grub_strlen (path), &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining encoding size")); + grub_print_error (); + return NULL; + } + + encoding = grub_malloc (sz); + + if (encoding == NULL) + { + grub_print_error (); + return NULL; + } + + optr = grub_stpcpy (encoding, IEEE1275_DEV); + escape_commas (path, optr); + return encoding; +} + +static char * +get_parent_devname (const char *devname) +{ + char *parent, *pptr; + + parent = grub_strdup (devname); + + if (parent == NULL) + { + grub_print_error (); + return NULL; + } + + pptr = grub_strstr (parent, IEEE1275_DISK_ALIAS); + + if (pptr != NULL) + *pptr = '\0'; + + return parent; +} + +static void +free_parent_dev (struct parent_dev *parent) +{ + if (parent != NULL) + { + grub_free (parent->name); + grub_free (parent->type); + grub_free (parent); + } +} + +static struct parent_dev * +init_parent (const char *parent) +{ + struct parent_dev *op; + + op = grub_zalloc (sizeof (struct parent_dev)); + + if (op == NULL) + { + grub_print_error (); + return NULL; + } + + op->name = grub_strdup (parent); + op->type = grub_malloc (IEEE1275_MAX_PROP_LEN); + + if ((op->name == NULL) || (op->type == NULL)) + { + grub_print_error (); + free_parent_dev (op); + return NULL; + } + + return op; +} + +static struct parent_dev * +open_new_parent (const char *parent) +{ + struct parent_dev *op = init_parent(parent); + grub_ieee1275_ihandle_t ihandle; + grub_ieee1275_phandle_t phandle; + grub_uint32_t address_cells = 2; + + if (op == NULL) + return NULL; + + grub_ieee1275_open (parent, &ihandle); + + if (ihandle == 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, "unable to open %s", parent); + grub_print_error (); + free_parent_dev (op); + return NULL; + } + + if (grub_ieee1275_instance_to_package (ihandle, &phandle)) + { + grub_error (GRUB_ERR_BAD_DEVICE, "unable to get parent %s", parent); + grub_print_error (); + free_parent_dev (op); + return NULL; + } + + /* + * IEEE Std 1275-1994 page 110: A missing "address-cells" property + * signifies that the number of address cells is two. So ignore on error. + */ + if (grub_ieee1275_get_integer_property (phandle, "#address-cells", + &address_cells, + sizeof (address_cells), 0) != 0) + address_cells = 2; + + grub_ieee1275_get_property (phandle, "device_type", op->type, + IEEE1275_MAX_PROP_LEN, NULL); + + op->ihandle = ihandle; + op->address_cells = address_cells; + return op; +} + +static struct parent_dev * +open_parent (const char *parent) +{ + struct parent_dev *op; + + op = grub_named_list_find (GRUB_AS_NAMED_LIST (parent_devs), parent); + + if (op == NULL) + { + op = open_new_parent (parent); + + if (op != NULL) + grub_list_push (GRUB_AS_LIST_P (&parent_devs), GRUB_AS_LIST (op)); + } + + return op; +} + +static void +display_parents (void) +{ + struct parent_dev *parent; + + grub_printf ("-------------------- PARENTS --------------------\n"); + + FOR_LIST_ELEMENTS (parent, parent_devs) + { + grub_printf ("name: %s\n", parent->name); + grub_printf ("type: %s\n", parent->type); + grub_printf ("address_cells %x\n", parent->address_cells); + } + + grub_printf ("-------------------------------------------------\n"); +} + +static char * +canonicalise_4cell_ua (grub_ieee1275_ihandle_t ihandle, char *unit_address) +{ + grub_uint32_t phy_lo, phy_hi, lun_lo, lun_hi; + int valid_phy = 0; + grub_size_t size; + char *canon = NULL; + + valid_phy = grub_ieee1275_decode_unit4 (ihandle, unit_address, + grub_strlen (unit_address), &phy_lo, + &phy_hi, &lun_lo, &lun_hi); + + if ((valid_phy == 0) && (phy_hi != 0xffffffff)) + canon = grub_ieee1275_encode_uint4 (ihandle, phy_lo, phy_hi, + lun_lo, lun_hi, &size); + + return canon; +} + +static char * +canonicalise_disk (const char *devname) +{ + char *canon, *parent; + struct parent_dev *op; + + canon = grub_ieee1275_canonicalise_devname (devname); + + if (canon == NULL) + { + /* This should not happen. */ + grub_error (GRUB_ERR_BAD_DEVICE, "canonicalise devname failed"); + grub_print_error (); + return NULL; + } + + /* Don't try to open the parent of a virtual device. */ + if (grub_strstr (canon, "virtual-devices")) + return canon; + + parent = get_parent_devname (canon); + + if (parent == NULL) + return NULL; + + op = open_parent (parent); + + /* + * Devices with 4 address cells can have many different types of addressing + * (phy, wwn, and target lun). Use the parents encode-unit / decode-unit + * to find the true canonical name. + */ + if ((op) && (op->address_cells == 4)) + { + char *unit_address, *real_unit_address, *real_canon; + grub_size_t real_unit_str_len; + + unit_address = grub_strstr (canon, IEEE1275_DISK_ALIAS); + unit_address += grub_strlen (IEEE1275_DISK_ALIAS); + + if (unit_address == NULL) + { + /* + * This should not be possible, but return the canonical name for + * the non-disk block device. + */ + grub_free (parent); + return (canon); + } + + real_unit_address = canonicalise_4cell_ua (op->ihandle, unit_address); + + if (real_unit_address == NULL) + { + /* + * This is not an error, since this function could be called with a devalias + * containing a drive that isn't installed in the system. + */ + grub_free (parent); + return NULL; + } + + real_unit_str_len = grub_strlen (op->name) + sizeof (IEEE1275_DISK_ALIAS) + + grub_strlen (real_unit_address); + if (grub_add (grub_strlen (op->name), sizeof (IEEE1275_DISK_ALIAS), &real_unit_str_len) || + grub_add (real_unit_str_len, grub_strlen (real_unit_address), &real_unit_str_len)) + { + grub_free (parent); + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of canonical name")); + grub_print_error (); + return NULL; + } + + real_canon = grub_malloc (real_unit_str_len); + if (real_canon == NULL) + { + grub_free (parent); + grub_print_error (); + return NULL; + } + + grub_snprintf (real_canon, real_unit_str_len, "%s/disk@%s", + op->name, real_unit_address); + + grub_free (canon); + canon = real_canon; + } + + grub_free (parent); + return (canon); +} + +static struct disk_dev * +add_canon_disk (const char *cname) +{ + grub_size_t sz; + struct disk_dev *dev; + + dev = grub_zalloc (sizeof (struct disk_dev)); + + if (dev == NULL) + goto failed; + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_RAW_DEVNAMES)) + { + /* + * Append :nolabel to the end of all SPARC disks. + * nolabel is mutually exclusive with all other + * arguments and allows a client program to open + * the entire (raw) disk. Any disk label is ignored. + */ + if (grub_add (grub_strlen (cname), sizeof (":nolabel"), &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while appending :nolabel to end of canonical name"); + goto failed; + } + + dev->raw_name = grub_malloc (sz); + + if (dev->raw_name == NULL) + goto failed; + + grub_snprintf (dev->raw_name, sz, "%s:nolabel", cname); + } + + /* + * Don't use grub_ieee1275_encode_devname here, the devpath in grub.cfg doesn't + * understand device aliases, which the layer above sometimes sends us. + */ + dev->grub_devpath = encode_grub_devname(cname); + + if (dev->grub_devpath == NULL) + goto failed; + + dev->name = grub_strdup (cname); + + if (dev->name == NULL) + goto failed; + + dev->valid = 1; + grub_list_push (GRUB_AS_LIST_P (&disk_devs), GRUB_AS_LIST (dev)); + return dev; + + failed: + grub_print_error (); + + if (dev != NULL) + { + grub_free (dev->name); + grub_free (dev->grub_devpath); + grub_free (dev->raw_name); + } + + grub_free (dev); + return NULL; +} + +static grub_err_t +add_disk (const char *path) +{ + grub_err_t ret = GRUB_ERR_NONE; + struct disk_dev *dev; + char *canon; + + canon = canonicalise_disk (path); + dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon); + + if ((canon != NULL) && (dev == NULL)) + { + struct disk_dev *ob_device; + + ob_device = add_canon_disk (canon); + + if (ob_device == NULL) + ret = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure to add disk"); + } + else if (dev != NULL) + dev->valid = 1; + + grub_free (canon); + return (ret); +} + +static grub_err_t +grub_obdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *dest) +{ + grub_err_t ret = GRUB_ERR_NONE; + struct disk_dev *dev; + unsigned long long pos; + grub_ssize_t result = 0; + + if (disk->data == NULL) + return grub_error (GRUB_ERR_BAD_DEVICE, "invalid disk data"); + + dev = (struct disk_dev *)disk->data; + pos = sector << disk->log_sector_size; + grub_ieee1275_seek (dev->ihandle, pos, &result); + + if (result < 0) + { + dev->opened = 0; + return grub_error (GRUB_ERR_READ_ERROR, "seek error, can't seek block %llu", + (long long) sector); + } + + grub_ieee1275_read (dev->ihandle, dest, size << disk->log_sector_size, + &result); + + if (result != (grub_ssize_t) (size << disk->log_sector_size)) + { + dev->opened = 0; + return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " + "from `%s'"), + (unsigned long long) sector, + disk->name); + } + return ret; +} + +static void +grub_obdisk_close (grub_disk_t disk) +{ + grub_memset (disk, 0, sizeof (*disk)); +} + +static void +scan_usb_disk (const char *parent) +{ + struct parent_dev *op; + grub_ssize_t result; + + op = open_parent (parent); + + if (op == NULL) + { + grub_error (GRUB_ERR_BAD_DEVICE, "unable to open %s", parent); + grub_print_error (); + return; + } + + if ((grub_ieee1275_set_address (op->ihandle, 0, 0) == 0) && + (grub_ieee1275_no_data_command (op->ihandle, &tur, &result) == 0) && + (result == 0)) + { + char *buf; + + buf = grub_malloc (IEEE1275_MAX_PATH_LEN); + + if (buf == NULL) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); + grub_print_error (); + return; + } + + grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@0", parent); + add_disk (buf); + grub_free (buf); + } +} + +static void +scan_nvme_disk (const char *path) +{ + char *buf; + + buf = grub_malloc (IEEE1275_MAX_PATH_LEN); + + if (buf == NULL) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); + grub_print_error (); + return; + } + + grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@1", path); + add_disk (buf); + grub_free (buf); +} + +static void +scan_sparc_sas_2cell (struct parent_dev *op) +{ + grub_ssize_t result; + grub_uint8_t tgt; + char *buf; + + buf = grub_malloc (IEEE1275_MAX_PATH_LEN); + + if (buf == NULL) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); + grub_print_error (); + return; + } + + for (tgt = 0; tgt < 0xf; tgt++) + { + + if ((grub_ieee1275_set_address(op->ihandle, tgt, 0) == 0) && + (grub_ieee1275_no_data_command (op->ihandle, &tur, &result) == 0) && + (result == 0)) + { + + grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@%" + PRIxGRUB_UINT32_T, op->name, tgt); + + add_disk (buf); + } + } +} + +static void +scan_sparc_sas_4cell (struct parent_dev *op) +{ + grub_uint16_t exp; + grub_uint8_t phy; + char *buf; + + buf = grub_malloc (IEEE1275_MAX_PATH_LEN); + + if (buf == NULL) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "disk scan failure"); + grub_print_error (); + return; + } + + /* + * Cycle thru the potential for dual ported SAS disks + * behind a SAS expander. + */ + for (exp = 0; exp <= 0x100; exp+=0x100) + + /* The current limit is 32 disks on a phy. */ + for (phy = 0; phy < 0x20; phy++) + { + char *canon = NULL; + + grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "p%" PRIxGRUB_UINT32_T ",0", + exp | phy); + + canon = canonicalise_4cell_ua (op->ihandle, buf); + + if (canon != NULL) + { + grub_snprintf (buf, IEEE1275_MAX_PATH_LEN, "%s/disk@%s", + op->name, canon); + + add_disk (buf); + grub_free (canon); + } + } + + grub_free (buf); +} + +static void +scan_sparc_sas_disk (const char *parent) +{ + struct parent_dev *op; + + op = open_parent (parent); + + if ((op != NULL) && (op->address_cells == 4)) + scan_sparc_sas_4cell (op); + else if ((op != NULL) && (op->address_cells == 2)) + scan_sparc_sas_2cell (op); +} + +static void +iterate_devtree (const struct grub_ieee1275_devalias *alias) +{ + struct grub_ieee1275_devalias child; + + if ((grub_strcmp (alias->type, "scsi-2") == 0) || + (grub_strcmp (alias->type, "scsi-sas") == 0)) + return scan_sparc_sas_disk (alias->path); + + else if (grub_strcmp (alias->type, "nvme") == 0) + return scan_nvme_disk (alias->path); + + else if (grub_strcmp (alias->type, "scsi-usb") == 0) + return scan_usb_disk (alias->path); + + else if (grub_strcmp (alias->type, "block") == 0) + { + const char **bl = block_blacklist; + + while (*bl != NULL) + { + if (grub_strstr (alias->path, *bl)) + return; + bl++; + } + + add_disk (alias->path); + return; + } + + FOR_IEEE1275_DEVCHILDREN (alias->path, child) + iterate_devtree (&child); +} + +static void +enumerate_disks (void) +{ + struct grub_ieee1275_devalias alias; + + FOR_IEEE1275_DEVCHILDREN("/", alias) + iterate_devtree (&alias); +} + +static grub_err_t +add_bootpath (void) +{ + struct disk_dev *ob_device; + grub_err_t ret = GRUB_ERR_NONE; + char *dev, *alias; + char *type; + + dev = grub_ieee1275_get_boot_dev (); + + if (dev == NULL) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure adding boot device"); + + type = grub_ieee1275_get_device_type (dev); + + if (type == NULL) + { + grub_free (dev); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure adding boot device"); + } + + alias = NULL; + + if (grub_strcmp (type, "network") != 0) + { + dev = strip_ob_partition (dev); + ob_device = add_canon_disk (dev); + + if (ob_device == NULL) + ret = grub_error (GRUB_ERR_OUT_OF_MEMORY, "failure adding boot device"); + + ob_device->valid = 1; + + alias = grub_ieee1275_get_devname (dev); + + if (alias && grub_strcmp (alias, dev) != 0) + ob_device->grub_alias_devpath = grub_ieee1275_encode_devname (dev); + + ob_device->boot_dev = 1; + } + + grub_free (type); + grub_free (dev); + grub_free (alias); + return ret; +} + +static void +enumerate_aliases (void) +{ + struct grub_ieee1275_devalias alias; + + /* + * Some block device aliases are not in canonical form + * + * For example: + * + * disk3 /pci@301/pci@1/scsi@0/disk@p3 + * disk2 /pci@301/pci@1/scsi@0/disk@p2 + * disk1 /pci@301/pci@1/scsi@0/disk@p1 + * disk /pci@301/pci@1/scsi@0/disk@p0 + * disk0 /pci@301/pci@1/scsi@0/disk@p0 + * + * None of these devices are in canonical form. + * + * Also, just because there is a devalias, doesn't mean there is a disk + * at that location. And a valid boot block device doesn't have to have + * a devalias at all. + * + * At this point, all valid disks have been found in the system + * and devaliases that point to canonical names are stored in the + * disk_devs list already. + */ + FOR_IEEE1275_DEVALIASES (alias) + { + struct disk_dev *dev; + char *canon; + + if (grub_strcmp (alias.type, "block") != 0) + continue; + + canon = canonicalise_disk (alias.name); + + if (canon == NULL) + /* This is not an error, a devalias could point to a nonexistent disk. */ + continue; + + dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon); + + if (dev != NULL) + { + /* + * If more than one alias points to the same device, + * remove the previous one unless it is the boot dev, + * since the upper level will use the first one. The reason + * all the others are redone is in the case of hot-plugging + * a disk. If the boot disk gets hot-plugged, it will come + * thru here with a different name without the boot_dev flag + * set. + */ + if ((dev->boot_dev) && (dev->grub_alias_devpath)) + continue; + + grub_free (dev->grub_alias_devpath); + dev->grub_alias_devpath = grub_ieee1275_encode_devname (alias.path); + } + grub_free (canon); + } +} + +static void +display_disks (void) +{ + struct disk_dev *dev; + + grub_printf ("--------------------- DISKS ---------------------\n"); + + FOR_LIST_ELEMENTS (dev, disk_devs) + { + grub_printf ("name: %s\n", dev->name); + grub_printf ("grub_devpath: %s\n", dev->grub_devpath); + grub_printf ("grub_alias_devpath: %s\n", dev->grub_alias_devpath); + grub_printf ("valid: %s\n", (dev->valid) ? "yes" : "no"); + grub_printf ("boot_dev: %s\n", (dev->boot_dev) ? "yes" : "no"); + grub_printf ("opened: %s\n", (dev->ihandle) ? "yes" : "no"); + grub_printf ("block size: %" PRIuGRUB_UINT32_T "\n", + dev->block_size); + grub_printf ("num blocks: %" PRIuGRUB_UINT64_T "\n", + dev->num_blocks); + grub_printf ("log sector size: %" PRIuGRUB_UINT32_T "\n", + dev->log_sector_size); + grub_printf ("\n"); + } + + grub_printf ("-------------------------------------------------\n"); +} + +static void +display_stats (void) +{ + const char *debug = grub_env_get ("debug"); + + if (debug == NULL) + return; + + if (grub_strword (debug, "all") || grub_strword (debug, "obdisk")) + { + display_parents (); + display_disks (); + } +} + +static void +invalidate_all_disks (void) +{ + struct disk_dev *dev = NULL; + + if (disks_enumerated != 0) + FOR_LIST_ELEMENTS (dev, disk_devs) + dev->valid = 0; +} + +static struct disk_dev * +find_legacy_grub_devpath (const char *name) +{ + struct disk_dev *dev = NULL; + char *canon, *devpath = NULL; + + devpath = decode_grub_devname (name + sizeof ("ieee1275")); + canon = canonicalise_disk (devpath); + + if (canon != NULL) + dev = grub_named_list_find (GRUB_AS_NAMED_LIST (disk_devs), canon); + + grub_free (devpath); + grub_free (canon); + return dev; +} + +static void +enumerate_devices (void) +{ + invalidate_all_disks (); + enumerate_disks (); + enumerate_aliases (); + disks_enumerated = 1; + display_stats (); +} + +static struct disk_dev * +find_grub_devpath_real (const char *name) +{ + struct disk_dev *dev = NULL; + + FOR_LIST_ELEMENTS (dev, disk_devs) + { + if ((STRCMP (dev->grub_devpath, name)) + || (STRCMP (dev->grub_alias_devpath, name))) + break; + } + + return dev; +} + +static struct disk_dev * +find_grub_devpath (const char *name) +{ + struct disk_dev *dev = NULL; + int enumerated; + + do { + enumerated = disks_enumerated; + dev = find_grub_devpath_real (name); + + if (dev != NULL) + break; + + dev = find_legacy_grub_devpath (name); + + if (dev != NULL) + break; + + enumerate_devices (); + } while (enumerated == 0); + + return dev; +} + +static int +grub_obdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) +{ + struct disk_dev *dev; + const char *name; + + if (pull != GRUB_DISK_PULL_NONE) + return 0; + + enumerate_devices (); + + FOR_LIST_ELEMENTS (dev, disk_devs) + { + if (dev->valid == 1) + { + if (dev->grub_alias_devpath) + name = dev->grub_alias_devpath; + else + name = dev->grub_devpath; + + if (hook (name, hook_data)) + return 1; + } + } + + return 0; +} + +static grub_err_t +grub_obdisk_open (const char *name, grub_disk_t disk) +{ + grub_ieee1275_ihandle_t ihandle = 0; + struct disk_dev *dev = NULL; + + if (grub_strncmp (name, IEEE1275_DEV, sizeof (IEEE1275_DEV) - 1) != 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not IEEE1275 device"); + + dev = find_grub_devpath (name); + + if (dev == NULL) + { + grub_printf ("UNKNOWN DEVICE: %s\n", name); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "%s", name); + } + + if (dev->opened == 0) + { + if (dev->raw_name != NULL) + grub_ieee1275_open (dev->raw_name, &ihandle); + else + grub_ieee1275_open (dev->name, &ihandle); + + if (ihandle == 0) + { + grub_printf ("Can't open device %s\n", name); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device %s", name); + } + + dev->block_size = grub_ieee1275_get_block_size (ihandle); + dev->num_blocks = grub_ieee1275_num_blocks (ihandle); + + if (dev->num_blocks == 0) + dev->num_blocks = grub_ieee1275_num_blocks64 (ihandle); + + if (dev->num_blocks == 0) + dev->num_blocks = GRUB_DISK_SIZE_UNKNOWN; + + if (dev->block_size != 0) + dev->log_sector_size = grub_log2ull (dev->block_size); + else + dev->log_sector_size = 9; + + dev->ihandle = ihandle; + dev->opened = 1; + } + + disk->total_sectors = dev->num_blocks; + disk->id = dev->ihandle; + disk->data = dev; + disk->log_sector_size = dev->log_sector_size; + return GRUB_ERR_NONE; +} + + +static struct grub_disk_dev grub_obdisk_dev = + { + .name = "obdisk", + .id = GRUB_DISK_DEVICE_OBDISK_ID, + .disk_iterate = grub_obdisk_iterate, + .disk_open = grub_obdisk_open, + .disk_close = grub_obdisk_close, + .disk_read = grub_obdisk_read, + }; + +void +grub_obdisk_init (void) +{ + grub_disk_firmware_fini = grub_obdisk_fini; + add_bootpath (); + grub_disk_dev_register (&grub_obdisk_dev); +} + +void +grub_obdisk_fini (void) +{ + struct disk_dev *dev; + + FOR_LIST_ELEMENTS (dev, disk_devs) + { + if (dev->opened != 0) + grub_ieee1275_close (dev->ihandle); + } + + grub_disk_dev_unregister (&grub_obdisk_dev); +} diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 235c0fe2c..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; @@ -615,11 +650,11 @@ static struct grub_disk_dev grub_ofdisk_dev = { .name = "ofdisk", .id = GRUB_DISK_DEVICE_OFDISK_ID, - .iterate = grub_ofdisk_iterate, - .open = grub_ofdisk_open, - .close = grub_ofdisk_close, - .read = grub_ofdisk_read, - .write = grub_ofdisk_write, + .disk_iterate = grub_ofdisk_iterate, + .disk_open = grub_ofdisk_open, + .disk_close = grub_ofdisk_close, + .disk_read = grub_ofdisk_read, + .disk_write = grub_ofdisk_write, .next = 0 }; @@ -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 0f978ad05..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_type_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 2d8deaeaf..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,27 +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]); - 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)); @@ -123,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; @@ -164,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) @@ -181,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) @@ -221,10 +235,11 @@ static struct grub_disk_dev grub_loopback_dev = { .name = "loopback", .id = GRUB_DISK_DEVICE_LOOPBACK_ID, - .iterate = grub_loopback_iterate, - .open = grub_loopback_open, - .read = grub_loopback_read, - .write = grub_loopback_write, + .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 }; @@ -233,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 e5ffc01bf..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+"); @@ -77,11 +78,11 @@ static struct grub_disk_dev grub_memdisk_dev = { .name = "memdisk", .id = GRUB_DISK_DEVICE_MEMDISK_ID, - .iterate = grub_memdisk_iterate, - .open = grub_memdisk_open, - .close = grub_memdisk_close, - .read = grub_memdisk_read, - .write = grub_memdisk_write, + .disk_iterate = grub_memdisk_iterate, + .disk_open = grub_memdisk_open, + .disk_close = grub_memdisk_close, + .disk_read = grub_memdisk_read, + .disk_write = grub_memdisk_write, .next = 0 }; @@ -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/raid6_recover.c b/grub-core/disk/raid6_recover.c index aa674f6ca..75fe464a4 100644 --- a/grub-core/disk/raid6_recover.c +++ b/grub-core/disk/raid6_recover.c @@ -74,14 +74,26 @@ mod_255 (unsigned x) } static grub_err_t -grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, - char *buf, grub_disk_addr_t sector, grub_size_t size) +raid6_recover_read_node (void *data, int disknr, + grub_uint64_t sector, + void *buf, grub_size_t size) +{ + struct grub_diskfilter_segment *array = data; + + return grub_diskfilter_read_node (&array->nodes[disknr], + (grub_disk_addr_t)sector, + size >> GRUB_DISK_SECTOR_BITS, buf); +} + +grub_err_t +grub_raid6_recover_gen (void *data, grub_uint64_t nstripes, int disknr, int p, + char *buf, grub_uint64_t sector, grub_size_t size, + int layout, raid_recover_read_t read_func) { int i, q, pos; int bad1 = -1, bad2 = -1; char *pbuf = 0, *qbuf = 0; - size <<= GRUB_DISK_SECTOR_BITS; pbuf = grub_zalloc (size); if (!pbuf) goto quit; @@ -91,17 +103,17 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, goto quit; q = p + 1; - if (q == (int) array->node_count) + if (q == (int) nstripes) q = 0; pos = q + 1; - if (pos == (int) array->node_count) + if (pos == (int) nstripes) pos = 0; - for (i = 0; i < (int) array->node_count - 2; i++) + for (i = 0; i < (int) nstripes - 2; i++) { int c; - if (array->layout & GRUB_RAID_LAYOUT_MUL_FROM_POS) + if (layout & GRUB_RAID_LAYOUT_MUL_FROM_POS) c = pos; else c = i; @@ -109,8 +121,7 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, bad1 = c; else { - if (! grub_diskfilter_read_node (&array->nodes[pos], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (!read_func (data, pos, sector, buf, size)) { grub_crypto_xor (pbuf, pbuf, buf, size); grub_raid_block_mulx (c, buf, size); @@ -128,7 +139,7 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, } pos++; - if (pos == (int) array->node_count) + if (pos == (int) nstripes) pos = 0; } @@ -139,16 +150,14 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, if (bad2 < 0) { /* One bad device */ - if ((! grub_diskfilter_read_node (&array->nodes[p], sector, - size >> GRUB_DISK_SECTOR_BITS, buf))) + if (!read_func (data, p, sector, buf, size)) { grub_crypto_xor (buf, buf, pbuf, size); goto quit; } grub_errno = GRUB_ERR_NONE; - if (grub_diskfilter_read_node (&array->nodes[q], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (read_func (data, q, sector, buf, size)) goto quit; grub_crypto_xor (buf, buf, qbuf, size); @@ -160,14 +169,12 @@ grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, /* Two bad devices */ unsigned c; - if (grub_diskfilter_read_node (&array->nodes[p], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (read_func (data, p, sector, buf, size)) goto quit; grub_crypto_xor (pbuf, pbuf, buf, size); - if (grub_diskfilter_read_node (&array->nodes[q], sector, - size >> GRUB_DISK_SECTOR_BITS, buf)) + if (read_func (data, q, sector, buf, size)) goto quit; grub_crypto_xor (qbuf, qbuf, buf, size); @@ -190,6 +197,15 @@ quit: return grub_errno; } +static grub_err_t +grub_raid6_recover (struct grub_diskfilter_segment *array, int disknr, int p, + char *buf, grub_disk_addr_t sector, grub_size_t size) +{ + return grub_raid6_recover_gen (array, array->node_count, disknr, p, buf, + sector, size << GRUB_DISK_SECTOR_BITS, + array->layout, raid6_recover_read_node); +} + GRUB_MOD_INIT(raid6rec) { grub_raid6_init_table (); diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c index 4c6923f8b..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); @@ -747,11 +745,11 @@ static struct grub_disk_dev grub_scsi_dev = { .name = "scsi", .id = GRUB_DISK_DEVICE_SCSI_ID, - .iterate = grub_scsi_iterate, - .open = grub_scsi_open, - .close = grub_scsi_close, - .read = grub_scsi_read, - .write = grub_scsi_write, + .disk_iterate = grub_scsi_iterate, + .disk_open = grub_scsi_open, + .disk_close = grub_scsi_close, + .disk_read = grub_scsi_read, + .disk_write = grub_scsi_write, .next = 0 }; diff --git a/grub-core/disk/uboot/ubootdisk.c b/grub-core/disk/uboot/ubootdisk.c index a5ce07a99..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); @@ -264,23 +262,33 @@ uboot_disk_read (struct grub_disk *disk, } static grub_err_t -uboot_disk_write (struct grub_disk *disk __attribute__ ((unused)), - grub_disk_addr_t sector __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused)), - const char *buf __attribute__ ((unused))) +uboot_disk_write (struct grub_disk *disk, + grub_disk_addr_t offset, grub_size_t numblocks, const char *buf) { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "attempt to write (not supported)"); + struct ubootdisk_data *d; + int retval; + + d = disk->data; + + retval = grub_uboot_dev_write (d->dev, buf, numblocks, offset); + grub_dprintf ("ubootdisk", + "retval=%d, numblocks=%d, sector=%llu\n", + retval, numblocks, (grub_uint64_t) offset); + + if (retval != 0) + return grub_error (GRUB_ERR_IO, "U-Boot disk write error"); + + return GRUB_ERR_NONE; } static struct grub_disk_dev grub_ubootdisk_dev = { .name = "ubootdisk", .id = GRUB_DISK_DEVICE_UBOOTDISK_ID, - .iterate = uboot_disk_iterate, - .open = uboot_disk_open, - .close = uboot_disk_close, - .read = uboot_disk_read, - .write = uboot_disk_write, + .disk_iterate = uboot_disk_iterate, + .disk_open = uboot_disk_open, + .disk_close = uboot_disk_close, + .disk_read = uboot_disk_read, + .disk_write = uboot_disk_write, .next = 0 }; 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 b18a9238d..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; @@ -249,11 +247,11 @@ grub_virtdisk_write (grub_disk_t disk, grub_disk_addr_t sector, static struct grub_disk_dev grub_virtdisk_dev = { .name = "xen", .id = GRUB_DISK_DEVICE_XEN, - .iterate = grub_virtdisk_iterate, - .open = grub_virtdisk_open, - .close = grub_virtdisk_close, - .read = grub_virtdisk_read, - .write = grub_virtdisk_write, + .disk_iterate = grub_virtdisk_iterate, + .disk_open = grub_virtdisk_open, + .disk_close = grub_virtdisk_close, + .disk_read = grub_virtdisk_read, + .disk_write = grub_virtdisk_write, .next = 0 }; @@ -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 e49d0b6ff..ae476ef2c 100644 --- a/grub-core/efiemu/i386/loadcore64.c +++ b/grub-core/efiemu/i386/loadcore64.c @@ -98,6 +98,7 @@ grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs, break; case R_X86_64_PC32: + case R_X86_64_PLT32: err = grub_efiemu_write_value (addr, *addr32 + rel->r_addend + sym.off @@ -120,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 f6813b1ed..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) @@ -187,7 +187,7 @@ grub_efiemu_load_file (const char *filename) grub_file_t file; grub_err_t err; - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); if (! file) return grub_errno; diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c index e606dbffc..9b8e0d0ad 100644 --- a/grub-core/efiemu/mm.c +++ b/grub-core/efiemu/mm.c @@ -417,6 +417,7 @@ fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, default: grub_dprintf ("efiemu", "Unknown memory type %d. Assuming unusable\n", type); + /* FALLTHROUGH */ case GRUB_MEMORY_RESERVED: return grub_efiemu_add_to_mmap (addr, size, GRUB_EFI_UNUSABLE_MEMORY); @@ -553,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); @@ -659,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 d923e409f..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; @@ -174,17 +174,17 @@ efiemu_memset (grub_uint8_t *a, grub_uint8_t b, grub_size_t n) static inline void write_cmos (grub_uint8_t addr, grub_uint8_t val) { - __asm__ __volatile__ ("outb %%al,$0x70\n" - "mov %%cl, %%al\n" - "outb %%al,$0x71": :"a" (addr), "c" (val)); + asm volatile ("outb %%al,$0x70\n" + "mov %%cl, %%al\n" + "outb %%al,$0x71": :"a" (addr), "c" (val)); } static inline grub_uint8_t read_cmos (grub_uint8_t addr) { grub_uint8_t ret; - __asm__ __volatile__ ("outb %%al, $0x70\n" - "inb $0x71, %%al": "=a"(ret) :"a" (addr)); + asm volatile ("outb %%al, $0x70\n" + "inb $0x71, %%al": "=a"(ret) :"a" (addr)); return ret; } @@ -202,7 +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 53d76a64d..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 @@ -418,28 +451,21 @@ grub_font_load (const char *filename) #endif if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+') - file = grub_buffile_open (filename, 1024); + 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, 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 f673897e0..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; @@ -685,12 +688,12 @@ grub_affs_mtime (grub_device_t device, grub_int32_t *t) static struct grub_fs grub_affs_fs = { .name = "affs", - .dir = grub_affs_dir, - .open = grub_affs_open, - .read = grub_affs_read, - .close = grub_affs_close, - .label = grub_affs_label, - .mtime = grub_affs_mtime, + .fs_dir = grub_affs_dir, + .fs_open = grub_affs_open, + .fs_read = grub_affs_read, + .fs_close = grub_affs_close, + .fs_label = grub_affs_label, + .fs_mtime = grub_affs_mtime, #ifdef GRUB_UTIL .reserved_first_sector = 0, @@ -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 d2b490bce..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 @@ -1082,13 +1085,13 @@ static struct grub_fs grub_bfs_fs = { #else .name = "bfs", #endif - .dir = grub_bfs_dir, - .open = grub_bfs_open, - .read = grub_bfs_read, - .close = grub_bfs_close, - .label = grub_bfs_label, + .fs_dir = grub_bfs_dir, + .fs_open = grub_bfs_open, + .fs_read = grub_bfs_read, + .fs_close = grub_bfs_close, + .fs_label = grub_bfs_label, #ifndef MODE_AFS - .uuid = grub_bfs_uuid, + .fs_uuid = grub_bfs_uuid, #endif #ifdef GRUB_UTIL .reserved_first_sector = 1, @@ -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 9cffa91fa..7bf8d922f 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -17,6 +17,14 @@ * along with GRUB. If not, see . */ +/* + * Tell zstd to expose functions that aren't part of the stable API, which + * aren't safe to use when linking against a dynamic library. We vendor in a + * specific zstd version, so we know what we're getting. We need these unstable + * functions to provide our own allocator, which uses grub_malloc(), to zstd. + */ +#define ZSTD_STATIC_LINKING_ONLY + #include #include #include @@ -27,8 +35,12 @@ #include #include #include +#include #include #include +#include +#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -45,6 +57,9 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define GRUB_BTRFS_LZO_BLOCK_MAX_CSIZE (GRUB_BTRFS_LZO_BLOCK_SIZE + \ (GRUB_BTRFS_LZO_BLOCK_SIZE / 16) + 64 + 3) +#define ZSTD_BTRFS_MAX_WINDOWLOG 17 +#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG) + typedef grub_uint8_t grub_btrfs_checksum_t[0x20]; typedef grub_uint16_t grub_btrfs_uuid_t[8]; @@ -77,7 +92,8 @@ struct btrfs_header { grub_btrfs_checksum_t checksum; grub_btrfs_uuid_t uuid; - grub_uint8_t dummy[0x30]; + grub_uint64_t bytenr; + grub_uint8_t dummy[0x28]; grub_uint32_t nitems; grub_uint8_t level; } GRUB_PACKED; @@ -119,6 +135,10 @@ struct grub_btrfs_chunk_item #define GRUB_BTRFS_CHUNK_TYPE_RAID1 0x10 #define GRUB_BTRFS_CHUNK_TYPE_DUPLICATED 0x20 #define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 +#define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 +#define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 +#define GRUB_BTRFS_CHUNK_TYPE_RAID1C3 0x200 +#define GRUB_BTRFS_CHUNK_TYPE_RAID1C4 0x400 grub_uint8_t dummy2[0xc]; grub_uint16_t nstripes; grub_uint16_t nsubstripes; @@ -175,7 +195,7 @@ struct grub_btrfs_time { grub_int64_t sec; grub_uint32_t nanosec; -} __attribute__ ((aligned (4))); +} GRUB_PACKED; struct grub_btrfs_inode { @@ -212,6 +232,7 @@ struct grub_btrfs_extent_data #define GRUB_BTRFS_COMPRESSION_NONE 0 #define GRUB_BTRFS_COMPRESSION_ZLIB 1 #define GRUB_BTRFS_COMPRESSION_LZO 2 +#define GRUB_BTRFS_COMPRESSION_ZSTD 3 #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 @@ -227,11 +248,11 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, static grub_err_t read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb) { + struct grub_btrfs_superblock sblock; unsigned i; grub_err_t err = GRUB_ERR_NONE; for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++) { - struct grub_btrfs_superblock sblock; /* Don't try additional superblocks beyond device size. */ if (i && (grub_le_to_cpu64 (sblock.this_device.size) >> GRUB_DISK_SECTOR_BITS) <= superblock_sectors[i]) @@ -284,6 +305,25 @@ free_iterator (struct grub_btrfs_leaf_descriptor *desc) grub_free (desc->data); } +static grub_err_t +check_btrfs_header (struct grub_btrfs_data *data, struct btrfs_header *header, + grub_disk_addr_t addr) +{ + if (grub_le_to_cpu64 (header->bytenr) != addr) + { + grub_dprintf ("btrfs", "btrfs_header.bytenr is not equal node addr\n"); + return grub_error (GRUB_ERR_BAD_FS, + "header bytenr is not equal node addr"); + } + if (grub_memcmp (data->sblock.uuid, header->uuid, sizeof(grub_btrfs_uuid_t))) + { + grub_dprintf ("btrfs", "btrfs_header.uuid doesn't match sblock uuid\n"); + return grub_error (GRUB_ERR_BAD_FS, + "header uuid doesn't match sblock uuid"); + } + return GRUB_ERR_NONE; +} + static grub_err_t save_ref (struct grub_btrfs_leaf_descriptor *desc, grub_disk_addr_t addr, unsigned i, unsigned m, int l) @@ -292,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; @@ -341,6 +385,7 @@ next (struct grub_btrfs_data *data, &head, sizeof (head), 0); if (err) return -err; + check_btrfs_header (data, &head, grub_le_to_cpu64 (node.addr)); save_ref (desc, grub_le_to_cpu64 (node.addr), 0, grub_le_to_cpu32 (head.nitems), !head.level); @@ -375,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; } @@ -402,6 +447,7 @@ lower_bound (struct grub_btrfs_data *data, recursion_depth + 1); if (err) return err; + check_btrfs_header (data, &head, addr); addr += sizeof (head); if (head.level) { @@ -564,7 +610,7 @@ find_device_iter (const char *name, void *data) } static grub_device_t -find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) +find_device (struct grub_btrfs_data *data, grub_uint64_t id) { struct find_device_ctx ctx = { .data = data, @@ -576,28 +622,28 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) for (i = 0; i < data->n_devices_attached; i++) if (id == data->devices_attached[i].id) return data->devices_attached[i].dev; - if (do_rescan) - grub_device_iterate (find_device_iter, &ctx); - if (!ctx.dev_found) - { - grub_error (GRUB_ERR_BAD_FS, - N_("couldn't find a necessary member device " - "of multi-device filesystem")); - return NULL; - } + + grub_device_iterate (find_device_iter, &ctx); + data->n_devices_attached++; 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) { - grub_device_close (ctx.dev_found); data->devices_attached = tmp; + + fail: + if (ctx.dev_found) + grub_device_close (ctx.dev_found); return NULL; } } @@ -606,6 +652,211 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) return ctx.dev_found; } +static grub_err_t +btrfs_read_from_chunk (struct grub_btrfs_data *data, + struct grub_btrfs_chunk_item *chunk, + grub_uint64_t stripen, grub_uint64_t stripe_offset, + int redundancy, grub_uint64_t csize, + void *buf) +{ + struct grub_btrfs_chunk_stripe *stripe; + grub_disk_addr_t paddr; + grub_device_t dev; + grub_err_t err; + + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); + /* Right now the redundancy handling is easy. + With RAID5-like it will be more difficult. */ + stripe += stripen + redundancy; + + paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; + + grub_dprintf ("btrfs", "stripe %" PRIxGRUB_UINT64_T + " maps to 0x%" PRIxGRUB_UINT64_T "\n" + "reading paddr 0x%" PRIxGRUB_UINT64_T "\n", + stripen, stripe->offset, paddr); + + dev = find_device (data, stripe->device_id); + if (!dev) + { + grub_dprintf ("btrfs", + "couldn't find a necessary member device " + "of multi-device filesystem\n"); + grub_errno = GRUB_ERR_NONE; + return GRUB_ERR_READ_ERROR; + } + + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buf); + return err; +} + +struct raid56_buffer { + void *buf; + int data_is_valid; +}; + +static void +rebuild_raid5 (char *dest, struct raid56_buffer *buffers, + grub_uint64_t nstripes, grub_uint64_t csize) +{ + grub_uint64_t i; + int first; + + for(i = 0; buffers[i].data_is_valid && i < nstripes; i++); + + if (i == nstripes) + { + grub_dprintf ("btrfs", "called rebuild_raid5(), but all disks are OK\n"); + return; + } + + grub_dprintf ("btrfs", "rebuilding RAID 5 stripe #%" PRIuGRUB_UINT64_T "\n", i); + + for (i = 0, first = 1; i < nstripes; i++) + { + if (!buffers[i].data_is_valid) + continue; + + if (first) { + grub_memcpy(dest, buffers[i].buf, csize); + first = 0; + } else + grub_crypto_xor (dest, dest, buffers[i].buf, csize); + } +} + +static grub_err_t +raid6_recover_read_buffer (void *data, int disk_nr, + grub_uint64_t addr __attribute__ ((unused)), + void *dest, grub_size_t size) +{ + struct raid56_buffer *buffers = data; + + if (!buffers[disk_nr].data_is_valid) + return grub_errno = GRUB_ERR_READ_ERROR; + + grub_memcpy(dest, buffers[disk_nr].buf, size); + + return grub_errno = GRUB_ERR_NONE; +} + +static void +rebuild_raid6 (struct raid56_buffer *buffers, grub_uint64_t nstripes, + grub_uint64_t csize, grub_uint64_t parities_pos, void *dest, + grub_uint64_t stripen) + +{ + grub_raid6_recover_gen (buffers, nstripes, stripen, parities_pos, + dest, 0, csize, 0, raid6_recover_read_buffer); +} + +static grub_err_t +raid56_read_retry (struct grub_btrfs_data *data, + struct grub_btrfs_chunk_item *chunk, + grub_uint64_t stripe_offset, grub_uint64_t stripen, + grub_uint64_t csize, void *buf, grub_uint64_t parities_pos) +{ + struct raid56_buffer *buffers; + grub_uint64_t nstripes = grub_le_to_cpu16 (chunk->nstripes); + grub_uint64_t chunk_type = grub_le_to_cpu64 (chunk->type); + grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY; + grub_uint64_t i, failed_devices; + + buffers = grub_calloc (nstripes, sizeof (*buffers)); + if (!buffers) + goto cleanup; + + for (i = 0; i < nstripes; i++) + { + buffers[i].buf = grub_zalloc (csize); + if (!buffers[i].buf) + goto cleanup; + } + + for (failed_devices = 0, i = 0; i < nstripes; i++) + { + struct grub_btrfs_chunk_stripe *stripe; + grub_disk_addr_t paddr; + grub_device_t dev; + grub_err_t err; + + /* + * The struct grub_btrfs_chunk_stripe array lives + * behind struct grub_btrfs_chunk_item. + */ + stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1) + i; + + paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; + grub_dprintf ("btrfs", "reading paddr %" PRIxGRUB_UINT64_T + " from stripe ID %" PRIxGRUB_UINT64_T "\n", + paddr, stripe->device_id); + + dev = find_device (data, stripe->device_id); + if (!dev) + { + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " FAILED (dev ID %" + PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); + failed_devices++; + continue; + } + + err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, + paddr & (GRUB_DISK_SECTOR_SIZE - 1), + csize, buffers[i].buf); + if (err == GRUB_ERR_NONE) + { + buffers[i].data_is_valid = 1; + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T " OK (dev ID %" + PRIxGRUB_UINT64_T ")\n", i, stripe->device_id); + } + else + { + grub_dprintf ("btrfs", "stripe %" PRIuGRUB_UINT64_T + " READ FAILED (dev ID %" PRIxGRUB_UINT64_T ")\n", + i, stripe->device_id); + failed_devices++; + } + } + + if (failed_devices > 1 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5)) + { + grub_dprintf ("btrfs", "not enough disks for RAID 5: total %" PRIuGRUB_UINT64_T + ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + ret = GRUB_ERR_READ_ERROR; + goto cleanup; + } + else if (failed_devices > 2 && (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID6)) + { + grub_dprintf ("btrfs", "not enough disks for RAID 6: total %" PRIuGRUB_UINT64_T + ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + ret = GRUB_ERR_READ_ERROR; + goto cleanup; + } + else + grub_dprintf ("btrfs", "enough disks for RAID 5: total %" + PRIuGRUB_UINT64_T ", missing %" PRIuGRUB_UINT64_T "\n", + nstripes, failed_devices); + + /* We have enough disks. So, rebuild the data. */ + if (chunk_type & GRUB_BTRFS_CHUNK_TYPE_RAID5) + rebuild_raid5 (buf, buffers, nstripes, csize); + else + rebuild_raid6 (buffers, nstripes, csize, parities_pos, buf, stripen); + + ret = GRUB_ERR_NONE; + cleanup: + if (buffers) + for (i = 0; i < nstripes; i++) + grub_free (buffers[i].buf); + grub_free (buffers); + + return ret; +} + static grub_err_t grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, void *buf, grub_size_t size, int recursion_depth) @@ -619,7 +870,6 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_err_t err = 0; struct grub_btrfs_key key_out; int challoc = 0; - grub_device_t dev; struct grub_btrfs_key key_in; grub_size_t chsize; grub_disk_addr_t chaddr; @@ -662,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; @@ -684,6 +951,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, grub_uint16_t nstripes; unsigned redundancy = 1; unsigned i, j; + int is_raid56; + grub_uint64_t parities_pos = 0; + + is_raid56 = !!(grub_le_to_cpu64 (chunk->type) & + (GRUB_BTRFS_CHUNK_TYPE_RAID5 | + GRUB_BTRFS_CHUNK_TYPE_RAID6)); if (grub_le_to_cpu64 (chunk->size) <= off) { @@ -714,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: @@ -764,6 +1065,103 @@ 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: + case GRUB_BTRFS_CHUNK_TYPE_RAID6: + { + grub_uint64_t nparities, stripe_nr, high, low; + + redundancy = 1; /* no redundancy for now */ + + if (grub_le_to_cpu64 (chunk->type) & GRUB_BTRFS_CHUNK_TYPE_RAID5) + { + grub_dprintf ("btrfs", "RAID5\n"); + nparities = 1; + } + else + { + grub_dprintf ("btrfs", "RAID6\n"); + nparities = 2; + } + + /* + * RAID 6 layout consists of several stripes spread over + * the disks, e.g.: + * + * Disk_0 Disk_1 Disk_2 Disk_3 + * A0 B0 P0 Q0 + * Q1 A1 B1 P1 + * P2 Q2 A2 B2 + * + * Note: placement of the parities depend on row number. + * + * Pay attention that the btrfs terminology may differ from + * terminology used in other RAID implementations, e.g. LVM, + * dm or md. The main difference is that btrfs calls contiguous + * block of data on a given disk, e.g. A0, stripe instead of chunk. + * + * The variables listed below have following meaning: + * - stripe_nr is the stripe number excluding the parities + * (A0 = 0, B0 = 1, A1 = 2, B1 = 3, etc.), + * - high is the row number (0 for A0...Q0, 1 for Q1...P1, etc.), + * - stripen is the disk number in a row (0 for A0, Q1, P2, + * 1 for B0, A1, Q2, etc.), + * - off is the logical address to read, + * - chunk_stripe_length is the size of a stripe (typically 64 KiB), + * - nstripes is the number of disks in a row, + * - low is the offset of the data inside a stripe, + * - stripe_offset is the data offset in an array, + * - csize is the "potential" data to read; it will be reduced + * to size if the latter is smaller, + * - nparities is the number of parities (1 for RAID 5, 2 for + * RAID 6); used only in RAID 5/6 code. + */ + stripe_nr = grub_divmod64 (off, chunk_stripe_length, &low); + + /* + * stripen is computed without the parities + * (0 for A0, A1, A2, 1 for B0, B1, B2, etc.). + */ + if (nparities >= nstripes) + return grub_error (GRUB_ERR_BAD_FS, + "invalid RAID5/6: nparities >= nstripes"); + high = grub_divmod64 (stripe_nr, nstripes - nparities, &stripen); + + /* + * The stripes are spread over the disks. Every each row their + * positions are shifted by 1 place. So, the real disks number + * change. Hence, we have to take into account current row number + * modulo nstripes (0 for A0, 1 for A1, 2 for A2, etc.). + */ + grub_divmod64 (high + stripen, nstripes, &stripen); + + /* + * parities_pos is equal to ((high - nparities) % nstripes) + * (see the diagram above). However, (high - nparities) can + * be negative, e.g. when high == 0, leading to an incorrect + * results. (high + nstripes - nparities) is always positive and + * modulo nstripes is equal to ((high - nparities) % nstripes). + */ + grub_divmod64 (high + nstripes - nparities, nstripes, &parities_pos); + + stripe_offset = chunk_stripe_length * high + low; + csize = chunk_stripe_length - low; + break; } default: @@ -778,51 +1176,68 @@ 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++) { - for (i = 0; i < redundancy; i++) + grub_size_t est_chunk_alloc = 0; + + grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T + "+0x%" PRIxGRUB_UINT64_T + " (%d stripes (%d substripes) of %" + PRIxGRUB_UINT64_T ")\n", + grub_le_to_cpu64 (key->offset), + grub_le_to_cpu64 (chunk->size), + grub_le_to_cpu16 (chunk->nstripes), + grub_le_to_cpu16 (chunk->nsubstripes), + grub_le_to_cpu64 (chunk->stripe_length)); + grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", + addr); + + if (grub_mul (sizeof (struct grub_btrfs_chunk_stripe), + grub_le_to_cpu16 (chunk->nstripes), &est_chunk_alloc) || + grub_add (est_chunk_alloc, + sizeof (struct grub_btrfs_chunk_item), &est_chunk_alloc) || + est_chunk_alloc > chunk->size) { - struct grub_btrfs_chunk_stripe *stripe; - grub_disk_addr_t paddr; - - stripe = (struct grub_btrfs_chunk_stripe *) (chunk + 1); - /* Right now the redundancy handling is easy. - With RAID5-like it will be more difficult. */ - stripe += stripen + i; - - paddr = grub_le_to_cpu64 (stripe->offset) + stripe_offset; - - grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T - " (%d stripes (%d substripes) of %" - PRIxGRUB_UINT64_T ") stripe %" PRIxGRUB_UINT64_T - " maps to 0x%" PRIxGRUB_UINT64_T "\n", - grub_le_to_cpu64 (key->offset), - grub_le_to_cpu64 (chunk->size), - grub_le_to_cpu16 (chunk->nstripes), - grub_le_to_cpu16 (chunk->nsubstripes), - grub_le_to_cpu64 (chunk->stripe_length), - stripen, stripe->offset); - grub_dprintf ("btrfs", "reading paddr 0x%" PRIxGRUB_UINT64_T - " for laddr 0x%" PRIxGRUB_UINT64_T "\n", paddr, - addr); - - dev = find_device (data, stripe->device_id, j); - if (!dev) - { - err = grub_errno; - grub_errno = GRUB_ERR_NONE; - continue; - } - - err = grub_disk_read (dev->disk, paddr >> GRUB_DISK_SECTOR_BITS, - paddr & (GRUB_DISK_SECTOR_SIZE - 1), - csize, buf); - if (!err) - break; - grub_errno = GRUB_ERR_NONE; + err = GRUB_ERR_BAD_FS; + break; } - if (i != redundancy) + + if (grub_le_to_cpu16 (chunk->nstripes) > avail_stripes) + { + err = GRUB_ERR_BAD_FS; + break; + } + + if (is_raid56) + { + err = btrfs_read_from_chunk (data, chunk, stripen, + stripe_offset, + 0, /* no mirror */ + csize, buf); + grub_errno = GRUB_ERR_NONE; + if (err) + err = raid56_read_retry (data, chunk, stripe_offset, + stripen, csize, buf, parities_pos); + } + else + for (i = 0; i < redundancy; i++) + { + err = btrfs_read_from_chunk (data, chunk, stripen, + stripe_offset, + i, /* redundancy */ + csize, buf); + if (!err) + break; + grub_errno = GRUB_ERR_NONE; + } + if (!err) break; } if (err) @@ -861,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); @@ -881,7 +1296,8 @@ grub_btrfs_unmount (struct grub_btrfs_data *data) unsigned i; /* The device 0 is closed one layer upper. */ for (i = 1; i < data->n_devices_attached; i++) - grub_device_close (data->devices_attached[i].dev); + if (data->devices_attached[i].dev) + grub_device_close (data->devices_attached[i].dev); grub_free (data->devices_attached); grub_free (data->extent); grub_free (data); @@ -912,6 +1328,96 @@ grub_btrfs_read_inode (struct grub_btrfs_data *data, return grub_btrfs_read_logical (data, elemaddr, inode, sizeof (*inode), 0); } +static void *grub_zstd_malloc (void *state __attribute__((unused)), size_t size) +{ + return grub_malloc (size); +} + +static void grub_zstd_free (void *state __attribute__((unused)), void *address) +{ + return grub_free (address); +} + +static ZSTD_customMem grub_zstd_allocator (void) +{ + ZSTD_customMem allocator; + + allocator.customAlloc = &grub_zstd_malloc; + allocator.customFree = &grub_zstd_free; + allocator.opaque = NULL; + + return allocator; +} + +static grub_ssize_t +grub_btrfs_zstd_decompress (char *ibuf, grub_size_t isize, grub_off_t off, + char *obuf, grub_size_t osize) +{ + void *allocated = NULL; + char *otmpbuf = obuf; + grub_size_t otmpsize = osize; + ZSTD_DCtx *dctx = NULL; + grub_size_t zstd_ret; + grub_ssize_t ret = -1; + + /* + * Zstd will fail if it can't fit the entire output in the destination + * buffer, so if osize isn't large enough, allocate a temporary buffer. + */ + if (otmpsize < ZSTD_BTRFS_MAX_INPUT) + { + allocated = grub_malloc (ZSTD_BTRFS_MAX_INPUT); + if (!allocated) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed allocate a zstd buffer"); + goto err; + } + otmpbuf = (char *) allocated; + otmpsize = ZSTD_BTRFS_MAX_INPUT; + } + + /* Create the ZSTD_DCtx. */ + dctx = ZSTD_createDCtx_advanced (grub_zstd_allocator ()); + if (!dctx) + { + /* ZSTD_createDCtx_advanced() only fails if it is out of memory. */ + grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to create a zstd context"); + goto err; + } + + /* + * Get the real input size, there may be junk at the + * end of the frame. + */ + isize = ZSTD_findFrameCompressedSize (ibuf, isize); + if (ZSTD_isError (isize)) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted"); + goto err; + } + + /* Decompress and check for errors. */ + zstd_ret = ZSTD_decompressDCtx (dctx, otmpbuf, otmpsize, ibuf, isize); + if (ZSTD_isError (zstd_ret)) + { + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "zstd data corrupted"); + goto err; + } + + /* + * Move the requested data into the obuf. obuf may be equal + * to otmpbuf, which is why grub_memmove() is required. + */ + grub_memmove (obuf, otmpbuf + off, osize); + ret = osize; + +err: + grub_free (allocated); + ZSTD_freeDCtx (dctx); + + return ret; +} + static grub_ssize_t grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off, char *obuf, grub_size_t osize) @@ -1016,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) { @@ -1028,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) { @@ -1067,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; @@ -1087,7 +1628,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, if (data->extent->compression != GRUB_BTRFS_COMPRESSION_NONE && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZLIB - && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO) + && data->extent->compression != GRUB_BTRFS_COMPRESSION_LZO + && data->extent->compression != GRUB_BTRFS_COMPRESSION_ZSTD) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "compression type 0x%x not supported", @@ -1127,6 +1669,15 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, != (grub_ssize_t) csize) return -1; } + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD) + { + if (grub_btrfs_zstd_decompress (data->extent->inl, data->extsize - + ((grub_uint8_t *) data->extent->inl + - (grub_uint8_t *) data->extent), + extoff, buf, csize) + != (grub_ssize_t) csize) + return -1; + } else grub_memcpy (buf, data->extent->inl + extoff, csize); break; @@ -1164,6 +1715,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, ret = grub_btrfs_lzo_decompress (tmp, zsize, extoff + grub_le_to_cpu64 (data->extent->offset), buf, csize); + else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_ZSTD) + ret = grub_btrfs_zstd_decompress (tmp, zsize, extoff + + grub_le_to_cpu64 (data->extent->offset), + buf, csize); else ret = -1; @@ -1249,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) @@ -1339,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); @@ -1403,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); @@ -1432,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; } @@ -1520,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; @@ -1541,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 @@ -1561,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; @@ -1578,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; @@ -1588,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)); @@ -1718,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, @@ -1725,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; } @@ -1751,14 +2424,14 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), static struct grub_fs grub_btrfs_fs = { .name = "btrfs", - .dir = grub_btrfs_dir, - .open = grub_btrfs_open, - .read = grub_btrfs_read, - .close = grub_btrfs_close, - .uuid = grub_btrfs_uuid, - .label = grub_btrfs_label, + .fs_dir = grub_btrfs_dir, + .fs_open = grub_btrfs_open, + .fs_read = grub_btrfs_read, + .fs_close = grub_btrfs_close, + .fs_uuid = grub_btrfs_uuid, + .fs_label = grub_btrfs_label, #ifdef GRUB_UTIL - .embed = grub_btrfs_embed, + .fs_embed = grub_btrfs_embed, .reserved_first_sector = 1, .blocklist_install = 0, #endif @@ -1766,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 0842701a6..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; @@ -328,11 +329,11 @@ static struct grub_disk_dev grub_cbfsdisk_dev = { .name = "cbfsdisk", .id = GRUB_DISK_DEVICE_CBFSDISK_ID, - .iterate = grub_cbfsdisk_iterate, - .open = grub_cbfsdisk_open, - .close = grub_cbfsdisk_close, - .read = grub_cbfsdisk_read, - .write = grub_cbfsdisk_write, + .disk_iterate = grub_cbfsdisk_iterate, + .disk_open = grub_cbfsdisk_open, + .disk_close = grub_cbfsdisk_close, + .disk_read = grub_cbfsdisk_read, + .disk_write = grub_cbfsdisk_write, .next = 0 }; @@ -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); @@ -375,10 +376,10 @@ fini_cbfsdisk (void) static struct grub_fs grub_cbfs_fs = { .name = "cbfs", - .dir = grub_cbfs_dir, - .open = grub_cbfs_open, - .read = grub_cbfs_read, - .close = grub_cbfs_close, + .fs_dir = grub_cbfs_dir, + .fs_open = grub_cbfs_open, + .fs_read = grub_cbfs_read, + .fs_close = grub_cbfs_close, #ifdef GRUB_UTIL .reserved_first_sector = 0, .blocklist_install = 0, @@ -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 50fea47d1..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+"); @@ -36,6 +37,11 @@ struct grub_archelp_data grub_off_t size; }; +#if __GNUC__ >= 9 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Waddress-of-packed-member" +#endif + static grub_err_t grub_cpio_find_file (struct grub_archelp_data *data, char **name, grub_int32_t *mtime, grub_uint32_t *mode) @@ -43,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; @@ -55,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) @@ -71,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; @@ -96,19 +116,30 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, return GRUB_ERR_NONE; } +#if __GNUC__ >= 9 +#pragma GCC diagnostic pop +#endif + static char * grub_cpio_get_link_target (struct grub_archelp_data *data) { char *ret; grub_err_t err; + grub_size_t sz; if (data->size == 0) return grub_strdup (""); - 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) { @@ -233,10 +264,10 @@ grub_cpio_close (grub_file_t file) static struct grub_fs grub_cpio_fs = { .name = FSNAME, - .dir = grub_cpio_dir, - .open = grub_cpio_open, - .read = grub_cpio_read, - .close = grub_cpio_close, + .fs_dir = grub_cpio_dir, + .fs_open = grub_cpio_open, + .fs_read = grub_cpio_read, + .fs_close = grub_cpio_close, #ifdef GRUB_UTIL .reserved_first_sector = 0, .blocklist_install = 0, 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 cdce63bcc..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,9 @@ 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) * flags here as the related features are implemented into the driver. */ @@ -109,7 +113,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); | EXT4_FEATURE_INCOMPAT_EXTENTS \ | EXT4_FEATURE_INCOMPAT_FLEX_BG \ | EXT2_FEATURE_INCOMPAT_META_BG \ - | EXT4_FEATURE_INCOMPAT_64BIT) + | EXT4_FEATURE_INCOMPAT_64BIT \ + | EXT4_FEATURE_INCOMPAT_ENCRYPT) /* List of rationales for the ignored "incompatible" features: * needs_recovery: Not really back-incompatible - was added as such to forbid * ext2 drivers from mounting an ext3 volume with a dirty @@ -120,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 @@ -138,6 +155,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define EXT3_JOURNAL_FLAG_DELETED 4 #define EXT3_JOURNAL_FLAG_LAST_TAG 8 +#define EXT4_ENCRYPT_FLAG 0x800 #define EXT4_EXTENTS_FLAG 0x80000 /* The ext2 superblock. */ @@ -403,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) { @@ -422,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++) { @@ -431,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); @@ -448,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 @@ -469,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; @@ -700,22 +751,36 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) { char *symlink; struct grub_fshelp_node *diro = node; + grub_size_t sz; if (! diro->inode_read) { grub_ext2_read_inode (diro->data, diro->ino, &diro->inode); if (grub_errno) return 0; + + if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "symlink is encrypted"); + return 0; + } } - 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)); @@ -749,6 +814,12 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, return 0; } + if (diro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "directory is encrypted"); + return 0; + } + /* Search the file. */ while (fpos < grub_le_to_cpu32 (diro->inode.size)) { @@ -859,6 +930,12 @@ grub_ext2_open (struct grub_file *file, const char *name) goto fail; } + if (fdiro->inode.flags & grub_cpu_to_le32_compile_time (EXT4_ENCRYPT_FLAG)) + { + err = grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "file is encrypted"); + goto fail; + } + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode)); grub_free (fdiro); @@ -1025,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; @@ -1051,13 +1128,13 @@ grub_ext2_mtime (grub_device_t device, grub_int32_t *tm) static struct grub_fs grub_ext2_fs = { .name = "ext2", - .dir = grub_ext2_dir, - .open = grub_ext2_open, - .read = grub_ext2_read, - .close = grub_ext2_close, - .label = grub_ext2_label, - .uuid = grub_ext2_uuid, - .mtime = grub_ext2_mtime, + .fs_dir = grub_ext2_dir, + .fs_open = grub_ext2_open, + .fs_read = grub_ext2_read, + .fs_close = grub_ext2_close, + .fs_label = grub_ext2_label, + .fs_uuid = grub_ext2_uuid, + .fs_mtime = grub_ext2_mtime, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -1067,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 new file mode 100644 index 000000000..72b4aa1e6 --- /dev/null +++ b/grub-core/fs/f2fs.c @@ -0,0 +1,1377 @@ +/* + * f2fs.c - Flash-Friendly File System + * + * Written by Jaegeuk Kim + * + * Copyright (C) 2015 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* F2FS Magic Number. */ +#define F2FS_SUPER_MAGIC 0xf2f52010 + +#define CHECKSUM_OFFSET 4092 /* Must be aligned 4 bytes. */ +#define U32_CHECKSUM_OFFSET (CHECKSUM_OFFSET >> 2) +#define CRCPOLY_LE 0xedb88320 + +/* Byte-size offset. */ +#define F2FS_SUPER_OFFSET ((grub_disk_addr_t)1024) +#define F2FS_SUPER_OFFSET0 (F2FS_SUPER_OFFSET >> GRUB_DISK_SECTOR_BITS) +#define F2FS_SUPER_OFFSET1 ((F2FS_SUPER_OFFSET + F2FS_BLKSIZE) >> \ + GRUB_DISK_SECTOR_BITS) + +/* 9 bits for 512 bytes. */ +#define F2FS_MIN_LOG_SECTOR_SIZE 9 + +/* Support only 4KB block. */ +#define F2FS_BLK_BITS 12 +#define F2FS_BLKSIZE (1 << F2FS_BLK_BITS) +#define F2FS_BLK_SEC_BITS (F2FS_BLK_BITS - GRUB_DISK_SECTOR_BITS) + +#define VERSION_LEN 256 +#define F2FS_MAX_EXTENSION 64 + +#define CP_COMPACT_SUM_FLAG 0x00000004 +#define CP_UMOUNT_FLAG 0x00000001 + +#define MAX_ACTIVE_LOGS 16 +#define MAX_ACTIVE_NODE_LOGS 8 +#define MAX_ACTIVE_DATA_LOGS 8 +#define NR_CURSEG_DATA_TYPE 3 +#define NR_CURSEG_NODE_TYPE 3 +#define NR_CURSEG_TYPE (NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE) + +#define ENTRIES_IN_SUM 512 +#define SUMMARY_SIZE 7 +#define SUM_FOOTER_SIZE 5 +#define JENTRY_SIZE (sizeof(struct grub_f2fs_nat_jent)) +#define SUM_ENTRIES_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM) +#define SUM_JOURNAL_SIZE (F2FS_BLKSIZE - SUM_FOOTER_SIZE - SUM_ENTRIES_SIZE) +#define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) / JENTRY_SIZE) +#define NAT_JOURNAL_RESERVED ((SUM_JOURNAL_SIZE - 2) % JENTRY_SIZE) + +#define NAT_ENTRY_SIZE (sizeof(struct grub_f2fs_nat_entry)) +#define NAT_ENTRY_PER_BLOCK (F2FS_BLKSIZE / NAT_ENTRY_SIZE) + +#define F2FS_NAME_LEN 255 +#define F2FS_SLOT_LEN 8 +#define NR_DENTRY_IN_BLOCK 214 +#define SIZE_OF_DIR_ENTRY 11 /* By byte. */ +#define BITS_PER_BYTE 8 +#define SIZE_OF_DENTRY_BITMAP ((NR_DENTRY_IN_BLOCK + BITS_PER_BYTE - 1) / \ + BITS_PER_BYTE) +#define SIZE_OF_RESERVED (F2FS_BLKSIZE - \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + NR_DENTRY_IN_BLOCK + SIZE_OF_DENTRY_BITMAP)) + +#define F2FS_INLINE_XATTR_ADDRS 50 /* 200 bytes for inline xattrs. */ +#define DEF_ADDRS_PER_INODE 923 /* Address Pointers in an Inode. */ + +#define ADDRS_PER_BLOCK 1018 /* Address Pointers in a Direct Block. */ +#define NIDS_PER_BLOCK 1018 /* Node IDs in an Indirect Block. */ +#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1) +#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2) +#define NODE_IND1_BLOCK (DEF_ADDRS_PER_INODE + 3) +#define NODE_IND2_BLOCK (DEF_ADDRS_PER_INODE + 4) +#define NODE_DIND_BLOCK (DEF_ADDRS_PER_INODE + 5) + +#define MAX_INLINE_DATA (4 * (DEF_ADDRS_PER_INODE - \ + F2FS_INLINE_XATTR_ADDRS - 1)) +#define NR_INLINE_DENTRY (MAX_INLINE_DATA * BITS_PER_BYTE / \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + BITS_PER_BYTE + 1)) +#define INLINE_DENTRY_BITMAP_SIZE ((NR_INLINE_DENTRY + BITS_PER_BYTE - 1) / \ + BITS_PER_BYTE) +#define INLINE_RESERVED_SIZE (MAX_INLINE_DATA - \ + ((SIZE_OF_DIR_ENTRY + F2FS_SLOT_LEN) * \ + NR_INLINE_DENTRY + \ + INLINE_DENTRY_BITMAP_SIZE)) +#define CURSEG_HOT_DATA 0 + +#define CKPT_FLAG_SET(ckpt, f) (ckpt)->ckpt_flags & \ + grub_cpu_to_le32_compile_time (f) + +#define F2FS_INLINE_XATTR 0x01 /* File inline xattr flag. */ +#define F2FS_INLINE_DATA 0x02 /* File inline data flag. */ +#define F2FS_INLINE_DENTRY 0x04 /* File inline dentry flag. */ +#define F2FS_DATA_EXIST 0x08 /* File inline data exist flag. */ +#define F2FS_INLINE_DOTS 0x10 /* File having implicit dot dentries. */ + +#define MAX_VOLUME_NAME 512 +#define MAX_NAT_BITMAP_SIZE 3900 + +enum FILE_TYPE +{ + F2FS_FT_UNKNOWN, + F2FS_FT_REG_FILE = 1, + F2FS_FT_DIR = 2, + F2FS_FT_SYMLINK = 7 +}; + +struct grub_f2fs_superblock +{ + grub_uint32_t magic; + grub_uint16_t dummy1[2]; + grub_uint32_t log_sectorsize; + grub_uint32_t log_sectors_per_block; + grub_uint32_t log_blocksize; + grub_uint32_t log_blocks_per_seg; + grub_uint32_t segs_per_sec; + grub_uint32_t secs_per_zone; + grub_uint32_t checksum_offset; + grub_uint8_t dummy2[40]; + grub_uint32_t cp_blkaddr; + grub_uint32_t sit_blkaddr; + grub_uint32_t nat_blkaddr; + grub_uint32_t ssa_blkaddr; + grub_uint32_t main_blkaddr; + grub_uint32_t root_ino; + grub_uint32_t node_ino; + grub_uint32_t meta_ino; + grub_uint8_t uuid[16]; + grub_uint16_t volume_name[MAX_VOLUME_NAME]; + grub_uint32_t extension_count; + grub_uint8_t extension_list[F2FS_MAX_EXTENSION][8]; + grub_uint32_t cp_payload; + grub_uint8_t version[VERSION_LEN]; + grub_uint8_t init_version[VERSION_LEN]; +} GRUB_PACKED; + +struct grub_f2fs_checkpoint +{ + grub_uint64_t checkpoint_ver; + grub_uint64_t user_block_count; + grub_uint64_t valid_block_count; + grub_uint32_t rsvd_segment_count; + grub_uint32_t overprov_segment_count; + grub_uint32_t free_segment_count; + grub_uint32_t cur_node_segno[MAX_ACTIVE_NODE_LOGS]; + grub_uint16_t cur_node_blkoff[MAX_ACTIVE_NODE_LOGS]; + grub_uint32_t cur_data_segno[MAX_ACTIVE_DATA_LOGS]; + grub_uint16_t cur_data_blkoff[MAX_ACTIVE_DATA_LOGS]; + grub_uint32_t ckpt_flags; + grub_uint32_t cp_pack_total_block_count; + grub_uint32_t cp_pack_start_sum; + grub_uint32_t valid_node_count; + grub_uint32_t valid_inode_count; + grub_uint32_t next_free_nid; + grub_uint32_t sit_ver_bitmap_bytesize; + grub_uint32_t nat_ver_bitmap_bytesize; + grub_uint32_t checksum_offset; + grub_uint64_t elapsed_time; + grub_uint8_t alloc_type[MAX_ACTIVE_LOGS]; + grub_uint8_t sit_nat_version_bitmap[MAX_NAT_BITMAP_SIZE]; + grub_uint32_t checksum; +} GRUB_PACKED; + +struct grub_f2fs_nat_entry { + grub_uint8_t version; + grub_uint32_t ino; + grub_uint32_t block_addr; +} GRUB_PACKED; + +struct grub_f2fs_nat_jent +{ + grub_uint32_t nid; + struct grub_f2fs_nat_entry ne; +} GRUB_PACKED; + +struct grub_f2fs_nat_journal { + grub_uint16_t n_nats; + struct grub_f2fs_nat_jent entries[NAT_JOURNAL_ENTRIES]; + grub_uint8_t reserved[NAT_JOURNAL_RESERVED]; +} GRUB_PACKED; + +struct grub_f2fs_nat_block { + struct grub_f2fs_nat_entry ne[NAT_ENTRY_PER_BLOCK]; +} GRUB_PACKED; + +struct grub_f2fs_dir_entry +{ + grub_uint32_t hash_code; + grub_uint32_t ino; + grub_uint16_t name_len; + grub_uint8_t file_type; +} GRUB_PACKED; + +struct grub_f2fs_inline_dentry +{ + grub_uint8_t dentry_bitmap[INLINE_DENTRY_BITMAP_SIZE]; + grub_uint8_t reserved[INLINE_RESERVED_SIZE]; + struct grub_f2fs_dir_entry dentry[NR_INLINE_DENTRY]; + grub_uint8_t filename[NR_INLINE_DENTRY][F2FS_SLOT_LEN]; +} GRUB_PACKED; + +struct grub_f2fs_dentry_block { + grub_uint8_t dentry_bitmap[SIZE_OF_DENTRY_BITMAP]; + grub_uint8_t reserved[SIZE_OF_RESERVED]; + struct grub_f2fs_dir_entry dentry[NR_DENTRY_IN_BLOCK]; + grub_uint8_t filename[NR_DENTRY_IN_BLOCK][F2FS_SLOT_LEN]; +} GRUB_PACKED; + +struct grub_f2fs_inode +{ + grub_uint16_t i_mode; + grub_uint8_t i_advise; + grub_uint8_t i_inline; + grub_uint32_t i_uid; + grub_uint32_t i_gid; + grub_uint32_t i_links; + grub_uint64_t i_size; + grub_uint64_t i_blocks; + grub_uint64_t i_atime; + grub_uint64_t i_ctime; + grub_uint64_t i_mtime; + grub_uint32_t i_atime_nsec; + grub_uint32_t i_ctime_nsec; + grub_uint32_t i_mtime_nsec; + grub_uint32_t i_generation; + grub_uint32_t i_current_depth; + grub_uint32_t i_xattr_nid; + grub_uint32_t i_flags; + grub_uint32_t i_pino; + grub_uint32_t i_namelen; + grub_uint8_t i_name[F2FS_NAME_LEN]; + grub_uint8_t i_dir_level; + grub_uint8_t i_ext[12]; + grub_uint32_t i_addr[DEF_ADDRS_PER_INODE]; + grub_uint32_t i_nid[5]; +} GRUB_PACKED; + +struct grub_direct_node { + grub_uint32_t addr[ADDRS_PER_BLOCK]; +} GRUB_PACKED; + +struct grub_indirect_node { + grub_uint32_t nid[NIDS_PER_BLOCK]; +} GRUB_PACKED; + +struct grub_f2fs_node +{ + union + { + struct grub_f2fs_inode i; + struct grub_direct_node dn; + struct grub_indirect_node in; + /* Should occupy F2FS_BLKSIZE totally. */ + char buf[F2FS_BLKSIZE - 40]; + }; + grub_uint8_t dummy[40]; +} GRUB_PACKED; + +struct grub_fshelp_node +{ + struct grub_f2fs_data *data; + struct grub_f2fs_node inode; + grub_uint32_t ino; + int inode_read; +}; + +struct grub_f2fs_data +{ + struct grub_f2fs_superblock sblock; + struct grub_f2fs_checkpoint ckpt; + + grub_uint32_t root_ino; + grub_uint32_t blocks_per_seg; + grub_uint32_t cp_blkaddr; + grub_uint32_t nat_blkaddr; + + struct grub_f2fs_nat_journal nat_j; + char *nat_bitmap; + grub_uint32_t nat_bitmap_size; + + grub_disk_t disk; + struct grub_f2fs_node *inode; + struct grub_fshelp_node diropen; +}; + +struct grub_f2fs_dir_iter_ctx +{ + struct grub_f2fs_data *data; + grub_fshelp_iterate_dir_hook_t hook; + void *hook_data; + grub_uint8_t *bitmap; + grub_uint8_t (*filename)[F2FS_SLOT_LEN]; + struct grub_f2fs_dir_entry *dentry; + int max; +}; + +struct grub_f2fs_dir_ctx +{ + grub_fs_dir_hook_t hook; + void *hook_data; + struct grub_f2fs_data *data; +}; + +static grub_dl_t my_mod; + +static int +grub_f2fs_test_bit_le (int nr, const grub_uint8_t *addr) +{ + return addr[nr >> 3] & (1 << (nr & 7)); +} + +static char * +get_inline_addr (struct grub_f2fs_inode *inode) +{ + return (char *) &inode->i_addr[1]; +} + +static grub_uint64_t +grub_f2fs_file_size (struct grub_f2fs_inode *inode) +{ + return grub_le_to_cpu64 (inode->i_size); +} + +static grub_uint32_t +start_cp_addr (struct grub_f2fs_data *data) +{ + struct grub_f2fs_checkpoint *ckpt = &data->ckpt; + grub_uint32_t start_addr = data->cp_blkaddr; + + if (!(ckpt->checkpoint_ver & grub_cpu_to_le64_compile_time(1))) + return start_addr + data->blocks_per_seg; + + return start_addr; +} + +static grub_uint32_t +start_sum_block (struct grub_f2fs_data *data) +{ + struct grub_f2fs_checkpoint *ckpt = &data->ckpt; + + return start_cp_addr (data) + grub_le_to_cpu32 (ckpt->cp_pack_start_sum); +} + +static grub_uint32_t +sum_blk_addr (struct grub_f2fs_data *data, int base, int type) +{ + struct grub_f2fs_checkpoint *ckpt = &data->ckpt; + + return start_cp_addr (data) + + grub_le_to_cpu32 (ckpt->cp_pack_total_block_count) - + (base + 1) + type; +} + +static void * +nat_bitmap_ptr (struct grub_f2fs_data *data, grub_uint32_t *nat_bitmap_size) +{ + struct grub_f2fs_checkpoint *ckpt = &data->ckpt; + grub_uint32_t offset; + *nat_bitmap_size = MAX_NAT_BITMAP_SIZE; + + if (grub_le_to_cpu32 (data->sblock.cp_payload) > 0) + return ckpt->sit_nat_version_bitmap; + + offset = grub_le_to_cpu32 (ckpt->sit_ver_bitmap_bytesize); + if (offset >= MAX_NAT_BITMAP_SIZE) + return NULL; + + *nat_bitmap_size = *nat_bitmap_size - offset; + + return ckpt->sit_nat_version_bitmap + offset; +} + +static grub_uint32_t +get_node_id (struct grub_f2fs_node *rn, int off, int inode_block) +{ + if (inode_block) + return grub_le_to_cpu32 (rn->i.i_nid[off - NODE_DIR1_BLOCK]); + + return grub_le_to_cpu32 (rn->in.nid[off]); +} + +static grub_err_t +grub_f2fs_block_read (struct grub_f2fs_data *data, grub_uint32_t blkaddr, + void *buf) +{ + return grub_disk_read (data->disk, + ((grub_disk_addr_t)blkaddr) << F2FS_BLK_SEC_BITS, + 0, F2FS_BLKSIZE, buf); +} + +/* CRC32 */ +static grub_uint32_t +grub_f2fs_cal_crc32 (const void *buf, const grub_uint32_t len) +{ + grub_uint32_t crc = F2FS_SUPER_MAGIC; + unsigned char *p = (unsigned char *)buf; + grub_uint32_t tmp = len; + int i; + + while (tmp--) + { + crc ^= *p++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); + } + + return crc; +} + +static int +grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32_t len) +{ + grub_uint32_t cal_crc = 0; + + cal_crc = grub_f2fs_cal_crc32 (buf, len); + + return (cal_crc == blk_crc) ? 1 : 0; +} + +static int +grub_f2fs_test_bit (grub_uint32_t nr, const char *p, grub_uint32_t len) +{ + int mask; + grub_uint32_t shifted_nr = (nr >> 3); + + if (shifted_nr >= len) + return -1; + + p += shifted_nr; + mask = 1 << (7 - (nr & 0x07)); + + return mask & *p; +} + +static int +grub_f2fs_sanity_check_sb (struct grub_f2fs_superblock *sb) +{ + grub_uint32_t log_sectorsize, log_sectors_per_block; + + if (sb->magic != grub_cpu_to_le32_compile_time (F2FS_SUPER_MAGIC)) + return -1; + + if (sb->log_blocksize != grub_cpu_to_le32_compile_time (F2FS_BLK_BITS)) + return -1; + + log_sectorsize = grub_le_to_cpu32 (sb->log_sectorsize); + log_sectors_per_block = grub_le_to_cpu32 (sb->log_sectors_per_block); + + if (log_sectorsize > F2FS_BLK_BITS) + return -1; + + if (log_sectorsize < F2FS_MIN_LOG_SECTOR_SIZE) + return -1; + + if (log_sectors_per_block + log_sectorsize != F2FS_BLK_BITS) + return -1; + + return 0; +} + +static int +grub_f2fs_read_sb (struct grub_f2fs_data *data, grub_disk_addr_t offset) +{ + grub_disk_t disk = data->disk; + grub_err_t err; + + /* Read first super block. */ + err = grub_disk_read (disk, offset, 0, sizeof (data->sblock), &data->sblock); + if (err) + return -1; + + return grub_f2fs_sanity_check_sb (&data->sblock); +} + +static void * +validate_checkpoint (struct grub_f2fs_data *data, grub_uint32_t cp_addr, + grub_uint64_t *version) +{ + grub_uint32_t *cp_page_1, *cp_page_2; + struct grub_f2fs_checkpoint *cp_block; + grub_uint64_t cur_version = 0, pre_version = 0; + grub_uint32_t crc = 0; + grub_uint32_t crc_offset; + grub_err_t err; + + /* Read the 1st cp block in this CP pack. */ + cp_page_1 = grub_malloc (F2FS_BLKSIZE); + if (!cp_page_1) + return NULL; + + err = grub_f2fs_block_read (data, cp_addr, cp_page_1); + if (err) + goto invalid_cp1; + + cp_block = (struct grub_f2fs_checkpoint *)cp_page_1; + crc_offset = grub_le_to_cpu32 (cp_block->checksum_offset); + if (crc_offset != CHECKSUM_OFFSET) + goto invalid_cp1; + + crc = grub_le_to_cpu32 (*(cp_page_1 + U32_CHECKSUM_OFFSET)); + if (!grub_f2fs_crc_valid (crc, cp_block, crc_offset)) + goto invalid_cp1; + + pre_version = grub_le_to_cpu64 (cp_block->checkpoint_ver); + + /* Read the 2nd cp block in this CP pack. */ + cp_page_2 = grub_malloc (F2FS_BLKSIZE); + if (!cp_page_2) + goto invalid_cp1; + + cp_addr += grub_le_to_cpu32 (cp_block->cp_pack_total_block_count) - 1; + + err = grub_f2fs_block_read (data, cp_addr, cp_page_2); + if (err) + goto invalid_cp2; + + cp_block = (struct grub_f2fs_checkpoint *)cp_page_2; + crc_offset = grub_le_to_cpu32 (cp_block->checksum_offset); + if (crc_offset != CHECKSUM_OFFSET) + goto invalid_cp2; + + crc = grub_le_to_cpu32 (*(cp_page_2 + U32_CHECKSUM_OFFSET)); + if (!grub_f2fs_crc_valid (crc, cp_block, crc_offset)) + goto invalid_cp2; + + cur_version = grub_le_to_cpu64 (cp_block->checkpoint_ver); + if (cur_version == pre_version) + { + *version = cur_version; + grub_free (cp_page_2); + + return cp_page_1; + } + + invalid_cp2: + grub_free (cp_page_2); + + invalid_cp1: + grub_free (cp_page_1); + + return NULL; +} + +static grub_err_t +grub_f2fs_read_cp (struct grub_f2fs_data *data) +{ + void *cp1, *cp2, *cur_page; + grub_uint64_t cp1_version = 0, cp2_version = 0; + grub_uint64_t cp_start_blk_no; + + /* + * Finding out valid cp block involves read both + * sets (cp pack1 and cp pack 2). + */ + cp_start_blk_no = data->cp_blkaddr; + cp1 = validate_checkpoint (data, cp_start_blk_no, &cp1_version); + if (!cp1 && grub_errno) + return grub_errno; + + /* The second checkpoint pack should start at the next segment. */ + cp_start_blk_no += data->blocks_per_seg; + cp2 = validate_checkpoint (data, cp_start_blk_no, &cp2_version); + if (!cp2 && grub_errno) + { + grub_free (cp1); + return grub_errno; + } + + if (cp1 && cp2) + cur_page = (cp2_version > cp1_version) ? cp2 : cp1; + else if (cp1) + cur_page = cp1; + else if (cp2) + cur_page = cp2; + else + return grub_error (GRUB_ERR_BAD_FS, "no checkpoints"); + + grub_memcpy (&data->ckpt, cur_page, F2FS_BLKSIZE); + + grub_free (cp1); + grub_free (cp2); + + return 0; +} + +static grub_err_t +get_nat_journal (struct grub_f2fs_data *data) +{ + grub_uint32_t block; + char *buf; + grub_err_t err; + + buf = grub_malloc (F2FS_BLKSIZE); + if (!buf) + return grub_errno; + + if (CKPT_FLAG_SET(&data->ckpt, CP_COMPACT_SUM_FLAG)) + block = start_sum_block (data); + else if (CKPT_FLAG_SET (&data->ckpt, CP_UMOUNT_FLAG)) + block = sum_blk_addr (data, NR_CURSEG_TYPE, CURSEG_HOT_DATA); + else + block = sum_blk_addr (data, NR_CURSEG_DATA_TYPE, CURSEG_HOT_DATA); + + err = grub_f2fs_block_read (data, block, buf); + if (err) + goto fail; + + if (CKPT_FLAG_SET (&data->ckpt, CP_COMPACT_SUM_FLAG)) + grub_memcpy (&data->nat_j, buf, SUM_JOURNAL_SIZE); + else + grub_memcpy (&data->nat_j, buf + SUM_ENTRIES_SIZE, SUM_JOURNAL_SIZE); + + fail: + grub_free (buf); + + return err; +} + +static grub_err_t +get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid, + grub_uint32_t *blkaddr) +{ + grub_uint16_t n = grub_le_to_cpu16 (data->nat_j.n_nats); + grub_uint16_t i; + + if (n > NAT_JOURNAL_ENTRIES) + return grub_error (GRUB_ERR_BAD_FS, + "invalid number of nat journal entries"); + + for (i = 0; i < n; i++) + { + if (grub_le_to_cpu32 (data->nat_j.entries[i].nid) == nid) + { + *blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr); + break; + } + } + + return GRUB_ERR_NONE; +} + +static grub_uint32_t +get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid) +{ + struct grub_f2fs_nat_block *nat_block; + grub_uint32_t seg_off, block_off, entry_off, block_addr; + grub_uint32_t blkaddr = 0; + grub_err_t err; + int result_bit; + + err = get_blkaddr_from_nat_journal (data, nid, &blkaddr); + if (err != GRUB_ERR_NONE) + return 0; + + if (blkaddr) + return blkaddr; + + nat_block = grub_malloc (F2FS_BLKSIZE); + if (!nat_block) + return 0; + + block_off = nid / NAT_ENTRY_PER_BLOCK; + entry_off = nid % NAT_ENTRY_PER_BLOCK; + + seg_off = block_off / data->blocks_per_seg; + block_addr = data->nat_blkaddr + + ((seg_off * data->blocks_per_seg) << 1) + + (block_off & (data->blocks_per_seg - 1)); + + result_bit = grub_f2fs_test_bit (block_off, data->nat_bitmap, + data->nat_bitmap_size); + if (result_bit > 0) + block_addr += data->blocks_per_seg; + else if (result_bit == -1) + { + grub_free (nat_block); + return 0; + } + + err = grub_f2fs_block_read (data, block_addr, nat_block); + if (err) + { + grub_free (nat_block); + return 0; + } + + blkaddr = grub_le_to_cpu32 (nat_block->ne[entry_off].block_addr); + + grub_free (nat_block); + + return blkaddr; +} + +static int +grub_get_node_path (struct grub_f2fs_inode *inode, grub_uint32_t block, + grub_uint32_t offset[4], grub_uint32_t noffset[4]) +{ + grub_uint32_t direct_blks = ADDRS_PER_BLOCK; + grub_uint32_t dptrs_per_blk = NIDS_PER_BLOCK; + grub_uint32_t indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK; + grub_uint32_t dindirect_blks = indirect_blks * NIDS_PER_BLOCK; + grub_uint32_t direct_index = DEF_ADDRS_PER_INODE; + int n = 0; + int level = -1; + + if (inode->i_inline & F2FS_INLINE_XATTR) + direct_index -= F2FS_INLINE_XATTR_ADDRS; + + noffset[0] = 0; + + if (block < direct_index) + { + offset[n] = block; + level = 0; + goto got; + } + + block -= direct_index; + if (block < direct_blks) + { + offset[n++] = NODE_DIR1_BLOCK; + noffset[n] = 1; + offset[n] = block; + level = 1; + goto got; + } + + block -= direct_blks; + if (block < direct_blks) + { + offset[n++] = NODE_DIR2_BLOCK; + noffset[n] = 2; + offset[n] = block; + level = 1; + goto got; + } + + block -= direct_blks; + if (block < indirect_blks) + { + offset[n++] = NODE_IND1_BLOCK; + noffset[n] = 3; + offset[n++] = block / direct_blks; + noffset[n] = 4 + offset[n - 1]; + offset[n] = block % direct_blks; + level = 2; + goto got; + } + + block -= indirect_blks; + if (block < indirect_blks) + { + offset[n++] = NODE_IND2_BLOCK; + noffset[n] = 4 + dptrs_per_blk; + offset[n++] = block / direct_blks; + noffset[n] = 5 + dptrs_per_blk + offset[n - 1]; + offset[n] = block % direct_blks; + level = 2; + goto got; + } + + block -= indirect_blks; + if (block < dindirect_blks) + { + offset[n++] = NODE_DIND_BLOCK; + noffset[n] = 5 + (dptrs_per_blk * 2); + offset[n++] = block / indirect_blks; + noffset[n] = 6 + (dptrs_per_blk * 2) + + offset[n - 1] * (dptrs_per_blk + 1); + offset[n++] = (block / direct_blks) % dptrs_per_blk; + noffset[n] = 7 + (dptrs_per_blk * 2) + + offset[n - 2] * (dptrs_per_blk + 1) + offset[n - 1]; + offset[n] = block % direct_blks; + level = 3; + goto got; + } + + got: + return level; +} + +static grub_err_t +grub_f2fs_read_node (struct grub_f2fs_data *data, + grub_uint32_t nid, struct grub_f2fs_node *np) +{ + grub_uint32_t blkaddr; + + blkaddr = get_node_blkaddr (data, nid); + if (!blkaddr) + return grub_errno; + + return grub_f2fs_block_read (data, blkaddr, np); +} + +static struct grub_f2fs_data * +grub_f2fs_mount (grub_disk_t disk) +{ + struct grub_f2fs_data *data; + grub_err_t err; + + data = grub_malloc (sizeof (*data)); + if (!data) + return NULL; + + data->disk = disk; + + if (grub_f2fs_read_sb (data, F2FS_SUPER_OFFSET0)) + { + if (grub_f2fs_read_sb (data, F2FS_SUPER_OFFSET1)) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, + "not a F2FS filesystem (no superblock)"); + goto fail; + } + } + + data->root_ino = grub_le_to_cpu32 (data->sblock.root_ino); + data->cp_blkaddr = grub_le_to_cpu32 (data->sblock.cp_blkaddr); + data->nat_blkaddr = grub_le_to_cpu32 (data->sblock.nat_blkaddr); + data->blocks_per_seg = 1 << + grub_le_to_cpu32 (data->sblock.log_blocks_per_seg); + + err = grub_f2fs_read_cp (data); + if (err) + goto fail; + + data->nat_bitmap = nat_bitmap_ptr (data, &data->nat_bitmap_size); + if (data->nat_bitmap == NULL) + goto fail; + + err = get_nat_journal (data); + if (err) + goto fail; + + data->diropen.data = data; + data->diropen.ino = data->root_ino; + data->diropen.inode_read = 1; + data->inode = &data->diropen.inode; + + err = grub_f2fs_read_node (data, data->root_ino, data->inode); + if (err) + goto fail; + + return data; + + fail: + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, "not a F2FS filesystem"); + + grub_free (data); + + return NULL; +} + +/* Guarantee inline_data was handled by caller. */ +static grub_disk_addr_t +grub_f2fs_get_block (grub_fshelp_node_t node, grub_disk_addr_t block_ofs) +{ + struct grub_f2fs_data *data = node->data; + struct grub_f2fs_inode *inode = &node->inode.i; + grub_uint32_t offset[4], noffset[4], nids[4]; + struct grub_f2fs_node *node_block; + grub_uint32_t block_addr = -1; + int level, i; + + level = grub_get_node_path (inode, block_ofs, offset, noffset); + + if (level < 0) + return -1; + + if (level == 0) + return grub_le_to_cpu32 (inode->i_addr[offset[0]]); + + node_block = grub_malloc (F2FS_BLKSIZE); + if (!node_block) + return -1; + + nids[1] = get_node_id (&node->inode, offset[0], 1); + + /* Get indirect or direct nodes. */ + for (i = 1; i <= level; i++) + { + grub_f2fs_read_node (data, nids[i], node_block); + if (grub_errno) + goto fail; + + if (i < level) + nids[i + 1] = get_node_id (node_block, offset[i], 0); + } + + block_addr = grub_le_to_cpu32 (node_block->dn.addr[offset[level]]); + + fail: + grub_free (node_block); + + return block_addr; +} + +static grub_ssize_t +grub_f2fs_read_file (grub_fshelp_node_t node, + grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) +{ + struct grub_f2fs_inode *inode = &node->inode.i; + grub_off_t filesize = grub_f2fs_file_size (inode); + char *inline_addr = get_inline_addr (inode); + + if (inode->i_inline & F2FS_INLINE_DATA) + { + if (filesize > MAX_INLINE_DATA) + return -1; + + if (len > filesize - pos) + len = filesize - pos; + + grub_memcpy (buf, inline_addr + pos, len); + return len; + } + + return grub_fshelp_read_file (node->data->disk, node, + read_hook, read_hook_data, + pos, len, buf, grub_f2fs_get_block, + filesize, + F2FS_BLK_SEC_BITS, 0); +} + +static char * +grub_f2fs_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + struct grub_fshelp_node *diro = node; + grub_uint64_t filesize; + grub_size_t sz; + + if (!diro->inode_read) + { + grub_f2fs_read_node (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + filesize = grub_f2fs_file_size(&diro->inode.i); + + if (grub_add (filesize, 1, &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow")); + return 0; + } + symlink = grub_malloc (sz); + if (!symlink) + return 0; + + grub_f2fs_read_file (diro, 0, 0, 0, filesize, symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + + symlink[filesize] = '\0'; + + return symlink; +} + +static int +grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx) +{ + struct grub_fshelp_node *fdiro; + int i; + + for (i = 0; i < ctx->max;) + { + char *filename; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + enum FILE_TYPE ftype; + int name_len; + int ret; + int sz; + + if (grub_f2fs_test_bit_le (i, ctx->bitmap) == 0) + { + i++; + continue; + } + + ftype = ctx->dentry[i].file_type; + name_len = grub_le_to_cpu16 (ctx->dentry[i].name_len); + + if (name_len >= F2FS_NAME_LEN) + return 0; + + if (grub_add (name_len, 1, &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory entry name length overflow")); + return 0; + } + filename = grub_malloc (sz); + if (!filename) + return 0; + + grub_memcpy (filename, ctx->filename[i], name_len); + filename[name_len] = 0; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!fdiro) + { + grub_free(filename); + return 0; + } + + if (ftype == F2FS_FT_DIR) + type = GRUB_FSHELP_DIR; + else if (ftype == F2FS_FT_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if (ftype == F2FS_FT_REG_FILE) + type = GRUB_FSHELP_REG; + + fdiro->data = ctx->data; + fdiro->ino = grub_le_to_cpu32 (ctx->dentry[i].ino); + fdiro->inode_read = 0; + + ret = ctx->hook (filename, type, fdiro, ctx->hook_data); + grub_free(filename); + if (ret) + return 1; + + i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; + } + + return 0; +} + +static int +grub_f2fs_iterate_inline_dir (struct grub_f2fs_inode *dir, + struct grub_f2fs_dir_iter_ctx *ctx) +{ + struct grub_f2fs_inline_dentry *de_blk; + + de_blk = (struct grub_f2fs_inline_dentry *) get_inline_addr (dir); + + ctx->bitmap = de_blk->dentry_bitmap; + ctx->dentry = de_blk->dentry; + ctx->filename = de_blk->filename; + ctx->max = NR_INLINE_DENTRY; + + return grub_f2fs_check_dentries (ctx); +} + +static int +grub_f2fs_iterate_dir (grub_fshelp_node_t dir, + grub_fshelp_iterate_dir_hook_t hook, void *hook_data) +{ + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + struct grub_f2fs_inode *inode; + struct grub_f2fs_dir_iter_ctx ctx = { + .data = diro->data, + .hook = hook, + .hook_data = hook_data + }; + grub_off_t fpos = 0; + + if (!diro->inode_read) + { + grub_f2fs_read_node (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + inode = &diro->inode.i; + + if (inode->i_inline & F2FS_INLINE_DENTRY) + return grub_f2fs_iterate_inline_dir (inode, &ctx); + + while (fpos < grub_f2fs_file_size (inode)) + { + struct grub_f2fs_dentry_block *de_blk; + char *buf; + int ret; + + buf = grub_zalloc (F2FS_BLKSIZE); + if (!buf) + return 0; + + grub_f2fs_read_file (diro, 0, 0, fpos, F2FS_BLKSIZE, buf); + if (grub_errno) + { + grub_free (buf); + return 0; + } + + de_blk = (struct grub_f2fs_dentry_block *) buf; + + ctx.bitmap = de_blk->dentry_bitmap; + ctx.dentry = de_blk->dentry; + ctx.filename = de_blk->filename; + ctx.max = NR_DENTRY_IN_BLOCK; + + ret = grub_f2fs_check_dentries (&ctx); + grub_free (buf); + if (ret) + return 1; + + fpos += F2FS_BLKSIZE; + } + + return 0; +} + +static int +grub_f2fs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node, void *data) +{ + struct grub_f2fs_dir_ctx *ctx = data; + struct grub_dirhook_info info; + + grub_memset (&info, 0, sizeof (info)); + if (!node->inode_read) + { + grub_f2fs_read_node (ctx->data, node->ino, &node->inode); + if (!grub_errno) + node->inode_read = 1; + grub_errno = GRUB_ERR_NONE; + } + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_le_to_cpu64 (node->inode.i.i_mtime); + } + + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + + return ctx->hook (filename, &info, ctx->hook_data); +} + +static grub_err_t +grub_f2fs_dir (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data) +{ + struct grub_f2fs_dir_ctx ctx = { + .hook = hook, + .hook_data = hook_data + }; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + ctx.data = grub_f2fs_mount (device->disk); + if (!ctx.data) + goto fail; + + grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro, + grub_f2fs_iterate_dir, grub_f2fs_read_symlink, + GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_f2fs_iterate_dir (fdiro, grub_f2fs_dir_iter, &ctx); + + fail: + if (fdiro != &ctx.data->diropen) + grub_free (fdiro); + grub_free (ctx.data); + grub_dl_unref (my_mod); + + return grub_errno; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_f2fs_open (struct grub_file *file, const char *name) +{ + struct grub_f2fs_data *data = NULL; + struct grub_fshelp_node *fdiro = 0; + struct grub_f2fs_inode *inode; + + grub_dl_ref (my_mod); + + data = grub_f2fs_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, + grub_f2fs_iterate_dir, grub_f2fs_read_symlink, + GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (!fdiro->inode_read) + { + grub_f2fs_read_node (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + grub_memcpy (data->inode, &fdiro->inode, sizeof (*data->inode)); + grub_free (fdiro); + + inode = &(data->inode->i); + file->size = grub_f2fs_file_size (inode); + file->data = data; + file->offset = 0; + + if (inode->i_inline & F2FS_INLINE_DATA && file->size > MAX_INLINE_DATA) + grub_error (GRUB_ERR_BAD_FS, "corrupted inline_data: need fsck"); + + return 0; + + fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_ssize_t +grub_f2fs_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_f2fs_data *data = (struct grub_f2fs_data *) file->data; + + return grub_f2fs_read_file (&data->diropen, + file->read_hook, file->read_hook_data, + file->offset, len, buf); +} + +static grub_err_t +grub_f2fs_close (grub_file_t file) +{ + struct grub_f2fs_data *data = (struct grub_f2fs_data *) file->data; + + grub_free (data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +static grub_uint8_t * +grub_f2fs_utf16_to_utf8 (grub_uint16_t *in_buf_le) +{ + grub_uint16_t in_buf[MAX_VOLUME_NAME]; + grub_uint8_t *out_buf; + int len = 0; + + out_buf = grub_malloc (MAX_VOLUME_NAME * GRUB_MAX_UTF8_PER_UTF16 + 1); + if (!out_buf) + return NULL; + + while (*in_buf_le != 0 && len < MAX_VOLUME_NAME) { + in_buf[len] = grub_le_to_cpu16 (in_buf_le[len]); + len++; + } + + *grub_utf16_to_utf8 (out_buf, in_buf, len) = '\0'; + + return out_buf; +} + +#if __GNUC__ >= 9 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Waddress-of-packed-member" +#endif + +static grub_err_t +grub_f2fs_label (grub_device_t device, char **label) +{ + struct grub_f2fs_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_f2fs_mount (disk); + if (data) + *label = (char *) grub_f2fs_utf16_to_utf8 (data->sblock.volume_name); + else + *label = NULL; + + grub_free (data); + grub_dl_unref (my_mod); + + return grub_errno; +} + +#if __GNUC__ >= 9 +#pragma GCC diagnostic pop +#endif + +static grub_err_t +grub_f2fs_uuid (grub_device_t device, char **uuid) +{ + struct grub_f2fs_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_f2fs_mount (disk); + if (data) + { + *uuid = + grub_xasprintf + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + data->sblock.uuid[0], data->sblock.uuid[1], + data->sblock.uuid[2], data->sblock.uuid[3], + data->sblock.uuid[4], data->sblock.uuid[5], + data->sblock.uuid[6], data->sblock.uuid[7], + data->sblock.uuid[8], data->sblock.uuid[9], + data->sblock.uuid[10], data->sblock.uuid[11], + data->sblock.uuid[12], data->sblock.uuid[13], + data->sblock.uuid[14], data->sblock.uuid[15]); + } + else + *uuid = NULL; + + grub_free (data); + grub_dl_unref (my_mod); + + return grub_errno; +} + +static struct grub_fs grub_f2fs_fs = { + .name = "f2fs", + .fs_dir = grub_f2fs_dir, + .fs_open = grub_f2fs_open, + .fs_read = grub_f2fs_read, + .fs_close = grub_f2fs_close, + .fs_label = grub_f2fs_label, + .fs_uuid = grub_f2fs_uuid, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, + .blocklist_install = 0, +#endif + .next = 0 +}; + +GRUB_MOD_INIT (f2fs) +{ + grub_f2fs_fs.mod = mod; + grub_fs_register (&grub_f2fs_fs); + my_mod = mod; +} + +GRUB_MOD_FINI (f2fs) +{ + grub_fs_unregister (&grub_f2fs_fs); +} diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index 8d8dc35ce..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)) @@ -1229,12 +1287,12 @@ static struct grub_fs grub_fat_fs = #else .name = "fat", #endif - .dir = grub_fat_dir, - .open = grub_fat_open, - .read = grub_fat_read, - .close = grub_fat_close, - .label = grub_fat_label, - .uuid = grub_fat_uuid, + .fs_dir = grub_fat_dir, + .fs_open = grub_fat_open, + .fs_read = grub_fat_read, + .fs_close = grub_fat_close, + .fs_label = grub_fat_label, + .fs_uuid = grub_fat_uuid, #ifdef GRUB_UTIL #ifdef MODE_EXFAT /* ExFAT BPB is 30 larger than FAT32 one. */ @@ -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 fc3683178..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; @@ -1417,13 +1418,13 @@ grub_hfs_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_hfs_fs = { .name = "hfs", - .dir = grub_hfs_dir, - .open = grub_hfs_open, - .read = grub_hfs_read, - .close = grub_hfs_close, - .label = grub_hfs_label, - .uuid = grub_hfs_uuid, - .mtime = grub_hfs_mtime, + .fs_dir = grub_hfs_dir, + .fs_open = grub_hfs_open, + .fs_read = grub_hfs_read, + .fs_close = grub_hfs_close, + .fs_label = grub_hfs_label, + .fs_uuid = grub_hfs_uuid, + .fs_mtime = grub_hfs_mtime, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -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 21159e858..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; } @@ -661,12 +704,20 @@ list_nodes (void *record, void *hook_arg) char *filename; int i; struct grub_fshelp_node *node; + grub_uint16_t *keyname; struct grub_hfsplus_catfile *fileinfo; enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; struct list_nodes_ctx *ctx = hook_arg; catkey = (struct grub_hfsplus_catkey *) record; + if (grub_be_to_cpu16 (catkey->keylen) < HFSPLUS_CATKEY_MIN_LEN || + grub_be_to_cpu16 (catkey->keylen) > HFSPLUS_CATKEY_MAX_LEN) + { + grub_error (GRUB_ERR_BAD_FS, "catalog key length is out of range"); + return 1; + } + fileinfo = (struct grub_hfsplus_catfile *) ((char *) record + grub_be_to_cpu16 (catkey->keylen) @@ -714,37 +765,39 @@ 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_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname)); + if (!keyname) + { + grub_free (filename); + return 0; + } + /* Make sure the byte order of the UTF16 string is correct. */ for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) { - catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); + keyname[i] = grub_be_to_cpu16 (catkey->name[i]); - if (catkey->name[i] == '/') - catkey->name[i] = ':'; + if (keyname[i] == '/') + keyname[i] = ':'; /* If the name is obviously invalid, skip this node. */ - if (catkey->name[i] == 0) + if (keyname[i] == 0) { + grub_free (keyname); grub_free (filename); return 0; } } - *grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, + *grub_utf16_to_utf8 ((grub_uint8_t *) filename, keyname, grub_be_to_cpu16 (catkey->namelen)) = '\0'; - /* Restore the byte order to what it was previously. */ - for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) - { - if (catkey->name[i] == ':') - catkey->name[i] = '/'; - catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); - } + grub_free (keyname); /* hfs+ is case insensitive. */ if (! ctx->dir->data->case_sensitive) @@ -975,6 +1028,7 @@ grub_hfsplus_label (grub_device_t device, char **label) grub_disk_t disk = device->disk; struct grub_hfsplus_catkey *catkey; int i, label_len; + grub_uint16_t *label_name; struct grub_hfsplus_key_internal intern; struct grub_hfsplus_btnode *node = NULL; grub_disk_addr_t ptr = 0; @@ -1003,22 +1057,50 @@ 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); - for (i = 0; i < label_len; i++) - { - catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); - /* If the name is obviously invalid, skip this node. */ - if (catkey->name[i] == 0) - return 0; + /* Ensure that the length is >= 0. */ + if (label_len < 0) + label_len = 0; + + /* Ensure label length is at most 255 Unicode characters. */ + if (label_len > 255) + label_len = 255; + + label_name = grub_calloc (label_len, sizeof (*label_name)); + if (!label_name) + { + grub_free (node); + grub_free (data); + return grub_errno; } - *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1); - if (! *label) - return grub_errno; + for (i = 0; i < label_len; i++) + { + label_name[i] = grub_be_to_cpu16 (catkey->name[i]); - *grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name, + /* If the name is obviously invalid, skip this node. */ + if (label_name[i] == 0) + { + grub_free (label_name); + grub_free (node); + grub_free (data); + return 0; + } + } + + *label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1); + if (! *label) + { + grub_free (label_name); + grub_free (node); + grub_free (data); + return grub_errno; + } + + *grub_utf16_to_utf8 ((grub_uint8_t *) (*label), label_name, label_len) = '\0'; + grub_free (label_name); grub_free (node); grub_free (data); @@ -1027,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; @@ -1078,13 +1160,13 @@ grub_hfsplus_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_hfsplus_fs = { .name = "hfsplus", - .dir = grub_hfsplus_dir, - .open = grub_hfsplus_open, - .read = grub_hfsplus_read, - .close = grub_hfsplus_close, - .label = grub_hfsplus_label, - .mtime = grub_hfsplus_mtime, - .uuid = grub_hfsplus_uuid, + .fs_dir = grub_hfsplus_dir, + .fs_open = grub_hfsplus_open, + .fs_read = grub_hfsplus_read, + .fs_close = grub_hfsplus_close, + .fs_label = grub_hfsplus_label, + .fs_mtime = grub_hfsplus_mtime, + .fs_uuid = grub_hfsplus_uuid, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -1094,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 c9c8374bf..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; @@ -1099,13 +1244,13 @@ grub_iso9660_mtime (grub_device_t device, grub_int32_t *timebuf) static struct grub_fs grub_iso9660_fs = { .name = "iso9660", - .dir = grub_iso9660_dir, - .open = grub_iso9660_open, - .read = grub_iso9660_read, - .close = grub_iso9660_close, - .label = grub_iso9660_label, - .uuid = grub_iso9660_uuid, - .mtime = grub_iso9660_mtime, + .fs_dir = grub_iso9660_dir, + .fs_open = grub_iso9660_open, + .fs_read = grub_iso9660_read, + .fs_close = grub_iso9660_close, + .fs_label = grub_iso9660_label, + .fs_uuid = grub_iso9660_uuid, + .fs_mtime = grub_iso9660_mtime, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -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 aab3e8c7b..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)); @@ -505,6 +559,10 @@ le_to_cpu16_copy (grub_uint16_t *out, grub_uint16_t *in, grub_size_t len) *out++ = grub_le_to_cpu16 (*in++); } +#if __GNUC__ >= 9 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Waddress-of-packed-member" +#endif /* Read in the next dirent from the directory described by DIRO. */ static grub_err_t @@ -563,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]; @@ -582,6 +640,9 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) return 0; } +#if __GNUC__ >= 9 +#pragma GCC diagnostic pop +#endif /* Read LEN bytes from the file described by DATA starting with byte POS. Return the amount of read bytes in READ. */ @@ -698,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; @@ -930,12 +990,12 @@ grub_jfs_label (grub_device_t device, char **label) static struct grub_fs grub_jfs_fs = { .name = "jfs", - .dir = grub_jfs_dir, - .open = grub_jfs_open, - .read = grub_jfs_read, - .close = grub_jfs_close, - .label = grub_jfs_label, - .uuid = grub_jfs_uuid, + .fs_dir = grub_jfs_dir, + .fs_open = grub_jfs_open, + .fs_read = grub_jfs_read, + .fs_close = grub_jfs_close, + .fs_label = grub_jfs_label, + .fs_uuid = grub_jfs_uuid, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -945,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 d451b3426..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) @@ -687,10 +706,10 @@ static struct grub_fs grub_minix_fs = .name = "minix", #endif #endif - .dir = grub_minix_dir, - .open = grub_minix_open, - .read = grub_minix_read, - .close = grub_minix_close, + .fs_dir = grub_minix_dir, + .fs_open = grub_minix_open, + .fs_read = grub_minix_read, + .fs_close = grub_minix_close, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -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 598a2a55b..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; @@ -1192,13 +1211,13 @@ grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm) static struct grub_fs grub_nilfs2_fs = { .name = "nilfs2", - .dir = grub_nilfs2_dir, - .open = grub_nilfs2_open, - .read = grub_nilfs2_read, - .close = grub_nilfs2_close, - .label = grub_nilfs2_label, - .uuid = grub_nilfs2_uuid, - .mtime = grub_nilfs2_mtime, + .fs_dir = grub_nilfs2_dir, + .fs_open = grub_nilfs2_open, + .fs_read = grub_nilfs2_read, + .fs_close = grub_nilfs2_close, + .fs_label = grub_nilfs2_label, + .fs_uuid = grub_nilfs2_uuid, + .fs_mtime = grub_nilfs2_mtime, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 0, @@ -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 6f8468862..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: @@ -1212,12 +1527,12 @@ grub_ntfs_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_ntfs_fs = { .name = "ntfs", - .dir = grub_ntfs_dir, - .open = grub_ntfs_open, - .read = grub_ntfs_read, - .close = grub_ntfs_close, - .label = grub_ntfs_label, - .uuid = grub_ntfs_uuid, + .fs_dir = grub_ntfs_dir, + .fs_open = grub_ntfs_open, + .fs_read = grub_ntfs_read, + .fs_close = grub_ntfs_close, + .fs_label = grub_ntfs_label, + .fs_uuid = grub_ntfs_uuid, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -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 31f3aa9a4..bcde43349 100644 --- a/grub-core/fs/proc.c +++ b/grub-core/fs/proc.c @@ -172,26 +172,27 @@ grub_procfs_open (struct grub_file *file, const char *path) static struct grub_disk_dev grub_procfs_dev = { .name = "proc", .id = GRUB_DISK_DEVICE_PROCFS_ID, - .iterate = grub_procdev_iterate, - .open = grub_procdev_open, - .close = grub_procdev_close, - .read = grub_procdev_read, - .write = grub_procdev_write, + .disk_iterate = grub_procdev_iterate, + .disk_open = grub_procdev_open, + .disk_close = grub_procdev_close, + .disk_read = grub_procdev_read, + .disk_write = grub_procdev_write, .next = 0 }; static struct grub_fs grub_procfs_fs = { .name = "procfs", - .dir = grub_procfs_dir, - .open = grub_procfs_open, - .read = grub_procfs_read, - .close = grub_procfs_close, + .fs_dir = grub_procfs_dir, + .fs_open = grub_procfs_open, + .fs_read = grub_procfs_read, + .fs_close = grub_procfs_close, .next = 0 }; GRUB_MOD_INIT (procfs) { + grub_procfs_fs.mod = mod; grub_disk_dev_register (&grub_procfs_dev); grub_fs_register (&grub_procfs_fs); } diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c index 39736f63c..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; @@ -1402,12 +1403,12 @@ grub_reiserfs_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_reiserfs_fs = { .name = "reiserfs", - .dir = grub_reiserfs_dir, - .open = grub_reiserfs_open, - .read = grub_reiserfs_read, - .close = grub_reiserfs_close, - .label = grub_reiserfs_label, - .uuid = grub_reiserfs_uuid, + .fs_dir = grub_reiserfs_dir, + .fs_open = grub_reiserfs_open, + .fs_read = grub_reiserfs_read, + .fs_close = grub_reiserfs_close, + .fs_label = grub_reiserfs_label, + .fs_uuid = grub_reiserfs_uuid, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -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 2e3544408..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; @@ -461,11 +462,11 @@ grub_romfs_label (grub_device_t device, char **label) static struct grub_fs grub_romfs_fs = { .name = "romfs", - .dir = grub_romfs_dir, - .open = grub_romfs_open, - .read = grub_romfs_read, - .close = grub_romfs_close, - .label = grub_romfs_label, + .fs_dir = grub_romfs_dir, + .fs_open = grub_romfs_open, + .fs_read = grub_romfs_read, + .fs_close = grub_romfs_close, + .fs_label = grub_romfs_label, #ifdef GRUB_UTIL .reserved_first_sector = 0, .blocklist_install = 0, @@ -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 57b8d8da6..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, @@ -741,11 +769,11 @@ grub_sfs_label (grub_device_t device, char **label) static struct grub_fs grub_sfs_fs = { .name = "sfs", - .dir = grub_sfs_dir, - .open = grub_sfs_open, - .read = grub_sfs_read, - .close = grub_sfs_close, - .label = grub_sfs_label, + .fs_dir = grub_sfs_dir, + .fs_open = grub_sfs_open, + .fs_read = grub_sfs_read, + .fs_close = grub_sfs_close, + .fs_label = grub_sfs_label, #ifdef GRUB_UTIL .reserved_first_sector = 0, .blocklist_install = 1, @@ -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 2c967c65a..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,16 +1031,16 @@ 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 = { .name = "squash4", - .dir = grub_squash_dir, - .open = grub_squash_open, - .read = grub_squash_read, - .close = grub_squash_close, - .mtime = grub_squash_mtime, + .fs_dir = grub_squash_dir, + .fs_open = grub_squash_open, + .fs_read = grub_squash_read, + .fs_close = grub_squash_close, + .fs_mtime = grub_squash_mtime, #ifdef GRUB_UTIL .reserved_first_sector = 0, .blocklist_install = 0, @@ -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 39bf197aa..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; } @@ -324,10 +351,10 @@ grub_cpio_close (grub_file_t file) static struct grub_fs grub_cpio_fs = { .name = "tarfs", - .dir = grub_cpio_dir, - .open = grub_cpio_open, - .read = grub_cpio_read, - .close = grub_cpio_close, + .fs_dir = grub_cpio_dir, + .fs_open = grub_cpio_open, + .fs_read = grub_cpio_read, + .fs_close = grub_cpio_close, #ifdef GRUB_UTIL .reserved_first_sector = 0, .blocklist_install = 0, @@ -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 839bff889..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; @@ -321,6 +327,32 @@ struct grub_udf_partmap }; } GRUB_PACKED; +struct grub_udf_pvd +{ + struct grub_udf_tag tag; + grub_uint32_t seq_num; + grub_uint32_t pvd_num; + grub_uint8_t ident[32]; + grub_uint16_t vol_seq_num; + grub_uint16_t max_vol_seq_num; + grub_uint16_t interchange_level; + grub_uint16_t max_interchange_level; + grub_uint32_t charset_list; + grub_uint32_t max_charset_list; + grub_uint8_t volset_ident[128]; + struct grub_udf_charspec desc_charset; + struct grub_udf_charspec expl_charset; + struct grub_udf_extent_ad vol_abstract; + struct grub_udf_extent_ad vol_copyright; + struct grub_udf_regid app_ident; + struct grub_udf_timestamp recording_time; + struct grub_udf_regid imp_ident; + grub_uint8_t imp_use[64]; + grub_uint32_t pred_vds_loc; + grub_uint16_t flags; + grub_uint8_t reserved[22]; +} GRUB_PACKED; + struct grub_udf_lvd { struct grub_udf_tag tag; @@ -348,6 +380,7 @@ struct grub_udf_aed struct grub_udf_data { grub_disk_t disk; + struct grub_udf_pvd pvd; struct grub_udf_lvd lvd; struct grub_udf_pd pds[GRUB_UDF_MAX_PDS]; struct grub_udf_partmap *pms[GRUB_UDF_MAX_PMS]; @@ -430,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)) { @@ -448,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); @@ -482,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; @@ -500,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); @@ -535,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; @@ -555,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; + } } } @@ -574,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] @@ -581,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; @@ -692,7 +787,17 @@ grub_udf_mount (grub_disk_t disk) } tag.tag_ident = U16 (tag.tag_ident); - if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD) + if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PVD) + { + if (grub_disk_read (disk, block << lbshift, 0, + sizeof (struct grub_udf_pvd), + &data->pvd)) + { + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); + goto fail; + } + } + else if (tag.tag_ident == GRUB_UDF_TAG_IDENT_PD) { if (data->npd >= GRUB_UDF_MAX_PDS) { @@ -836,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++) @@ -846,20 +951,49 @@ 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; } +static char * +read_dstring (const grub_uint8_t *raw, grub_size_t sz) +{ + grub_size_t len; + + if (raw[0] == 0) { + char *outbuf = grub_malloc (1); + if (!outbuf) + return NULL; + outbuf[0] = 0; + return outbuf; + } + + len = raw[sz - 1]; + if (len > sz - 1) + len = sz - 1; + return read_string (raw, len, NULL); +} + static int grub_udf_iterate_dir (grub_fshelp_node_t dir, grub_fshelp_iterate_dir_hook_t hook, void *hook_data) @@ -898,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. */ @@ -921,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)) { @@ -946,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; @@ -957,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; } @@ -973,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. */ @@ -1010,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; } @@ -1022,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"); @@ -1197,7 +1349,7 @@ grub_udf_label (grub_device_t device, char **label) if (data) { - *label = read_string (data->lvd.ident, sizeof (data->lvd.ident), 0); + *label = read_dstring (data->lvd.ident, sizeof (data->lvd.ident)); grub_free (data); } else @@ -1206,13 +1358,95 @@ grub_udf_label (grub_device_t device, char **label) return grub_errno; } +static char * +gen_uuid_from_volset (char *volset_ident) +{ + grub_size_t i; + grub_size_t len; + grub_size_t nonhexpos; + grub_uint8_t buf[17]; + char *uuid; + + len = grub_strlen (volset_ident); + if (len < 8) + return NULL; + + uuid = grub_malloc (17); + if (!uuid) + return NULL; + + if (len > 16) + len = 16; + + grub_memset (buf, 0, sizeof (buf)); + grub_memcpy (buf, volset_ident, len); + + nonhexpos = 16; + for (i = 0; i < 16; ++i) + { + if (!grub_isxdigit (buf[i])) + { + nonhexpos = i; + break; + } + } + + if (nonhexpos < 8) + { + grub_snprintf (uuid, 17, "%02x%02x%02x%02x%02x%02x%02x%02x", + buf[0], buf[1], buf[2], buf[3], + buf[4], buf[5], buf[6], buf[7]); + } + else if (nonhexpos < 16) + { + for (i = 0; i < 8; ++i) + uuid[i] = grub_tolower (buf[i]); + grub_snprintf (uuid+8, 9, "%02x%02x%02x%02x", + buf[8], buf[9], buf[10], buf[11]); + } + else + { + for (i = 0; i < 16; ++i) + uuid[i] = grub_tolower (buf[i]); + uuid[16] = 0; + } + + return uuid; +} + +static grub_err_t +grub_udf_uuid (grub_device_t device, char **uuid) +{ + char *volset_ident; + struct grub_udf_data *data; + data = grub_udf_mount (device->disk); + + if (data) + { + volset_ident = read_dstring (data->pvd.volset_ident, sizeof (data->pvd.volset_ident)); + if (volset_ident) + { + *uuid = gen_uuid_from_volset (volset_ident); + grub_free (volset_ident); + } + else + *uuid = 0; + grub_free (data); + } + else + *uuid = 0; + + return grub_errno; +} + static struct grub_fs grub_udf_fs = { .name = "udf", - .dir = grub_udf_dir, - .open = grub_udf_open, - .read = grub_udf_read, - .close = grub_udf_close, - .label = grub_udf_label, + .fs_dir = grub_udf_dir, + .fs_open = grub_udf_open, + .fs_read = grub_udf_read, + .fs_close = grub_udf_close, + .fs_label = grub_udf_label, + .fs_uuid = grub_udf_uuid, #ifdef GRUB_UTIL .reserved_first_sector = 1, .blocklist_install = 1, @@ -1222,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 293f027aa..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; @@ -875,13 +876,13 @@ static struct grub_fs grub_ufs_fs = .name = "ufs1", #endif #endif - .dir = grub_ufs_dir, - .open = grub_ufs_open, - .read = grub_ufs_read, - .close = grub_ufs_close, - .label = grub_ufs_label, - .uuid = grub_ufs_uuid, - .mtime = grub_ufs_mtime, + .fs_dir = grub_ufs_dir, + .fs_open = grub_ufs_open, + .fs_read = grub_ufs_read, + .fs_close = grub_ufs_close, + .fs_label = grub_ufs_label, + .fs_uuid = grub_ufs_uuid, + .fs_mtime = grub_ufs_mtime, /* FIXME: set reserved_first_sector. */ #ifdef GRUB_UTIL .blocklist_install = 1, @@ -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 9f66dd6e4..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,15 +76,51 @@ 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 */ -/* We do not currently verify metadata UUID so it is safe to read such filesystem */ +/* + * Directory entries with ftype are explicitly handled by GRUB code. + * + * We do not currently read the inode btrees, so it is safe to read filesystems + * with the XFS_SB_FEAT_INCOMPAT_SPINODES feature. + * + * We do not currently verify metadata UUID, so it is safe to read filesystems + * with the XFS_SB_FEAT_INCOMPAT_META_UUID feature. + * + * We do not currently replay the log, so it is safe to read filesystems + * with the XFS_SB_FEAT_INCOMPAT_EXCHRANGE feature. + * + * We do not currently read directory parent pointers, so it is safe to read + * filesystems with the XFS_SB_FEAT_INCOMPAT_PARENT feature. + * + * We do not currently look at realtime or quota metadata, so it is safe to + * read filesystems with the XFS_SB_FEAT_INCOMPAT_METADIR feature. + */ #define XFS_SB_FEAT_INCOMPAT_SUPPORTED \ (XFS_SB_FEAT_INCOMPAT_FTYPE | \ - XFS_SB_FEAT_INCOMPAT_META_UUID) + XFS_SB_FEAT_INCOMPAT_SPINODES | \ + XFS_SB_FEAT_INCOMPAT_META_UUID | \ + XFS_SB_FEAT_INCOMPAT_BIGTIME | \ + XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \ + XFS_SB_FEAT_INCOMPAT_NREXT64 | \ + XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \ + XFS_SB_FEAT_INCOMPAT_PARENT | \ + XFS_SB_FEAT_INCOMPAT_METADIR) struct grub_xfs_sblock { @@ -167,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 { @@ -211,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; @@ -287,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 @@ -480,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), @@ -500,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; @@ -529,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++) { @@ -547,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)) || @@ -570,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 { @@ -625,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) { @@ -646,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; @@ -696,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 (); @@ -713,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; } @@ -755,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) @@ -815,21 +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 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; @@ -849,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); @@ -887,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, @@ -901,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; @@ -919,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); @@ -927,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); @@ -943,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, @@ -955,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); @@ -1125,12 +1324,12 @@ grub_xfs_uuid (grub_device_t device, char **uuid) static struct grub_fs grub_xfs_fs = { .name = "xfs", - .dir = grub_xfs_dir, - .open = grub_xfs_open, - .read = grub_xfs_read, - .close = grub_xfs_close, - .label = grub_xfs_label, - .uuid = grub_xfs_uuid, + .fs_dir = grub_xfs_dir, + .fs_open = grub_xfs_open, + .fs_read = grub_xfs_read, + .fs_close = grub_xfs_close, + .fs_label = grub_xfs_label, + .fs_uuid = grub_xfs_uuid, #ifdef GRUB_UTIL .reserved_first_sector = 0, .blocklist_install = 1, @@ -1140,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 6e1fff9e9..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++) @@ -4348,15 +4545,15 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)), static struct grub_fs grub_zfs_fs = { .name = "zfs", - .dir = grub_zfs_dir, - .open = grub_zfs_open, - .read = grub_zfs_read, - .close = grub_zfs_close, - .label = zfs_label, - .uuid = zfs_uuid, - .mtime = zfs_mtime, + .fs_dir = grub_zfs_dir, + .fs_open = grub_zfs_open, + .fs_read = grub_zfs_read, + .fs_close = grub_zfs_close, + .fs_label = zfs_label, + .fs_uuid = zfs_uuid, + .fs_mtime = zfs_mtime, #ifdef GRUB_UTIL - .embed = grub_zfs_embed, + .fs_embed = grub_zfs_embed, .reserved_first_sector = 1, .blocklist_install = 0, #endif @@ -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_lz4.c b/grub-core/fs/zfs/zfs_lz4.c index 2f73449f0..5453822d0 100644 --- a/grub-core/fs/zfs/zfs_lz4.c +++ b/grub-core/fs/zfs/zfs_lz4.c @@ -73,7 +73,6 @@ static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, #define U32 grub_uint32_t #define S32 grub_int32_t #define U64 grub_uint64_t -typedef grub_size_t size_t; typedef struct _U16_S { U16 v; @@ -133,10 +132,10 @@ typedef struct _U64_S { /* Decompression functions */ grub_err_t -lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len); +lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len); grub_err_t -lz4_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len) +lz4_decompress(void *s_start, void *d_start, grub_size_t s_len, grub_size_t d_len) { const BYTE *src = s_start; U32 bufsiz = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | @@ -167,7 +166,7 @@ LZ4_uncompress_unknownOutputSize(const char *source, BYTE *const oend = op + maxOutputSize; BYTE *cpy; - size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 }; + grub_size_t dec[] = { 0, 3, 2, 3, 0, 0, 0, 0 }; /* Main Loop */ while (ip < iend) { @@ -237,8 +236,8 @@ LZ4_uncompress_unknownOutputSize(const char *source, /* copy repeated sequence */ if unlikely(op - ref < STEPSIZE) { #if LZ4_ARCH64 - size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 }; - size_t dec2 = dec2table[op - ref]; + grub_size_t dec2table[] = { 0, 0, 0, -1, 0, 1, 2, 3 }; + grub_size_t dec2 = dec2table[op - ref]; #else const int dec2 = 0; #endif 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 87eef621d..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) @@ -425,7 +430,7 @@ grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args) if (argc > 0) { grub_file_t file; - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY); if (!file) return grub_errno; real_size = grub_file_read (file, buf, 1024); 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/cstub.c b/grub-core/gdb/cstub.c index c94411b10..b64acd70f 100644 --- a/grub-core/gdb/cstub.c +++ b/grub-core/gdb/cstub.c @@ -336,6 +336,7 @@ grub_gdb_trap (int trap_no) /* sAA..AA: Step one instruction from AA..AA(optional). */ case 's': stepping = 1; + /* FALLTHROUGH */ /* cAA..AA: Continue at address AA..AA(optional). */ case 'c': 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 03cc3b7f6..337753c57 100644 --- a/grub-core/genmod.sh.in +++ b/grub-core/genmod.sh.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ set -e # Copyright (C) 2010 Free Software Foundation, Inc. @@ -57,7 +57,14 @@ 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 \ -R .note -R .comment -R .ARM.exidx $tmpfile || exit 1 fi if ! test -z "${TARGET_OBJ2ELF}"; then @@ -79,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 bd98d84cd..ab457cb2b 100644 --- a/grub-core/genmoddep.awk +++ b/grub-core/genmoddep.awk @@ -18,6 +18,10 @@ BEGIN { { if ($1 == "defined") { + if ($3 !~ /^\.refptr\./ && $3 in symtab) { + printf "%s in %s is duplicated in %s\n", $3, $2, symtab[$3] >"/dev/stderr"; + error++; + } symtab[$3] = $2; modtab[$2] = "" modtab[$2] } else if ($1 == "undefined") { @@ -27,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++; @@ -55,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/gensyminfo.sh.in b/grub-core/gensyminfo.sh.in index 2e8716b42..9bc767532 100644 --- a/grub-core/gensyminfo.sh.in +++ b/grub-core/gensyminfo.sh.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ set -e # Copyright (C) 2010 Free Software Foundation, Inc. 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 4880cefe3..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; } } @@ -291,7 +296,7 @@ grub_mofile_open (struct grub_gettext_context *ctx, /* Using fd_mo and not another variable because it's needed for grub_gettext_get_info. */ - fd = grub_file_open (filename); + fd = grub_file_open (filename, GRUB_FILE_TYPE_GETTEXT_CATALOG); if (!fd) return grub_errno; @@ -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 02978392c..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) @@ -743,7 +743,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) p.view = view; p.theme_dir = grub_get_dirname (theme_path); - file = grub_file_open (theme_path); + file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME); if (! file) { grub_free (p.theme_dir); 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/gnulib-fix-null-deref.diff b/grub-core/gnulib-fix-null-deref.diff deleted file mode 100644 index a2fba8c3b..000000000 --- a/grub-core/gnulib-fix-null-deref.diff +++ /dev/null @@ -1,13 +0,0 @@ -=== modified file 'grub-core/gnulib/argp-parse.c' ---- grub-core/gnulib/argp-parse.c 2010-04-02 22:45:01 +0000 -+++ grub-core/gnulib/argp-parse.c 2011-04-10 13:25:52 +0000 -@@ -935,7 +935,7 @@ - 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/gnulib-no-abort.diff b/grub-core/gnulib-no-abort.diff deleted file mode 100644 index 8377338f7..000000000 --- a/grub-core/gnulib-no-abort.diff +++ /dev/null @@ -1,30 +0,0 @@ -=== modified file 'grub-core/gnulib/regcomp.c' ---- grub-core/gnulib/regcomp.c 2010-09-20 10:35:33 +0000 -+++ grub-core/gnulib/regcomp.c 2012-03-10 11:31:42 +0000 -@@ -549,13 +549,9 @@ regerror (int errcode, const regex_t *_R - if (BE (errcode < 0 - || errcode >= (int) (sizeof (__re_error_msgid_idx) - / sizeof (__re_error_msgid_idx[0])), 0)) -- /* Only error codes returned by the rest of the code should be passed -- to this routine. If we are given anything else, or if other regex -- code generates an invalid error code, then the program has a bug. -- Dump core so we can fix it. */ -- abort (); -- -- msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); -+ msg = gettext ("unknown regexp error"); -+ else -+ msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); - - msg_size = strlen (msg) + 1; /* Includes the null. */ - -@@ -1119,7 +1119,7 @@ - } - break; - default: -- abort (); -+ break; - } - - if (mb_chars || has_period) - diff --git a/grub-core/gnulib-no-gets.diff b/grub-core/gnulib-no-gets.diff deleted file mode 100644 index 1a9487e84..000000000 --- a/grub-core/gnulib-no-gets.diff +++ /dev/null @@ -1,10 +0,0 @@ ---- /tmp/x.diff 2013-04-11 16:51:42.777873536 +0200 -+++ grub-core/gnulib/stdio.in.h 2013-04-11 16:51:49.917873298 +0200 -@@ -700,7 +700,6 @@ - removed it. */ - #undef gets - #if HAVE_RAW_DECL_GETS --_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); - #endif - - diff --git a/grub-core/gnulib/Makefile.am b/grub-core/gnulib/Makefile.am deleted file mode 100644 index 3444397fe..000000000 --- a/grub-core/gnulib/Makefile.am +++ /dev/null @@ -1,1747 +0,0 @@ -## DO NOT EDIT! GENERATED AUTOMATICALLY! -## Process this file with automake to produce Makefile.in. -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This file is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this file. If not, see . -# -# As a special exception to the GNU General Public License, -# this file may be distributed as part of a program that -# contains a configuration script generated by Autoconf, under -# the same distribution terms as the rest of that program. -# -# Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex - -AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects - -SUBDIRS = -noinst_HEADERS = -noinst_LIBRARIES = -noinst_LTLIBRARIES = -EXTRA_DIST = -BUILT_SOURCES = -SUFFIXES = -MOSTLYCLEANFILES = core *.stackdump -MOSTLYCLEANDIRS = -CLEANFILES = -DISTCLEANFILES = -MAINTAINERCLEANFILES = - -AM_CPPFLAGS = -AM_CFLAGS = - -noinst_LIBRARIES += libgnu.a - -libgnu_a_SOURCES = -libgnu_a_LIBADD = $(gl_LIBOBJS) -libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) -EXTRA_libgnu_a_SOURCES = - -## begin gnulib module alloca - - -libgnu_a_LIBADD += @ALLOCA@ -libgnu_a_DEPENDENCIES += @ALLOCA@ -EXTRA_DIST += alloca.c - -EXTRA_libgnu_a_SOURCES += alloca.c - -## end gnulib module alloca - -## begin gnulib module alloca-opt - -BUILT_SOURCES += $(ALLOCA_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -if GL_GENERATE_ALLOCA_H -alloca.h: alloca.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/alloca.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -else -alloca.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += alloca.h alloca.h-t - -EXTRA_DIST += alloca.in.h - -## end gnulib module alloca-opt - -## begin gnulib module argp - -libgnu_a_SOURCES += argp.h argp-ba.c argp-eexst.c \ - argp-fmtstream.c argp-fmtstream.h argp-fs-xinl.c argp-help.c \ - argp-namefrob.h argp-parse.c argp-pin.c argp-pv.c argp-pvh.c \ - argp-xinl.c - -## end gnulib module argp - -## begin gnulib module btowc - - -EXTRA_DIST += btowc.c - -EXTRA_libgnu_a_SOURCES += btowc.c - -## end gnulib module btowc - -## begin gnulib module configmake - -# Listed in the same order as the GNU makefile conventions, and -# provided by autoconf 2.59c+. -# The Automake-defined pkg* macros are appended, in the order -# listed in the Automake 1.10a+ documentation. -configmake.h: Makefile - $(AM_V_GEN)rm -f $@-t && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - echo '#define PREFIX "$(prefix)"'; \ - echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ - echo '#define BINDIR "$(bindir)"'; \ - echo '#define SBINDIR "$(sbindir)"'; \ - echo '#define LIBEXECDIR "$(libexecdir)"'; \ - echo '#define DATAROOTDIR "$(datarootdir)"'; \ - echo '#define DATADIR "$(datadir)"'; \ - echo '#define SYSCONFDIR "$(sysconfdir)"'; \ - echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ - echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ - echo '#define INCLUDEDIR "$(includedir)"'; \ - echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ - echo '#define DOCDIR "$(docdir)"'; \ - echo '#define INFODIR "$(infodir)"'; \ - echo '#define HTMLDIR "$(htmldir)"'; \ - echo '#define DVIDIR "$(dvidir)"'; \ - echo '#define PDFDIR "$(pdfdir)"'; \ - echo '#define PSDIR "$(psdir)"'; \ - echo '#define LIBDIR "$(libdir)"'; \ - echo '#define LISPDIR "$(lispdir)"'; \ - echo '#define LOCALEDIR "$(localedir)"'; \ - echo '#define MANDIR "$(mandir)"'; \ - echo '#define MANEXT "$(manext)"'; \ - echo '#define PKGDATADIR "$(pkgdatadir)"'; \ - echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ - echo '#define PKGLIBDIR "$(pkglibdir)"'; \ - echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ - } | sed '/""/d' > $@-t && \ - mv -f $@-t $@ - -BUILT_SOURCES += configmake.h -CLEANFILES += configmake.h configmake.h-t - -## end gnulib module configmake - -## begin gnulib module dirname-lgpl - -libgnu_a_SOURCES += dirname-lgpl.c basename-lgpl.c stripslash.c - -EXTRA_DIST += dirname.h - -## end gnulib module dirname-lgpl - -## begin gnulib module dosname - - -EXTRA_DIST += dosname.h - -## end gnulib module dosname - -## begin gnulib module errno - -BUILT_SOURCES += $(ERRNO_H) - -# We need the following in order to create when the system -# doesn't have one that is POSIX compliant. -if GL_GENERATE_ERRNO_H -errno.h: errno.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \ - -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \ - -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \ - -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \ - -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \ - -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \ - -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \ - < $(srcdir)/errno.in.h; \ - } > $@-t && \ - mv $@-t $@ -else -errno.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += errno.h errno.h-t - -EXTRA_DIST += errno.in.h - -## end gnulib module errno - -## begin gnulib module error - - -EXTRA_DIST += error.c error.h - -EXTRA_libgnu_a_SOURCES += error.c - -## end gnulib module error - -## begin gnulib module float - -BUILT_SOURCES += $(FLOAT_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -if GL_GENERATE_FLOAT_H -float.h: float.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ - -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \ - < $(srcdir)/float.in.h; \ - } > $@-t && \ - mv $@-t $@ -else -float.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += float.h float.h-t - -EXTRA_DIST += float.c float.in.h itold.c - -EXTRA_libgnu_a_SOURCES += float.c itold.c - -## end gnulib module float - -## begin gnulib module fnmatch - -BUILT_SOURCES += $(FNMATCH_H) - -# We need the following in order to create when the system -# doesn't have one that supports the required API. -if GL_GENERATE_FNMATCH_H -fnmatch.h: fnmatch.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - < $(srcdir)/fnmatch.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -else -fnmatch.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += fnmatch.h fnmatch.h-t - -EXTRA_DIST += fnmatch.c fnmatch.in.h fnmatch_loop.c - -EXTRA_libgnu_a_SOURCES += fnmatch.c fnmatch_loop.c - -## end gnulib module fnmatch - -## begin gnulib module getdelim - - -EXTRA_DIST += getdelim.c - -EXTRA_libgnu_a_SOURCES += getdelim.c - -## end gnulib module getdelim - -## begin gnulib module getline - - -EXTRA_DIST += getline.c - -EXTRA_libgnu_a_SOURCES += getline.c - -## end gnulib module getline - -## begin gnulib module getopt-posix - -BUILT_SOURCES += $(GETOPT_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - < $(srcdir)/getopt.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -MOSTLYCLEANFILES += getopt.h getopt.h-t - -EXTRA_DIST += getopt.c getopt.in.h getopt1.c getopt_int.h - -EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c - -## end gnulib module getopt-posix - -## begin gnulib module gettext - -# This is for those projects which use "gettextize --intl" to put a source-code -# copy of libintl into their package. In such projects, every Makefile.am needs -# -I$(top_builddir)/intl, so that can be found in this directory. -# For the Makefile.ams in other directories it is the maintainer's -# responsibility; for the one from gnulib we do it here. -# This option has no effect when the user disables NLS (because then the intl -# directory contains no libintl.h file) or when the project does not use -# "gettextize --intl". -AM_CPPFLAGS += -I$(top_builddir)/intl - -EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath - -## end gnulib module gettext - -## begin gnulib module gettext-h - -libgnu_a_SOURCES += gettext.h - -## end gnulib module gettext-h - -## begin gnulib module havelib - - -EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath - -## end gnulib module havelib - -## begin gnulib module intprops - - -EXTRA_DIST += intprops.h - -## end gnulib module intprops - -## begin gnulib module langinfo - -BUILT_SOURCES += langinfo.h - -# We need the following in order to create an empty placeholder for -# when the system doesn't have one. -langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \ - -e 's/@''GNULIB_NL_LANGINFO''@/$(GNULIB_NL_LANGINFO)/g' \ - -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ - -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ - -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ - -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \ - -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \ - -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/langinfo.in.h; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += langinfo.h langinfo.h-t - -EXTRA_DIST += langinfo.in.h - -## end gnulib module langinfo - -## begin gnulib module localcharset - -libgnu_a_SOURCES += localcharset.h localcharset.c - -# We need the following in order to install a simple file in $(libdir) -# which is shared with other installed packages. We use a list of referencing -# packages so that "make uninstall" will remove the file if and only if it -# is not used by another installed package. -# On systems with glibc-2.1 or newer, the file is redundant, therefore we -# avoid installing it. - -all-local: charset.alias ref-add.sed ref-del.sed - -charset_alias = $(DESTDIR)$(libdir)/charset.alias -charset_tmp = $(DESTDIR)$(libdir)/charset.tmp -install-exec-local: install-exec-localcharset -install-exec-localcharset: all-local - if test $(GLIBC21) = no; then \ - case '$(host_os)' in \ - darwin[56]*) \ - need_charset_alias=true ;; \ - darwin* | cygwin* | mingw* | pw32* | cegcc*) \ - need_charset_alias=false ;; \ - *) \ - need_charset_alias=true ;; \ - esac ; \ - else \ - need_charset_alias=false ; \ - fi ; \ - if $$need_charset_alias; then \ - $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ - fi ; \ - if test -f $(charset_alias); then \ - sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - else \ - if $$need_charset_alias; then \ - sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ - rm -f $(charset_tmp) ; \ - fi ; \ - fi - -uninstall-local: uninstall-localcharset -uninstall-localcharset: all-local - if test -f $(charset_alias); then \ - sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ - if grep '^# Packages using this file: $$' $(charset_tmp) \ - > /dev/null; then \ - rm -f $(charset_alias); \ - else \ - $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ - fi; \ - rm -f $(charset_tmp); \ - fi - -charset.alias: config.charset - $(AM_V_GEN)rm -f t-$@ $@ && \ - $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \ - mv t-$@ $@ - -SUFFIXES += .sed .sin -.sin.sed: - $(AM_V_GEN)rm -f t-$@ $@ && \ - sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \ - mv t-$@ $@ - -CLEANFILES += charset.alias ref-add.sed ref-del.sed - -EXTRA_DIST += config.charset ref-add.sin ref-del.sin - -## end gnulib module localcharset - -## begin gnulib module locale - -BUILT_SOURCES += locale.h - -# We need the following in order to create when the system -# doesn't have one that provides all definitions. -locale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \ - -e 's/@''GNULIB_LOCALECONV''@/$(GNULIB_LOCALECONV)/g' \ - -e 's/@''GNULIB_SETLOCALE''@/$(GNULIB_SETLOCALE)/g' \ - -e 's/@''GNULIB_DUPLOCALE''@/$(GNULIB_DUPLOCALE)/g' \ - -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \ - -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \ - -e 's|@''REPLACE_LOCALECONV''@|$(REPLACE_LOCALECONV)|g' \ - -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \ - -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \ - -e 's|@''REPLACE_STRUCT_LCONV''@|$(REPLACE_STRUCT_LCONV)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/locale.in.h; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += locale.h locale.h-t - -EXTRA_DIST += locale.in.h - -## end gnulib module locale - -## begin gnulib module localeconv - - -EXTRA_DIST += localeconv.c - -EXTRA_libgnu_a_SOURCES += localeconv.c - -## end gnulib module localeconv - -## begin gnulib module malloc-gnu - - -EXTRA_DIST += malloc.c - -EXTRA_libgnu_a_SOURCES += malloc.c - -## end gnulib module malloc-gnu - -## begin gnulib module malloc-posix - - -EXTRA_DIST += malloc.c - -EXTRA_libgnu_a_SOURCES += malloc.c - -## end gnulib module malloc-posix - -## begin gnulib module mbrtowc - - -EXTRA_DIST += mbrtowc.c - -EXTRA_libgnu_a_SOURCES += mbrtowc.c - -## end gnulib module mbrtowc - -## begin gnulib module mbsinit - - -EXTRA_DIST += mbsinit.c - -EXTRA_libgnu_a_SOURCES += mbsinit.c - -## end gnulib module mbsinit - -## begin gnulib module mbsrtowcs - - -EXTRA_DIST += mbsrtowcs-impl.h mbsrtowcs-state.c mbsrtowcs.c - -EXTRA_libgnu_a_SOURCES += mbsrtowcs-state.c mbsrtowcs.c - -## end gnulib module mbsrtowcs - -## begin gnulib module mbswidth - -libgnu_a_SOURCES += mbswidth.h mbswidth.c - -## end gnulib module mbswidth - -## begin gnulib module mbtowc - - -EXTRA_DIST += mbtowc-impl.h mbtowc.c - -EXTRA_libgnu_a_SOURCES += mbtowc.c - -## end gnulib module mbtowc - -## begin gnulib module memchr - - -EXTRA_DIST += memchr.c memchr.valgrind - -EXTRA_libgnu_a_SOURCES += memchr.c - -## end gnulib module memchr - -## begin gnulib module mempcpy - - -EXTRA_DIST += mempcpy.c - -EXTRA_libgnu_a_SOURCES += mempcpy.c - -## end gnulib module mempcpy - -## begin gnulib module msvc-inval - - -EXTRA_DIST += msvc-inval.c msvc-inval.h - -EXTRA_libgnu_a_SOURCES += msvc-inval.c - -## end gnulib module msvc-inval - -## begin gnulib module msvc-nothrow - - -EXTRA_DIST += msvc-nothrow.c msvc-nothrow.h - -EXTRA_libgnu_a_SOURCES += msvc-nothrow.c - -## end gnulib module msvc-nothrow - -## begin gnulib module nl_langinfo - - -EXTRA_DIST += nl_langinfo.c - -EXTRA_libgnu_a_SOURCES += nl_langinfo.c - -## end gnulib module nl_langinfo - -## begin gnulib module progname - -libgnu_a_SOURCES += progname.h progname.c - -## end gnulib module progname - -## begin gnulib module rawmemchr - - -EXTRA_DIST += rawmemchr.c rawmemchr.valgrind - -EXTRA_libgnu_a_SOURCES += rawmemchr.c - -## end gnulib module rawmemchr - -## begin gnulib module realloc-posix - - -EXTRA_DIST += realloc.c - -EXTRA_libgnu_a_SOURCES += realloc.c - -## end gnulib module realloc-posix - -## begin gnulib module regex - - -EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c - -EXTRA_libgnu_a_SOURCES += regcomp.c regex.c regex_internal.c regexec.c - -## end gnulib module regex - -## begin gnulib module size_max - -libgnu_a_SOURCES += size_max.h - -## end gnulib module size_max - -## begin gnulib module sleep - - -EXTRA_DIST += sleep.c - -EXTRA_libgnu_a_SOURCES += sleep.c - -## end gnulib module sleep - -## begin gnulib module snippet/_Noreturn - -# Because this Makefile snippet defines a variable used by other -# gnulib Makefile snippets, it must be present in all Makefile.am that -# need it. This is ensured by the applicability 'all' defined above. - -_NORETURN_H=$(top_srcdir)/build-aux/snippet/_Noreturn.h - -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/_Noreturn.h - -## end gnulib module snippet/_Noreturn - -## begin gnulib module snippet/arg-nonnull - -# The BUILT_SOURCES created by this Makefile snippet are not used via #include -# statements but through direct file reference. Therefore this snippet must be -# present in all Makefile.am that need it. This is ensured by the applicability -# 'all' defined above. - -BUILT_SOURCES += arg-nonnull.h -# The arg-nonnull.h that gets inserted into generated .h files is the same as -# build-aux/snippet/arg-nonnull.h, except that it has the copyright header cut -# off. -arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h - $(AM_V_GEN)rm -f $@-t $@ && \ - sed -n -e '/GL_ARG_NONNULL/,$$p' \ - < $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ - > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t - -ARG_NONNULL_H=arg-nonnull.h - -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/arg-nonnull.h - -## end gnulib module snippet/arg-nonnull - -## begin gnulib module snippet/c++defs - -# The BUILT_SOURCES created by this Makefile snippet are not used via #include -# statements but through direct file reference. Therefore this snippet must be -# present in all Makefile.am that need it. This is ensured by the applicability -# 'all' defined above. - -BUILT_SOURCES += c++defs.h -# The c++defs.h that gets inserted into generated .h files is the same as -# build-aux/snippet/c++defs.h, except that it has the copyright header cut off. -c++defs.h: $(top_srcdir)/build-aux/snippet/c++defs.h - $(AM_V_GEN)rm -f $@-t $@ && \ - sed -n -e '/_GL_CXXDEFS/,$$p' \ - < $(top_srcdir)/build-aux/snippet/c++defs.h \ - > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += c++defs.h c++defs.h-t - -CXXDEFS_H=c++defs.h - -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/c++defs.h - -## end gnulib module snippet/c++defs - -## begin gnulib module snippet/warn-on-use - -BUILT_SOURCES += warn-on-use.h -# The warn-on-use.h that gets inserted into generated .h files is the same as -# build-aux/snippet/warn-on-use.h, except that it has the copyright header cut -# off. -warn-on-use.h: $(top_srcdir)/build-aux/snippet/warn-on-use.h - $(AM_V_GEN)rm -f $@-t $@ && \ - sed -n -e '/^.ifndef/,$$p' \ - < $(top_srcdir)/build-aux/snippet/warn-on-use.h \ - > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t - -WARN_ON_USE_H=warn-on-use.h - -EXTRA_DIST += $(top_srcdir)/build-aux/snippet/warn-on-use.h - -## end gnulib module snippet/warn-on-use - -## begin gnulib module stdalign - -BUILT_SOURCES += $(STDALIGN_H) - -# We need the following in order to create when the system -# doesn't have one that works. -if GL_GENERATE_STDALIGN_H -stdalign.h: stdalign.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/stdalign.in.h; \ - } > $@-t && \ - mv $@-t $@ -else -stdalign.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += stdalign.h stdalign.h-t - -EXTRA_DIST += stdalign.in.h - -## end gnulib module stdalign - -## begin gnulib module stdbool - -BUILT_SOURCES += $(STDBOOL_H) - -# We need the following in order to create when the system -# doesn't have one that works. -if GL_GENERATE_STDBOOL_H -stdbool.h: stdbool.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ - } > $@-t && \ - mv $@-t $@ -else -stdbool.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += stdbool.h stdbool.h-t - -EXTRA_DIST += stdbool.in.h - -## end gnulib module stdbool - -## begin gnulib module stddef - -BUILT_SOURCES += $(STDDEF_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -if GL_GENERATE_STDDEF_H -stddef.h: stddef.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ - -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ - -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ - < $(srcdir)/stddef.in.h; \ - } > $@-t && \ - mv $@-t $@ -else -stddef.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += stddef.h stddef.h-t - -EXTRA_DIST += stddef.in.h - -## end gnulib module stddef - -## begin gnulib module stdint - -BUILT_SOURCES += $(STDINT_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -if GL_GENERATE_STDINT_H -stdint.h: stdint.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ - -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ - -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ - -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ - -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ - -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ - -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ - -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ - -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ - -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ - -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ - -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ - -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ - -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ - -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ - -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ - -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ - -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ - < $(srcdir)/stdint.in.h; \ - } > $@-t && \ - mv $@-t $@ -else -stdint.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += stdint.h stdint.h-t - -EXTRA_DIST += stdint.in.h - -## end gnulib module stdint - -## begin gnulib module stdio - -BUILT_SOURCES += stdio.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ - -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \ - -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \ - -e 's/@''GNULIB_FDOPEN''@/$(GNULIB_FDOPEN)/g' \ - -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \ - -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \ - -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \ - -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \ - -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \ - -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \ - -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \ - -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \ - -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \ - -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \ - -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \ - -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \ - -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \ - -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \ - -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \ - -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \ - -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \ - -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \ - -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \ - -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \ - -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \ - -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \ - -e 's/@''GNULIB_PCLOSE''@/$(GNULIB_PCLOSE)/g' \ - -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \ - -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \ - -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \ - -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \ - -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \ - -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \ - -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \ - -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \ - -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \ - -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \ - -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \ - -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \ - -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \ - -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ - -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ - -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ - -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ - -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ - -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \ - -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \ - -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \ - -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ - -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ - -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ - < $(srcdir)/stdio.in.h | \ - sed -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ - -e 's|@''HAVE_DECL_FSEEKO''@|$(HAVE_DECL_FSEEKO)|g' \ - -e 's|@''HAVE_DECL_FTELLO''@|$(HAVE_DECL_FTELLO)|g' \ - -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \ - -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ - -e 's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \ - -e 's|@''HAVE_DECL_SNPRINTF''@|$(HAVE_DECL_SNPRINTF)|g' \ - -e 's|@''HAVE_DECL_VSNPRINTF''@|$(HAVE_DECL_VSNPRINTF)|g' \ - -e 's|@''HAVE_DPRINTF''@|$(HAVE_DPRINTF)|g' \ - -e 's|@''HAVE_FSEEKO''@|$(HAVE_FSEEKO)|g' \ - -e 's|@''HAVE_FTELLO''@|$(HAVE_FTELLO)|g' \ - -e 's|@''HAVE_PCLOSE''@|$(HAVE_PCLOSE)|g' \ - -e 's|@''HAVE_POPEN''@|$(HAVE_POPEN)|g' \ - -e 's|@''HAVE_RENAMEAT''@|$(HAVE_RENAMEAT)|g' \ - -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ - -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ - -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ - -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \ - -e 's|@''REPLACE_FDOPEN''@|$(REPLACE_FDOPEN)|g' \ - -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ - -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \ - -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ - -e 's|@''REPLACE_FPURGE''@|$(REPLACE_FPURGE)|g' \ - -e 's|@''REPLACE_FREOPEN''@|$(REPLACE_FREOPEN)|g' \ - -e 's|@''REPLACE_FSEEK''@|$(REPLACE_FSEEK)|g' \ - -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ - -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \ - -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ - -e 's|@''REPLACE_GETDELIM''@|$(REPLACE_GETDELIM)|g' \ - -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \ - -e 's|@''REPLACE_OBSTACK_PRINTF''@|$(REPLACE_OBSTACK_PRINTF)|g' \ - -e 's|@''REPLACE_PERROR''@|$(REPLACE_PERROR)|g' \ - -e 's|@''REPLACE_POPEN''@|$(REPLACE_POPEN)|g' \ - -e 's|@''REPLACE_PRINTF''@|$(REPLACE_PRINTF)|g' \ - -e 's|@''REPLACE_REMOVE''@|$(REPLACE_REMOVE)|g' \ - -e 's|@''REPLACE_RENAME''@|$(REPLACE_RENAME)|g' \ - -e 's|@''REPLACE_RENAMEAT''@|$(REPLACE_RENAMEAT)|g' \ - -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ - -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ - -e 's|@''REPLACE_STDIO_READ_FUNCS''@|$(REPLACE_STDIO_READ_FUNCS)|g' \ - -e 's|@''REPLACE_STDIO_WRITE_FUNCS''@|$(REPLACE_STDIO_WRITE_FUNCS)|g' \ - -e 's|@''REPLACE_TMPFILE''@|$(REPLACE_TMPFILE)|g' \ - -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ - -e 's|@''REPLACE_VDPRINTF''@|$(REPLACE_VDPRINTF)|g' \ - -e 's|@''REPLACE_VFPRINTF''@|$(REPLACE_VFPRINTF)|g' \ - -e 's|@''REPLACE_VPRINTF''@|$(REPLACE_VPRINTF)|g' \ - -e 's|@''REPLACE_VSNPRINTF''@|$(REPLACE_VSNPRINTF)|g' \ - -e 's|@''REPLACE_VSPRINTF''@|$(REPLACE_VSPRINTF)|g' \ - -e 's|@''ASM_SYMBOL_PREFIX''@|$(ASM_SYMBOL_PREFIX)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += stdio.h stdio.h-t - -EXTRA_DIST += stdio.in.h - -## end gnulib module stdio - -## begin gnulib module stdlib - -BUILT_SOURCES += stdlib.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ - $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ - -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ - -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ - -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ - -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ - -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ - -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ - -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ - -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ - -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ - -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ - -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ - -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ - -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ - -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ - -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \ - -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ - -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ - -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ - -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ - -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ - -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ - -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ - -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ - -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \ - -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ - -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ - -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ - -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ - -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ - -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ - -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ - -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ - < $(srcdir)/stdlib.in.h | \ - sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ - -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ - -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ - -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ - -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \ - -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \ - -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \ - -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \ - -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \ - -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \ - -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \ - -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \ - -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ - -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \ - -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \ - -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ - -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ - -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ - -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ - -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \ - -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \ - -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ - -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ - -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ - -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ - -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ - -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ - -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ - -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ - -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ - -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ - -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ - -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ - -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \ - -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ - -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ - -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ - -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ - -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ - -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ - -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ - -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ - -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _Noreturn/r $(_NORETURN_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += stdlib.h stdlib.h-t - -EXTRA_DIST += stdlib.in.h - -## end gnulib module stdlib - -## begin gnulib module strcase - - -EXTRA_DIST += strcasecmp.c strncasecmp.c - -EXTRA_libgnu_a_SOURCES += strcasecmp.c strncasecmp.c - -## end gnulib module strcase - -## begin gnulib module strchrnul - - -EXTRA_DIST += strchrnul.c strchrnul.valgrind - -EXTRA_libgnu_a_SOURCES += strchrnul.c - -## end gnulib module strchrnul - -## begin gnulib module streq - - -EXTRA_DIST += streq.h - -## end gnulib module streq - -## begin gnulib module strerror - - -EXTRA_DIST += strerror.c - -EXTRA_libgnu_a_SOURCES += strerror.c - -## end gnulib module strerror - -## begin gnulib module strerror-override - - -EXTRA_DIST += strerror-override.c strerror-override.h - -EXTRA_libgnu_a_SOURCES += strerror-override.c - -## end gnulib module strerror-override - -## begin gnulib module string - -BUILT_SOURCES += string.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ - -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \ - -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \ - -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \ - -e 's/@''GNULIB_MBSNLEN''@/$(GNULIB_MBSNLEN)/g' \ - -e 's/@''GNULIB_MBSCHR''@/$(GNULIB_MBSCHR)/g' \ - -e 's/@''GNULIB_MBSRCHR''@/$(GNULIB_MBSRCHR)/g' \ - -e 's/@''GNULIB_MBSSTR''@/$(GNULIB_MBSSTR)/g' \ - -e 's/@''GNULIB_MBSCASECMP''@/$(GNULIB_MBSCASECMP)/g' \ - -e 's/@''GNULIB_MBSNCASECMP''@/$(GNULIB_MBSNCASECMP)/g' \ - -e 's/@''GNULIB_MBSPCASECMP''@/$(GNULIB_MBSPCASECMP)/g' \ - -e 's/@''GNULIB_MBSCASESTR''@/$(GNULIB_MBSCASESTR)/g' \ - -e 's/@''GNULIB_MBSCSPN''@/$(GNULIB_MBSCSPN)/g' \ - -e 's/@''GNULIB_MBSPBRK''@/$(GNULIB_MBSPBRK)/g' \ - -e 's/@''GNULIB_MBSSPN''@/$(GNULIB_MBSSPN)/g' \ - -e 's/@''GNULIB_MBSSEP''@/$(GNULIB_MBSSEP)/g' \ - -e 's/@''GNULIB_MBSTOK_R''@/$(GNULIB_MBSTOK_R)/g' \ - -e 's/@''GNULIB_MEMCHR''@/$(GNULIB_MEMCHR)/g' \ - -e 's/@''GNULIB_MEMMEM''@/$(GNULIB_MEMMEM)/g' \ - -e 's/@''GNULIB_MEMPCPY''@/$(GNULIB_MEMPCPY)/g' \ - -e 's/@''GNULIB_MEMRCHR''@/$(GNULIB_MEMRCHR)/g' \ - -e 's/@''GNULIB_RAWMEMCHR''@/$(GNULIB_RAWMEMCHR)/g' \ - -e 's/@''GNULIB_STPCPY''@/$(GNULIB_STPCPY)/g' \ - -e 's/@''GNULIB_STPNCPY''@/$(GNULIB_STPNCPY)/g' \ - -e 's/@''GNULIB_STRCHRNUL''@/$(GNULIB_STRCHRNUL)/g' \ - -e 's/@''GNULIB_STRDUP''@/$(GNULIB_STRDUP)/g' \ - -e 's/@''GNULIB_STRNCAT''@/$(GNULIB_STRNCAT)/g' \ - -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \ - -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \ - -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \ - -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \ - -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \ - -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \ - -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \ - -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \ - -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \ - -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ - -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ - < $(srcdir)/string.in.h | \ - sed -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ - -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \ - -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ - -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \ - -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ - -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ - -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ - -e 's|@''HAVE_RAWMEMCHR''@|$(HAVE_RAWMEMCHR)|g' \ - -e 's|@''HAVE_STPCPY''@|$(HAVE_STPCPY)|g' \ - -e 's|@''HAVE_STPNCPY''@|$(HAVE_STPNCPY)|g' \ - -e 's|@''HAVE_STRCHRNUL''@|$(HAVE_STRCHRNUL)|g' \ - -e 's|@''HAVE_DECL_STRDUP''@|$(HAVE_DECL_STRDUP)|g' \ - -e 's|@''HAVE_DECL_STRNDUP''@|$(HAVE_DECL_STRNDUP)|g' \ - -e 's|@''HAVE_DECL_STRNLEN''@|$(HAVE_DECL_STRNLEN)|g' \ - -e 's|@''HAVE_STRPBRK''@|$(HAVE_STRPBRK)|g' \ - -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ - -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ - -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ - -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \ - -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ - -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ - -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ - -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ - -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ - -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ - -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ - -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ - -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ - -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ - -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ - -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ - -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ - -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ - -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ - -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ - -e 's|@''UNDEFINE_STRTOK_R''@|$(UNDEFINE_STRTOK_R)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - < $(srcdir)/string.in.h; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += string.h string.h-t - -EXTRA_DIST += string.in.h - -## end gnulib module string - -## begin gnulib module strings - -BUILT_SOURCES += strings.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_H)|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ - -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \ - -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ - -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ - -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/strings.in.h; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += strings.h strings.h-t - -EXTRA_DIST += strings.in.h - -## end gnulib module strings - -## begin gnulib module strndup - - -EXTRA_DIST += strndup.c - -EXTRA_libgnu_a_SOURCES += strndup.c - -## end gnulib module strndup - -## begin gnulib module strnlen - - -EXTRA_DIST += strnlen.c - -EXTRA_libgnu_a_SOURCES += strnlen.c - -## end gnulib module strnlen - -## begin gnulib module strnlen1 - -libgnu_a_SOURCES += strnlen1.h strnlen1.c - -## end gnulib module strnlen1 - -## begin gnulib module sys_types - -BUILT_SOURCES += sys/types.h - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -sys/types.h: sys_types.in.h $(top_builddir)/config.status - $(AM_V_at)$(MKDIR_P) sys - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \ - -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ - < $(srcdir)/sys_types.in.h; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += sys/types.h sys/types.h-t - -EXTRA_DIST += sys_types.in.h - -## end gnulib module sys_types - -## begin gnulib module sysexits - -BUILT_SOURCES += $(SYSEXITS_H) - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -if GL_GENERATE_SYSEXITS_H -sysexits.h: sysexits.in.h $(top_builddir)/config.status - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_H)|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \ - < $(srcdir)/sysexits.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -else -sysexits.h: $(top_builddir)/config.status - rm -f $@ -endif -MOSTLYCLEANFILES += sysexits.h sysexits.h-t - -EXTRA_DIST += sysexits.in.h - -## end gnulib module sysexits - -## begin gnulib module unistd - -BUILT_SOURCES += unistd.h -libgnu_a_SOURCES += unistd.c - -# We need the following in order to create an empty placeholder for -# when the system doesn't have one. -unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ - -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ - -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \ - -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ - -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ - -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \ - -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \ - -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ - -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ - -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \ - -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ - -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ - -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ - -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \ - -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \ - -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ - -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ - -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \ - -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \ - -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \ - -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \ - -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \ - -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \ - -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \ - -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \ - -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \ - -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \ - -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \ - -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \ - -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \ - -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \ - -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \ - -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \ - -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \ - -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \ - -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \ - -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \ - -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \ - -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \ - -e 's/@''GNULIB_SETHOSTNAME''@/$(GNULIB_SETHOSTNAME)/g' \ - -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \ - -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \ - -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \ - -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \ - -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_GL_UNISTD_H_GETOPT)/g' \ - -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \ - -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \ - -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \ - -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ - -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ - -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ - < $(srcdir)/unistd.in.h | \ - sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ - -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ - -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \ - -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \ - -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \ - -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \ - -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \ - -e 's|@''HAVE_FDATASYNC''@|$(HAVE_FDATASYNC)|g' \ - -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ - -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ - -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ - -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ - -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ - -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \ - -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ - -e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \ - -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \ - -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \ - -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \ - -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \ - -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \ - -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \ - -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \ - -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ - -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \ - -e 's|@''HAVE_SETHOSTNAME''@|$(HAVE_SETHOSTNAME)|g' \ - -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ - -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \ - -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \ - -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \ - -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \ - -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \ - -e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \ - -e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \ - -e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \ - -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \ - -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \ - -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \ - -e 's|@''HAVE_DECL_SETHOSTNAME''@|$(HAVE_DECL_SETHOSTNAME)|g' \ - -e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \ - -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \ - -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \ - | \ - sed -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ - -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ - -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ - -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ - -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ - -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ - -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ - -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ - -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ - -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ - -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ - -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \ - -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ - -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ - -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \ - -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ - -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \ - -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \ - -e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \ - -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \ - -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \ - -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ - -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \ - -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \ - -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \ - -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \ - -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \ - -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \ - -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \ - -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += unistd.h unistd.h-t - -EXTRA_DIST += unistd.in.h - -## end gnulib module unistd - -## begin gnulib module unitypes - -BUILT_SOURCES += $(LIBUNISTRING_UNITYPES_H) - -unitypes.h: unitypes.in.h - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/unitypes.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -MOSTLYCLEANFILES += unitypes.h unitypes.h-t - -EXTRA_DIST += unitypes.in.h - -## end gnulib module unitypes - -## begin gnulib module uniwidth/base - -BUILT_SOURCES += $(LIBUNISTRING_UNIWIDTH_H) - -uniwidth.h: uniwidth.in.h - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - cat $(srcdir)/uniwidth.in.h; \ - } > $@-t && \ - mv -f $@-t $@ -MOSTLYCLEANFILES += uniwidth.h uniwidth.h-t - -EXTRA_DIST += localcharset.h uniwidth.in.h - -## end gnulib module uniwidth/base - -## begin gnulib module uniwidth/width - -if LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH -libgnu_a_SOURCES += uniwidth/width.c -endif - -EXTRA_DIST += uniwidth/cjk.h - -## end gnulib module uniwidth/width - -## begin gnulib module vasnprintf - - -EXTRA_DIST += asnprintf.c float+.h printf-args.c printf-args.h printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h - -EXTRA_libgnu_a_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c - -## end gnulib module vasnprintf - -## begin gnulib module verify - - -EXTRA_DIST += verify.h - -## end gnulib module verify - -## begin gnulib module vsnprintf - - -EXTRA_DIST += vsnprintf.c - -EXTRA_libgnu_a_SOURCES += vsnprintf.c - -## end gnulib module vsnprintf - -## begin gnulib module wchar - -BUILT_SOURCES += wchar.h - -# We need the following in order to create when the system -# version does not work standalone. -wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ - -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ - -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ - -e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \ - -e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \ - -e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \ - -e 's/@''GNULIB_MBRTOWC''@/$(GNULIB_MBRTOWC)/g' \ - -e 's/@''GNULIB_MBRLEN''@/$(GNULIB_MBRLEN)/g' \ - -e 's/@''GNULIB_MBSRTOWCS''@/$(GNULIB_MBSRTOWCS)/g' \ - -e 's/@''GNULIB_MBSNRTOWCS''@/$(GNULIB_MBSNRTOWCS)/g' \ - -e 's/@''GNULIB_WCRTOMB''@/$(GNULIB_WCRTOMB)/g' \ - -e 's/@''GNULIB_WCSRTOMBS''@/$(GNULIB_WCSRTOMBS)/g' \ - -e 's/@''GNULIB_WCSNRTOMBS''@/$(GNULIB_WCSNRTOMBS)/g' \ - -e 's/@''GNULIB_WCWIDTH''@/$(GNULIB_WCWIDTH)/g' \ - -e 's/@''GNULIB_WMEMCHR''@/$(GNULIB_WMEMCHR)/g' \ - -e 's/@''GNULIB_WMEMCMP''@/$(GNULIB_WMEMCMP)/g' \ - -e 's/@''GNULIB_WMEMCPY''@/$(GNULIB_WMEMCPY)/g' \ - -e 's/@''GNULIB_WMEMMOVE''@/$(GNULIB_WMEMMOVE)/g' \ - -e 's/@''GNULIB_WMEMSET''@/$(GNULIB_WMEMSET)/g' \ - -e 's/@''GNULIB_WCSLEN''@/$(GNULIB_WCSLEN)/g' \ - -e 's/@''GNULIB_WCSNLEN''@/$(GNULIB_WCSNLEN)/g' \ - -e 's/@''GNULIB_WCSCPY''@/$(GNULIB_WCSCPY)/g' \ - -e 's/@''GNULIB_WCPCPY''@/$(GNULIB_WCPCPY)/g' \ - -e 's/@''GNULIB_WCSNCPY''@/$(GNULIB_WCSNCPY)/g' \ - -e 's/@''GNULIB_WCPNCPY''@/$(GNULIB_WCPNCPY)/g' \ - -e 's/@''GNULIB_WCSCAT''@/$(GNULIB_WCSCAT)/g' \ - -e 's/@''GNULIB_WCSNCAT''@/$(GNULIB_WCSNCAT)/g' \ - -e 's/@''GNULIB_WCSCMP''@/$(GNULIB_WCSCMP)/g' \ - -e 's/@''GNULIB_WCSNCMP''@/$(GNULIB_WCSNCMP)/g' \ - -e 's/@''GNULIB_WCSCASECMP''@/$(GNULIB_WCSCASECMP)/g' \ - -e 's/@''GNULIB_WCSNCASECMP''@/$(GNULIB_WCSNCASECMP)/g' \ - -e 's/@''GNULIB_WCSCOLL''@/$(GNULIB_WCSCOLL)/g' \ - -e 's/@''GNULIB_WCSXFRM''@/$(GNULIB_WCSXFRM)/g' \ - -e 's/@''GNULIB_WCSDUP''@/$(GNULIB_WCSDUP)/g' \ - -e 's/@''GNULIB_WCSCHR''@/$(GNULIB_WCSCHR)/g' \ - -e 's/@''GNULIB_WCSRCHR''@/$(GNULIB_WCSRCHR)/g' \ - -e 's/@''GNULIB_WCSCSPN''@/$(GNULIB_WCSCSPN)/g' \ - -e 's/@''GNULIB_WCSSPN''@/$(GNULIB_WCSSPN)/g' \ - -e 's/@''GNULIB_WCSPBRK''@/$(GNULIB_WCSPBRK)/g' \ - -e 's/@''GNULIB_WCSSTR''@/$(GNULIB_WCSSTR)/g' \ - -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ - -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ - < $(srcdir)/wchar.in.h | \ - sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ - -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \ - -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \ - -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \ - -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \ - -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \ - -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \ - -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \ - -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \ - -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \ - -e 's|@''HAVE_WMEMCHR''@|$(HAVE_WMEMCHR)|g' \ - -e 's|@''HAVE_WMEMCMP''@|$(HAVE_WMEMCMP)|g' \ - -e 's|@''HAVE_WMEMCPY''@|$(HAVE_WMEMCPY)|g' \ - -e 's|@''HAVE_WMEMMOVE''@|$(HAVE_WMEMMOVE)|g' \ - -e 's|@''HAVE_WMEMSET''@|$(HAVE_WMEMSET)|g' \ - -e 's|@''HAVE_WCSLEN''@|$(HAVE_WCSLEN)|g' \ - -e 's|@''HAVE_WCSNLEN''@|$(HAVE_WCSNLEN)|g' \ - -e 's|@''HAVE_WCSCPY''@|$(HAVE_WCSCPY)|g' \ - -e 's|@''HAVE_WCPCPY''@|$(HAVE_WCPCPY)|g' \ - -e 's|@''HAVE_WCSNCPY''@|$(HAVE_WCSNCPY)|g' \ - -e 's|@''HAVE_WCPNCPY''@|$(HAVE_WCPNCPY)|g' \ - -e 's|@''HAVE_WCSCAT''@|$(HAVE_WCSCAT)|g' \ - -e 's|@''HAVE_WCSNCAT''@|$(HAVE_WCSNCAT)|g' \ - -e 's|@''HAVE_WCSCMP''@|$(HAVE_WCSCMP)|g' \ - -e 's|@''HAVE_WCSNCMP''@|$(HAVE_WCSNCMP)|g' \ - -e 's|@''HAVE_WCSCASECMP''@|$(HAVE_WCSCASECMP)|g' \ - -e 's|@''HAVE_WCSNCASECMP''@|$(HAVE_WCSNCASECMP)|g' \ - -e 's|@''HAVE_WCSCOLL''@|$(HAVE_WCSCOLL)|g' \ - -e 's|@''HAVE_WCSXFRM''@|$(HAVE_WCSXFRM)|g' \ - -e 's|@''HAVE_WCSDUP''@|$(HAVE_WCSDUP)|g' \ - -e 's|@''HAVE_WCSCHR''@|$(HAVE_WCSCHR)|g' \ - -e 's|@''HAVE_WCSRCHR''@|$(HAVE_WCSRCHR)|g' \ - -e 's|@''HAVE_WCSCSPN''@|$(HAVE_WCSCSPN)|g' \ - -e 's|@''HAVE_WCSSPN''@|$(HAVE_WCSSPN)|g' \ - -e 's|@''HAVE_WCSPBRK''@|$(HAVE_WCSPBRK)|g' \ - -e 's|@''HAVE_WCSSTR''@|$(HAVE_WCSSTR)|g' \ - -e 's|@''HAVE_WCSTOK''@|$(HAVE_WCSTOK)|g' \ - -e 's|@''HAVE_WCSWIDTH''@|$(HAVE_WCSWIDTH)|g' \ - -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \ - -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ - | \ - sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ - -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \ - -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \ - -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \ - -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \ - -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \ - -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \ - -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \ - -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \ - -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ - -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \ - -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ - -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += wchar.h wchar.h-t - -EXTRA_DIST += wchar.in.h - -## end gnulib module wchar - -## begin gnulib module wcrtomb - - -EXTRA_DIST += wcrtomb.c - -EXTRA_libgnu_a_SOURCES += wcrtomb.c - -## end gnulib module wcrtomb - -## begin gnulib module wctype-h - -BUILT_SOURCES += wctype.h -libgnu_a_SOURCES += wctype-h.c - -# We need the following in order to create when the system -# doesn't have one that works with the given compiler. -wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) - $(AM_V_GEN)rm -f $@-t $@ && \ - { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ - sed -e 's|@''GUARD_PREFIX''@|GL|g' \ - -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ - -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ - -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ - -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ - -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ - -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ - -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ - -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ - -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ - -e 's/@''GNULIB_TOWCTRANS''@/$(GNULIB_TOWCTRANS)/g' \ - -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \ - -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ - -e 's/@''HAVE_WCTYPE_T''@/$(HAVE_WCTYPE_T)/g' \ - -e 's/@''HAVE_WCTRANS_T''@/$(HAVE_WCTRANS_T)/g' \ - -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ - -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \ - -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ - -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ - -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ - -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ - < $(srcdir)/wctype.in.h; \ - } > $@-t && \ - mv $@-t $@ -MOSTLYCLEANFILES += wctype.h wctype.h-t - -EXTRA_DIST += wctype.in.h - -## end gnulib module wctype-h - -## begin gnulib module wcwidth - - -EXTRA_DIST += wcwidth.c - -EXTRA_libgnu_a_SOURCES += wcwidth.c - -## end gnulib module wcwidth - -## begin gnulib module xsize - -libgnu_a_SOURCES += xsize.h xsize.c - -## end gnulib module xsize - - -mostlyclean-local: mostlyclean-generic - @for dir in '' $(MOSTLYCLEANDIRS); do \ - if test -n "$$dir" && test -d $$dir; then \ - echo "rmdir $$dir"; rmdir $$dir; \ - fi; \ - done; \ - : diff --git a/grub-core/gnulib/alloca.c b/grub-core/gnulib/alloca.c deleted file mode 100644 index ee0f01886..000000000 --- a/grub-core/gnulib/alloca.c +++ /dev/null @@ -1,478 +0,0 @@ -/* alloca.c -- allocate automatically reclaimed memory - (Mostly) portable public-domain implementation -- D A Gwyn - - This implementation of the PWB library alloca function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - J.Otto Tennant contributed the Cray support. - - There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. */ - -#include - -#include - -#include -#include - -#ifdef emacs -# include "lisp.h" -# include "blockinput.h" -# ifdef EMACS_FREE -# undef free -# define free EMACS_FREE -# endif -#else -# define memory_full() abort () -#endif - -/* If compiling with GCC 2, this file's not needed. */ -#if !defined (__GNUC__) || __GNUC__ < 2 - -/* If someone has defined alloca as a macro, - there must be some other way alloca is supposed to work. */ -# ifndef alloca - -# ifdef emacs -# ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -# ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -/* Using #error here is not wise since this file should work for - old and obscure compilers. */ -# endif /* STACK_DIRECTION undefined */ -# endif /* static */ -# endif /* emacs */ - -/* If your stack is a linked list of frames, you have to - provide an "address metric" ADDRESS_FUNCTION macro. */ - -# if defined (CRAY) && defined (CRAY_STACKSEG_END) -long i00afunc (); -# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) -# else -# define ADDRESS_FUNCTION(arg) &(arg) -# endif - -/* Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ - -# ifndef STACK_DIRECTION -# define STACK_DIRECTION 0 /* Direction unknown. */ -# endif - -# if STACK_DIRECTION != 0 - -# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ - -# else /* STACK_DIRECTION == 0; need run-time code. */ - -static int stack_dir; /* 1 or -1 once known. */ -# define STACK_DIR stack_dir - -static int -find_stack_direction (int *addr, int depth) -{ - int dir, dummy = 0; - if (! addr) - addr = &dummy; - *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; - dir = depth ? find_stack_direction (addr, depth - 1) : 0; - return dir + dummy; -} - -# endif /* STACK_DIRECTION == 0 */ - -/* An "alloca header" is used to: - (a) chain together all alloca'ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc - alignment chunk size. The following default should work okay. */ - -# ifndef ALIGN_SIZE -# define ALIGN_SIZE sizeof(double) -# endif - -typedef union hdr -{ - char align[ALIGN_SIZE]; /* To force sizeof(header). */ - struct - { - union hdr *next; /* For chaining headers. */ - char *deep; /* For stack depth measure. */ - } h; -} header; - -static header *last_alloca_header = NULL; /* -> last alloca header. */ - -/* Return a pointer to at least SIZE bytes of storage, - which will be automatically reclaimed upon exit from - the procedure that called alloca. Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. */ - -void * -alloca (size_t size) -{ - auto char probe; /* Probes stack depth: */ - register char *depth = ADDRESS_FUNCTION (probe); - -# if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* Unknown growth direction. */ - STACK_DIR = find_stack_direction (NULL, (size & 1) + 20); -# endif - - /* Reclaim garbage, defined as all alloca'd storage that - was allocated from deeper in the stack than currently. */ - - { - register header *hp; /* Traverses linked list. */ - -# ifdef emacs - BLOCK_INPUT; -# endif - - for (hp = last_alloca_header; hp != NULL;) - if ((STACK_DIR > 0 && hp->h.deep > depth) - || (STACK_DIR < 0 && hp->h.deep < depth)) - { - register header *np = hp->h.next; - - free (hp); /* Collect garbage. */ - - hp = np; /* -> next header. */ - } - else - break; /* Rest are not deeper. */ - - last_alloca_header = hp; /* -> last valid storage. */ - -# ifdef emacs - UNBLOCK_INPUT; -# endif - } - - if (size == 0) - return NULL; /* No allocation required. */ - - /* Allocate combined header + user data storage. */ - - { - /* Address of header. */ - register header *new; - - size_t combined_size = sizeof (header) + size; - if (combined_size < sizeof (header)) - memory_full (); - - new = malloc (combined_size); - - if (! new) - memory_full (); - - new->h.next = last_alloca_header; - new->h.deep = depth; - - last_alloca_header = new; - - /* User storage begins just after header. */ - - return (void *) (new + 1); - } -} - -# if defined (CRAY) && defined (CRAY_STACKSEG_END) - -# ifdef DEBUG_I00AFUNC -# include -# endif - -# ifndef CRAY_STACK -# define CRAY_STACK -# ifndef CRAY2 -/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ -struct stack_control_header - { - long shgrow:32; /* Number of times stack has grown. */ - long shaseg:32; /* Size of increments to stack. */ - long shhwm:32; /* High water mark of stack. */ - long shsize:32; /* Current size of stack (all segments). */ - }; - -/* The stack segment linkage control information occurs at - the high-address end of a stack segment. (The stack - grows from low addresses to high addresses.) The initial - part of the stack segment linkage control information is - 0200 (octal) words. This provides for register storage - for the routine which overflows the stack. */ - -struct stack_segment_linkage - { - long ss[0200]; /* 0200 overflow words. */ - long sssize:32; /* Number of words in this segment. */ - long ssbase:32; /* Offset to stack base. */ - long:32; - long sspseg:32; /* Offset to linkage control of previous - segment of stack. */ - long:32; - long sstcpt:32; /* Pointer to task common address block. */ - long sscsnm; /* Private control structure number for - microtasking. */ - long ssusr1; /* Reserved for user. */ - long ssusr2; /* Reserved for user. */ - long sstpid; /* Process ID for pid based multi-tasking. */ - long ssgvup; /* Pointer to multitasking thread giveup. */ - long sscray[7]; /* Reserved for Cray Research. */ - long ssa0; - long ssa1; - long ssa2; - long ssa3; - long ssa4; - long ssa5; - long ssa6; - long ssa7; - long sss0; - long sss1; - long sss2; - long sss3; - long sss4; - long sss5; - long sss6; - long sss7; - }; - -# else /* CRAY2 */ -/* The following structure defines the vector of words - returned by the STKSTAT library routine. */ -struct stk_stat - { - long now; /* Current total stack size. */ - long maxc; /* Amount of contiguous space which would - be required to satisfy the maximum - stack demand to date. */ - long high_water; /* Stack high-water mark. */ - long overflows; /* Number of stack overflow ($STKOFEN) calls. */ - long hits; /* Number of internal buffer hits. */ - long extends; /* Number of block extensions. */ - long stko_mallocs; /* Block allocations by $STKOFEN. */ - long underflows; /* Number of stack underflow calls ($STKRETN). */ - long stko_free; /* Number of deallocations by $STKRETN. */ - long stkm_free; /* Number of deallocations by $STKMRET. */ - long segments; /* Current number of stack segments. */ - long maxs; /* Maximum number of stack segments so far. */ - long pad_size; /* Stack pad size. */ - long current_address; /* Current stack segment address. */ - long current_size; /* Current stack segment size. This - number is actually corrupted by STKSTAT to - include the fifteen word trailer area. */ - long initial_address; /* Address of initial segment. */ - long initial_size; /* Size of initial segment. */ - }; - -/* The following structure describes the data structure which trails - any stack segment. I think that the description in 'asdef' is - out of date. I only describe the parts that I am sure about. */ - -struct stk_trailer - { - long this_address; /* Address of this block. */ - long this_size; /* Size of this block (does not include - this trailer). */ - long unknown2; - long unknown3; - long link; /* Address of trailer block of previous - segment. */ - long unknown5; - long unknown6; - long unknown7; - long unknown8; - long unknown9; - long unknown10; - long unknown11; - long unknown12; - long unknown13; - long unknown14; - }; - -# endif /* CRAY2 */ -# endif /* not CRAY_STACK */ - -# ifdef CRAY2 -/* Determine a "stack measure" for an arbitrary ADDRESS. - I doubt that "lint" will like this much. */ - -static long -i00afunc (long *address) -{ - struct stk_stat status; - struct stk_trailer *trailer; - long *block, size; - long result = 0; - - /* We want to iterate through all of the segments. The first - step is to get the stack status structure. We could do this - more quickly and more directly, perhaps, by referencing the - $LM00 common block, but I know that this works. */ - - STKSTAT (&status); - - /* Set up the iteration. */ - - trailer = (struct stk_trailer *) (status.current_address - + status.current_size - - 15); - - /* There must be at least one stack segment. Therefore it is - a fatal error if "trailer" is null. */ - - if (trailer == 0) - abort (); - - /* Discard segments that do not contain our argument address. */ - - while (trailer != 0) - { - block = (long *) trailer->this_address; - size = trailer->this_size; - if (block == 0 || size == 0) - abort (); - trailer = (struct stk_trailer *) trailer->link; - if ((block <= address) && (address < (block + size))) - break; - } - - /* Set the result to the offset in this segment and add the sizes - of all predecessor segments. */ - - result = address - block; - - if (trailer == 0) - { - return result; - } - - do - { - if (trailer->this_size <= 0) - abort (); - result += trailer->this_size; - trailer = (struct stk_trailer *) trailer->link; - } - while (trailer != 0); - - /* We are done. Note that if you present a bogus address (one - not in any segment), you will get a different number back, formed - from subtracting the address of the first block. This is probably - not what you want. */ - - return (result); -} - -# else /* not CRAY2 */ -/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. - Determine the number of the cell within the stack, - given the address of the cell. The purpose of this - routine is to linearize, in some sense, stack addresses - for alloca. */ - -static long -i00afunc (long address) -{ - long stkl = 0; - - long size, pseg, this_segment, stack; - long result = 0; - - struct stack_segment_linkage *ssptr; - - /* Register B67 contains the address of the end of the - current stack segment. If you (as a subprogram) store - your registers on the stack and find that you are past - the contents of B67, you have overflowed the segment. - - B67 also points to the stack segment linkage control - area, which is what we are really interested in. */ - - stkl = CRAY_STACKSEG_END (); - ssptr = (struct stack_segment_linkage *) stkl; - - /* If one subtracts 'size' from the end of the segment, - one has the address of the first word of the segment. - - If this is not the first segment, 'pseg' will be - nonzero. */ - - pseg = ssptr->sspseg; - size = ssptr->sssize; - - this_segment = stkl - size; - - /* It is possible that calling this routine itself caused - a stack overflow. Discard stack segments which do not - contain the target address. */ - - while (!(this_segment <= address && address <= stkl)) - { -# ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); -# endif - if (pseg == 0) - break; - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - this_segment = stkl - size; - } - - result = address - this_segment; - - /* If you subtract pseg from the current end of the stack, - you get the address of the previous stack segment's end. - This seems a little convoluted to me, but I'll bet you save - a cycle somewhere. */ - - while (pseg != 0) - { -# ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o\n", pseg, size); -# endif - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - result += size; - } - return (result); -} - -# endif /* not CRAY2 */ -# endif /* CRAY */ - -# endif /* no alloca */ -#endif /* not GCC 2 */ diff --git a/grub-core/gnulib/alloca.in.h b/grub-core/gnulib/alloca.in.h deleted file mode 100644 index 72d28ee30..000000000 --- a/grub-core/gnulib/alloca.in.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Memory allocation on the stack. - - Copyright (C) 1995, 1999, 2001-2004, 2006-2013 Free Software Foundation, - Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, 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 - . - */ - -/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H - means there is a real alloca function. */ -#ifndef _GL_ALLOCA_H -#define _GL_ALLOCA_H - -/* alloca (N) returns a pointer to N bytes of memory - allocated on the stack, which will last until the function returns. - Use of alloca should be avoided: - - inside arguments of function calls - undefined behaviour, - - in inline functions - the allocation may actually last until the - calling function returns, - - for huge N (say, N >= 65536) - you never know how large (or small) - the stack is, and when the stack cannot fulfill the memory allocation - request, the program just crashes. - */ - -#ifndef alloca -# ifdef __GNUC__ -# define alloca __builtin_alloca -# elif defined _AIX -# define alloca __alloca -# elif defined _MSC_VER -# include -# define alloca _alloca -# elif defined __DECC && defined __VMS -# define alloca __ALLOCA -# elif defined __TANDEM && defined _TNS_E_TARGET -# ifdef __cplusplus -extern "C" -# endif -void *_alloca (unsigned short); -# pragma intrinsic (_alloca) -# define alloca _alloca -# else -# include -# ifdef __cplusplus -extern "C" -# endif -void *alloca (size_t); -# endif -#endif - -#endif /* _GL_ALLOCA_H */ diff --git a/grub-core/gnulib/argp-ba.c b/grub-core/gnulib/argp-ba.c deleted file mode 100644 index 5abc9d00a..000000000 --- a/grub-core/gnulib/argp-ba.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Default definition for ARGP_PROGRAM_BUG_ADDRESS. - Copyright (C) 1996-1997, 1999, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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 . */ - -/* If set by the user program, it should point to string that is the - bug-reporting address for the program. It will be printed by argp_help if - the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help - messages), embedded in a sentence that says something like "Report bugs to - ADDR." */ -const char *argp_program_bug_address -/* This variable should be zero-initialized. On most systems, putting it into - BSS is sufficient. Not so on Mac OS X 10.3 and 10.4, see - - . */ -#if defined __ELF__ - /* On ELF systems, variables in BSS behave well. */ -#else - = (const char *) 0 -#endif - ; diff --git a/grub-core/gnulib/argp-eexst.c b/grub-core/gnulib/argp-eexst.c deleted file mode 100644 index a8bb77fcf..000000000 --- a/grub-core/gnulib/argp-eexst.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Default definition for ARGP_ERR_EXIT_STATUS - Copyright (C) 1997, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include "argp.h" - -/* The exit status that argp will use when exiting due to a parsing error. - If not defined or set by the user program, this defaults to EX_USAGE from - . */ -error_t argp_err_exit_status = EX_USAGE; diff --git a/grub-core/gnulib/argp-fmtstream.c b/grub-core/gnulib/argp-fmtstream.c deleted file mode 100644 index 02406ff2a..000000000 --- a/grub-core/gnulib/argp-fmtstream.c +++ /dev/null @@ -1,488 +0,0 @@ -/* Word-wrapping and line-truncating streams - Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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 . */ - -/* This package emulates glibc 'line_wrap_stream' semantics for systems that - don't have that. */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#include "argp-fmtstream.h" -#include "argp-namefrob.h" -#include "mbswidth.h" - -#ifndef ARGP_FMTSTREAM_USE_LINEWRAP - -#ifndef isblank -#define isblank(ch) ((ch)==' ' || (ch)=='\t') -#endif - -#if defined _LIBC && defined USE_IN_LIBIO -# include -# include -# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) -#endif - -#define INIT_BUF_SIZE 200 -#define PRINTF_SIZE_GUESS 150 - -/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines - written on it with LMARGIN spaces and limits them to RMARGIN columns - total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by - replacing the whitespace before them with a newline and WMARGIN spaces. - Otherwise, chars beyond RMARGIN are simply dropped until a newline. - Returns NULL if there was an error. */ -argp_fmtstream_t -__argp_make_fmtstream (FILE *stream, - size_t lmargin, size_t rmargin, ssize_t wmargin) -{ - argp_fmtstream_t fs; - - fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream)); - if (fs != NULL) - { - fs->stream = stream; - - fs->lmargin = lmargin; - fs->rmargin = rmargin; - fs->wmargin = wmargin; - fs->point_col = 0; - fs->point_offs = 0; - - fs->buf = (char *) malloc (INIT_BUF_SIZE); - if (! fs->buf) - { - free (fs); - fs = 0; - } - else - { - fs->p = fs->buf; - fs->end = fs->buf + INIT_BUF_SIZE; - } - } - - return fs; -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_make_fmtstream, argp_make_fmtstream) -#endif -#endif - -/* Flush FS to its stream, and free it (but don't close the stream). */ -void -__argp_fmtstream_free (argp_fmtstream_t fs) -{ - __argp_fmtstream_update (fs); - if (fs->p > fs->buf) - { -#ifdef USE_IN_LIBIO - __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); -#else - fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); -#endif - } - free (fs->buf); - free (fs); -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_fmtstream_free, argp_fmtstream_free) -#endif -#endif - - -/* Return the pointer to the first character that doesn't fit in l columns. */ -static inline const ptrdiff_t -add_width (const char *ptr, const char *end, size_t l) -{ - mbstate_t ps; - const char *ptr0 = ptr; - - memset (&ps, 0, sizeof (ps)); - - while (ptr < end) - { - wchar_t wc; - size_t s, k; - - s = mbrtowc (&wc, ptr, end - ptr, &ps); - if (s == (size_t) -1) - break; - if (s == (size_t) -2) - { - if (1 >= l) - break; - l--; - ptr++; - continue; - } - - if (wc == '\e' && ptr + 3 < end - && ptr[1] == '[' && (ptr[2] == '0' || ptr[2] == '1') - && ptr[3] == 'm') - { - ptr += 4; - continue; - } - - k = wcwidth (wc); - - if (k >= l) - break; - l -= k; - ptr += s; - } - return ptr - ptr0; -} - -/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the - end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ -void -__argp_fmtstream_update (argp_fmtstream_t fs) -{ - char *buf, *nl; - size_t len; - - /* Scan the buffer for newlines. */ - buf = fs->buf + fs->point_offs; - while (buf < fs->p) - { - size_t r; - - if (fs->point_col == 0 && fs->lmargin != 0) - { - /* We are starting a new line. Print spaces to the left margin. */ - const size_t pad = fs->lmargin; - if (fs->p + pad < fs->end) - { - /* We can fit in them in the buffer by moving the - buffer text up and filling in the beginning. */ - memmove (buf + pad, buf, fs->p - buf); - fs->p += pad; /* Compensate for bigger buffer. */ - memset (buf, ' ', pad); /* Fill in the spaces. */ - buf += pad; /* Don't bother searching them. */ - } - else - { - /* No buffer space for spaces. Must flush. */ - size_t i; - for (i = 0; i < pad; i++) - { -#ifdef USE_IN_LIBIO - if (_IO_fwide (fs->stream, 0) > 0) - putwc_unlocked (L' ', fs->stream); - else -#endif - putc_unlocked (' ', fs->stream); - } - } - fs->point_col = pad; - } - - len = fs->p - buf; - nl = memchr (buf, '\n', len); - - if (fs->point_col < 0) - fs->point_col = 0; - - if (!nl) - { - size_t display_width = mbsnwidth (buf, fs->p - buf, MBSW_STOP_AT_NUL); - /* The buffer ends in a partial line. */ - - if (fs->point_col + display_width < fs->rmargin) - { - /* The remaining buffer text is a partial line and fits - within the maximum line width. Advance point for the - characters to be written and stop scanning. */ - fs->point_col += display_width; - break; - } - else - /* Set the end-of-line pointer for the code below to - the end of the buffer. */ - nl = fs->p; - } - else - { - size_t display_width = mbsnwidth (buf, nl - buf, MBSW_STOP_AT_NUL); - if (display_width < (ssize_t) fs->rmargin) - { - /* The buffer contains a full line that fits within the maximum - line width. Reset point and scan the next line. */ - fs->point_col = 0; - buf = nl + 1; - continue; - } - } - - /* This line is too long. */ - r = fs->rmargin - 1; - - if (fs->wmargin < 0) - { - /* Truncate the line by overwriting the excess with the - newline and anything after it in the buffer. */ - if (nl < fs->p) - { - memmove (buf + (r - fs->point_col), nl, fs->p - nl); - fs->p -= buf + (r - fs->point_col) - nl; - /* Reset point for the next line and start scanning it. */ - fs->point_col = 0; - buf += r + 1; /* Skip full line plus \n. */ - } - else - { - /* The buffer ends with a partial line that is beyond the - maximum line width. Advance point for the characters - written, and discard those past the max from the buffer. */ - fs->point_col += len; - fs->p -= fs->point_col - r; - break; - } - } - else - { - /* Do word wrap. Go to the column just past the maximum line - width and scan back for the beginning of the word there. - Then insert a line break. */ - - char *p, *nextline; - int i; - - p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); - while (p >= buf && !isblank ((unsigned char) *p)) - --p; - nextline = p + 1; /* This will begin the next line. */ - - if (nextline > buf) - { - /* Swallow separating blanks. */ - if (p >= buf) - do - --p; - while (p >= buf && isblank ((unsigned char) *p)); - nl = p + 1; /* The newline will replace the first blank. */ - } - else - { - /* A single word that is greater than the maximum line width. - Oh well. Put it on an overlong line by itself. */ - p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); - /* Find the end of the long word. */ - if (p < nl) - do - ++p; - while (p < nl && !isblank ((unsigned char) *p)); - if (p == nl) - { - /* It already ends a line. No fussing required. */ - fs->point_col = 0; - buf = nl + 1; - continue; - } - /* We will move the newline to replace the first blank. */ - nl = p; - /* Swallow separating blanks. */ - do - ++p; - while (isblank ((unsigned char) *p)); - /* The next line will start here. */ - nextline = p; - } - - /* Note: There are a bunch of tests below for - NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall - at the end of the buffer, and NEXTLINE is in fact empty (and so - we need not be careful to maintain its contents). */ - - if ((nextline == buf + len + 1 - ? fs->end - nl < fs->wmargin + 1 - : nextline - (nl + 1) < fs->wmargin) - && fs->p > nextline) - { - /* The margin needs more blanks than we removed. */ - if (mbsnwidth (fs->p, fs->end - fs->p, MBSW_STOP_AT_NUL) - > fs->wmargin + 1) - /* Make some space for them. */ - { - size_t mv = fs->p - nextline; - memmove (nl + 1 + fs->wmargin, nextline, mv); - nextline = nl + 1 + fs->wmargin; - len = nextline + mv - buf; - *nl++ = '\n'; - } - else - /* Output the first line so we can use the space. */ - { -#ifdef _LIBC - __fxprintf (fs->stream, "%.*s\n", - (int) (nl - fs->buf), fs->buf); -#else - if (nl > fs->buf) - fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream); - putc_unlocked ('\n', fs->stream); -#endif - - len += buf - fs->buf; - nl = buf = fs->buf; - } - } - else - /* We can fit the newline and blanks in before - the next word. */ - *nl++ = '\n'; - - if (nextline - nl >= fs->wmargin - || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin)) - /* Add blanks up to the wrap margin column. */ - for (i = 0; i < fs->wmargin; ++i) - *nl++ = ' '; - else - for (i = 0; i < fs->wmargin; ++i) -#ifdef USE_IN_LIBIO - if (_IO_fwide (fs->stream, 0) > 0) - putwc_unlocked (L' ', fs->stream); - else -#endif - putc_unlocked (' ', fs->stream); - - /* Copy the tail of the original buffer into the current buffer - position. */ - if (nl < nextline) - memmove (nl, nextline, buf + len - nextline); - len -= nextline - buf; - - /* Continue the scan on the remaining lines in the buffer. */ - buf = nl; - - /* Restore bufp to include all the remaining text. */ - fs->p = nl + len; - - /* Reset the counter of what has been output this line. If wmargin - is 0, we want to avoid the lmargin getting added, so we set - point_col to a magic value of -1 in that case. */ - fs->point_col = fs->wmargin ? fs->wmargin : -1; - } - } - - /* Remember that we've scanned as far as the end of the buffer. */ - fs->point_offs = fs->p - fs->buf; -} - -/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by - growing the buffer, or by flushing it. True is returned iff we succeed. */ -int -__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) -{ - if ((size_t) (fs->end - fs->p) < amount) - { - ssize_t wrote; - - /* Flush FS's buffer. */ - __argp_fmtstream_update (fs); - -#ifdef _LIBC - __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); - wrote = fs->p - fs->buf; -#else - wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); -#endif - if (wrote == fs->p - fs->buf) - { - fs->p = fs->buf; - fs->point_offs = 0; - } - else - { - fs->p -= wrote; - fs->point_offs -= wrote; - memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf); - return 0; - } - - if ((size_t) (fs->end - fs->buf) < amount) - /* Gotta grow the buffer. */ - { - size_t old_size = fs->end - fs->buf; - size_t new_size = old_size + amount; - char *new_buf; - - if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size))) - { - __set_errno (ENOMEM); - return 0; - } - - fs->buf = new_buf; - fs->end = new_buf + new_size; - fs->p = fs->buf; - } - } - - return 1; -} - -ssize_t -__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) -{ - int out; - size_t avail; - size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ - - do - { - va_list args; - - if (! __argp_fmtstream_ensure (fs, size_guess)) - return -1; - - va_start (args, fmt); - avail = fs->end - fs->p; - out = __vsnprintf (fs->p, avail, fmt, args); - va_end (args); - if ((size_t) out >= avail) - size_guess = out + 1; - } - while ((size_t) out >= avail); - - fs->p += out; - - return out; -} -#if 0 -/* Not exported. */ -#ifdef weak_alias -weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) -#endif -#endif - -#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ diff --git a/grub-core/gnulib/argp-fmtstream.h b/grub-core/gnulib/argp-fmtstream.h deleted file mode 100644 index 000090ea6..000000000 --- a/grub-core/gnulib/argp-fmtstream.h +++ /dev/null @@ -1,359 +0,0 @@ -/* Word-wrapping and line-truncating streams. - Copyright (C) 1997, 2006-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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 . */ - -/* This package emulates glibc 'line_wrap_stream' semantics for systems that - don't have that. If the system does have it, it is just a wrapper for - that. This header file is only used internally while compiling argp, and - shouldn't be installed. */ - -#ifndef _ARGP_FMTSTREAM_H -#define _ARGP_FMTSTREAM_H - -#include -#include -#include - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The __-protected variants of the attributes 'format' and 'printf' are - accepted by gcc versions 2.6.4 (effectively 2.7) and later. - We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because - gnulib and libintl do '#define printf __printf__' when they override - the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -#else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ -#endif - -#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ - || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)) -/* line_wrap_stream is available, so use that. */ -#define ARGP_FMTSTREAM_USE_LINEWRAP -#endif - -#ifdef ARGP_FMTSTREAM_USE_LINEWRAP -/* Just be a simple wrapper for line_wrap_stream; the semantics are - *slightly* different, as line_wrap_stream doesn't actually make a new - object, it just modifies the given stream (reversibly) to do - line-wrapping. Since we control who uses this code, it doesn't matter. */ - -#include - -typedef FILE *argp_fmtstream_t; - -#define argp_make_fmtstream line_wrap_stream -#define __argp_make_fmtstream line_wrap_stream -#define argp_fmtstream_free line_unwrap_stream -#define __argp_fmtstream_free line_unwrap_stream - -#define __argp_fmtstream_putc(fs,ch) putc(ch,fs) -#define argp_fmtstream_putc(fs,ch) putc(ch,fs) -#define __argp_fmtstream_puts(fs,str) fputs(str,fs) -#define argp_fmtstream_puts(fs,str) fputs(str,fs) -#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) -#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) -#define __argp_fmtstream_printf fprintf -#define argp_fmtstream_printf fprintf - -#define __argp_fmtstream_lmargin line_wrap_lmargin -#define argp_fmtstream_lmargin line_wrap_lmargin -#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin -#define argp_fmtstream_set_lmargin line_wrap_set_lmargin -#define __argp_fmtstream_rmargin line_wrap_rmargin -#define argp_fmtstream_rmargin line_wrap_rmargin -#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin -#define argp_fmtstream_set_rmargin line_wrap_set_rmargin -#define __argp_fmtstream_wmargin line_wrap_wmargin -#define argp_fmtstream_wmargin line_wrap_wmargin -#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin -#define argp_fmtstream_set_wmargin line_wrap_set_wmargin -#define __argp_fmtstream_point line_wrap_point -#define argp_fmtstream_point line_wrap_point - -#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ -/* Guess we have to define our own version. */ - -struct argp_fmtstream -{ - FILE *stream; /* The stream we're outputting to. */ - - size_t lmargin, rmargin; /* Left and right margins. */ - ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */ - - /* Point in buffer to which we've processed for wrapping, but not output. */ - size_t point_offs; - /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */ - ssize_t point_col; - - char *buf; /* Output buffer. */ - char *p; /* Current end of text in BUF. */ - char *end; /* Absolute end of BUF. */ -}; - -typedef struct argp_fmtstream *argp_fmtstream_t; - -/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines - written on it with LMARGIN spaces and limits them to RMARGIN columns - total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by - replacing the whitespace before them with a newline and WMARGIN spaces. - Otherwise, chars beyond RMARGIN are simply dropped until a newline. - Returns NULL if there was an error. */ -extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream, - size_t __lmargin, - size_t __rmargin, - ssize_t __wmargin); -extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream, - size_t __lmargin, - size_t __rmargin, - ssize_t __wmargin); - -/* Flush __FS to its stream, and free it (but don't close the stream). */ -extern void __argp_fmtstream_free (argp_fmtstream_t __fs); -extern void argp_fmtstream_free (argp_fmtstream_t __fs); - -extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, - const char *__fmt, ...) - _GL_ATTRIBUTE_FORMAT ((printf, 2, 3)); -extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, - const char *__fmt, ...) - _GL_ATTRIBUTE_FORMAT ((printf, 2, 3)); - -#if _LIBC -extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); -extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); - -extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); -extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); - -extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len); -extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len); -#endif - -/* Access macros for various bits of state. */ -#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) -#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin) -#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin) -#define __argp_fmtstream_lmargin argp_fmtstream_lmargin -#define __argp_fmtstream_rmargin argp_fmtstream_rmargin -#define __argp_fmtstream_wmargin argp_fmtstream_wmargin - -#if _LIBC -/* Set __FS's left margin to LMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, - size_t __lmargin); -extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, - size_t __lmargin); - -/* Set __FS's right margin to __RMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, - size_t __rmargin); -extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, - size_t __rmargin); - -/* Set __FS's wrap margin to __WMARGIN and return the old value. */ -extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, - size_t __wmargin); -extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, - size_t __wmargin); - -/* Return the column number of the current output point in __FS. */ -extern size_t argp_fmtstream_point (argp_fmtstream_t __fs); -extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs); -#endif - -/* Internal routines. */ -extern void _argp_fmtstream_update (argp_fmtstream_t __fs); -extern void __argp_fmtstream_update (argp_fmtstream_t __fs); -extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); -extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); - -#if !_LIBC || defined __OPTIMIZE__ -/* Inline versions of above routines. */ - -#if !_LIBC -#define __argp_fmtstream_putc argp_fmtstream_putc -#define __argp_fmtstream_puts argp_fmtstream_puts -#define __argp_fmtstream_write argp_fmtstream_write -#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin -#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin -#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin -#define __argp_fmtstream_point argp_fmtstream_point -#define __argp_fmtstream_update _argp_fmtstream_update -#define __argp_fmtstream_ensure _argp_fmtstream_ensure -_GL_INLINE_HEADER_BEGIN -#ifndef ARGP_FS_EI -# define ARGP_FS_EI _GL_INLINE -#endif -#endif - -#ifndef ARGP_FS_EI -# ifdef __GNUC__ - /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 - inline semantics, unless -fgnu89-inline is used. It defines a macro - __GNUC_STDC_INLINE__ to indicate this situation or a macro - __GNUC_GNU_INLINE__ to indicate the opposite situation. - - GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline - semantics but warns, unless -fgnu89-inline is used: - warning: C99 inline functions are not supported; using GNU89 - warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute - It defines a macro __GNUC_GNU_INLINE__ to indicate this situation. - - Whereas Apple GCC 4.0.1 build 5479 without -std=c99 or -std=gnu99 - implements the GNU C inline semantics and defines the macro - __GNUC_GNU_INLINE__, but it does not warn and does not support - __attribute__ ((__gnu_inline__)). - - All in all, these are the possible combinations. For every compiler, - we need to choose ARGP_FS_EI so that the corresponding table cell - contains an "ok". - - \ ARGP_FS_EI inline extern extern - \ inline inline - CC \ __attribute__ - ((gnu_inline)) - - gcc 4.3.0 error ok ok - gcc 4.3.0 -std=gnu99 -fgnu89-inline error ok ok - gcc 4.3.0 -std=gnu99 ok error ok - - gcc 4.2.2 error ok ok - gcc 4.2.2 -std=gnu99 -fgnu89-inline error ok ok - gcc 4.2.2 -std=gnu99 error warning ok - - gcc 4.1.2 error ok warning - gcc 4.1.2 -std=gnu99 error ok warning - - Apple gcc 4.0.1 error ok warning - Apple gcc 4.0.1 -std=gnu99 ok error warning - */ -# if defined __GNUC_STDC_INLINE__ -# define ARGP_FS_EI inline -# elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) -# define ARGP_FS_EI extern inline __attribute__ ((__gnu_inline__)) -# else -# define ARGP_FS_EI extern inline -# endif -# else - /* With other compilers, assume the ISO C99 meaning of 'inline', if - the compiler supports 'inline' at all. */ -# define ARGP_FS_EI inline -# endif -#endif - -ARGP_FS_EI size_t -__argp_fmtstream_write (argp_fmtstream_t __fs, - const char *__str, size_t __len) -{ - if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) - { - memcpy (__fs->p, __str, __len); - __fs->p += __len; - return __len; - } - else - return 0; -} - -ARGP_FS_EI int -__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str) -{ - size_t __len = strlen (__str); - if (__len) - { - size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); - return __wrote == __len ? 0 : -1; - } - else - return 0; -} - -ARGP_FS_EI int -__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) -{ - if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) - return *__fs->p++ = __ch; - else - return EOF; -} - -/* Set __FS's left margin to __LMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->lmargin; - __fs->lmargin = __lmargin; - return __old; -} - -/* Set __FS's right margin to __RMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->rmargin; - __fs->rmargin = __rmargin; - return __old; -} - -/* Set FS's wrap margin to __WMARGIN and return the old value. */ -ARGP_FS_EI size_t -__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) -{ - size_t __old; - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - __old = __fs->wmargin; - __fs->wmargin = __wmargin; - return __old; -} - -/* Return the column number of the current output point in __FS. */ -ARGP_FS_EI size_t -__argp_fmtstream_point (argp_fmtstream_t __fs) -{ - if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) - __argp_fmtstream_update (__fs); - return __fs->point_col >= 0 ? __fs->point_col : 0; -} - -#if !_LIBC -#undef __argp_fmtstream_putc -#undef __argp_fmtstream_puts -#undef __argp_fmtstream_write -#undef __argp_fmtstream_set_lmargin -#undef __argp_fmtstream_set_rmargin -#undef __argp_fmtstream_set_wmargin -#undef __argp_fmtstream_point -#undef __argp_fmtstream_update -#undef __argp_fmtstream_ensure -_GL_INLINE_HEADER_END -#endif - -#endif /* !_LIBC || __OPTIMIZE__ */ - -#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ - -#endif /* argp-fmtstream.h */ diff --git a/grub-core/gnulib/argp-fs-xinl.c b/grub-core/gnulib/argp-fs-xinl.c deleted file mode 100644 index 35547d93d..000000000 --- a/grub-core/gnulib/argp-fs-xinl.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Real definitions for extern inline functions in argp-fmtstream.h - Copyright (C) 1997, 2003-2004, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef _LIBC -# define ARGP_FS_EI -#else -# define ARGP_FS_EI _GL_EXTERN_INLINE -#endif -#undef __OPTIMIZE__ -#define __OPTIMIZE__ 1 -#include "argp-fmtstream.h" - -#if 0 -/* Not exported. */ -/* Add weak aliases. */ -#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias) - -weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc) -weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts) -weak_alias (__argp_fmtstream_write, argp_fmtstream_write) -weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin) -weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin) -weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin) -weak_alias (__argp_fmtstream_point, argp_fmtstream_point) - -#endif -#endif diff --git a/grub-core/gnulib/argp-help.c b/grub-core/gnulib/argp-help.c deleted file mode 100644 index b9be63f40..000000000 --- a/grub-core/gnulib/argp-help.c +++ /dev/null @@ -1,1960 +0,0 @@ -/* Hierarchical argument parsing help output - Copyright (C) 1995-2005, 2007, 2009-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_IN_LIBIO -# include -#endif - -#ifdef _LIBC -# include -# undef dgettext -# define dgettext(domain, msgid) \ - INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) -#else -# include "gettext.h" -#endif - -#include "argp.h" -#include "argp-fmtstream.h" -#include "argp-namefrob.h" -#include "mbswidth.h" - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* User-selectable (using an environment variable) formatting parameters. - - These may be specified in an environment variable called 'ARGP_HELP_FMT', - with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2 - Where VALn must be a positive integer. The list of variables is in the - UPARAM_NAMES vector, below. */ - -/* Default parameters. */ -#define DUP_ARGS 0 /* True if option argument can be duplicated. */ -#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */ -#define SHORT_OPT_COL 2 /* column in which short options start */ -#define LONG_OPT_COL 6 /* column in which long options start */ -#define DOC_OPT_COL 2 /* column in which doc options start */ -#define OPT_DOC_COL 29 /* column in which option text starts */ -#define HEADER_COL 1 /* column in which group headers are printed */ -#define USAGE_INDENT 12 /* indentation of wrapped usage lines */ -#define RMARGIN 79 /* right margin used for wrapping */ - -/* User-selectable (using an environment variable) formatting parameters. - They must all be of type 'int' for the parsing code to work. */ -struct uparams -{ - /* If true, arguments for an option are shown with both short and long - options, even when a given option has both, e.g. '-x ARG, --longx=ARG'. - If false, then if an option has both, the argument is only shown with - the long one, e.g., '-x, --longx=ARG', and a message indicating that - this really means both is printed below the options. */ - int dup_args; - - /* This is true if when DUP_ARGS is false, and some duplicate arguments have - been suppressed, an explanatory message should be printed. */ - int dup_args_note; - - /* Various output columns. */ - int short_opt_col; /* column in which short options start */ - int long_opt_col; /* column in which long options start */ - int doc_opt_col; /* column in which doc options start */ - int opt_doc_col; /* column in which option text starts */ - int header_col; /* column in which group headers are printed */ - int usage_indent; /* indentation of wrapped usage lines */ - int rmargin; /* right margin used for wrapping */ - - int valid; /* True when the values in here are valid. */ -}; - -/* This is a global variable, as user options are only ever read once. */ -static struct uparams uparams = { - DUP_ARGS, DUP_ARGS_NOTE, - SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL, - USAGE_INDENT, RMARGIN, - 0 -}; - -/* A particular uparam, and what the user name is. */ -struct uparam_name -{ - const char *name; /* User name. */ - int is_bool; /* Whether it's 'boolean'. */ - size_t uparams_offs; /* Location of the (int) field in UPARAMS. */ -}; - -/* The name-field mappings we know about. */ -static const struct uparam_name uparam_names[] = -{ - { "dup-args", 1, offsetof (struct uparams, dup_args) }, - { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) }, - { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) }, - { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) }, - { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) }, - { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) }, - { "header-col", 0, offsetof (struct uparams, header_col) }, - { "usage-indent", 0, offsetof (struct uparams, usage_indent) }, - { "rmargin", 0, offsetof (struct uparams, rmargin) }, - { 0 } -}; - -static void -validate_uparams (const struct argp_state *state, struct uparams *upptr) -{ - const struct uparam_name *up; - - for (up = uparam_names; up->name; up++) - { - if (up->is_bool - || up->uparams_offs == offsetof (struct uparams, rmargin)) - continue; - if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) - { - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -ARGP_HELP_FMT: %s value is less than or equal to %s"), - "rmargin", up->name); - return; - } - } - uparams = *upptr; - uparams.valid = 1; -} - -/* Read user options from the environment, and fill in UPARAMS appropriately. */ -static void -fill_in_uparams (const struct argp_state *state) -{ - const char *var = getenv ("ARGP_HELP_FMT"); - struct uparams new_params = uparams; - -#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0); - - if (var) - { - /* Parse var. */ - while (*var) - { - SKIPWS (var); - - if (isalpha ((unsigned char) *var)) - { - size_t var_len; - const struct uparam_name *un; - int unspec = 0, val = 0; - const char *arg = var; - - while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_') - arg++; - var_len = arg - var; - - SKIPWS (arg); - - if (*arg == '\0' || *arg == ',') - unspec = 1; - else if (*arg == '=') - { - arg++; - SKIPWS (arg); - } - - if (unspec) - { - if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') - { - val = 0; - var += 3; - var_len -= 3; - } - else - val = 1; - } - else if (isdigit ((unsigned char) *arg)) - { - val = atoi (arg); - while (isdigit ((unsigned char) *arg)) - arg++; - SKIPWS (arg); - } - - for (un = uparam_names; un->name; un++) - if (strlen (un->name) == var_len - && strncmp (var, un->name, var_len) == 0) - { - if (unspec && !un->is_bool) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -%.*s: ARGP_HELP_FMT parameter requires a value"), - (int) var_len, var); - else if (val < 0) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "\ -%.*s: ARGP_HELP_FMT parameter must be positive"), - (int) var_len, var); - else - *(int *)((char *)&new_params + un->uparams_offs) = val; - break; - } - if (! un->name) - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, "\ -%.*s: Unknown ARGP_HELP_FMT parameter"), - (int) var_len, var); - - var = arg; - if (*var == ',') - var++; - } - else if (*var) - { - __argp_failure (state, 0, 0, - dgettext (state->root_argp->argp_domain, - "Garbage in ARGP_HELP_FMT: %s"), var); - break; - } - } - validate_uparams (state, &new_params); - } -} - -/* Returns true if OPT hasn't been marked invisible. Visibility only affects - whether OPT is displayed or used in sorting, not option shadowing. */ -#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN)) - -/* Returns true if OPT is an alias for an earlier option. */ -#define oalias(opt) ((opt)->flags & OPTION_ALIAS) - -/* Returns true if OPT is a documentation-only entry. */ -#define odoc(opt) ((opt)->flags & OPTION_DOC) - -/* Returns true if OPT should not be translated */ -#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS) - -/* Returns true if OPT is the end-of-list marker for a list of options. */ -#define oend(opt) __option_is_end (opt) - -/* Returns true if OPT has a short option. */ -#define oshort(opt) __option_is_short (opt) - -/* - The help format for a particular option is like: - - -xARG, -yARG, --long1=ARG, --long2=ARG Documentation... - - Where ARG will be omitted if there's no argument, for this option, or - will be surrounded by "[" and "]" appropriately if the argument is - optional. The documentation string is word-wrapped appropriately, and if - the list of options is long enough, it will be started on a separate line. - If there are no short options for a given option, the first long option is - indented slightly in a way that's supposed to make most long options appear - to be in a separate column. - - For example, the following output (from ps): - - -p PID, --pid=PID List the process PID - --pgrp=PGRP List processes in the process group PGRP - -P, -x, --no-parent Include processes without parents - -Q, --all-fields Don't elide unusable fields (normally if there's - some reason ps can't print a field for any - process, it's removed from the output entirely) - -r, --reverse, --gratuitously-long-reverse-option - Reverse the order of any sort - --session[=SID] Add the processes from the session SID (which - defaults to the sid of the current process) - - Here are some more options: - -f ZOT, --foonly=ZOT Glork a foonly - -z, --zaza Snit a zar - - -?, --help Give this help list - --usage Give a short usage message - -V, --version Print program version - - The struct argp_option array for the above could look like: - - { - {"pid", 'p', "PID", 0, "List the process PID"}, - {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"}, - {"no-parent", 'P', 0, 0, "Include processes without parents"}, - {0, 'x', 0, OPTION_ALIAS}, - {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" - " if there's some reason ps can't" - " print a field for any process, it's" - " removed from the output entirely)" }, - {"reverse", 'r', 0, 0, "Reverse the order of any sort"}, - {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, - {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL, - "Add the processes from the session" - " SID (which defaults to the sid of" - " the current process)" }, - - {0,0,0,0, "Here are some more options:"}, - {"foonly", 'f', "ZOT", 0, "Glork a foonly"}, - {"zaza", 'z', 0, 0, "Snit a zar"}, - - {0} - } - - Note that the last three options are automatically supplied by argp_parse, - unless you tell it not to with ARGP_NO_HELP. - -*/ - -/* Returns true if CH occurs between BEG and END. */ -static int -find_char (char ch, char *beg, char *end) -{ - while (beg < end) - if (*beg == ch) - return 1; - else - beg++; - return 0; -} - -struct hol_cluster; /* fwd decl */ - -struct hol_entry -{ - /* First option. */ - const struct argp_option *opt; - /* Number of options (including aliases). */ - unsigned num; - - /* A pointers into the HOL's short_options field, to the first short option - letter for this entry. The order of the characters following this point - corresponds to the order of options pointed to by OPT, and there are at - most NUM. A short option recorded in an option following OPT is only - valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's - probably been shadowed by some other entry). */ - char *short_options; - - /* Entries are sorted by their group first, in the order: - 1, 2, ..., n, 0, -m, ..., -2, -1 - and then alphabetically within each group. The default is 0. */ - int group; - - /* The cluster of options this entry belongs to, or 0 if none. */ - struct hol_cluster *cluster; - - /* The argp from which this option came. */ - const struct argp *argp; - - /* Position in the array */ - unsigned ord; -}; - -/* A cluster of entries to reflect the argp tree structure. */ -struct hol_cluster -{ - /* A descriptive header printed before options in this cluster. */ - const char *header; - - /* Used to order clusters within the same group with the same parent, - according to the order in which they occurred in the parent argp's child - list. */ - int index; - - /* How to sort this cluster with respect to options and other clusters at the - same depth (clusters always follow options in the same group). */ - int group; - - /* The cluster to which this cluster belongs, or 0 if it's at the base - level. */ - struct hol_cluster *parent; - - /* The argp from which this cluster is (eventually) derived. */ - const struct argp *argp; - - /* The distance this cluster is from the root. */ - int depth; - - /* Clusters in a given hol are kept in a linked list, to make freeing them - possible. */ - struct hol_cluster *next; -}; - -/* A list of options for help. */ -struct hol -{ - /* An array of hol_entry's. */ - struct hol_entry *entries; - /* The number of entries in this hol. If this field is zero, the others - are undefined. */ - unsigned num_entries; - - /* A string containing all short options in this HOL. Each entry contains - pointers into this string, so the order can't be messed with blindly. */ - char *short_options; - - /* Clusters of entries in this hol. */ - struct hol_cluster *clusters; -}; - -/* Create a struct hol from the options in ARGP. CLUSTER is the - hol_cluster in which these entries occur, or 0, if at the root. */ -static struct hol * -make_hol (const struct argp *argp, struct hol_cluster *cluster) -{ - char *so; - const struct argp_option *o; - const struct argp_option *opts = argp->options; - struct hol_entry *entry; - unsigned num_short_options = 0; - struct hol *hol = malloc (sizeof (struct hol)); - - assert (hol); - - hol->num_entries = 0; - hol->clusters = 0; - - if (opts) - { - int cur_group = 0; - - /* The first option must not be an alias. */ - assert (! oalias (opts)); - - /* Calculate the space needed. */ - for (o = opts; ! oend (o); o++) - { - if (! oalias (o)) - hol->num_entries++; - if (oshort (o)) - num_short_options++; /* This is an upper bound. */ - } - - hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries); - hol->short_options = malloc (num_short_options + 1); - - assert (hol->entries && hol->short_options); - if (SIZE_MAX <= UINT_MAX) - assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry)); - - /* Fill in the entries. */ - so = hol->short_options; - for (o = opts, entry = hol->entries; ! oend (o); entry++) - { - entry->opt = o; - entry->num = 0; - entry->short_options = so; - entry->group = cur_group = - o->group - ? o->group - : ((!o->name && !o->key) - ? cur_group + 1 - : cur_group); - entry->cluster = cluster; - entry->argp = argp; - - do - { - entry->num++; - if (oshort (o) && ! find_char (o->key, hol->short_options, so)) - /* O has a valid short option which hasn't already been used.*/ - *so++ = o->key; - o++; - } - while (! oend (o) && oalias (o)); - } - *so = '\0'; /* null terminated so we can find the length */ - } - - return hol; -} - -/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the - associated argp child list entry), INDEX, and PARENT, and return a pointer - to it. ARGP is the argp that this cluster results from. */ -static struct hol_cluster * -hol_add_cluster (struct hol *hol, int group, const char *header, int index, - struct hol_cluster *parent, const struct argp *argp) -{ - struct hol_cluster *cl = malloc (sizeof (struct hol_cluster)); - if (cl) - { - cl->group = group; - cl->header = header; - - cl->index = index; - cl->parent = parent; - cl->argp = argp; - cl->depth = parent ? parent->depth + 1 : 0; - - cl->next = hol->clusters; - hol->clusters = cl; - } - return cl; -} - -/* Free HOL and any resources it uses. */ -static void -hol_free (struct hol *hol) -{ - struct hol_cluster *cl = hol->clusters; - - while (cl) - { - struct hol_cluster *next = cl->next; - free (cl); - cl = next; - } - - if (hol->num_entries > 0) - { - free (hol->entries); - free (hol->short_options); - } - - free (hol); -} - -static int -hol_entry_short_iterate (const struct hol_entry *entry, - int (*func)(const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie), - const char *domain, void *cookie) -{ - unsigned nopts; - int val = 0; - const struct argp_option *opt, *real = entry->opt; - char *so = entry->short_options; - - for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) - if (oshort (opt) && *so == opt->key) - { - if (!oalias (opt)) - real = opt; - if (ovisible (opt)) - val = (*func)(opt, real, domain, cookie); - so++; - } - - return val; -} - -static inline int -#if __GNUC__ >= 3 -__attribute__ ((always_inline)) -#endif -hol_entry_long_iterate (const struct hol_entry *entry, - int (*func)(const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie), - const char *domain, void *cookie) -{ - unsigned nopts; - int val = 0; - const struct argp_option *opt, *real = entry->opt; - - for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) - if (opt->name) - { - if (!oalias (opt)) - real = opt; - if (ovisible (opt)) - val = (*func)(opt, real, domain, cookie); - } - - return val; -} - -/* Iterator that returns true for the first short option. */ -static int -until_short (const struct argp_option *opt, const struct argp_option *real, - const char *domain, void *cookie) -{ - return oshort (opt) ? opt->key : 0; -} - -/* Returns the first valid short option in ENTRY, or 0 if there is none. */ -static char -hol_entry_first_short (const struct hol_entry *entry) -{ - return hol_entry_short_iterate (entry, until_short, - entry->argp->argp_domain, 0); -} - -/* Returns the first valid long option in ENTRY, or 0 if there is none. */ -static const char * -hol_entry_first_long (const struct hol_entry *entry) -{ - const struct argp_option *opt; - unsigned num; - for (opt = entry->opt, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - return opt->name; - return 0; -} - -/* Returns the entry in HOL with the long option name NAME, or 0 if there is - none. */ -static struct hol_entry * -hol_find_entry (struct hol *hol, const char *name) -{ - struct hol_entry *entry = hol->entries; - unsigned num_entries = hol->num_entries; - - while (num_entries-- > 0) - { - const struct argp_option *opt = entry->opt; - unsigned num_opts = entry->num; - - while (num_opts-- > 0) - if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0) - return entry; - else - opt++; - - entry++; - } - - return 0; -} - -/* If an entry with the long option NAME occurs in HOL, set its special - sort position to GROUP. */ -static void -hol_set_group (struct hol *hol, const char *name, int group) -{ - struct hol_entry *entry = hol_find_entry (hol, name); - if (entry) - entry->group = group; -} - -/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. - EQ is what to return if GROUP1 and GROUP2 are the same. */ -static int -group_cmp (int group1, int group2, int eq) -{ - if (group1 == group2) - return eq; - else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0)) - return group1 - group2; - else - return group2 - group1; -} - -/* Compare clusters CL1 & CL2 by the order that they should appear in - output. */ -static int -hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2) -{ - /* If one cluster is deeper than the other, use its ancestor at the same - level, so that finding the common ancestor is straightforward. - - clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */ - while (cl1->depth > cl2->depth) - cl1 = cl1->parent; - while (cl2->depth > cl1->depth) - cl2 = cl2->parent; - - /* Now reduce both clusters to their ancestors at the point where both have - a common parent; these can be directly compared. */ - while (cl1->parent != cl2->parent) - cl1 = cl1->parent, cl2 = cl2->parent; - - return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index); -} - -/* Return the ancestor of CL that's just below the root (i.e., has a parent - of 0). */ -static struct hol_cluster * -hol_cluster_base (struct hol_cluster *cl) -{ - while (cl->parent) - cl = cl->parent; - return cl; -} - -/* Return true if CL1 is a child of CL2. */ -static int -hol_cluster_is_child (const struct hol_cluster *cl1, - const struct hol_cluster *cl2) -{ - while (cl1 && cl1 != cl2) - cl1 = cl1->parent; - return cl1 == cl2; -} - -/* Given the name of an OPTION_DOC option, modifies NAME to start at the tail - that should be used for comparisons, and returns true iff it should be - treated as a non-option. */ -static int -canon_doc_option (const char **name) -{ - int non_opt; - - if (!*name) - non_opt = 1; - else - { - /* Skip initial whitespace. */ - while (isspace ((unsigned char) **name)) - (*name)++; - /* Decide whether this looks like an option (leading '-') or not. */ - non_opt = (**name != '-'); - /* Skip until part of name used for sorting. */ - while (**name && !isalnum ((unsigned char) **name)) - (*name)++; - } - return non_opt; -} - -#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1) - -/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help - listing. */ -static int -hol_entry_cmp (const struct hol_entry *entry1, - const struct hol_entry *entry2) -{ - /* The group numbers by which the entries should be ordered; if either is - in a cluster, then this is just the group within the cluster. */ - int group1 = entry1->group, group2 = entry2->group; - int rc; - - if (entry1->cluster != entry2->cluster) - { - /* The entries are not within the same cluster, so we can't compare them - directly, we have to use the appropriate clustering level too. */ - if (! entry1->cluster) - /* ENTRY1 is at the "base level", not in a cluster, so we have to - compare it's group number with that of the base cluster in which - ENTRY2 resides. Note that if they're in the same group, the - clustered option always comes laster. */ - return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1); - else if (! entry2->cluster) - /* Likewise, but ENTRY2's not in a cluster. */ - return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1); - else - /* Both entries are in clusters, we can just compare the clusters. */ - return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ? - rc : HOL_ENTRY_PTRCMP (entry1, entry2); - } - else if (group1 == group2) - /* The entries are both in the same cluster and group, so compare them - alphabetically. */ - { - int short1 = hol_entry_first_short (entry1); - int short2 = hol_entry_first_short (entry2); - int doc1 = odoc (entry1->opt); - int doc2 = odoc (entry2->opt); - const char *long1 = hol_entry_first_long (entry1); - const char *long2 = hol_entry_first_long (entry2); - - if (doc1) - doc1 = canon_doc_option (&long1); - if (doc2) - doc2 = canon_doc_option (&long2); - - if (doc1 != doc2) - /* "documentation" options always follow normal options (or - documentation options that *look* like normal options). */ - return doc1 - doc2; - else if (!short1 && !short2 && long1 && long2) - /* Only long options. */ - return (rc = __strcasecmp (long1, long2)) ? - rc : HOL_ENTRY_PTRCMP (entry1, entry2); - else - /* Compare short/short, long/short, short/long, using the first - character of long options. Entries without *any* valid - options (such as options with OPTION_HIDDEN set) will be put - first, but as they're not displayed, it doesn't matter where - they are. */ - { - unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0; - unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0; - /* Use tolower, not _tolower, since only the former is - guaranteed to work on something already lower case. */ - int lower_cmp = tolower (first1) - tolower (first2); - /* Compare ignoring case, except when the options are both the - same letter, in which case lower-case always comes first. */ - return lower_cmp ? lower_cmp : - (rc = first2 - first1) ? - rc : HOL_ENTRY_PTRCMP (entry1, entry2); - } - } - else - /* Within the same cluster, but not the same group, so just compare - groups. */ - return group_cmp (group1, group2, HOL_ENTRY_PTRCMP (entry1, entry2)); -} - -/* Version of hol_entry_cmp with correct signature for qsort. */ -static int -hol_entry_qcmp (const void *entry1_v, const void *entry2_v) -{ - return hol_entry_cmp (entry1_v, entry2_v); -} - -/* Sort HOL by group and alphabetically by option name (with short options - taking precedence over long). Since the sorting is for display purposes - only, the shadowing of options isn't effected. */ -static void -hol_sort (struct hol *hol) -{ - if (hol->num_entries > 0) - { - unsigned i; - struct hol_entry *e; - for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++) - e->ord = i; - qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry), - hol_entry_qcmp); - } -} - -/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow - any in MORE with the same name. */ -static void -hol_append (struct hol *hol, struct hol *more) -{ - struct hol_cluster **cl_end = &hol->clusters; - - /* Steal MORE's cluster list, and add it to the end of HOL's. */ - while (*cl_end) - cl_end = &(*cl_end)->next; - *cl_end = more->clusters; - more->clusters = 0; - - /* Merge entries. */ - if (more->num_entries > 0) - { - if (hol->num_entries == 0) - { - hol->num_entries = more->num_entries; - hol->entries = more->entries; - hol->short_options = more->short_options; - more->num_entries = 0; /* Mark MORE's fields as invalid. */ - } - else - /* Append the entries in MORE to those in HOL, taking care to only add - non-shadowed SHORT_OPTIONS values. */ - { - unsigned left; - char *so, *more_so; - struct hol_entry *e; - unsigned num_entries = hol->num_entries + more->num_entries; - struct hol_entry *entries = - malloc (num_entries * sizeof (struct hol_entry)); - unsigned hol_so_len = strlen (hol->short_options); - char *short_options = - malloc (hol_so_len + strlen (more->short_options) + 1); - - assert (entries && short_options); - if (SIZE_MAX <= UINT_MAX) - assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry)); - - __mempcpy (__mempcpy (entries, hol->entries, - hol->num_entries * sizeof (struct hol_entry)), - more->entries, - more->num_entries * sizeof (struct hol_entry)); - - __mempcpy (short_options, hol->short_options, hol_so_len); - - /* Fix up the short options pointers from HOL. */ - for (e = entries, left = hol->num_entries; left > 0; e++, left--) - e->short_options = - short_options + (e->short_options - hol->short_options); - - /* Now add the short options from MORE, fixing up its entries - too. */ - so = short_options + hol_so_len; - more_so = more->short_options; - for (left = more->num_entries; left > 0; e++, left--) - { - int opts_left; - const struct argp_option *opt; - - e->short_options = so; - - for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--) - { - int ch = *more_so; - if (oshort (opt) && ch == opt->key) - /* The next short option in MORE_SO, CH, is from OPT. */ - { - if (! find_char (ch, short_options, - short_options + hol_so_len)) - /* The short option CH isn't shadowed by HOL's options, - so add it to the sum. */ - *so++ = ch; - more_so++; - } - } - } - - *so = '\0'; - - free (hol->entries); - free (hol->short_options); - - hol->entries = entries; - hol->num_entries = num_entries; - hol->short_options = short_options; - } - } - - hol_free (more); -} - -/* Inserts enough spaces to make sure STREAM is at column COL. */ -static void -indent_to (argp_fmtstream_t stream, unsigned col) -{ - int needed = col - __argp_fmtstream_point (stream); - while (needed-- > 0) - __argp_fmtstream_putc (stream, ' '); -} - -/* Output to STREAM either a space, or a newline if there isn't room for at - least ENSURE characters before the right margin. */ -static void -space (argp_fmtstream_t stream, size_t ensure) -{ - if (__argp_fmtstream_point (stream) + ensure - >= __argp_fmtstream_rmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - else - __argp_fmtstream_putc (stream, ' '); -} - -/* If the option REAL has an argument, we print it in using the printf - format REQ_FMT or OPT_FMT depending on whether it's a required or - optional argument. */ -static void -arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt, - const char *domain, argp_fmtstream_t stream) -{ - if (real->arg) - { - if (real->flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, opt_fmt, - dgettext (domain, real->arg)); - else - __argp_fmtstream_printf (stream, req_fmt, - dgettext (domain, real->arg)); - } -} - -/* Helper functions for hol_entry_help. */ - -/* State used during the execution of hol_help. */ -struct hol_help_state -{ - /* PREV_ENTRY should contain the previous entry printed, or 0. */ - struct hol_entry *prev_entry; - - /* If an entry is in a different group from the previous one, and SEP_GROUPS - is true, then a blank line will be printed before any output. */ - int sep_groups; - - /* True if a duplicate option argument was suppressed (only ever set if - UPARAMS.dup_args is false). */ - int suppressed_dup_arg; -}; - -/* Some state used while printing a help entry (used to communicate with - helper functions). See the doc for hol_entry_help for more info, as most - of the fields are copied from its arguments. */ -struct pentry_state -{ - const struct hol_entry *entry; - argp_fmtstream_t stream; - struct hol_help_state *hhstate; - - /* True if nothing's been printed so far. */ - int first; - - /* If non-zero, the state that was used to print this help. */ - const struct argp_state *state; -}; - -/* If a user doc filter should be applied to DOC, do so. */ -static const char * -filter_doc (const char *doc, int key, const struct argp *argp, - const struct argp_state *state) -{ - if (argp->help_filter) - /* We must apply a user filter to this output. */ - { - void *input = __argp_input (argp, state); - return (*argp->help_filter) (key, doc, input); - } - else - /* No filter. */ - return doc; -} - -/* Prints STR as a header line, with the margin lines set appropriately, and - notes the fact that groups should be separated with a blank line. ARGP is - the argp that should dictate any user doc filtering to take place. Note - that the previous wrap margin isn't restored, but the left margin is reset - to 0. */ -static void -print_header (const char *str, const struct argp *argp, - struct pentry_state *pest) -{ - const char *tstr = dgettext (argp->argp_domain, str); - const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state); - - if (fstr) - { - if (*fstr) - { - if (pest->hhstate->prev_entry) - /* Precede with a blank line. */ - __argp_fmtstream_putc (pest->stream, '\n'); - indent_to (pest->stream, uparams.header_col); - __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col); - __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col); - __argp_fmtstream_puts (pest->stream, fstr); - __argp_fmtstream_set_lmargin (pest->stream, 0); - __argp_fmtstream_putc (pest->stream, '\n'); - } - - pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */ - } - - if (fstr != tstr) - free ((char *) fstr); -} - -/* Inserts a comma if this isn't the first item on the line, and then makes - sure we're at least to column COL. If this *is* the first item on a line, - prints any pending whitespace/headers that should precede this line. Also - clears FIRST. */ -static void -comma (unsigned col, struct pentry_state *pest) -{ - if (pest->first) - { - const struct hol_entry *pe = pest->hhstate->prev_entry; - const struct hol_cluster *cl = pest->entry->cluster; - - if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group) - __argp_fmtstream_putc (pest->stream, '\n'); - - if (cl && cl->header && *cl->header - && (!pe - || (pe->cluster != cl - && !hol_cluster_is_child (pe->cluster, cl)))) - /* If we're changing clusters, then this must be the start of the - ENTRY's cluster unless that is an ancestor of the previous one - (in which case we had just popped into a sub-cluster for a bit). - If so, then print the cluster's header line. */ - { - int old_wm = __argp_fmtstream_wmargin (pest->stream); - print_header (cl->header, cl->argp, pest); - __argp_fmtstream_set_wmargin (pest->stream, old_wm); - } - - pest->first = 0; - } - else - __argp_fmtstream_puts (pest->stream, ", "); - - indent_to (pest->stream, col); -} - -/* Print help for ENTRY to STREAM. */ -static void -hol_entry_help (struct hol_entry *entry, const struct argp_state *state, - argp_fmtstream_t stream, struct hol_help_state *hhstate) -{ - unsigned num; - const struct argp_option *real = entry->opt, *opt; - char *so = entry->short_options; - int have_long_opt = 0; /* We have any long options. */ - /* Saved margins. */ - int old_lm = __argp_fmtstream_set_lmargin (stream, 0); - int old_wm = __argp_fmtstream_wmargin (stream); - /* PEST is a state block holding some of our variables that we'd like to - share with helper functions. */ - struct pentry_state pest; - - pest.entry = entry; - pest.stream = stream; - pest.hhstate = hhstate; - pest.first = 1; - pest.state = state; - - if (! odoc (real)) - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - { - have_long_opt = 1; - break; - } - - /* First emit short options. */ - __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */ - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (oshort (opt) && opt->key == *so) - /* OPT has a valid (non shadowed) short option. */ - { - if (ovisible (opt)) - { - comma (uparams.short_opt_col, &pest); - __argp_fmtstream_putc (stream, '-'); - __argp_fmtstream_putc (stream, *so); - if (!have_long_opt || uparams.dup_args) - arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream); - else if (real->arg) - hhstate->suppressed_dup_arg = 1; - } - so++; - } - - /* Now, long options. */ - if (odoc (real)) - /* A "documentation" option. */ - { - __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && *opt->name && ovisible (opt)) - { - comma (uparams.doc_opt_col, &pest); - /* Calling dgettext here isn't quite right, since sorting will - have been done on the original; but documentation options - should be pretty rare anyway... */ - __argp_fmtstream_puts (stream, - onotrans (opt) ? - opt->name : - dgettext (state->root_argp->argp_domain, - opt->name)); - } - } - else - /* A real long option. */ - { - int first_long_opt = 1; - - __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col); - for (opt = real, num = entry->num; num > 0; opt++, num--) - if (opt->name && ovisible (opt)) - { - comma (uparams.long_opt_col, &pest); - __argp_fmtstream_printf (stream, "--%s", opt->name); - if (first_long_opt || uparams.dup_args) - arg (real, "=%s", "[=%s]", state->root_argp->argp_domain, - stream); - else if (real->arg) - hhstate->suppressed_dup_arg = 1; - } - } - - /* Next, documentation strings. */ - __argp_fmtstream_set_lmargin (stream, 0); - - if (pest.first) - { - /* Didn't print any switches, what's up? */ - if (!oshort (real) && !real->name) - /* This is a group header, print it nicely. */ - print_header (real->doc, entry->argp, &pest); - else - /* Just a totally shadowed option or null header; print nothing. */ - goto cleanup; /* Just return, after cleaning up. */ - } - else - { - const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain, - real->doc) : 0; - const char *fstr = filter_doc (tstr, real->key, entry->argp, state); - if (fstr && *fstr) - { - unsigned int col = __argp_fmtstream_point (stream); - - __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col); - __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col); - - if (col > (unsigned int) (uparams.opt_doc_col + 3)) - __argp_fmtstream_putc (stream, '\n'); - else if (col >= (unsigned int) uparams.opt_doc_col) - __argp_fmtstream_puts (stream, " "); - else - indent_to (stream, uparams.opt_doc_col); - - __argp_fmtstream_puts (stream, fstr); - } - if (fstr && fstr != tstr) - free ((char *) fstr); - - /* Reset the left margin. */ - __argp_fmtstream_set_lmargin (stream, 0); - __argp_fmtstream_putc (stream, '\n'); - } - - hhstate->prev_entry = entry; - -cleanup: - __argp_fmtstream_set_lmargin (stream, old_lm); - __argp_fmtstream_set_wmargin (stream, old_wm); -} - -/* Output a long help message about the options in HOL to STREAM. */ -static void -hol_help (struct hol *hol, const struct argp_state *state, - argp_fmtstream_t stream) -{ - unsigned num; - struct hol_entry *entry; - struct hol_help_state hhstate = { 0, 0, 0 }; - - for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--) - hol_entry_help (entry, state, stream, &hhstate); - - if (hhstate.suppressed_dup_arg && uparams.dup_args_note) - { - const char *tstr = dgettext (state->root_argp->argp_domain, "\ -Mandatory or optional arguments to long options are also mandatory or \ -optional for any corresponding short options."); - const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE, - state ? state->root_argp : 0, state); - if (fstr && *fstr) - { - __argp_fmtstream_putc (stream, '\n'); - __argp_fmtstream_puts (stream, fstr); - __argp_fmtstream_putc (stream, '\n'); - } - if (fstr && fstr != tstr) - free ((char *) fstr); - } -} - -/* Helper functions for hol_usage. */ - -/* If OPT is a short option without an arg, append its key to the string - pointer pointer to by COOKIE, and advance the pointer. */ -static int -add_argless_short_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - char **snao_end = cookie; - if (!(opt->arg || real->arg) - && !((opt->flags | real->flags) & OPTION_NO_USAGE)) - *(*snao_end)++ = opt->key; - return 0; -} - -/* If OPT is a short option with an arg, output a usage entry for it to the - stream pointed at by COOKIE. */ -static int -usage_argful_short_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - argp_fmtstream_t stream = cookie; - const char *arg = opt->arg; - int flags = opt->flags | real->flags; - - if (! arg) - arg = real->arg; - - if (arg && !(flags & OPTION_NO_USAGE)) - { - arg = dgettext (domain, arg); - - if (flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg); - else - { - /* Manually do line wrapping so that it (probably) won't - get wrapped at the embedded space. */ - space (stream, 6 + strlen (arg)); - __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg); - } - } - - return 0; -} - -/* Output a usage entry for the long option opt to the stream pointed at by - COOKIE. */ -static int -usage_long_opt (const struct argp_option *opt, - const struct argp_option *real, - const char *domain, void *cookie) -{ - argp_fmtstream_t stream = cookie; - const char *arg = opt->arg; - int flags = opt->flags | real->flags; - - if (! arg) - arg = real->arg; - - if (! (flags & OPTION_NO_USAGE) && !odoc (opt)) - { - if (arg) - { - arg = dgettext (domain, arg); - if (flags & OPTION_ARG_OPTIONAL) - __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg); - else - __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg); - } - else - __argp_fmtstream_printf (stream, " [--%s]", opt->name); - } - - return 0; -} - -/* Print a short usage description for the arguments in HOL to STREAM. */ -static void -hol_usage (struct hol *hol, argp_fmtstream_t stream) -{ - if (hol->num_entries > 0) - { - unsigned nentries; - struct hol_entry *entry; - char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1); - char *snao_end = short_no_arg_opts; - - /* First we put a list of short options without arguments. */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_short_iterate (entry, add_argless_short_opt, - entry->argp->argp_domain, &snao_end); - if (snao_end > short_no_arg_opts) - { - *snao_end++ = 0; - __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts); - } - - /* Now a list of short options *with* arguments. */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_short_iterate (entry, usage_argful_short_opt, - entry->argp->argp_domain, stream); - - /* Finally, a list of long options (whew!). */ - for (entry = hol->entries, nentries = hol->num_entries - ; nentries > 0 - ; entry++, nentries--) - hol_entry_long_iterate (entry, usage_long_opt, - entry->argp->argp_domain, stream); - } -} - -/* Make a HOL containing all levels of options in ARGP. CLUSTER is the - cluster in which ARGP's entries should be clustered, or 0. */ -static struct hol * -argp_hol (const struct argp *argp, struct hol_cluster *cluster) -{ - const struct argp_child *child = argp->children; - struct hol *hol = make_hol (argp, cluster); - if (child) - while (child->argp) - { - struct hol_cluster *child_cluster = - ((child->group || child->header) - /* Put CHILD->argp within its own cluster. */ - ? hol_add_cluster (hol, child->group, child->header, - child - argp->children, cluster, argp) - /* Just merge it into the parent's cluster. */ - : cluster); - hol_append (hol, argp_hol (child->argp, child_cluster)) ; - child++; - } - return hol; -} - -/* Calculate how many different levels with alternative args strings exist in - ARGP. */ -static size_t -argp_args_levels (const struct argp *argp) -{ - size_t levels = 0; - const struct argp_child *child = argp->children; - - if (argp->args_doc && strchr (argp->args_doc, '\n')) - levels++; - - if (child) - while (child->argp) - levels += argp_args_levels ((child++)->argp); - - return levels; -} - -/* Print all the non-option args documented in ARGP to STREAM. Any output is - preceded by a space. LEVELS is a pointer to a byte vector the length - returned by argp_args_levels; it should be initialized to zero, and - updated by this routine for the next call if ADVANCE is true. True is - returned as long as there are more patterns to output. */ -static int -argp_args_usage (const struct argp *argp, const struct argp_state *state, - char **levels, int advance, argp_fmtstream_t stream) -{ - char *our_level = *levels; - int multiple = 0; - const struct argp_child *child = argp->children; - const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0; - const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state); - - if (fdoc) - { - const char *cp = fdoc; - nl = __strchrnul (cp, '\n'); - if (*nl != '\0') - /* This is a "multi-level" args doc; advance to the correct position - as determined by our state in LEVELS, and update LEVELS. */ - { - int i; - multiple = 1; - for (i = 0; i < *our_level; i++) - cp = nl + 1, nl = __strchrnul (cp, '\n'); - (*levels)++; - } - - /* Manually do line wrapping so that it (probably) won't get wrapped at - any embedded spaces. */ - space (stream, 1 + mbsnwidth (cp, nl - cp, MBSW_STOP_AT_NUL)); - - __argp_fmtstream_write (stream, cp, nl - cp); - } - if (fdoc && fdoc != tdoc) - free ((char *)fdoc); /* Free user's modified doc string. */ - - if (child) - while (child->argp) - advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream); - - if (advance && multiple) - { - /* Need to increment our level. */ - if (*nl) - /* There's more we can do here. */ - { - (*our_level)++; - advance = 0; /* Our parent shouldn't advance also. */ - } - else if (*our_level > 0) - /* We had multiple levels, but used them up; reset to zero. */ - *our_level = 0; - } - - return !advance; -} - -/* Print the documentation for ARGP to STREAM; if POST is false, then - everything preceding a '\v' character in the documentation strings (or - the whole string, for those with none) is printed, otherwise, everything - following the '\v' character (nothing for strings without). Each separate - bit of documentation is separated a blank line, and if PRE_BLANK is true, - then the first is as well. If FIRST_ONLY is true, only the first - occurrence is output. Returns true if anything was output. */ -static int -argp_doc (const struct argp *argp, const struct argp_state *state, - int post, int pre_blank, int first_only, - argp_fmtstream_t stream) -{ - const char *text; - const char *inp_text; - size_t inp_text_len = 0; - const char *trans_text; - void *input = 0; - int anything = 0; - const struct argp_child *child = argp->children; - - if (argp->doc) - { - char *vt = strchr (argp->doc, '\v'); - if (vt) - { - if (post) - { - inp_text = vt + 1; - if (! *inp_text) - inp_text = 0; - } - else - { - inp_text_len = vt - argp->doc; - inp_text = inp_text_len ? __strndup (argp->doc, inp_text_len) : 0; - } - } - else - inp_text = post ? 0 : argp->doc; - trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL; - } - else - trans_text = inp_text = 0; - - if (argp->help_filter) - /* We have to filter the doc strings. */ - { - input = __argp_input (argp, state); - text = - (*argp->help_filter) (post - ? ARGP_KEY_HELP_POST_DOC - : ARGP_KEY_HELP_PRE_DOC, - trans_text, input); - } - else - text = (const char *) trans_text; - - if (text) - { - if (pre_blank) - __argp_fmtstream_putc (stream, '\n'); - - __argp_fmtstream_puts (stream, text); - - if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - - anything = 1; - } - - if (text && text != trans_text) - free ((char *) text); /* Free TEXT returned from the help filter. */ - - if (inp_text && inp_text_len) - free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */ - - if (post && argp->help_filter) - /* Now see if we have to output an ARGP_KEY_HELP_EXTRA text. */ - { - text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input); - if (text) - { - if (anything || pre_blank) - __argp_fmtstream_putc (stream, '\n'); - __argp_fmtstream_puts (stream, text); - free ((char *) text); - if (__argp_fmtstream_point (stream) - > __argp_fmtstream_lmargin (stream)) - __argp_fmtstream_putc (stream, '\n'); - anything = 1; - } - } - - if (child) - while (child->argp && !(first_only && anything)) - anything |= - argp_doc ((child++)->argp, state, - post, anything || pre_blank, first_only, - stream); - - return anything; -} - -/* Output a usage message for ARGP to STREAM. If called from - argp_state_help, STATE is the relevant parsing state. FLAGS are from the - set ARGP_HELP_*. NAME is what to use wherever a "program name" is - needed. */ -static void -_help (const struct argp *argp, const struct argp_state *state, FILE *stream, - unsigned flags, char *name) -{ - int anything = 0; /* Whether we've output anything. */ - struct hol *hol = 0; - argp_fmtstream_t fs; - - if (! stream) - return; - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - - if (! uparams.valid) - fill_in_uparams (state); - - fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); - if (! fs) - { -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - return; - } - - if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG)) - { - hol = argp_hol (argp, 0); - - /* If present, these options always come last. */ - hol_set_group (hol, "help", -1); - hol_set_group (hol, "version", -1); - - hol_sort (hol); - } - - if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE)) - /* Print a short "Usage:" message. */ - { - int first_pattern = 1, more_patterns; - size_t num_pattern_levels = argp_args_levels (argp); - char *pattern_levels = alloca (num_pattern_levels); - - memset (pattern_levels, 0, num_pattern_levels); - - do - { - int old_lm; - int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent); - char *levels = pattern_levels; - - if (first_pattern) - __argp_fmtstream_printf (fs, "%s %s", - dgettext (argp->argp_domain, "Usage:"), - name); - else - __argp_fmtstream_printf (fs, "%s %s", - dgettext (argp->argp_domain, " or: "), - name); - - /* We set the lmargin as well as the wmargin, because hol_usage - manually wraps options with newline to avoid annoying breaks. */ - old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent); - - if (flags & ARGP_HELP_SHORT_USAGE) - /* Just show where the options go. */ - { - if (hol->num_entries > 0) - __argp_fmtstream_puts (fs, dgettext (argp->argp_domain, - " [OPTION...]")); - } - else - /* Actually print the options. */ - { - hol_usage (hol, fs); - flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */ - } - - more_patterns = argp_args_usage (argp, state, &levels, 1, fs); - - __argp_fmtstream_set_wmargin (fs, old_wm); - __argp_fmtstream_set_lmargin (fs, old_lm); - - __argp_fmtstream_putc (fs, '\n'); - anything = 1; - - first_pattern = 0; - } - while (more_patterns); - } - - if (flags & ARGP_HELP_PRE_DOC) - anything |= argp_doc (argp, state, 0, 0, 1, fs); - - if (flags & ARGP_HELP_SEE) - { - __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\ -Try '%s --help' or '%s --usage' for more information.\n"), - name, name); - anything = 1; - } - - if (flags & ARGP_HELP_LONG) - /* Print a long, detailed help message. */ - { - /* Print info about all the options. */ - if (hol->num_entries > 0) - { - if (anything) - __argp_fmtstream_putc (fs, '\n'); - hol_help (hol, state, fs); - anything = 1; - } - } - - if (flags & ARGP_HELP_POST_DOC) - /* Print any documentation strings at the end. */ - anything |= argp_doc (argp, state, 1, anything, 0, fs); - - if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address) - { - if (anything) - __argp_fmtstream_putc (fs, '\n'); - __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, - "Report bugs to %s.\n"), - argp_program_bug_address); - anything = 1; - } - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - - if (hol) - hol_free (hol); - - __argp_fmtstream_free (fs); -} - -/* Output a usage message for ARGP to STREAM. FLAGS are from the set - ARGP_HELP_*. NAME is what to use wherever a "program name" is needed. */ -void __argp_help (const struct argp *argp, FILE *stream, - unsigned flags, char *name) -{ - struct argp_state state; - memset (&state, 0, sizeof state); - state.root_argp = argp; - _help (argp, &state, stream, flags, name); -} -#ifdef weak_alias -weak_alias (__argp_help, argp_help) -#endif - -#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME) -char * -__argp_short_program_name (void) -{ -# if HAVE_DECL_PROGRAM_INVOCATION_NAME - return __argp_base_name (program_invocation_name); -# else - /* FIXME: What now? Miles suggests that it is better to use NULL, - but currently the value is passed on directly to fputs_unlocked, - so that requires more changes. */ -# if __GNUC__ -# warning No reasonable value to return -# endif /* __GNUC__ */ - return ""; -# endif -} -#endif - -/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are - from the set ARGP_HELP_*. */ -void -__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) -{ - if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream) - { - if (state && (state->flags & ARGP_LONG_ONLY)) - flags |= ARGP_HELP_LONG_ONLY; - - _help (state ? state->root_argp : 0, state, stream, flags, - state ? state->name : __argp_short_program_name ()); - - if (!state || ! (state->flags & ARGP_NO_EXIT)) - { - if (flags & ARGP_HELP_EXIT_ERR) - exit (argp_err_exit_status); - if (flags & ARGP_HELP_EXIT_OK) - exit (0); - } - } -} -#ifdef weak_alias -weak_alias (__argp_state_help, argp_state_help) -#endif - -/* If appropriate, print the printf string FMT and following args, preceded - by the program name and ':', to stderr, and followed by a "Try ... --help" - message, then exit (1). */ -void -__argp_error (const struct argp_state *state, const char *fmt, ...) -{ - if (!state || !(state->flags & ARGP_NO_ERRS)) - { - FILE *stream = state ? state->err_stream : stderr; - - if (stream) - { - va_list ap; - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - - va_start (ap, fmt); - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - { - char *buf; - - if (__asprintf (&buf, fmt, ap) < 0) - buf = NULL; - - __fwprintf (stream, L"%s: %s\n", - state ? state->name : __argp_short_program_name (), - buf); - - free (buf); - } - else -#endif - { - fputs_unlocked (state - ? state->name : __argp_short_program_name (), - stream); - putc_unlocked (':', stream); - putc_unlocked (' ', stream); - - vfprintf (stream, fmt, ap); - - putc_unlocked ('\n', stream); - } - - __argp_state_help (state, stream, ARGP_HELP_STD_ERR); - - va_end (ap); - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - } - } -} -#ifdef weak_alias -weak_alias (__argp_error, argp_error) -#endif - -/* Similar to the standard gnu error-reporting function error(), but will - respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print - to STATE->err_stream. This is useful for argument parsing code that is - shared between program startup (when exiting is desired) and runtime - option parsing (when typically an error code is returned instead). The - difference between this function and argp_error is that the latter is for - *parsing errors*, and the former is for other problems that occur during - parsing but don't reflect a (syntactic) problem with the input. */ -void -__argp_failure (const struct argp_state *state, int status, int errnum, - const char *fmt, ...) -{ - if (!state || !(state->flags & ARGP_NO_ERRS)) - { - FILE *stream = state ? state->err_stream : stderr; - - if (stream) - { -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __flockfile (stream); -#endif - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - __fwprintf (stream, L"%s", - state ? state->name : __argp_short_program_name ()); - else -#endif - fputs_unlocked (state - ? state->name : __argp_short_program_name (), - stream); - - if (fmt) - { - va_list ap; - - va_start (ap, fmt); -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - { - char *buf; - - if (__asprintf (&buf, fmt, ap) < 0) - buf = NULL; - - __fwprintf (stream, L": %s", buf); - - free (buf); - } - else -#endif - { - putc_unlocked (':', stream); - putc_unlocked (' ', stream); - - vfprintf (stream, fmt, ap); - } - - va_end (ap); - } - - if (errnum) - { - char buf[200]; - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - __fwprintf (stream, L": %s", - __strerror_r (errnum, buf, sizeof (buf))); - else -#endif - { - char const *s = NULL; - putc_unlocked (':', stream); - putc_unlocked (' ', stream); -#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P && !defined strerror_r) - s = __strerror_r (errnum, buf, sizeof buf); -#elif HAVE_DECL_STRERROR_R - if (__strerror_r (errnum, buf, sizeof buf) == 0) - s = buf; -#endif -#if !_LIBC - if (! s && ! (s = strerror (errnum))) - s = dgettext (state->root_argp->argp_domain, - "Unknown system error"); -#endif - fputs (s, stream); - } - } - -#ifdef USE_IN_LIBIO - if (_IO_fwide (stream, 0) > 0) - putwc_unlocked (L'\n', stream); - else -#endif - putc_unlocked ('\n', stream); - -#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) - __funlockfile (stream); -#endif - - if (status && (!state || !(state->flags & ARGP_NO_EXIT))) - exit (status); - } - } -} -#ifdef weak_alias -weak_alias (__argp_failure, argp_failure) -#endif diff --git a/grub-core/gnulib/argp-namefrob.h b/grub-core/gnulib/argp-namefrob.h deleted file mode 100644 index 6333958c6..000000000 --- a/grub-core/gnulib/argp-namefrob.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Name frobnication for compiling argp outside of glibc - Copyright (C) 1997, 2003, 2007, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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 . */ - -#if !_LIBC -/* This code is written for inclusion in gnu-libc, and uses names in the - namespace reserved for libc. If we're not compiling in libc, define those - names to be the normal ones instead. */ - -/* argp-parse functions */ -#undef __argp_parse -#define __argp_parse argp_parse -#undef __option_is_end -#define __option_is_end _option_is_end -#undef __option_is_short -#define __option_is_short _option_is_short -#undef __argp_input -#define __argp_input _argp_input - -/* argp-help functions */ -#undef __argp_help -#define __argp_help argp_help -#undef __argp_error -#define __argp_error argp_error -#undef __argp_failure -#define __argp_failure argp_failure -#undef __argp_state_help -#define __argp_state_help argp_state_help -#undef __argp_usage -#define __argp_usage argp_usage - -/* argp-fmtstream functions */ -#undef __argp_make_fmtstream -#define __argp_make_fmtstream argp_make_fmtstream -#undef __argp_fmtstream_free -#define __argp_fmtstream_free argp_fmtstream_free -#undef __argp_fmtstream_putc -#define __argp_fmtstream_putc argp_fmtstream_putc -#undef __argp_fmtstream_puts -#define __argp_fmtstream_puts argp_fmtstream_puts -#undef __argp_fmtstream_write -#define __argp_fmtstream_write argp_fmtstream_write -#undef __argp_fmtstream_printf -#define __argp_fmtstream_printf argp_fmtstream_printf -#undef __argp_fmtstream_set_lmargin -#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin -#undef __argp_fmtstream_set_rmargin -#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin -#undef __argp_fmtstream_set_wmargin -#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin -#undef __argp_fmtstream_point -#define __argp_fmtstream_point argp_fmtstream_point -#undef __argp_fmtstream_update -#define __argp_fmtstream_update _argp_fmtstream_update -#undef __argp_fmtstream_ensure -#define __argp_fmtstream_ensure _argp_fmtstream_ensure -#undef __argp_fmtstream_lmargin -#define __argp_fmtstream_lmargin argp_fmtstream_lmargin -#undef __argp_fmtstream_rmargin -#define __argp_fmtstream_rmargin argp_fmtstream_rmargin -#undef __argp_fmtstream_wmargin -#define __argp_fmtstream_wmargin argp_fmtstream_wmargin - -/* normal libc functions we call */ -#undef __flockfile -#define __flockfile flockfile -#undef __funlockfile -#define __funlockfile funlockfile -#undef __mempcpy -#define __mempcpy mempcpy -#undef __sleep -#define __sleep sleep -#undef __strcasecmp -#define __strcasecmp strcasecmp -#undef __strchrnul -#define __strchrnul strchrnul -#undef __strerror_r -#define __strerror_r strerror_r -#undef __strndup -#define __strndup strndup -#undef __vsnprintf -#define __vsnprintf vsnprintf - -#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED -# define clearerr_unlocked(x) clearerr (x) -#endif -#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED -# define feof_unlocked(x) feof (x) -#endif -#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED -# define ferror_unlocked(x) ferror (x) -#endif -#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED -# define fflush_unlocked(x) fflush (x) -#endif -#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED -# define fgets_unlocked(x,y,z) fgets (x,y,z) -#endif -#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED -# define fputc_unlocked(x,y) fputc (x,y) -#endif -#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED -# define fputs_unlocked(x,y) fputs (x,y) -#endif -#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED -# define fread_unlocked(w,x,y,z) fread (w,x,y,z) -#endif -#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED -# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) -#endif -#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED -# define getc_unlocked(x) getc (x) -#endif -#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED -# define getchar_unlocked() getchar () -#endif -#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED -# define putc_unlocked(x,y) putc (x,y) -#endif -#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED -# define putchar_unlocked(x) putchar (x) -#endif - -#endif /* !_LIBC */ - -#ifndef __set_errno -# define __set_errno(e) (errno = (e)) -#endif - -#if defined GNULIB_ARGP_DISABLE_DIRNAME -# define __argp_base_name(arg) arg -#elif defined GNULIB_ARGP_EXTERN_BASENAME -extern char *__argp_base_name (const char *arg); -#else -# include "dirname.h" -# define __argp_base_name last_component -#endif - -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME -# define __argp_short_program_name() (program_invocation_short_name) -#else -extern char *__argp_short_program_name (void); -#endif diff --git a/grub-core/gnulib/argp-parse.c b/grub-core/gnulib/argp-parse.c deleted file mode 100644 index 67ea32c54..000000000 --- a/grub-core/gnulib/argp-parse.c +++ /dev/null @@ -1,953 +0,0 @@ -/* Hierarchical argument parsing, layered over getopt - Copyright (C) 1995-2000, 2002-2004, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _LIBC -# include -# undef dgettext -# define dgettext(domain, msgid) \ - INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) -#else -# include "gettext.h" -#endif -#define N_(msgid) msgid - -#include "argp.h" -#include "argp-namefrob.h" - -#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d)) - -/* Getopt return values. */ -#define KEY_END (-1) /* The end of the options. */ -#define KEY_ARG 1 /* A non-option argument. */ -#define KEY_ERR '?' /* An error parsing the options. */ - -/* The meta-argument used to prevent any further arguments being interpreted - as options. */ -#define QUOTE "--" - -/* The number of bits we steal in a long-option value for our own use. */ -#define GROUP_BITS CHAR_BIT - -/* The number of bits available for the user value. */ -#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS) -#define USER_MASK ((1 << USER_BITS) - 1) - -/* EZ alias for ARGP_ERR_UNKNOWN. */ -#define EBADKEY ARGP_ERR_UNKNOWN - -/* Default options. */ - -/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep - for one second intervals, decrementing _ARGP_HANG until it's zero. Thus - you can force the program to continue by attaching a debugger and setting - it to 0 yourself. */ -static volatile int _argp_hang; - -#define OPT_PROGNAME -2 -#define OPT_USAGE -3 -#define OPT_HANG -4 - -static const struct argp_option argp_default_options[] = -{ - {"help", '?', 0, 0, N_("give this help list"), -1}, - {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0}, - {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0}, - {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, - N_("hang for SECS seconds (default 3600)"), 0}, - {NULL, 0, 0, 0, NULL, 0} -}; - -static error_t -argp_default_parser (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case '?': - __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); - break; - case OPT_USAGE: - __argp_state_help (state, state->out_stream, - ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); - break; - - case OPT_PROGNAME: /* Set the program name. */ -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME - program_invocation_name = arg; -#endif - /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka - __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined - to be that, so we have to be a bit careful here.] */ - - /* Update what we use for messages. */ - state->name = __argp_base_name (arg); - -#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - program_invocation_short_name = state->name; -#endif - - if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) - == ARGP_PARSE_ARGV0) - /* Update what getopt uses too. */ - state->argv[0] = arg; - - break; - - case OPT_HANG: - _argp_hang = atoi (arg ? arg : "3600"); - while (_argp_hang-- > 0) - __sleep (1); - break; - - default: - return EBADKEY; - } - return 0; -} - -static const struct argp argp_default_argp = - {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; - - -static const struct argp_option argp_version_options[] = -{ - {"version", 'V', 0, 0, N_("print program version"), -1}, - {NULL, 0, 0, 0, NULL, 0} -}; - -static error_t -argp_version_parser (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 'V': - if (argp_program_version_hook) - (*argp_program_version_hook) (state->out_stream, state); - else if (argp_program_version) - fprintf (state->out_stream, "%s\n", argp_program_version); - else - __argp_error (state, "%s", - dgettext (state->root_argp->argp_domain, - "(PROGRAM ERROR) No version known!?")); - if (! (state->flags & ARGP_NO_EXIT)) - exit (0); - break; - default: - return EBADKEY; - } - return 0; -} - -static const struct argp argp_version_argp = - {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; - -/* Returns the offset into the getopt long options array LONG_OPTIONS of a - long option with called NAME, or -1 if none is found. Passing NULL as - NAME will return the number of options. */ -static int -find_long_option (struct option *long_options, const char *name) -{ - struct option *l = long_options; - while (l->name != NULL) - if (name != NULL && strcmp (l->name, name) == 0) - return l - long_options; - else - l++; - if (name == NULL) - return l - long_options; - else - return -1; -} - - -/* The state of a "group" during parsing. Each group corresponds to a - particular argp structure from the tree of such descending from the top - level argp passed to argp_parse. */ -struct group -{ - /* This group's parsing function. */ - argp_parser_t parser; - - /* Which argp this group is from. */ - const struct argp *argp; - - /* Points to the point in SHORT_OPTS corresponding to the end of the short - options for this group. We use it to determine from which group a - particular short options is from. */ - char *short_end; - - /* The number of non-option args successfully handled by this parser. */ - unsigned args_processed; - - /* This group's parser's parent's group. */ - struct group *parent; - unsigned parent_index; /* And the our position in the parent. */ - - /* These fields are swapped into and out of the state structure when - calling this group's parser. */ - void *input, **child_inputs; - void *hook; -}; - -/* Call GROUP's parser with KEY and ARG, swapping any group-specific info - from STATE before calling, and back into state afterwards. If GROUP has - no parser, EBADKEY is returned. */ -static error_t -group_parse (struct group *group, struct argp_state *state, int key, char *arg) -{ - if (group->parser) - { - error_t err; - state->hook = group->hook; - state->input = group->input; - state->child_inputs = group->child_inputs; - state->arg_num = group->args_processed; - err = (*group->parser)(key, arg, state); - group->hook = state->hook; - return err; - } - else - return EBADKEY; -} - -struct parser -{ - const struct argp *argp; - - /* SHORT_OPTS is the getopt short options string for the union of all the - groups of options. */ - char *short_opts; - /* LONG_OPTS is the array of getop long option structures for the union of - all the groups of options. */ - struct option *long_opts; - /* OPT_DATA is the getopt data used for the re-entrant getopt. */ - struct _getopt_data opt_data; - - /* States of the various parsing groups. */ - struct group *groups; - /* The end of the GROUPS array. */ - struct group *egroup; - /* A vector containing storage for the CHILD_INPUTS field in all groups. */ - void **child_inputs; - - /* True if we think using getopt is still useful; if false, then - remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is - cleared whenever getopt returns KEY_END, but may be set again if the user - moves the next argument pointer backwards. */ - int try_getopt; - - /* State block supplied to parsing routines. */ - struct argp_state state; - - /* Memory used by this parser. */ - void *storage; -}; - -/* The next usable entries in the various parser tables being filled in by - convert_options. */ -struct parser_convert_state -{ - struct parser *parser; - char *short_end; - struct option *long_end; - void **child_inputs_end; -}; - -/* Converts all options in ARGP (which is put in GROUP) and ancestors - into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and - CVT->LONG_END are the points at which new options are added. Returns the - next unused group entry. CVT holds state used during the conversion. */ -static struct group * -convert_options (const struct argp *argp, - struct group *parent, unsigned parent_index, - struct group *group, struct parser_convert_state *cvt) -{ - /* REAL is the most recent non-alias value of OPT. */ - const struct argp_option *real = argp->options; - const struct argp_child *children = argp->children; - - if (real || argp->parser) - { - const struct argp_option *opt; - - if (real) - for (opt = real; !__option_is_end (opt); opt++) - { - if (! (opt->flags & OPTION_ALIAS)) - /* OPT isn't an alias, so we can use values from it. */ - real = opt; - - if (! (real->flags & OPTION_DOC)) - /* A real option (not just documentation). */ - { - if (__option_is_short (opt)) - /* OPT can be used as a short option. */ - { - *cvt->short_end++ = opt->key; - if (real->arg) - { - *cvt->short_end++ = ':'; - if (real->flags & OPTION_ARG_OPTIONAL) - *cvt->short_end++ = ':'; - } - *cvt->short_end = '\0'; /* keep 0 terminated */ - } - - if (opt->name - && find_long_option (cvt->parser->long_opts, opt->name) < 0) - /* OPT can be used as a long option. */ - { - cvt->long_end->name = opt->name; - cvt->long_end->has_arg = - (real->arg - ? (real->flags & OPTION_ARG_OPTIONAL - ? optional_argument - : required_argument) - : no_argument); - cvt->long_end->flag = 0; - /* we add a disambiguating code to all the user's - values (which is removed before we actually call - the function to parse the value); this means that - the user loses use of the high 8 bits in all his - values (the sign of the lower bits is preserved - however)... */ - cvt->long_end->val = - ((opt->key ? opt->key : real->key) & USER_MASK) - + (((group - cvt->parser->groups) + 1) << USER_BITS); - - /* Keep the LONG_OPTS list terminated. */ - (++cvt->long_end)->name = NULL; - } - } - } - - group->parser = argp->parser; - group->argp = argp; - group->short_end = cvt->short_end; - group->args_processed = 0; - group->parent = parent; - group->parent_index = parent_index; - group->input = 0; - group->hook = 0; - group->child_inputs = 0; - - if (children) - /* Assign GROUP's CHILD_INPUTS field some space from - CVT->child_inputs_end.*/ - { - unsigned num_children = 0; - while (children[num_children].argp) - num_children++; - group->child_inputs = cvt->child_inputs_end; - cvt->child_inputs_end += num_children; - } - - parent = group++; - } - else - parent = 0; - - if (children) - { - unsigned index = 0; - while (children->argp) - group = - convert_options (children++->argp, parent, index++, group, cvt); - } - - return group; -} - -/* Find the merged set of getopt options, with keys appropriately prefixed. */ -static void -parser_convert (struct parser *parser, const struct argp *argp, int flags) -{ - struct parser_convert_state cvt; - - cvt.parser = parser; - cvt.short_end = parser->short_opts; - cvt.long_end = parser->long_opts; - cvt.child_inputs_end = parser->child_inputs; - - if (flags & ARGP_IN_ORDER) - *cvt.short_end++ = '-'; - else if (flags & ARGP_NO_ARGS) - *cvt.short_end++ = '+'; - *cvt.short_end = '\0'; - - cvt.long_end->name = NULL; - - parser->argp = argp; - - if (argp) - parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); - else - parser->egroup = parser->groups; /* No parsers at all! */ -} - -/* Lengths of various parser fields which we will allocated. */ -struct parser_sizes -{ - size_t short_len; /* Getopt short options string. */ - size_t long_len; /* Getopt long options vector. */ - size_t num_groups; /* Group structures we allocate. */ - size_t num_child_inputs; /* Child input slots. */ -}; - -/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of - argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by - the maximum lengths of the resulting merged getopt short options string and - long-options array, respectively. */ -static void -calc_sizes (const struct argp *argp, struct parser_sizes *szs) -{ - const struct argp_child *child = argp->children; - const struct argp_option *opt = argp->options; - - if (opt || argp->parser) - { - szs->num_groups++; - if (opt) - { - int num_opts = 0; - while (!__option_is_end (opt++)) - num_opts++; - szs->short_len += num_opts * 3; /* opt + up to 2 ':'s */ - szs->long_len += num_opts; - } - } - - if (child) - while (child->argp) - { - calc_sizes ((child++)->argp, szs); - szs->num_child_inputs++; - } -} - -/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ -static error_t -parser_init (struct parser *parser, const struct argp *argp, - int argc, char **argv, int flags, void *input) -{ - error_t err = 0; - struct group *group; - struct parser_sizes szs; - struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER; - char *storage; - size_t glen, gsum; - size_t clen, csum; - size_t llen, lsum; - size_t slen, ssum; - - szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; - szs.long_len = 0; - szs.num_groups = 0; - szs.num_child_inputs = 0; - - if (argp) - calc_sizes (argp, &szs); - - /* Lengths of the various bits of storage used by PARSER. */ - glen = (szs.num_groups + 1) * sizeof (struct group); - clen = szs.num_child_inputs * sizeof (void *); - llen = (szs.long_len + 1) * sizeof (struct option); - slen = szs.short_len + 1; - - /* Sums of previous lengths, properly aligned. There's no need to - align gsum, since struct group is aligned at least as strictly as - void * (since it contains a void * member). And there's no need - to align lsum, since struct option is aligned at least as - strictly as char. */ - gsum = glen; - csum = alignto (gsum + clen, alignof (struct option)); - lsum = csum + llen; - ssum = lsum + slen; - - parser->storage = malloc (ssum); - if (! parser->storage) - return ENOMEM; - - storage = parser->storage; - parser->groups = parser->storage; - parser->child_inputs = (void **) (storage + gsum); - parser->long_opts = (struct option *) (storage + csum); - parser->short_opts = storage + lsum; - parser->opt_data = opt_data; - - memset (parser->child_inputs, 0, clen); - parser_convert (parser, argp, flags); - - memset (&parser->state, 0, sizeof (struct argp_state)); - parser->state.root_argp = parser->argp; - parser->state.argc = argc; - parser->state.argv = argv; - parser->state.flags = flags; - parser->state.err_stream = stderr; - parser->state.out_stream = stdout; - parser->state.next = 0; /* Tell getopt to initialize. */ - parser->state.pstate = parser; - - parser->try_getopt = 1; - - /* Call each parser for the first time, giving it a chance to propagate - values to child parsers. */ - if (parser->groups < parser->egroup) - parser->groups->input = input; - for (group = parser->groups; - group < parser->egroup && (!err || err == EBADKEY); - group++) - { - if (group->parent) - /* If a child parser, get the initial input value from the parent. */ - group->input = group->parent->child_inputs[group->parent_index]; - - if (!group->parser - && group->argp->children && group->argp->children->argp) - /* For the special case where no parsing function is supplied for an - argp, propagate its input to its first child, if any (this just - makes very simple wrapper argps more convenient). */ - group->child_inputs[0] = group->input; - - err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); - } - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - - if (err) - return err; - - if (parser->state.flags & ARGP_NO_ERRS) - { - parser->opt_data.opterr = 0; - if (parser->state.flags & ARGP_PARSE_ARGV0) - /* getopt always skips ARGV[0], so we have to fake it out. As long - as OPTERR is 0, then it shouldn't actually try to access it. */ - parser->state.argv--, parser->state.argc++; - } - else - parser->opt_data.opterr = 1; /* Print error messages. */ - - if (parser->state.argv == argv && argv[0]) - /* There's an argv[0]; use it for messages. */ - parser->state.name = __argp_base_name (argv[0]); - else - parser->state.name = __argp_short_program_name (); - - return 0; -} - -/* Free any storage consumed by PARSER (but not PARSER itself). */ -static error_t -parser_finalize (struct parser *parser, - error_t err, int arg_ebadkey, int *end_index) -{ - struct group *group; - - if (err == EBADKEY && arg_ebadkey) - /* Suppress errors generated by unparsed arguments. */ - err = 0; - - if (! err) - { - if (parser->state.next == parser->state.argc) - /* We successfully parsed all arguments! Call all the parsers again, - just a few more times... */ - { - for (group = parser->groups; - group < parser->egroup && (!err || err==EBADKEY); - group++) - if (group->args_processed == 0) - err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); - for (group = parser->egroup - 1; - group >= parser->groups && (!err || err==EBADKEY); - group--) - err = group_parse (group, &parser->state, ARGP_KEY_END, 0); - - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - - /* Tell the user that all arguments are parsed. */ - if (end_index) - *end_index = parser->state.next; - } - else if (end_index) - /* Return any remaining arguments to the user. */ - *end_index = parser->state.next; - else - /* No way to return the remaining arguments, they must be bogus. */ - { - if (!(parser->state.flags & ARGP_NO_ERRS) - && parser->state.err_stream) - fprintf (parser->state.err_stream, - dgettext (parser->argp->argp_domain, - "%s: Too many arguments\n"), - parser->state.name); - err = EBADKEY; - } - } - - /* Okay, we're all done, with either an error or success; call the parsers - to indicate which one. */ - - if (err) - { - /* Maybe print an error message. */ - if (err == EBADKEY) - /* An appropriate message describing what the error was should have - been printed earlier. */ - __argp_state_help (&parser->state, parser->state.err_stream, - ARGP_HELP_STD_ERR); - - /* Since we didn't exit, give each parser an error indication. */ - for (group = parser->groups; group < parser->egroup; group++) - group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); - } - else - /* Notify parsers of success, and propagate back values from parsers. */ - { - /* We pass over the groups in reverse order so that child groups are - given a chance to do there processing before passing back a value to - the parent. */ - for (group = parser->egroup - 1 - ; group >= parser->groups && (!err || err == EBADKEY) - ; group--) - err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - } - - /* Call parsers once more, to do any final cleanup. Errors are ignored. */ - for (group = parser->egroup - 1; group >= parser->groups; group--) - group_parse (group, &parser->state, ARGP_KEY_FINI, 0); - - if (err == EBADKEY) - err = EINVAL; - - free (parser->storage); - - return err; -} - -/* Call the user parsers to parse the non-option argument VAL, at the current - position, returning any error. The state NEXT pointer is assumed to have - been adjusted (by getopt) to point after this argument; this function will - adjust it correctly to reflect however many args actually end up being - consumed. */ -static error_t -parser_parse_arg (struct parser *parser, char *val) -{ - /* Save the starting value of NEXT, first adjusting it so that the arg - we're parsing is again the front of the arg vector. */ - int index = --parser->state.next; - error_t err = EBADKEY; - struct group *group; - int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ - - /* Try to parse the argument in each parser. */ - for (group = parser->groups - ; group < parser->egroup && err == EBADKEY - ; group++) - { - parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ - key = ARGP_KEY_ARG; - err = group_parse (group, &parser->state, key, val); - - if (err == EBADKEY) - /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ - { - parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ - key = ARGP_KEY_ARGS; - err = group_parse (group, &parser->state, key, 0); - } - } - - if (! err) - { - if (key == ARGP_KEY_ARGS) - /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't - changed by the user, *all* arguments should be considered - consumed. */ - parser->state.next = parser->state.argc; - - if (parser->state.next > index) - /* Remember that we successfully processed a non-option - argument -- but only if the user hasn't gotten tricky and set - the clock back. */ - (--group)->args_processed += (parser->state.next - index); - else - /* The user wants to reparse some args, give getopt another try. */ - parser->try_getopt = 1; - } - - return err; -} - -/* Call the user parsers to parse the option OPT, with argument VAL, at the - current position, returning any error. */ -static error_t -parser_parse_opt (struct parser *parser, int opt, char *val) -{ - /* The group key encoded in the high bits; 0 for short opts or - group_number + 1 for long opts. */ - int group_key = opt >> USER_BITS; - error_t err = EBADKEY; - - if (group_key == 0) - /* A short option. By comparing OPT's position in SHORT_OPTS to the - various starting positions in each group's SHORT_END field, we can - determine which group OPT came from. */ - { - struct group *group; - char *short_index = strchr (parser->short_opts, opt); - - if (short_index) - for (group = parser->groups; group < parser->egroup; group++) - if (group->short_end > short_index) - { - err = group_parse (group, &parser->state, opt, - parser->opt_data.optarg); - break; - } - } - else - /* A long option. We use shifts instead of masking for extracting - the user value in order to preserve the sign. */ - err = - group_parse (&parser->groups[group_key - 1], &parser->state, - (opt << GROUP_BITS) >> GROUP_BITS, - parser->opt_data.optarg); - - if (err == EBADKEY) - /* At least currently, an option not recognized is an error in the - parser, because we pre-compute which parser is supposed to deal - with each option. */ - { - static const char bad_key_err[] = - N_("(PROGRAM ERROR) Option should have been recognized!?"); - if (group_key == 0) - __argp_error (&parser->state, "-%c: %s", opt, - dgettext (parser->argp->argp_domain, bad_key_err)); - else - { - struct option *long_opt = parser->long_opts; - while (long_opt->val != opt && long_opt->name) - long_opt++; - __argp_error (&parser->state, "--%s: %s", - long_opt->name ? long_opt->name : "???", - dgettext (parser->argp->argp_domain, bad_key_err)); - } - } - - return err; -} - -/* Parse the next argument in PARSER (as indicated by PARSER->state.next). - Any error from the parsers is returned, and *ARGP_EBADKEY indicates - whether a value of EBADKEY is due to an unrecognized argument (which is - generally not fatal). */ -static error_t -parser_parse_next (struct parser *parser, int *arg_ebadkey) -{ - int opt; - error_t err = 0; - - if (parser->state.quoted && parser->state.next < parser->state.quoted) - /* The next argument pointer has been moved to before the quoted - region, so pretend we never saw the quoting "--", and give getopt - another chance. If the user hasn't removed it, getopt will just - process it again. */ - parser->state.quoted = 0; - - if (parser->try_getopt && !parser->state.quoted) - /* Give getopt a chance to parse this. */ - { - /* Put it back in OPTIND for getopt. */ - parser->opt_data.optind = parser->state.next; - /* Distinguish KEY_ERR from a real option. */ - parser->opt_data.optopt = KEY_END; - if (parser->state.flags & ARGP_LONG_ONLY) - opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); - else - opt = _getopt_long_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); - /* And see what getopt did. */ - parser->state.next = parser->opt_data.optind; - - if (opt == KEY_END) - /* Getopt says there are no more options, so stop using - getopt; we'll continue if necessary on our own. */ - { - parser->try_getopt = 0; - if (parser->state.next > 1 - && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) - == 0) - /* Not only is this the end of the options, but it's a - "quoted" region, which may have args that *look* like - options, so we definitely shouldn't try to use getopt past - here, whatever happens. */ - parser->state.quoted = parser->state.next; - } - else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END) - /* KEY_ERR can have the same value as a valid user short - option, but in the case of a real error, getopt sets OPTOPT - to the offending character, which can never be KEY_END. */ - { - *arg_ebadkey = 0; - return EBADKEY; - } - } - else - opt = KEY_END; - - if (opt == KEY_END) - { - /* We're past what getopt considers the options. */ - if (parser->state.next >= parser->state.argc - || (parser->state.flags & ARGP_NO_ARGS)) - /* Indicate that we're done. */ - { - *arg_ebadkey = 1; - return EBADKEY; - } - else - /* A non-option arg; simulate what getopt might have done. */ - { - opt = KEY_ARG; - parser->opt_data.optarg = parser->state.argv[parser->state.next++]; - } - } - - if (opt == KEY_ARG) - /* A non-option argument; try each parser in turn. */ - err = parser_parse_arg (parser, parser->opt_data.optarg); - else - err = parser_parse_opt (parser, opt, parser->opt_data.optarg); - - if (err == EBADKEY) - *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); - - return err; -} - -/* Parse the options strings in ARGC & ARGV according to the argp in ARGP. - FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the - index in ARGV of the first unparsed option is returned in it. If an - unknown option is present, EINVAL is returned; if some parser routine - returned a non-zero value, it is returned; otherwise 0 is returned. */ -error_t -__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, - int *end_index, void *input) -{ - error_t err; - struct parser parser; - - /* If true, then err == EBADKEY is a result of a non-option argument failing - to be parsed (which in some cases isn't actually an error). */ - int arg_ebadkey = 0; - -#ifndef _LIBC - if (!(flags & ARGP_PARSE_ARGV0)) - { -#if HAVE_DECL_PROGRAM_INVOCATION_NAME - if (!program_invocation_name) - program_invocation_name = argv[0]; -#endif -#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - if (!program_invocation_short_name) - program_invocation_short_name = __argp_base_name (argv[0]); -#endif - } -#endif - - if (! (flags & ARGP_NO_HELP)) - /* Add our own options. */ - { - struct argp_child *child = alloca (4 * sizeof (struct argp_child)); - struct argp *top_argp = alloca (sizeof (struct argp)); - - /* TOP_ARGP has no options, it just serves to group the user & default - argps. */ - memset (top_argp, 0, sizeof (*top_argp)); - top_argp->children = child; - - memset (child, 0, 4 * sizeof (struct argp_child)); - - if (argp) - (child++)->argp = argp; - (child++)->argp = &argp_default_argp; - if (argp_program_version || argp_program_version_hook) - (child++)->argp = &argp_version_argp; - child->argp = 0; - - argp = top_argp; - } - - /* Construct a parser for these arguments. */ - err = parser_init (&parser, argp, argc, argv, flags, input); - - if (! err) - /* Parse! */ - { - while (! err) - err = parser_parse_next (&parser, &arg_ebadkey); - err = parser_finalize (&parser, err, arg_ebadkey, end_index); - } - - return err; -} -#ifdef weak_alias -weak_alias (__argp_parse, argp_parse) -#endif - -/* Return the input field for ARGP in the parser corresponding to STATE; used - by the help routines. */ -void * -__argp_input (const struct argp *argp, const struct argp_state *state) -{ - if (state && state->pstate) - { - struct group *group; - struct parser *parser = state->pstate; - - for (group = parser->groups; group < parser->egroup; group++) - if (group->argp == argp) - return group->input; - } - - return 0; -} -#ifdef weak_alias -weak_alias (__argp_input, _argp_input) -#endif diff --git a/grub-core/gnulib/argp-pin.c b/grub-core/gnulib/argp-pin.c deleted file mode 100644 index 78cbb355b..000000000 --- a/grub-core/gnulib/argp-pin.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Full and short program names for argp module - Copyright (C) 2005, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME -char *program_invocation_short_name = 0; -#endif -#ifndef HAVE_PROGRAM_INVOCATION_NAME -char *program_invocation_name = 0; -#endif diff --git a/grub-core/gnulib/argp-pv.c b/grub-core/gnulib/argp-pv.c deleted file mode 100644 index c74070d12..000000000 --- a/grub-core/gnulib/argp-pv.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Default definition for ARGP_PROGRAM_VERSION. - Copyright (C) 1996-1997, 1999, 2006, 2009-2013 Free Software Foundation, - Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - 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 . */ - -/* If set by the user program to a non-zero value, then a default option - --version is added (unless the ARGP_NO_HELP flag is used), which will - print this string followed by a newline and exit (unless the - ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ -const char *argp_program_version -/* This variable should be zero-initialized. On most systems, putting it into - BSS is sufficient. Not so on Mac OS X 10.3 and 10.4, see - - . */ -#if defined __ELF__ - /* On ELF systems, variables in BSS behave well. */ -#else - = (const char *) 0 -#endif - ; diff --git a/grub-core/gnulib/argp-pvh.c b/grub-core/gnulib/argp-pvh.c deleted file mode 100644 index 885ff4b75..000000000 --- a/grub-core/gnulib/argp-pvh.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Default definition for ARGP_PROGRAM_VERSION_HOOK. - Copyright (C) 1996-1997, 1999, 2004, 2009-2013 Free Software Foundation, - Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "argp.h" - -/* If set by the user program to a non-zero value, then a default option - --version is added (unless the ARGP_NO_HELP flag is used), which calls - this function with a stream to print the version to and a pointer to the - current parsing state, and then exits (unless the ARGP_NO_EXIT flag is - used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ -void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL; diff --git a/grub-core/gnulib/argp-xinl.c b/grub-core/gnulib/argp-xinl.c deleted file mode 100644 index 04d8cf703..000000000 --- a/grub-core/gnulib/argp-xinl.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Real definitions for extern inline functions in argp.h - Copyright (C) 1997-1998, 2004, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if defined _LIBC || defined HAVE_FEATURES_H -# include -#endif - -#ifndef __USE_EXTERN_INLINES -# define __USE_EXTERN_INLINES 1 -#endif -#ifdef _LIBC -# define ARGP_EI -#else -# define ARGP_EI _GL_EXTERN_INLINE -#endif -#undef __OPTIMIZE__ -#define __OPTIMIZE__ 1 -#include "argp.h" - -/* Add weak aliases. */ -#if _LIBC - 0 && defined (weak_alias) - -weak_alias (__argp_usage, argp_usage) -weak_alias (__option_is_short, _option_is_short) -weak_alias (__option_is_end, _option_is_end) - -#endif diff --git a/grub-core/gnulib/argp.h b/grub-core/gnulib/argp.h deleted file mode 100644 index c4094a40c..000000000 --- a/grub-core/gnulib/argp.h +++ /dev/null @@ -1,650 +0,0 @@ -/* Hierarchical argument parsing, layered over getopt. - Copyright (C) 1995-1999, 2003-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Miles Bader . - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _ARGP_H -#define _ARGP_H - -#include -#include -#include -#include - -#define __need_error_t -#include - -#ifndef __THROW -# define __THROW -#endif -#ifndef __NTH -# define __NTH(fct) fct __THROW -#endif - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The __-protected variants of the attributes 'format' and 'printf' are - accepted by gcc versions 2.6.4 (effectively 2.7) and later. - We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because - gnulib and libintl do '#define printf __printf__' when they override - the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -#else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". - Other compilers use __restrict, __restrict__, and _Restrict, and - 'configure' might #define 'restrict' to those words. */ -#ifndef __restrict -# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) -# if 199901L <= __STDC_VERSION__ -# define __restrict restrict -# else -# define __restrict -# endif -# endif -#endif - -#ifndef __error_t_defined -typedef int error_t; -# define __error_t_defined -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* A description of a particular option. A pointer to an array of - these is passed in the OPTIONS field of an argp structure. Each option - entry can correspond to one long option and/or one short option; more - names for the same option can be added by following an entry in an option - array with options having the OPTION_ALIAS flag set. */ -struct argp_option -{ - /* The long option name. For more than one name for the same option, you - can use following options with the OPTION_ALIAS flag set. */ - const char *name; - - /* What key is returned for this option. If > 0 and printable, then it's - also accepted as a short option. */ - int key; - - /* If non-NULL, this is the name of the argument associated with this - option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ - const char *arg; - - /* OPTION_ flags. */ - int flags; - - /* The doc string for this option. If both NAME and KEY are 0, This string - will be printed outdented from the normal option column, making it - useful as a group header (it will be the first thing printed in its - group); in this usage, it's conventional to end the string with a ':'. - - Write the initial value as N_("TEXT") if you want xgettext to collect - it into a POT file. */ - const char *doc; - - /* The group this option is in. In a long help message, options are sorted - alphabetically within each group, and the groups presented in the order - 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with - if this field 0 will inherit the group number of the previous entry, or - zero if it's the first one, unless its a group header (NAME and KEY both - 0), in which case, the previous entry + 1 is the default. Automagic - options such as --help are put into group -1. */ - int group; -}; - -/* The argument associated with this option is optional. */ -#define OPTION_ARG_OPTIONAL 0x1 - -/* This option isn't displayed in any help messages. */ -#define OPTION_HIDDEN 0x2 - -/* This option is an alias for the closest previous non-alias option. This - means that it will be displayed in the same help entry, and will inherit - fields other than NAME and KEY from the aliased option. */ -#define OPTION_ALIAS 0x4 - -/* This option isn't actually an option (and so should be ignored by the - actual option parser), but rather an arbitrary piece of documentation that - should be displayed in much the same manner as the options. If this flag - is set, then the option NAME field is displayed unmodified (e.g., no '--' - prefix is added) at the left-margin (where a *short* option would normally - be displayed), and the documentation string in the normal place. The NAME - field will be translated using gettext, unless OPTION_NO_TRANS is set (see - below). For purposes of sorting, any leading whitespace and punctuation is - ignored, except that if the first non-whitespace character is not '-', this - entry is displayed after all options (and OPTION_DOC entries with a leading - '-') in the same group. */ -#define OPTION_DOC 0x8 - -/* This option shouldn't be included in "long" usage messages (but is still - included in help messages). This is mainly intended for options that are - completely documented in an argp's ARGS_DOC field, in which case including - the option in the generic usage list would be redundant. For instance, - if ARGS_DOC is "FOO BAR\n-x BLAH", and the '-x' option's purpose is to - distinguish these two cases, -x should probably be marked - OPTION_NO_USAGE. */ -#define OPTION_NO_USAGE 0x10 - -/* Valid only in conjunction with OPTION_DOC. This option disables translation - of option name. */ -#define OPTION_NO_TRANS 0x20 - - -struct argp; /* fwd declare this type */ -struct argp_state; /* " */ -struct argp_child; /* " */ - -/* The type of a pointer to an argp parsing function. */ -typedef error_t (*argp_parser_t) (int key, char *arg, - struct argp_state *state); - -/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such - returns will simply be ignored. For user keys, this error will be turned - into EINVAL (if the call to argp_parse is such that errors are propagated - back to the user instead of exiting); returning EINVAL itself would result - in an immediate stop to parsing in *all* cases. */ -#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ - -/* Special values for the KEY argument to an argument parsing function. - ARGP_ERR_UNKNOWN should be returned if they aren't understood. - - The sequence of keys to a parsing function is either (where each - uppercased word should be prefixed by 'ARGP_KEY_' and opt is a user key): - - INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all - or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed - or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized - - The third case is where every parser returned ARGP_KEY_UNKNOWN for an - argument, in which case parsing stops at that argument (returning the - unparsed arguments to the caller of argp_parse if requested, or stopping - with an error message if not). - - If an error occurs (either detected by argp, or because the parsing - function returned an error value), then the parser is called with - ARGP_KEY_ERROR, and no further calls are made. */ - -/* This is not an option at all, but rather a command line argument. If a - parser receiving this key returns success, the fact is recorded, and the - ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the - argument, a parser function decrements the NEXT field of the state it's - passed, the option won't be considered processed; this is to allow you to - actually modify the argument (perhaps into an option), and have it - processed again. */ -#define ARGP_KEY_ARG 0 -/* There are remaining arguments not parsed by any parser, which may be found - starting at (STATE->argv + STATE->next). If success is returned, but - STATE->next left untouched, it's assumed that all arguments were consume, - otherwise, the parser should adjust STATE->next to reflect any arguments - consumed. */ -#define ARGP_KEY_ARGS 0x1000006 -/* There are no more command line arguments at all. */ -#define ARGP_KEY_END 0x1000001 -/* Because it's common to want to do some special processing if there aren't - any non-option args, user parsers are called with this key if they didn't - successfully process any non-option arguments. Called just before - ARGP_KEY_END (where more general validity checks on previously parsed - arguments can take place). */ -#define ARGP_KEY_NO_ARGS 0x1000002 -/* Passed in before any parsing is done. Afterwards, the values of each - element of the CHILD_INPUT field, if any, in the state structure is - copied to each child's state to be the initial value of the INPUT field. */ -#define ARGP_KEY_INIT 0x1000003 -/* Use after all other keys, including SUCCESS & END. */ -#define ARGP_KEY_FINI 0x1000007 -/* Passed in when parsing has successfully been completed (even if there are - still arguments remaining). */ -#define ARGP_KEY_SUCCESS 0x1000004 -/* Passed in if an error occurs. */ -#define ARGP_KEY_ERROR 0x1000005 - -/* An argp structure contains a set of options declarations, a function to - deal with parsing one, documentation string, a possible vector of child - argp's, and perhaps a function to filter help output. When actually - parsing options, getopt is called with the union of all the argp - structures chained together through their CHILD pointers, with conflicts - being resolved in favor of the first occurrence in the chain. */ -struct argp -{ - /* An array of argp_option structures, terminated by an entry with both - NAME and KEY having a value of 0. */ - const struct argp_option *options; - - /* What to do with an option from this structure. KEY is the key - associated with the option, and ARG is any associated argument (NULL if - none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be - returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then - parsing is stopped immediately, and that value is returned from - argp_parse(). For special (non-user-supplied) values of KEY, see the - ARGP_KEY_ definitions below. */ - argp_parser_t parser; - - /* A string describing what other arguments are wanted by this program. It - is only used by argp_usage to print the "Usage:" message. If it - contains newlines, the strings separated by them are considered - alternative usage patterns, and printed on separate lines (lines after - the first are prefix by " or: " instead of "Usage:"). */ - const char *args_doc; - - /* If non-NULL, a string containing extra text to be printed before and - after the options in a long help message (separated by a vertical tab - '\v' character). - Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if - you want xgettext to collect the two pieces of text into a POT file. */ - const char *doc; - - /* A vector of argp_children structures, terminated by a member with a 0 - argp field, pointing to child argps should be parsed with this one. Any - conflicts are resolved in favor of this argp, or early argps in the - CHILDREN list. This field is useful if you use libraries that supply - their own argp structure, which you want to use in conjunction with your - own. */ - const struct argp_child *children; - - /* If non-zero, this should be a function to filter the output of help - messages. KEY is either a key from an option, in which case TEXT is - that option's help text, or a special key from the ARGP_KEY_HELP_ - defines, below, describing which other help text TEXT is. The function - should return either TEXT, if it should be used as-is, a replacement - string, which should be malloced, and will be freed by argp, or NULL, - meaning "print nothing". The value for TEXT is *after* any translation - has been done, so if any of the replacement text also needs translation, - that should be done by the filter function. INPUT is either the input - supplied to argp_parse, or NULL, if argp_help was called directly. */ - char *(*help_filter) (int __key, const char *__text, void *__input); - - /* If non-zero the strings used in the argp library are translated using - the domain described by this string. Otherwise the currently installed - default domain is used. */ - const char *argp_domain; -}; - -/* Possible KEY arguments to a help filter function. */ -#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceding options. */ -#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ -#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ -#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; - TEXT is NULL for this key. */ -/* Explanatory note emitted when duplicate option arguments have been - suppressed. */ -#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 -#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ - -/* When an argp has a non-zero CHILDREN field, it should point to a vector of - argp_child structures, each of which describes a subsidiary argp. */ -struct argp_child -{ - /* The child parser. */ - const struct argp *argp; - - /* Flags for this child. */ - int flags; - - /* If non-zero, an optional header to be printed in help output before the - child options. As a side-effect, a non-zero value forces the child - options to be grouped together; to achieve this effect without actually - printing a header string, use a value of "". */ - const char *header; - - /* Where to group the child options relative to the other ("consolidated") - options in the parent argp; the values are the same as the GROUP field - in argp_option structs, but all child-groupings follow parent options at - a particular group level. If both this field and HEADER are zero, then - they aren't grouped at all, but rather merged with the parent options - (merging the child's grouping levels with the parents). */ - int group; -}; - -/* Parsing state. This is provided to parsing functions called by argp, - which may examine and, as noted, modify fields. */ -struct argp_state -{ - /* The top level ARGP being parsed. */ - const struct argp *root_argp; - - /* The argument vector being parsed. May be modified. */ - int argc; - char **argv; - - /* The index in ARGV of the next arg that to be parsed. May be modified. */ - int next; - - /* The flags supplied to argp_parse. May be modified. */ - unsigned flags; - - /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the - number of the current arg, starting at zero, and incremented after each - such call returns. At all other times, this is the number of such - arguments that have been processed. */ - unsigned arg_num; - - /* If non-zero, the index in ARGV of the first argument following a special - '--' argument (which prevents anything following being interpreted as an - option). Only set once argument parsing has proceeded past this point. */ - int quoted; - - /* An arbitrary pointer passed in from the user. */ - void *input; - /* Values to pass to child parsers. This vector will be the same length as - the number of children for the current parser. */ - void **child_inputs; - - /* For the parser's use. Initialized to 0. */ - void *hook; - - /* The name used when printing messages. This is initialized to ARGV[0], - or PROGRAM_INVOCATION_NAME if that is unavailable. */ - char *name; - - /* Streams used when argp prints something. */ - FILE *err_stream; /* For errors; initialized to stderr. */ - FILE *out_stream; /* For information; initialized to stdout. */ - - void *pstate; /* Private, for use by argp. */ -}; - -/* Flags for argp_parse (note that the defaults are those that are - convenient for program command line parsing): */ - -/* Don't ignore the first element of ARGV. Normally (and always unless - ARGP_NO_ERRS is set) the first element of the argument vector is - skipped for option parsing purposes, as it corresponds to the program name - in a command line. */ -#define ARGP_PARSE_ARGV0 0x01 - -/* Don't print error messages for unknown options to stderr; unless this flag - is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program - name in the error messages. This flag implies ARGP_NO_EXIT (on the - assumption that silent exiting upon errors is bad behaviour). */ -#define ARGP_NO_ERRS 0x02 - -/* Don't parse any non-option args. Normally non-option args are parsed by - calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg - as the value. Since it's impossible to know which parse function wants to - handle it, each one is called in turn, until one returns 0 or an error - other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the - argp_parse returns prematurely (but with a return value of 0). If all - args have been parsed without error, all parsing functions are called one - last time with a key of ARGP_KEY_END. This flag needn't normally be set, - as the normal behavior is to stop parsing as soon as some argument can't - be handled. */ -#define ARGP_NO_ARGS 0x04 - -/* Parse options and arguments in the same order they occur on the command - line -- normally they're rearranged so that all options come first. */ -#define ARGP_IN_ORDER 0x08 - -/* Don't provide the standard long option --help, which causes usage and - option help information to be output to stdout, and exit (0) called. */ -#define ARGP_NO_HELP 0x10 - -/* Don't exit on errors (they may still result in error messages). */ -#define ARGP_NO_EXIT 0x20 - -/* Use the gnu getopt "long-only" rules for parsing arguments. */ -#define ARGP_LONG_ONLY 0x40 - -/* Turns off any message-printing/exiting options. */ -#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) - -/* Parse the options strings in ARGC & ARGV according to the options in ARGP. - FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the - index in ARGV of the first unparsed option is returned in it. If an - unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser - routine returned a non-zero value, it is returned; otherwise 0 is - returned. This function may also call exit unless the ARGP_NO_HELP flag - is set. INPUT is a pointer to a value to be passed in to the parser. */ -extern error_t argp_parse (const struct argp *__restrict __argp, - int /*argc*/, char **__restrict /*argv*/, - unsigned __flags, int *__restrict __arg_index, - void *__restrict __input); -extern error_t __argp_parse (const struct argp *__restrict __argp, - int /*argc*/, char **__restrict /*argv*/, - unsigned __flags, int *__restrict __arg_index, - void *__restrict __input); - -/* Global variables. */ - -/* GNULIB makes sure both program_invocation_name and - program_invocation_short_name are available */ -#ifdef GNULIB_PROGRAM_INVOCATION_NAME -extern char *program_invocation_name; -# undef HAVE_DECL_PROGRAM_INVOCATION_NAME -# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 -#endif - -#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME -extern char *program_invocation_short_name; -# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME -# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 -#endif - -/* If defined or set by the user program to a non-zero value, then a default - option --version is added (unless the ARGP_NO_HELP flag is used), which - will print this string followed by a newline and exit (unless the - ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ -extern const char *argp_program_version; - -/* If defined or set by the user program to a non-zero value, then a default - option --version is added (unless the ARGP_NO_HELP flag is used), which - calls this function with a stream to print the version to and a pointer to - the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is - used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ -extern void (*argp_program_version_hook) (FILE *__restrict __stream, - struct argp_state *__restrict - __state); - -/* If defined or set by the user program, it should point to string that is - the bug-reporting address for the program. It will be printed by - argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various - standard help messages), embedded in a sentence that says something like - "Report bugs to ADDR." */ -extern const char *argp_program_bug_address; - -/* The exit status that argp will use when exiting due to a parsing error. - If not defined or set by the user program, this defaults to EX_USAGE from - . */ -extern error_t argp_err_exit_status; - -/* Flags for argp_help. */ -#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ -#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ -#define ARGP_HELP_SEE 0x04 /* a "Try ... for more help" message. */ -#define ARGP_HELP_LONG 0x08 /* a long help message. */ -#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ -#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ -#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) -#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ -#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to - reflect ARGP_LONG_ONLY mode. */ - -/* These ARGP_HELP flags are only understood by argp_state_help. */ -#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ -#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ - -/* The standard thing to do after a program command line parsing error, if an - error message has already been printed. */ -#define ARGP_HELP_STD_ERR \ - (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) -/* The standard thing to do after a program command line parsing error, if no - more specific error message has been printed. */ -#define ARGP_HELP_STD_USAGE \ - (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) -/* The standard thing to do in response to a --help option. */ -#define ARGP_HELP_STD_HELP \ - (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ - | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) - -/* Output a usage message for ARGP to STREAM. FLAGS are from the set - ARGP_HELP_*. */ -extern void argp_help (const struct argp *__restrict __argp, - FILE *__restrict __stream, - unsigned __flags, char *__restrict __name); -extern void __argp_help (const struct argp *__restrict __argp, - FILE *__restrict __stream, unsigned __flags, - char *__name); - -/* The following routines are intended to be called from within an argp - parsing routine (thus taking an argp_state structure as the first - argument). They may or may not print an error message and exit, depending - on the flags in STATE -- in any case, the caller should be prepared for - them *not* to exit, and should return an appropriate error after calling - them. [argp_usage & argp_error should probably be called argp_state_..., - but they're used often enough that they should be short] */ - -/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are - from the set ARGP_HELP_*. */ -extern void argp_state_help (const struct argp_state *__restrict __state, - FILE *__restrict __stream, - unsigned int __flags); -extern void __argp_state_help (const struct argp_state *__restrict __state, - FILE *__restrict __stream, - unsigned int __flags); - -#if _LIBC -/* Possibly output the standard usage message for ARGP to stderr and exit. */ -extern void argp_usage (const struct argp_state *__state); -extern void __argp_usage (const struct argp_state *__state); -#endif - -/* If appropriate, print the printf string FMT and following args, preceded - by the program name and ':', to stderr, and followed by a "Try ... --help" - message, then exit (1). */ -extern void argp_error (const struct argp_state *__restrict __state, - const char *__restrict __fmt, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 2, 3)); -extern void __argp_error (const struct argp_state *__restrict __state, - const char *__restrict __fmt, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 2, 3)); - -/* Similar to the standard gnu error-reporting function error(), but will - respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print - to STATE->err_stream. This is useful for argument parsing code that is - shared between program startup (when exiting is desired) and runtime - option parsing (when typically an error code is returned instead). The - difference between this function and argp_error is that the latter is for - *parsing errors*, and the former is for other problems that occur during - parsing but don't reflect a (syntactic) problem with the input. */ -extern void argp_failure (const struct argp_state *__restrict __state, - int __status, int __errnum, - const char *__restrict __fmt, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 4, 5)); -extern void __argp_failure (const struct argp_state *__restrict __state, - int __status, int __errnum, - const char *__restrict __fmt, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 4, 5)); - -#if _LIBC -/* Returns true if the option OPT is a valid short option. */ -extern int _option_is_short (const struct argp_option *__opt) __THROW; -extern int __option_is_short (const struct argp_option *__opt) __THROW; - -/* Returns true if the option OPT is in fact the last (unused) entry in an - options array. */ -extern int _option_is_end (const struct argp_option *__opt) __THROW; -extern int __option_is_end (const struct argp_option *__opt) __THROW; -#endif - -/* Return the input field for ARGP in the parser corresponding to STATE; used - by the help routines. */ -extern void *_argp_input (const struct argp *__restrict __argp, - const struct argp_state *__restrict __state) - __THROW; -extern void *__argp_input (const struct argp *__restrict __argp, - const struct argp_state *__restrict __state) - __THROW; - -#if !_LIBC || defined __USE_EXTERN_INLINES - -# if !_LIBC -# define __argp_usage argp_usage -# define __argp_state_help argp_state_help -# define __option_is_short _option_is_short -# define __option_is_end _option_is_end -_GL_INLINE_HEADER_BEGIN -# ifndef ARGP_EI -# define ARGP_EI _GL_INLINE -# endif -# endif - -# ifndef ARGP_EI -# ifdef __GNUC__ - /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 - inline semantics, unless -fgnu89-inline is used. It defines a macro - __GNUC_STDC_INLINE__ to indicate this situation or a macro - __GNUC_GNU_INLINE__ to indicate the opposite situation. - GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline - semantics but warns, unless -fgnu89-inline is used: - warning: C99 inline functions are not supported; using GNU89 - warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute - It defines a macro __GNUC_GNU_INLINE__ to indicate this situation. */ -# if defined __GNUC_STDC_INLINE__ -# define ARGP_EI __inline__ -# elif defined __GNUC_GNU_INLINE__ -# define ARGP_EI extern __inline__ __attribute__ ((__gnu_inline__)) -# else -# define ARGP_EI extern __inline__ -# endif -# else - /* With other compilers, assume the ISO C99 meaning of 'inline', if - the compiler supports 'inline' at all. */ -# define ARGP_EI inline -# endif -# endif - -ARGP_EI void -__argp_usage (const struct argp_state *__state) -{ - __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); -} - -ARGP_EI int -__NTH (__option_is_short (const struct argp_option *__opt)) -{ - if (__opt->flags & OPTION_DOC) - return 0; - else - { - int __key = __opt->key; - return __key > 0 && __key <= UCHAR_MAX && isprint (__key); - } -} - -ARGP_EI int -__NTH (__option_is_end (const struct argp_option *__opt)) -{ - return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; -} - -# if !_LIBC -# undef __argp_usage -# undef __argp_state_help -# undef __option_is_short -# undef __option_is_end -_GL_INLINE_HEADER_END -# endif -#endif /* Use extern inlines. */ - -#ifdef __cplusplus -} -#endif - -#endif /* argp.h */ diff --git a/grub-core/gnulib/asnprintf.c b/grub-core/gnulib/asnprintf.c deleted file mode 100644 index 76e228d86..000000000 --- a/grub-core/gnulib/asnprintf.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Formatted output to strings. - Copyright (C) 1999, 2002, 2006, 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#include - -/* Specification. */ -#include "vasnprintf.h" - -#include - -char * -asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) -{ - va_list args; - char *result; - - va_start (args, format); - result = vasnprintf (resultbuf, lengthp, format, args); - va_end (args); - return result; -} diff --git a/grub-core/gnulib/basename-lgpl.c b/grub-core/gnulib/basename-lgpl.c deleted file mode 100644 index 9307e8314..000000000 --- a/grub-core/gnulib/basename-lgpl.c +++ /dev/null @@ -1,75 +0,0 @@ -/* basename.c -- return the last element in a file name - - Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2013 Free Software - Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "dirname.h" - -#include - -/* Return the address of the last file name component of NAME. If - NAME has no relative file name components because it is a file - system root, return the empty string. */ - -char * -last_component (char const *name) -{ - char const *base = name + FILE_SYSTEM_PREFIX_LEN (name); - char const *p; - bool saw_slash = false; - - while (ISSLASH (*base)) - base++; - - for (p = base; *p; p++) - { - if (ISSLASH (*p)) - saw_slash = true; - else if (saw_slash) - { - base = p; - saw_slash = false; - } - } - - return (char *) base; -} - -/* Return the length of the basename NAME. Typically NAME is the - value returned by base_name or last_component. Act like strlen - (NAME), except omit all trailing slashes. */ - -size_t -base_len (char const *name) -{ - size_t len; - size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name); - - for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--) - continue; - - if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1 - && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2]) - return 2; - - if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len - && len == prefix_len && ISSLASH (name[prefix_len])) - return prefix_len + 1; - - return len; -} diff --git a/grub-core/gnulib/btowc.c b/grub-core/gnulib/btowc.c deleted file mode 100644 index 6c7cbec9d..000000000 --- a/grub-core/gnulib/btowc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Convert unibyte character to wide character. - Copyright (C) 2008, 2010-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2008. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#include -#include - -wint_t -btowc (int c) -{ - if (c != EOF) - { - char buf[1]; - wchar_t wc; - - buf[0] = c; - if (mbtowc (&wc, buf, 1) >= 0) - return wc; - } - return WEOF; -} diff --git a/grub-core/gnulib/config.charset b/grub-core/gnulib/config.charset deleted file mode 100644 index a991419cd..000000000 --- a/grub-core/gnulib/config.charset +++ /dev/null @@ -1,684 +0,0 @@ -#! /bin/sh -# Output a system dependent table of character encoding aliases. -# -# Copyright (C) 2000-2004, 2006-2013 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, 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 . -# -# The table consists of lines of the form -# ALIAS CANONICAL -# -# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". -# ALIAS is compared in a case sensitive way. -# -# CANONICAL is the GNU canonical name for this character encoding. -# It must be an encoding supported by libiconv. Support by GNU libc is -# also desirable. CANONICAL is case insensitive. Usually an upper case -# MIME charset name is preferred. -# The current list of GNU canonical charset names is as follows. -# -# name MIME? used by which systems -# (darwin = Mac OS X, woe32 = native Windows) -# -# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin cygwin -# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin -# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin -# ISO-8859-3 Y glibc solaris cygwin -# ISO-8859-4 Y osf solaris freebsd netbsd openbsd darwin -# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin -# ISO-8859-6 Y glibc aix hpux solaris cygwin -# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin -# ISO-8859-8 Y glibc aix hpux osf solaris cygwin -# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin cygwin -# ISO-8859-13 glibc netbsd openbsd darwin cygwin -# ISO-8859-14 glibc cygwin -# ISO-8859-15 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin -# KOI8-R Y glibc solaris freebsd netbsd openbsd darwin -# KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin -# KOI8-T glibc -# CP437 dos -# CP775 dos -# CP850 aix osf dos -# CP852 dos -# CP855 dos -# CP856 aix -# CP857 dos -# CP861 dos -# CP862 dos -# CP864 dos -# CP865 dos -# CP866 freebsd netbsd openbsd darwin dos -# CP869 dos -# CP874 woe32 dos -# CP922 aix -# CP932 aix cygwin woe32 dos -# CP943 aix -# CP949 osf darwin woe32 dos -# CP950 woe32 dos -# CP1046 aix -# CP1124 aix -# CP1125 dos -# CP1129 aix -# CP1131 darwin -# CP1250 woe32 -# CP1251 glibc solaris netbsd openbsd darwin cygwin woe32 -# CP1252 aix woe32 -# CP1253 woe32 -# CP1254 woe32 -# CP1255 glibc woe32 -# CP1256 woe32 -# CP1257 woe32 -# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin -# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin -# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin -# EUC-TW glibc aix hpux irix osf solaris netbsd -# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin -# BIG5-HKSCS glibc solaris darwin -# GBK glibc aix osf solaris darwin cygwin woe32 dos -# GB18030 glibc solaris netbsd darwin -# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin -# JOHAB glibc solaris woe32 -# TIS-620 glibc aix hpux osf solaris cygwin -# VISCII Y glibc -# TCVN5712-1 glibc -# ARMSCII-8 glibc darwin -# GEORGIAN-PS glibc cygwin -# PT154 glibc -# HP-ROMAN8 hpux -# HP-ARABIC8 hpux -# HP-GREEK8 hpux -# HP-HEBREW8 hpux -# HP-TURKISH8 hpux -# HP-KANA8 hpux -# DEC-KANJI osf -# DEC-HANYU osf -# UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin -# -# Note: Names which are not marked as being a MIME name should not be used in -# Internet protocols for information interchange (mail, news, etc.). -# -# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications -# must understand both names and treat them as equivalent. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM - -host="$1" -os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` -echo "# This file contains a table of character encoding aliases," -echo "# suitable for operating system '${os}'." -echo "# It was automatically generated from config.charset." -# List of references, updated during installation: -echo "# Packages using this file: " -case "$os" in - linux-gnulibc1*) - # Linux libc5 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "C ASCII" - echo "POSIX ASCII" - for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \ - en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \ - en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \ - es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \ - et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \ - fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \ - it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \ - sv_FI sv_SE; do - echo "$l ISO-8859-1" - echo "$l.iso-8859-1 ISO-8859-1" - echo "$l.iso-8859-15 ISO-8859-15" - echo "$l.iso-8859-15@euro ISO-8859-15" - echo "$l@euro ISO-8859-15" - echo "$l.cp-437 CP437" - echo "$l.cp-850 CP850" - echo "$l.cp-1252 CP1252" - echo "$l.cp-1252@euro CP1252" - #echo "$l.atari-st ATARI-ST" # not a commonly used encoding - echo "$l.utf-8 UTF-8" - echo "$l.utf-8@euro UTF-8" - done - for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \ - sl_SI sr sr_CS sr_YU; do - echo "$l ISO-8859-2" - echo "$l.iso-8859-2 ISO-8859-2" - echo "$l.cp-852 CP852" - echo "$l.cp-1250 CP1250" - echo "$l.utf-8 UTF-8" - done - for l in mk mk_MK ru ru_RU; do - echo "$l ISO-8859-5" - echo "$l.iso-8859-5 ISO-8859-5" - echo "$l.koi8-r KOI8-R" - echo "$l.cp-866 CP866" - echo "$l.cp-1251 CP1251" - echo "$l.utf-8 UTF-8" - done - for l in ar ar_SA; do - echo "$l ISO-8859-6" - echo "$l.iso-8859-6 ISO-8859-6" - echo "$l.cp-864 CP864" - #echo "$l.cp-868 CP868" # not a commonly used encoding - echo "$l.cp-1256 CP1256" - echo "$l.utf-8 UTF-8" - done - for l in el el_GR gr gr_GR; do - echo "$l ISO-8859-7" - echo "$l.iso-8859-7 ISO-8859-7" - echo "$l.cp-869 CP869" - echo "$l.cp-1253 CP1253" - echo "$l.cp-1253@euro CP1253" - echo "$l.utf-8 UTF-8" - echo "$l.utf-8@euro UTF-8" - done - for l in he he_IL iw iw_IL; do - echo "$l ISO-8859-8" - echo "$l.iso-8859-8 ISO-8859-8" - echo "$l.cp-862 CP862" - echo "$l.cp-1255 CP1255" - echo "$l.utf-8 UTF-8" - done - for l in tr tr_TR; do - echo "$l ISO-8859-9" - echo "$l.iso-8859-9 ISO-8859-9" - echo "$l.cp-857 CP857" - echo "$l.cp-1254 CP1254" - echo "$l.utf-8 UTF-8" - done - for l in lt lt_LT lv lv_LV; do - #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name - echo "$l ISO-8859-13" - done - for l in ru_UA uk uk_UA; do - echo "$l KOI8-U" - done - for l in zh zh_CN; do - #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name - echo "$l GB2312" - done - for l in ja ja_JP ja_JP.EUC; do - echo "$l EUC-JP" - done - for l in ko ko_KR; do - echo "$l EUC-KR" - done - for l in th th_TH; do - echo "$l TIS-620" - done - for l in fa fa_IR; do - #echo "$l ISIRI-3342" # a broken encoding - echo "$l.utf-8 UTF-8" - done - ;; - linux* | *-gnu*) - # With glibc-2.1 or newer, we don't need any canonicalization, - # because glibc has iconv and both glibc and libiconv support all - # GNU canonical names directly. Therefore, the Makefile does not - # need to install the alias file at all. - # The following applies only to glibc-2.0.x and older libcs. - echo "ISO_646.IRV:1983 ASCII" - ;; - aix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "IBM-850 CP850" - echo "IBM-856 CP856" - echo "IBM-921 ISO-8859-13" - echo "IBM-922 CP922" - echo "IBM-932 CP932" - echo "IBM-943 CP943" - echo "IBM-1046 CP1046" - echo "IBM-1124 CP1124" - echo "IBM-1129 CP1129" - echo "IBM-1252 CP1252" - echo "IBM-eucCN GB2312" - echo "IBM-eucJP EUC-JP" - echo "IBM-eucKR EUC-KR" - echo "IBM-eucTW EUC-TW" - echo "big5 BIG5" - echo "GBK GBK" - echo "TIS-620 TIS-620" - echo "UTF-8 UTF-8" - ;; - hpux*) - echo "iso88591 ISO-8859-1" - echo "iso88592 ISO-8859-2" - echo "iso88595 ISO-8859-5" - echo "iso88596 ISO-8859-6" - echo "iso88597 ISO-8859-7" - echo "iso88598 ISO-8859-8" - echo "iso88599 ISO-8859-9" - echo "iso885915 ISO-8859-15" - echo "roman8 HP-ROMAN8" - echo "arabic8 HP-ARABIC8" - echo "greek8 HP-GREEK8" - echo "hebrew8 HP-HEBREW8" - echo "turkish8 HP-TURKISH8" - echo "kana8 HP-KANA8" - echo "tis620 TIS-620" - echo "big5 BIG5" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "hp15CN GB2312" - #echo "ccdc ?" # what is this? - echo "SJIS SHIFT_JIS" - echo "utf8 UTF-8" - ;; - irix*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-9 ISO-8859-9" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - ;; - osf*) - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "cp850 CP850" - echo "big5 BIG5" - echo "dechanyu DEC-HANYU" - echo "dechanzi GB2312" - echo "deckanji DEC-KANJI" - echo "deckorean EUC-KR" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "GBK GBK" - echo "KSC5601 CP949" - echo "sdeckanji EUC-JP" - echo "SJIS SHIFT_JIS" - echo "TACTIS TIS-620" - echo "UTF-8 UTF-8" - ;; - solaris*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-3 ISO-8859-3" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-6 ISO-8859-6" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-8 ISO-8859-8" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-15 ISO-8859-15" - echo "koi8-r KOI8-R" - echo "ansi-1251 CP1251" - echo "BIG5 BIG5" - echo "Big5-HKSCS BIG5-HKSCS" - echo "gb2312 GB2312" - echo "GBK GBK" - echo "GB18030 GB18030" - echo "cns11643 EUC-TW" - echo "5601 EUC-KR" - echo "ko_KR.johap92 JOHAB" - echo "eucJP EUC-JP" - echo "PCK SHIFT_JIS" - echo "TIS620.2533 TIS-620" - #echo "sun_eu_greek ?" # what is this? - echo "UTF-8 UTF-8" - ;; - freebsd* | os2*) - # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just - # reuse FreeBSD's locale data for OS/2. - echo "C ASCII" - echo "US-ASCII ASCII" - for l in la_LN lt_LN; do - echo "$l.ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ - lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do - echo "$l.ISO_8859-1 ISO-8859-1" - echo "$l.DIS_8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do - echo "$l.ISO_8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO_8859-4 ISO-8859-4" - done - for l in ru_RU ru_SU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO_8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ja_JP.Shift_JIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - netbsd*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-13 ISO-8859-13" - echo "ISO8859-15 ISO-8859-15" - echo "eucCN GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "eucTW EUC-TW" - echo "BIG5 BIG5" - echo "SJIS SHIFT_JIS" - ;; - openbsd*) - echo "646 ASCII" - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-13 ISO-8859-13" - echo "ISO8859-15 ISO-8859-15" - ;; - darwin[56]*) - # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "C ASCII" - for l in en_AU en_CA en_GB en_US la_LN; do - echo "$l.US-ASCII ASCII" - done - for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ - fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \ - nl_NL no_NO pt_PT sv_SE; do - echo "$l ISO-8859-1" - echo "$l.ISO8859-1 ISO-8859-1" - echo "$l.ISO8859-15 ISO-8859-15" - done - for l in la_LN; do - echo "$l.ISO8859-1 ISO-8859-1" - echo "$l.ISO8859-15 ISO-8859-15" - done - for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do - echo "$l.ISO8859-2 ISO-8859-2" - done - for l in la_LN lt_LT; do - echo "$l.ISO8859-4 ISO-8859-4" - done - for l in ru_RU; do - echo "$l.KOI8-R KOI8-R" - echo "$l.ISO8859-5 ISO-8859-5" - echo "$l.CP866 CP866" - done - for l in bg_BG; do - echo "$l.CP1251 CP1251" - done - echo "uk_UA.KOI8-U KOI8-U" - echo "zh_TW.BIG5 BIG5" - echo "zh_TW.Big5 BIG5" - echo "zh_CN.EUC GB2312" - echo "ja_JP.EUC EUC-JP" - echo "ja_JP.SJIS SHIFT_JIS" - echo "ko_KR.EUC EUC-KR" - ;; - darwin*) - # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is - # useless: - # - It returns the empty string when LANG is set to a locale of the - # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 - # LC_CTYPE file. - # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by - # the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. - # - The documentation says: - # "... all code that calls BSD system routines should ensure - # that the const *char parameters of these routines are in UTF-8 - # encoding. All BSD system functions expect their string - # parameters to be in UTF-8 encoding and nothing else." - # It also says - # "An additional caveat is that string parameters for files, - # paths, and other file-system entities must be in canonical - # UTF-8. In a canonical UTF-8 Unicode string, all decomposable - # characters are decomposed ..." - # but this is not true: You can pass non-decomposed UTF-8 strings - # to file system functions, and it is the OS which will convert - # them to decomposed UTF-8 before accessing the file system. - # - The Apple Terminal application displays UTF-8 by default. - # - However, other applications are free to use different encodings: - # - xterm uses ISO-8859-1 by default. - # - TextEdit uses MacRoman by default. - # We prefer UTF-8 over decomposed UTF-8-MAC because one should - # minimize the use of decomposed Unicode. Unfortunately, through the - # Darwin file system, decomposed UTF-8 strings are leaked into user - # space nevertheless. - # Then there are also the locales with encodings other than US-ASCII - # and UTF-8. These locales can be occasionally useful to users (e.g. - # when grepping through ISO-8859-1 encoded text files), when all their - # file names are in US-ASCII. - echo "ISO8859-1 ISO-8859-1" - echo "ISO8859-2 ISO-8859-2" - echo "ISO8859-4 ISO-8859-4" - echo "ISO8859-5 ISO-8859-5" - echo "ISO8859-7 ISO-8859-7" - echo "ISO8859-9 ISO-8859-9" - echo "ISO8859-13 ISO-8859-13" - echo "ISO8859-15 ISO-8859-15" - echo "KOI8-R KOI8-R" - echo "KOI8-U KOI8-U" - echo "CP866 CP866" - echo "CP949 CP949" - echo "CP1131 CP1131" - echo "CP1251 CP1251" - echo "eucCN GB2312" - echo "GB2312 GB2312" - echo "eucJP EUC-JP" - echo "eucKR EUC-KR" - echo "Big5 BIG5" - echo "Big5HKSCS BIG5-HKSCS" - echo "GBK GBK" - echo "GB18030 GB18030" - echo "SJIS SHIFT_JIS" - echo "ARMSCII-8 ARMSCII-8" - echo "PT154 PT154" - #echo "ISCII-DEV ?" - echo "* UTF-8" - ;; - beos* | haiku*) - # BeOS and Haiku have a single locale, and it has UTF-8 encoding. - echo "* UTF-8" - ;; - msdosdjgpp*) - # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore - # localcharset.c falls back to using the full locale name - # from the environment variables. - echo "#" - echo "# The encodings given here may not all be correct." - echo "# If you find that the encoding given for your language and" - echo "# country is not the one your DOS machine actually uses, just" - echo "# correct it in this file, and send a mail to" - echo "# Juan Manuel Guerrero " - echo "# and Bruno Haible ." - echo "#" - echo "C ASCII" - # ISO-8859-1 languages - echo "ca CP850" - echo "ca_ES CP850" - echo "da CP865" # not CP850 ?? - echo "da_DK CP865" # not CP850 ?? - echo "de CP850" - echo "de_AT CP850" - echo "de_CH CP850" - echo "de_DE CP850" - echo "en CP850" - echo "en_AU CP850" # not CP437 ?? - echo "en_CA CP850" - echo "en_GB CP850" - echo "en_NZ CP437" - echo "en_US CP437" - echo "en_ZA CP850" # not CP437 ?? - echo "es CP850" - echo "es_AR CP850" - echo "es_BO CP850" - echo "es_CL CP850" - echo "es_CO CP850" - echo "es_CR CP850" - echo "es_CU CP850" - echo "es_DO CP850" - echo "es_EC CP850" - echo "es_ES CP850" - echo "es_GT CP850" - echo "es_HN CP850" - echo "es_MX CP850" - echo "es_NI CP850" - echo "es_PA CP850" - echo "es_PY CP850" - echo "es_PE CP850" - echo "es_SV CP850" - echo "es_UY CP850" - echo "es_VE CP850" - echo "et CP850" - echo "et_EE CP850" - echo "eu CP850" - echo "eu_ES CP850" - echo "fi CP850" - echo "fi_FI CP850" - echo "fr CP850" - echo "fr_BE CP850" - echo "fr_CA CP850" - echo "fr_CH CP850" - echo "fr_FR CP850" - echo "ga CP850" - echo "ga_IE CP850" - echo "gd CP850" - echo "gd_GB CP850" - echo "gl CP850" - echo "gl_ES CP850" - echo "id CP850" # not CP437 ?? - echo "id_ID CP850" # not CP437 ?? - echo "is CP861" # not CP850 ?? - echo "is_IS CP861" # not CP850 ?? - echo "it CP850" - echo "it_CH CP850" - echo "it_IT CP850" - echo "lt CP775" - echo "lt_LT CP775" - echo "lv CP775" - echo "lv_LV CP775" - echo "nb CP865" # not CP850 ?? - echo "nb_NO CP865" # not CP850 ?? - echo "nl CP850" - echo "nl_BE CP850" - echo "nl_NL CP850" - echo "nn CP865" # not CP850 ?? - echo "nn_NO CP865" # not CP850 ?? - echo "no CP865" # not CP850 ?? - echo "no_NO CP865" # not CP850 ?? - echo "pt CP850" - echo "pt_BR CP850" - echo "pt_PT CP850" - echo "sv CP850" - echo "sv_SE CP850" - # ISO-8859-2 languages - echo "cs CP852" - echo "cs_CZ CP852" - echo "hr CP852" - echo "hr_HR CP852" - echo "hu CP852" - echo "hu_HU CP852" - echo "pl CP852" - echo "pl_PL CP852" - echo "ro CP852" - echo "ro_RO CP852" - echo "sk CP852" - echo "sk_SK CP852" - echo "sl CP852" - echo "sl_SI CP852" - echo "sq CP852" - echo "sq_AL CP852" - echo "sr CP852" # CP852 or CP866 or CP855 ?? - echo "sr_CS CP852" # CP852 or CP866 or CP855 ?? - echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? - # ISO-8859-3 languages - echo "mt CP850" - echo "mt_MT CP850" - # ISO-8859-5 languages - echo "be CP866" - echo "be_BE CP866" - echo "bg CP866" # not CP855 ?? - echo "bg_BG CP866" # not CP855 ?? - echo "mk CP866" # not CP855 ?? - echo "mk_MK CP866" # not CP855 ?? - echo "ru CP866" - echo "ru_RU CP866" - echo "uk CP1125" - echo "uk_UA CP1125" - # ISO-8859-6 languages - echo "ar CP864" - echo "ar_AE CP864" - echo "ar_DZ CP864" - echo "ar_EG CP864" - echo "ar_IQ CP864" - echo "ar_IR CP864" - echo "ar_JO CP864" - echo "ar_KW CP864" - echo "ar_MA CP864" - echo "ar_OM CP864" - echo "ar_QA CP864" - echo "ar_SA CP864" - echo "ar_SY CP864" - # ISO-8859-7 languages - echo "el CP869" - echo "el_GR CP869" - # ISO-8859-8 languages - echo "he CP862" - echo "he_IL CP862" - # ISO-8859-9 languages - echo "tr CP857" - echo "tr_TR CP857" - # Japanese - echo "ja CP932" - echo "ja_JP CP932" - # Chinese - echo "zh_CN GBK" - echo "zh_TW CP950" # not CP938 ?? - # Korean - echo "kr CP949" # not CP934 ?? - echo "kr_KR CP949" # not CP934 ?? - # Thai - echo "th CP874" - echo "th_TH CP874" - # Other - echo "eo CP850" - echo "eo_EO CP850" - ;; -esac diff --git a/grub-core/gnulib/dirname-lgpl.c b/grub-core/gnulib/dirname-lgpl.c deleted file mode 100644 index 82f66301f..000000000 --- a/grub-core/gnulib/dirname-lgpl.c +++ /dev/null @@ -1,86 +0,0 @@ -/* dirname.c -- return all but the last element in a file name - - Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2013 Free Software - Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "dirname.h" - -#include -#include - -/* Return the length of the prefix of FILE that will be used by - dir_name. If FILE is in the working directory, this returns zero - even though 'dir_name (FILE)' will return ".". Works properly even - if there are trailing slashes (by effectively ignoring them). */ - -size_t -dir_len (char const *file) -{ - size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file); - size_t length; - - /* Advance prefix_length beyond important leading slashes. */ - prefix_length += (prefix_length != 0 - ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE - && ISSLASH (file[prefix_length])) - : (ISSLASH (file[0]) - ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT - && ISSLASH (file[1]) && ! ISSLASH (file[2]) - ? 2 : 1)) - : 0)); - - /* Strip the basename and any redundant slashes before it. */ - for (length = last_component (file) - file; - prefix_length < length; length--) - if (! ISSLASH (file[length - 1])) - break; - return length; -} - - -/* In general, we can't use the builtin 'dirname' function if available, - since it has different meanings in different environments. - In some environments the builtin 'dirname' modifies its argument. - - Return the leading directories part of FILE, allocated with malloc. - Works properly even if there are trailing slashes (by effectively - ignoring them). Return NULL on failure. - - If lstat (FILE) would succeed, then { chdir (dir_name (FILE)); - lstat (base_name (FILE)); } will access the same file. Likewise, - if the sequence { chdir (dir_name (FILE)); - rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE - to "foo" in the same directory FILE was in. */ - -char * -mdir_name (char const *file) -{ - size_t length = dir_len (file); - bool append_dot = (length == 0 - || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE - && length == FILE_SYSTEM_PREFIX_LEN (file) - && file[2] != '\0' && ! ISSLASH (file[2]))); - char *dir = malloc (length + append_dot + 1); - if (!dir) - return NULL; - memcpy (dir, file, length); - if (append_dot) - dir[length++] = '.'; - dir[length] = '\0'; - return dir; -} diff --git a/grub-core/gnulib/dirname.h b/grub-core/gnulib/dirname.h deleted file mode 100644 index 4ad031200..000000000 --- a/grub-core/gnulib/dirname.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Take file names apart into directory and base names. - - Copyright (C) 1998, 2001, 2003-2006, 2009-2013 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef DIRNAME_H_ -# define DIRNAME_H_ 1 - -# include -# include -# include "dosname.h" - -# ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -# endif - -# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT -# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 -# endif - -# if GNULIB_DIRNAME -char *base_name (char const *file); -char *dir_name (char const *file); -# endif - -char *mdir_name (char const *file); -size_t base_len (char const *file) _GL_ATTRIBUTE_PURE; -size_t dir_len (char const *file) _GL_ATTRIBUTE_PURE; -char *last_component (char const *file) _GL_ATTRIBUTE_PURE; - -bool strip_trailing_slashes (char *file); - -#endif /* not DIRNAME_H_ */ diff --git a/grub-core/gnulib/dosname.h b/grub-core/gnulib/dosname.h deleted file mode 100644 index ba63ce4bd..000000000 --- a/grub-core/gnulib/dosname.h +++ /dev/null @@ -1,53 +0,0 @@ -/* File names on MS-DOS/Windows systems. - - Copyright (C) 2000-2001, 2004-2006, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - From Paul Eggert and Jim Meyering. */ - -#ifndef _DOSNAME_H -#define _DOSNAME_H - -#if (defined _WIN32 || defined __WIN32__ || \ - defined __MSDOS__ || defined __CYGWIN__ || \ - defined __EMX__ || defined __DJGPP__) - /* This internal macro assumes ASCII, but all hosts that support drive - letters use ASCII. */ -# define _IS_DRIVE_LETTER(C) (((unsigned int) (C) | ('a' - 'A')) - 'a' \ - <= 'z' - 'a') -# define FILE_SYSTEM_PREFIX_LEN(Filename) \ - (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) -# ifndef __CYGWIN__ -# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 -# endif -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#else -# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 -# define ISSLASH(C) ((C) == '/') -#endif - -#ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 -#endif - -#if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE -# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) -# else -# define IS_ABSOLUTE_FILE_NAME(F) \ - (ISSLASH ((F)[0]) || FILE_SYSTEM_PREFIX_LEN (F) != 0) -#endif -#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) - -#endif /* DOSNAME_H_ */ diff --git a/grub-core/gnulib/errno.in.h b/grub-core/gnulib/errno.in.h deleted file mode 100644 index 49b35464b..000000000 --- a/grub-core/gnulib/errno.in.h +++ /dev/null @@ -1,279 +0,0 @@ -/* A POSIX-like . - - Copyright (C) 2008-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _@GUARD_PREFIX@_ERRNO_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_ERRNO_H@ - -#ifndef _@GUARD_PREFIX@_ERRNO_H -#define _@GUARD_PREFIX@_ERRNO_H - - -/* On native Windows platforms, many macros are not defined. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - -/* These are the same values as defined by MSVC 10, for interoperability. */ - -# ifndef ENOMSG -# define ENOMSG 122 -# define GNULIB_defined_ENOMSG 1 -# endif - -# ifndef EIDRM -# define EIDRM 111 -# define GNULIB_defined_EIDRM 1 -# endif - -# ifndef ENOLINK -# define ENOLINK 121 -# define GNULIB_defined_ENOLINK 1 -# endif - -# ifndef EPROTO -# define EPROTO 134 -# define GNULIB_defined_EPROTO 1 -# endif - -# ifndef EBADMSG -# define EBADMSG 104 -# define GNULIB_defined_EBADMSG 1 -# endif - -# ifndef EOVERFLOW -# define EOVERFLOW 132 -# define GNULIB_defined_EOVERFLOW 1 -# endif - -# ifndef ENOTSUP -# define ENOTSUP 129 -# define GNULIB_defined_ENOTSUP 1 -# endif - -# ifndef ENETRESET -# define ENETRESET 117 -# define GNULIB_defined_ENETRESET 1 -# endif - -# ifndef ECONNABORTED -# define ECONNABORTED 106 -# define GNULIB_defined_ECONNABORTED 1 -# endif - -# ifndef ECANCELED -# define ECANCELED 105 -# define GNULIB_defined_ECANCELED 1 -# endif - -# ifndef EOWNERDEAD -# define EOWNERDEAD 133 -# define GNULIB_defined_EOWNERDEAD 1 -# endif - -# ifndef ENOTRECOVERABLE -# define ENOTRECOVERABLE 127 -# define GNULIB_defined_ENOTRECOVERABLE 1 -# endif - -# ifndef EINPROGRESS -# define EINPROGRESS 112 -# define EALREADY 103 -# define ENOTSOCK 128 -# define EDESTADDRREQ 109 -# define EMSGSIZE 115 -# define EPROTOTYPE 136 -# define ENOPROTOOPT 123 -# define EPROTONOSUPPORT 135 -# define EOPNOTSUPP 130 -# define EAFNOSUPPORT 102 -# define EADDRINUSE 100 -# define EADDRNOTAVAIL 101 -# define ENETDOWN 116 -# define ENETUNREACH 118 -# define ECONNRESET 108 -# define ENOBUFS 119 -# define EISCONN 113 -# define ENOTCONN 126 -# define ETIMEDOUT 138 -# define ECONNREFUSED 107 -# define ELOOP 114 -# define EHOSTUNREACH 110 -# define EWOULDBLOCK 140 -# define GNULIB_defined_ESOCK 1 -# endif - -# ifndef ETXTBSY -# define ETXTBSY 139 -# define ENODATA 120 /* not required by POSIX */ -# define ENOSR 124 /* not required by POSIX */ -# define ENOSTR 125 /* not required by POSIX */ -# define ETIME 137 /* not required by POSIX */ -# define EOTHER 131 /* not required by POSIX */ -# define GNULIB_defined_ESTREAMS 1 -# endif - -/* These are intentionally the same values as the WSA* error numbers, defined - in . */ -# define ESOCKTNOSUPPORT 10044 /* not required by POSIX */ -# define EPFNOSUPPORT 10046 /* not required by POSIX */ -# define ESHUTDOWN 10058 /* not required by POSIX */ -# define ETOOMANYREFS 10059 /* not required by POSIX */ -# define EHOSTDOWN 10064 /* not required by POSIX */ -# define EPROCLIM 10067 /* not required by POSIX */ -# define EUSERS 10068 /* not required by POSIX */ -# define EDQUOT 10069 -# define ESTALE 10070 -# define EREMOTE 10071 /* not required by POSIX */ -# define GNULIB_defined_EWINSOCK 1 - -# endif - - -/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros - EMULTIHOP, ENOLINK, EOVERFLOW are not defined. */ -# if @EMULTIHOP_HIDDEN@ -# define EMULTIHOP @EMULTIHOP_VALUE@ -# define GNULIB_defined_EMULTIHOP 1 -# endif -# if @ENOLINK_HIDDEN@ -# define ENOLINK @ENOLINK_VALUE@ -# define GNULIB_defined_ENOLINK 1 -# endif -# if @EOVERFLOW_HIDDEN@ -# define EOVERFLOW @EOVERFLOW_VALUE@ -# define GNULIB_defined_EOVERFLOW 1 -# endif - - -/* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK, - EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined. - Likewise, on NonStop Kernel, EDQUOT is not defined. - Define them here. Values >= 2000 seem safe to use: Solaris ESTALE = 151, - HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133. - - Note: When one of these systems defines some of these macros some day, - binaries will have to be recompiled so that they recognizes the new - errno values from the system. */ - -# ifndef ENOMSG -# define ENOMSG 2000 -# define GNULIB_defined_ENOMSG 1 -# endif - -# ifndef EIDRM -# define EIDRM 2001 -# define GNULIB_defined_EIDRM 1 -# endif - -# ifndef ENOLINK -# define ENOLINK 2002 -# define GNULIB_defined_ENOLINK 1 -# endif - -# ifndef EPROTO -# define EPROTO 2003 -# define GNULIB_defined_EPROTO 1 -# endif - -# ifndef EMULTIHOP -# define EMULTIHOP 2004 -# define GNULIB_defined_EMULTIHOP 1 -# endif - -# ifndef EBADMSG -# define EBADMSG 2005 -# define GNULIB_defined_EBADMSG 1 -# endif - -# ifndef EOVERFLOW -# define EOVERFLOW 2006 -# define GNULIB_defined_EOVERFLOW 1 -# endif - -# ifndef ENOTSUP -# define ENOTSUP 2007 -# define GNULIB_defined_ENOTSUP 1 -# endif - -# ifndef ENETRESET -# define ENETRESET 2011 -# define GNULIB_defined_ENETRESET 1 -# endif - -# ifndef ECONNABORTED -# define ECONNABORTED 2012 -# define GNULIB_defined_ECONNABORTED 1 -# endif - -# ifndef ESTALE -# define ESTALE 2009 -# define GNULIB_defined_ESTALE 1 -# endif - -# ifndef EDQUOT -# define EDQUOT 2010 -# define GNULIB_defined_EDQUOT 1 -# endif - -# ifndef ECANCELED -# define ECANCELED 2008 -# define GNULIB_defined_ECANCELED 1 -# endif - -/* On many platforms, the macros EOWNERDEAD and ENOTRECOVERABLE are not - defined. */ - -# ifndef EOWNERDEAD -# if defined __sun - /* Use the same values as defined for Solaris >= 8, for - interoperability. */ -# define EOWNERDEAD 58 -# define ENOTRECOVERABLE 59 -# elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - /* We have a conflict here: pthreads-win32 defines these values - differently than MSVC 10. It's hairy to decide which one to use. */ -# if defined __MINGW32__ && !defined USE_WINDOWS_THREADS - /* Use the same values as defined by pthreads-win32, for - interoperability. */ -# define EOWNERDEAD 43 -# define ENOTRECOVERABLE 44 -# else - /* Use the same values as defined by MSVC 10, for - interoperability. */ -# define EOWNERDEAD 133 -# define ENOTRECOVERABLE 127 -# endif -# else -# define EOWNERDEAD 2013 -# define ENOTRECOVERABLE 2014 -# endif -# define GNULIB_defined_EOWNERDEAD 1 -# define GNULIB_defined_ENOTRECOVERABLE 1 -# endif - -# ifndef EILSEQ -# define EILSEQ 2015 -# define GNULIB_defined_EILSEQ 1 -# endif - -#endif /* _@GUARD_PREFIX@_ERRNO_H */ -#endif /* _@GUARD_PREFIX@_ERRNO_H */ diff --git a/grub-core/gnulib/error.c b/grub-core/gnulib/error.c deleted file mode 100644 index 865b29340..000000000 --- a/grub-core/gnulib/error.c +++ /dev/null @@ -1,401 +0,0 @@ -/* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000-2007, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by David MacKenzie . */ - -#if !_LIBC -# include -#endif - -#include "error.h" - -#include -#include -#include -#include - -#if !_LIBC && ENABLE_NLS -# include "gettext.h" -# define _(msgid) gettext (msgid) -#endif - -#ifdef _LIBC -# include -# include -# include -# include -# define mbsrtowcs __mbsrtowcs -#endif - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -#endif - -#ifndef _ -# define _(String) String -#endif - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -void (*error_print_progname) (void); - -/* This variable is incremented each time 'error' is called. */ -unsigned int error_message_count; - -#ifdef _LIBC -/* In the GNU C library, there is a predefined variable for this. */ - -# define program_name program_invocation_name -# include -# include -# include - -/* In GNU libc we want do not want to use the common name 'error' directly. - Instead make it a weak alias. */ -extern void __error (int status, int errnum, const char *message, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); -extern void __error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, - ...) - __attribute__ ((__format__ (__printf__, 5, 6)));; -# define error __error -# define error_at_line __error_at_line - -# include -# define fflush(s) INTUSE(_IO_fflush) (s) -# undef putc -# define putc(c, fp) INTUSE(_IO_putc) (c, fp) - -# include - -#else /* not _LIBC */ - -# include -# include - -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ -/* Get declarations of the native Windows API functions. */ -# define WIN32_LEAN_AND_MEAN -# include -/* Get _get_osfhandle. */ -# include "msvc-nothrow.h" -# endif - -/* The gnulib override of fcntl is not needed in this file. */ -# undef fcntl - -# if !HAVE_DECL_STRERROR_R -# ifndef HAVE_DECL_STRERROR_R -"this configure-time declaration test was not run" -# endif -# if STRERROR_R_CHAR_P -char *strerror_r (); -# else -int strerror_r (); -# endif -# endif - -/* The calling program should define program_name and set it to the - name of the executing program. */ -extern char *program_name; - -# if HAVE_STRERROR_R || defined strerror_r -# define __strerror_r strerror_r -# endif /* HAVE_STRERROR_R || defined strerror_r */ -#endif /* not _LIBC */ - -#if !_LIBC -/* Return non-zero if FD is open. */ -static int -is_open (int fd) -{ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - /* On native Windows: The initial state of unassigned standard file - descriptors is that they are open but point to an INVALID_HANDLE_VALUE. - There is no fcntl, and the gnulib replacement fcntl does not support - F_GETFL. */ - return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE; -# else -# ifndef F_GETFL -# error Please port fcntl to your platform -# endif - return 0 <= fcntl (fd, F_GETFL); -# endif -} -#endif - -static void -flush_stdout (void) -{ -#if !_LIBC - int stdout_fd; - -# if GNULIB_FREOPEN_SAFER - /* Use of gnulib's freopen-safer module normally ensures that - fileno (stdout) == 1 - whenever stdout is open. */ - stdout_fd = STDOUT_FILENO; -# else - /* POSIX states that fileno (stdout) after fclose is unspecified. But in - practice it is not a problem, because stdout is statically allocated and - the fd of a FILE stream is stored as a field in its allocated memory. */ - stdout_fd = fileno (stdout); -# endif - /* POSIX states that fflush (stdout) after fclose is unspecified; it - is safe in glibc, but not on all other platforms. fflush (NULL) - is always defined, but too draconian. */ - if (0 <= stdout_fd && is_open (stdout_fd)) -#endif - fflush (stdout); -} - -static void -print_errno_message (int errnum) -{ - char const *s; - -#if defined HAVE_STRERROR_R || _LIBC - char errbuf[1024]; -# if STRERROR_R_CHAR_P || _LIBC - s = __strerror_r (errnum, errbuf, sizeof errbuf); -# else - if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0) - s = errbuf; - else - s = 0; -# endif -#else - s = strerror (errnum); -#endif - -#if !_LIBC - if (! s) - s = _("Unknown system error"); -#endif - -#if _LIBC - __fxprintf (NULL, ": %s", s); -#else - fprintf (stderr, ": %s", s); -#endif -} - -static void -error_tail (int status, int errnum, const char *message, va_list args) -{ -#if _LIBC - if (_IO_fwide (stderr, 0) > 0) - { -# define ALLOCA_LIMIT 2000 - size_t len = strlen (message) + 1; - wchar_t *wmessage = NULL; - mbstate_t st; - size_t res; - const char *tmp; - bool use_malloc = false; - - while (1) - { - if (__libc_use_alloca (len * sizeof (wchar_t))) - wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); - else - { - if (!use_malloc) - wmessage = NULL; - - wchar_t *p = (wchar_t *) realloc (wmessage, - len * sizeof (wchar_t)); - if (p == NULL) - { - free (wmessage); - fputws_unlocked (L"out of memory\n", stderr); - return; - } - wmessage = p; - use_malloc = true; - } - - memset (&st, '\0', sizeof (st)); - tmp = message; - - res = mbsrtowcs (wmessage, &tmp, len, &st); - if (res != len) - break; - - if (__builtin_expect (len >= SIZE_MAX / 2, 0)) - { - /* This really should not happen if everything is fine. */ - res = (size_t) -1; - break; - } - - len *= 2; - } - - if (res == (size_t) -1) - { - /* The string cannot be converted. */ - if (use_malloc) - { - free (wmessage); - use_malloc = false; - } - wmessage = (wchar_t *) L"???"; - } - - __vfwprintf (stderr, wmessage, args); - - if (use_malloc) - free (wmessage); - } - else -#endif - vfprintf (stderr, message, args); - va_end (args); - - ++error_message_count; - if (errnum) - print_errno_message (errnum); -#if _LIBC - __fxprintf (NULL, "\n"); -#else - putc ('\n', stderr); -#endif - fflush (stderr); - if (status) - exit (status); -} - - -/* Print the program name and error message MESSAGE, which is a printf-style - format string with optional args. - If ERRNUM is nonzero, print its corresponding system error message. - Exit with status STATUS if it is nonzero. */ -void -error (int status, int errnum, const char *message, ...) -{ - va_list args; - -#if defined _LIBC && defined __libc_ptf_call - /* We do not want this call to be cut short by a thread - cancellation. Therefore disable cancellation for now. */ - int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); -#endif - - flush_stdout (); -#ifdef _LIBC - _IO_flockfile (stderr); -#endif - if (error_print_progname) - (*error_print_progname) (); - else - { -#if _LIBC - __fxprintf (NULL, "%s: ", program_name); -#else - fprintf (stderr, "%s: ", program_name); -#endif - } - - va_start (args, message); - error_tail (status, errnum, message, args); - -#ifdef _LIBC - _IO_funlockfile (stderr); -# ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); -# endif -#endif -} - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -int error_one_per_line; - -void -error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, ...) -{ - va_list args; - - if (error_one_per_line) - { - static const char *old_file_name; - static unsigned int old_line_number; - - if (old_line_number == line_number - && (file_name == old_file_name - || strcmp (old_file_name, file_name) == 0)) - /* Simply return and print nothing. */ - return; - - old_file_name = file_name; - old_line_number = line_number; - } - -#if defined _LIBC && defined __libc_ptf_call - /* We do not want this call to be cut short by a thread - cancellation. Therefore disable cancellation for now. */ - int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); -#endif - - flush_stdout (); -#ifdef _LIBC - _IO_flockfile (stderr); -#endif - if (error_print_progname) - (*error_print_progname) (); - else - { -#if _LIBC - __fxprintf (NULL, "%s:", program_name); -#else - fprintf (stderr, "%s:", program_name); -#endif - } - -#if _LIBC - __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); -#else - fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); -#endif - - va_start (args, message); - error_tail (status, errnum, message, args); - -#ifdef _LIBC - _IO_funlockfile (stderr); -# ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); -# endif -#endif -} - -#ifdef _LIBC -/* Make the weak alias. */ -# undef error -# undef error_at_line -weak_alias (__error, error) -weak_alias (__error_at_line, error_at_line) -#endif diff --git a/grub-core/gnulib/error.h b/grub-core/gnulib/error.h deleted file mode 100644 index afcb0e10c..000000000 --- a/grub-core/gnulib/error.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Declaration for error-reporting function - Copyright (C) 1995-1997, 2003, 2006, 2008-2013 Free Software Foundation, - Inc. - This file is part of the GNU C Library. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The __-protected variants of the attributes 'format' and 'printf' are - accepted by gcc versions 2.6.4 (effectively 2.7) and later. - We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because - gnulib and libintl do '#define printf __printf__' when they override - the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -#else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Print a message with 'fprintf (stderr, FORMAT, ...)'; - if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). - If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */ - -extern void error (int __status, int __errnum, const char *__format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); - -extern void error_at_line (int __status, int __errnum, const char *__fname, - unsigned int __lineno, const char *__format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 5, 6)); - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -extern void (*error_print_progname) (void); - -/* This variable is incremented each time 'error' is called. */ -extern unsigned int error_message_count; - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -extern int error_one_per_line; - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ diff --git a/grub-core/gnulib/float+.h b/grub-core/gnulib/float+.h deleted file mode 100644 index 32fb790bb..000000000 --- a/grub-core/gnulib/float+.h +++ /dev/null @@ -1,147 +0,0 @@ -/* Supplemental information about the floating-point formats. - Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2007. - - 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, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _FLOATPLUS_H -#define _FLOATPLUS_H - -#include -#include - -/* Number of bits in the mantissa of a floating-point number, including the - "hidden bit". */ -#if FLT_RADIX == 2 -# define FLT_MANT_BIT FLT_MANT_DIG -# define DBL_MANT_BIT DBL_MANT_DIG -# define LDBL_MANT_BIT LDBL_MANT_DIG -#elif FLT_RADIX == 4 -# define FLT_MANT_BIT (FLT_MANT_DIG * 2) -# define DBL_MANT_BIT (DBL_MANT_DIG * 2) -# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2) -#elif FLT_RADIX == 16 -# define FLT_MANT_BIT (FLT_MANT_DIG * 4) -# define DBL_MANT_BIT (DBL_MANT_DIG * 4) -# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4) -#endif - -/* Bit mask that can be used to mask the exponent, as an unsigned number. */ -#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7) -#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) -#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7) - -/* Number of bits used for the exponent of a floating-point number, including - the exponent's sign. */ -#define FLT_EXP_BIT \ - (FLT_EXP_MASK < 0x100 ? 8 : \ - FLT_EXP_MASK < 0x200 ? 9 : \ - FLT_EXP_MASK < 0x400 ? 10 : \ - FLT_EXP_MASK < 0x800 ? 11 : \ - FLT_EXP_MASK < 0x1000 ? 12 : \ - FLT_EXP_MASK < 0x2000 ? 13 : \ - FLT_EXP_MASK < 0x4000 ? 14 : \ - FLT_EXP_MASK < 0x8000 ? 15 : \ - FLT_EXP_MASK < 0x10000 ? 16 : \ - FLT_EXP_MASK < 0x20000 ? 17 : \ - FLT_EXP_MASK < 0x40000 ? 18 : \ - FLT_EXP_MASK < 0x80000 ? 19 : \ - FLT_EXP_MASK < 0x100000 ? 20 : \ - FLT_EXP_MASK < 0x200000 ? 21 : \ - FLT_EXP_MASK < 0x400000 ? 22 : \ - FLT_EXP_MASK < 0x800000 ? 23 : \ - FLT_EXP_MASK < 0x1000000 ? 24 : \ - FLT_EXP_MASK < 0x2000000 ? 25 : \ - FLT_EXP_MASK < 0x4000000 ? 26 : \ - FLT_EXP_MASK < 0x8000000 ? 27 : \ - FLT_EXP_MASK < 0x10000000 ? 28 : \ - FLT_EXP_MASK < 0x20000000 ? 29 : \ - FLT_EXP_MASK < 0x40000000 ? 30 : \ - FLT_EXP_MASK <= 0x7fffffff ? 31 : \ - 32) -#define DBL_EXP_BIT \ - (DBL_EXP_MASK < 0x100 ? 8 : \ - DBL_EXP_MASK < 0x200 ? 9 : \ - DBL_EXP_MASK < 0x400 ? 10 : \ - DBL_EXP_MASK < 0x800 ? 11 : \ - DBL_EXP_MASK < 0x1000 ? 12 : \ - DBL_EXP_MASK < 0x2000 ? 13 : \ - DBL_EXP_MASK < 0x4000 ? 14 : \ - DBL_EXP_MASK < 0x8000 ? 15 : \ - DBL_EXP_MASK < 0x10000 ? 16 : \ - DBL_EXP_MASK < 0x20000 ? 17 : \ - DBL_EXP_MASK < 0x40000 ? 18 : \ - DBL_EXP_MASK < 0x80000 ? 19 : \ - DBL_EXP_MASK < 0x100000 ? 20 : \ - DBL_EXP_MASK < 0x200000 ? 21 : \ - DBL_EXP_MASK < 0x400000 ? 22 : \ - DBL_EXP_MASK < 0x800000 ? 23 : \ - DBL_EXP_MASK < 0x1000000 ? 24 : \ - DBL_EXP_MASK < 0x2000000 ? 25 : \ - DBL_EXP_MASK < 0x4000000 ? 26 : \ - DBL_EXP_MASK < 0x8000000 ? 27 : \ - DBL_EXP_MASK < 0x10000000 ? 28 : \ - DBL_EXP_MASK < 0x20000000 ? 29 : \ - DBL_EXP_MASK < 0x40000000 ? 30 : \ - DBL_EXP_MASK <= 0x7fffffff ? 31 : \ - 32) -#define LDBL_EXP_BIT \ - (LDBL_EXP_MASK < 0x100 ? 8 : \ - LDBL_EXP_MASK < 0x200 ? 9 : \ - LDBL_EXP_MASK < 0x400 ? 10 : \ - LDBL_EXP_MASK < 0x800 ? 11 : \ - LDBL_EXP_MASK < 0x1000 ? 12 : \ - LDBL_EXP_MASK < 0x2000 ? 13 : \ - LDBL_EXP_MASK < 0x4000 ? 14 : \ - LDBL_EXP_MASK < 0x8000 ? 15 : \ - LDBL_EXP_MASK < 0x10000 ? 16 : \ - LDBL_EXP_MASK < 0x20000 ? 17 : \ - LDBL_EXP_MASK < 0x40000 ? 18 : \ - LDBL_EXP_MASK < 0x80000 ? 19 : \ - LDBL_EXP_MASK < 0x100000 ? 20 : \ - LDBL_EXP_MASK < 0x200000 ? 21 : \ - LDBL_EXP_MASK < 0x400000 ? 22 : \ - LDBL_EXP_MASK < 0x800000 ? 23 : \ - LDBL_EXP_MASK < 0x1000000 ? 24 : \ - LDBL_EXP_MASK < 0x2000000 ? 25 : \ - LDBL_EXP_MASK < 0x4000000 ? 26 : \ - LDBL_EXP_MASK < 0x8000000 ? 27 : \ - LDBL_EXP_MASK < 0x10000000 ? 28 : \ - LDBL_EXP_MASK < 0x20000000 ? 29 : \ - LDBL_EXP_MASK < 0x40000000 ? 30 : \ - LDBL_EXP_MASK <= 0x7fffffff ? 31 : \ - 32) - -/* Number of bits used for a floating-point number: the mantissa (not - counting the "hidden bit", since it may or may not be explicit), the - exponent, and the sign. */ -#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1) -#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1) -#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1) - -/* Number of bytes used for a floating-point number. - This can be smaller than the 'sizeof'. For example, on i386 systems, - 'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence - LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but - sizeof (long double) = 12 or = 16. */ -#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) -#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) -#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) - -/* Verify that SIZEOF_FLT <= sizeof (float) etc. */ -typedef int verify_sizeof_flt[SIZEOF_FLT <= sizeof (float) ? 1 : -1]; -typedef int verify_sizeof_dbl[SIZEOF_DBL <= sizeof (double) ? 1 : - 1]; -typedef int verify_sizeof_ldbl[SIZEOF_LDBL <= sizeof (long double) ? 1 : - 1]; - -#endif /* _FLOATPLUS_H */ diff --git a/grub-core/gnulib/float.c b/grub-core/gnulib/float.c deleted file mode 100644 index 366945fa3..000000000 --- a/grub-core/gnulib/float.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Auxiliary definitions for . - Copyright (C) 2011-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2011. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ -const union gl_long_double_union gl_LDBL_MAX = - { { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL } }; -#elif defined __i386__ -const union gl_long_double_union gl_LDBL_MAX = - { { 0xFFFFFFFF, 0xFFFFFFFF, 32766 } }; -#else -/* This declaration is solely to ensure that after preprocessing - this file is never empty. */ -typedef int dummy; -#endif diff --git a/grub-core/gnulib/float.in.h b/grub-core/gnulib/float.in.h deleted file mode 100644 index 84e1950f9..000000000 --- a/grub-core/gnulib/float.in.h +++ /dev/null @@ -1,188 +0,0 @@ -/* A correct . - - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _@GUARD_PREFIX@_FLOAT_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_FLOAT_H@ - -#ifndef _@GUARD_PREFIX@_FLOAT_H -#define _@GUARD_PREFIX@_FLOAT_H - -/* 'long double' properties. */ - -#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) -/* Number of mantissa units, in base FLT_RADIX. */ -# undef LDBL_MANT_DIG -# define LDBL_MANT_DIG 64 -/* Number of decimal digits that is sufficient for representing a number. */ -# undef LDBL_DIG -# define LDBL_DIG 18 -/* x-1 where x is the smallest representable number > 1. */ -# undef LDBL_EPSILON -# define LDBL_EPSILON 1.0842021724855044340E-19L -/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ -# undef LDBL_MIN_EXP -# define LDBL_MIN_EXP (-16381) -/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ -# undef LDBL_MAX_EXP -# define LDBL_MAX_EXP 16384 -/* Minimum positive normalized number. */ -# undef LDBL_MIN -# define LDBL_MIN 3.3621031431120935063E-4932L -/* Maximum representable finite number. */ -# undef LDBL_MAX -# define LDBL_MAX 1.1897314953572317650E+4932L -/* Minimum e such that 10^e is in the range of normalized numbers. */ -# undef LDBL_MIN_10_EXP -# define LDBL_MIN_10_EXP (-4931) -/* Maximum e such that 10^e is in the range of representable finite numbers. */ -# undef LDBL_MAX_10_EXP -# define LDBL_MAX_10_EXP 4932 -#endif - -/* On FreeBSD/x86 6.4, the 'long double' type really has only 53 bits of - precision in the compiler but 64 bits of precision at runtime. See - . */ -#if defined __i386__ && defined __FreeBSD__ -/* Number of mantissa units, in base FLT_RADIX. */ -# undef LDBL_MANT_DIG -# define LDBL_MANT_DIG 64 -/* Number of decimal digits that is sufficient for representing a number. */ -# undef LDBL_DIG -# define LDBL_DIG 18 -/* x-1 where x is the smallest representable number > 1. */ -# undef LDBL_EPSILON -# define LDBL_EPSILON 1.084202172485504434007452800869941711426e-19L /* 2^-63 */ -/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ -# undef LDBL_MIN_EXP -# define LDBL_MIN_EXP (-16381) -/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ -# undef LDBL_MAX_EXP -# define LDBL_MAX_EXP 16384 -/* Minimum positive normalized number. */ -# undef LDBL_MIN -# define LDBL_MIN 3.3621031431120935E-4932L /* = 0x1p-16382L */ -/* Maximum representable finite number. */ -# undef LDBL_MAX -/* LDBL_MAX is represented as { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }. - But the largest literal that GCC allows us to write is - 0x0.fffffffffffff8p16384L = { 0xFFFFF800, 0xFFFFFFFF, 32766 }. - So, define it like this through a reference to an external variable - - const unsigned int LDBL_MAX[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }; - extern const long double LDBL_MAX; - - Unfortunately, this is not a constant expression. */ -union gl_long_double_union - { - struct { unsigned int lo; unsigned int hi; unsigned int exponent; } xd; - long double ld; - }; -extern const union gl_long_double_union gl_LDBL_MAX; -# define LDBL_MAX (gl_LDBL_MAX.ld) -/* Minimum e such that 10^e is in the range of normalized numbers. */ -# undef LDBL_MIN_10_EXP -# define LDBL_MIN_10_EXP (-4931) -/* Maximum e such that 10^e is in the range of representable finite numbers. */ -# undef LDBL_MAX_10_EXP -# define LDBL_MAX_10_EXP 4932 -#endif - -/* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are - wrong. - On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */ -#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__ -# undef LDBL_MIN_EXP -# define LDBL_MIN_EXP DBL_MIN_EXP -# undef LDBL_MIN_10_EXP -# define LDBL_MIN_10_EXP DBL_MIN_10_EXP -# undef LDBL_MIN -# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ -#endif -#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ -# undef LDBL_MAX -/* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }. - It is not easy to define: - #define LDBL_MAX 1.79769313486231580793728971405302307166e308L - is too small, whereas - #define LDBL_MAX 1.79769313486231580793728971405302307167e308L - is too large. Apparently a bug in GCC decimal-to-binary conversion. - Also, I can't get values larger than - #define LDBL63 ((long double) (1ULL << 63)) - #define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) - #define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) - #define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) - #define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL) - which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }. - So, define it like this through a reference to an external variable - - const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }; - extern const long double LDBL_MAX; - - or through a pointer cast - - #define LDBL_MAX \ - (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }) - - Unfortunately, this is not a constant expression, and the latter expression - does not work well when GCC is optimizing.. */ -union gl_long_double_union - { - struct { double hi; double lo; } dd; - long double ld; - }; -extern const union gl_long_double_union gl_LDBL_MAX; -# define LDBL_MAX (gl_LDBL_MAX.ld) -#endif - -/* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. - On IRIX 6.5, with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_EPSILON - are wrong. */ -#if defined __sgi && (LDBL_MANT_DIG >= 106) -# undef LDBL_MANT_DIG -# define LDBL_MANT_DIG 106 -# if defined __GNUC__ -# undef LDBL_MIN_EXP -# define LDBL_MIN_EXP DBL_MIN_EXP -# undef LDBL_MIN_10_EXP -# define LDBL_MIN_10_EXP DBL_MIN_10_EXP -# undef LDBL_MIN -# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ -# undef LDBL_EPSILON -# define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */ -# endif -#endif - -#if @REPLACE_ITOLD@ -/* Pull in a function that fixes the 'int' to 'long double' conversion - of glibc 2.7. */ -extern -# ifdef __cplusplus -"C" -# endif -void _Qp_itoq (long double *, int); -static void (*_gl_float_fix_itold) (long double *, int) = _Qp_itoq; -#endif - -#endif /* _@GUARD_PREFIX@_FLOAT_H */ -#endif /* _@GUARD_PREFIX@_FLOAT_H */ diff --git a/grub-core/gnulib/fnmatch.c b/grub-core/gnulib/fnmatch.c deleted file mode 100644 index 6a09e1a9b..000000000 --- a/grub-core/gnulib/fnmatch.c +++ /dev/null @@ -1,350 +0,0 @@ -/* Copyright (C) 1991-1993, 1996-2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _LIBC -# include -#endif - -/* Enable GNU extensions in fnmatch.h. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#if ! defined __builtin_expect && __GNUC__ < 3 -# define __builtin_expect(expr, expected) (expr) -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define WIDE_CHAR_SUPPORT \ - (HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \ - && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY)) - -/* For platform which support the ISO C amendment 1 functionality we - support user defined character classes. */ -#if defined _LIBC || WIDE_CHAR_SUPPORT -# include -# include -#endif - -/* We need some of the locale data (the collation sequence information) - but there is no interface to get this information in general. Therefore - we support a correct implementation only in glibc. */ -#ifdef _LIBC -# include "../locale/localeinfo.h" -# include "../locale/elem-hash.h" -# include "../locale/coll-lookup.h" -# include - -# define CONCAT(a,b) __CONCAT(a,b) -# define mbsrtowcs __mbsrtowcs -# define fnmatch __fnmatch -extern int fnmatch (const char *pattern, const char *string, int flags); -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */ -#define NO_LEADING_PERIOD(flags) \ - ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD)) - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself, and have not detected a bug - in the library. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand 'configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU - - -# if ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) -# define isblank(c) ((c) == ' ' || (c) == '\t') -# endif - -# define STREQ(s1, s2) (strcmp (s1, s2) == 0) - -# if defined _LIBC || WIDE_CHAR_SUPPORT -/* The GNU C library provides support for user-defined character classes - and the functions from ISO C amendment 1. */ -# ifdef CHARCLASS_NAME_MAX -# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX -# else -/* This shouldn't happen but some implementation might still have this - problem. Use a reasonable default value. */ -# define CHAR_CLASS_MAX_LENGTH 256 -# endif - -# ifdef _LIBC -# define IS_CHAR_CLASS(string) __wctype (string) -# else -# define IS_CHAR_CLASS(string) wctype (string) -# endif - -# ifdef _LIBC -# define ISWCTYPE(WC, WT) __iswctype (WC, WT) -# else -# define ISWCTYPE(WC, WT) iswctype (WC, WT) -# endif - -# if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC -/* In this case we are implementing the multibyte character handling. */ -# define HANDLE_MULTIBYTE 1 -# endif - -# else -# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, 'xdigit'. */ - -# define IS_CHAR_CLASS(string) \ - (STREQ (string, "alpha") || STREQ (string, "upper") \ - || STREQ (string, "lower") || STREQ (string, "digit") \ - || STREQ (string, "alnum") || STREQ (string, "xdigit") \ - || STREQ (string, "space") || STREQ (string, "print") \ - || STREQ (string, "punct") || STREQ (string, "graph") \ - || STREQ (string, "cntrl") || STREQ (string, "blank")) -# endif - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -/* Global variable. */ -static int posixly_correct; - -# ifndef internal_function -/* Inside GNU libc we mark some function in a special way. In other - environments simply ignore the marking. */ -# define internal_function -# endif - -/* Note that this evaluates C many times. */ -# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) -# define CHAR char -# define UCHAR unsigned char -# define INT int -# define FCT internal_fnmatch -# define EXT ext_match -# define END end_pattern -# define L_(CS) CS -# ifdef _LIBC -# define BTOWC(C) __btowc (C) -# else -# define BTOWC(C) btowc (C) -# endif -# define STRLEN(S) strlen (S) -# define STRCAT(D, S) strcat (D, S) -# ifdef _LIBC -# define MEMPCPY(D, S, N) __mempcpy (D, S, N) -# else -# if HAVE_MEMPCPY -# define MEMPCPY(D, S, N) mempcpy (D, S, N) -# else -# define MEMPCPY(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N))) -# endif -# endif -# define MEMCHR(S, C, N) memchr (S, C, N) -# include "fnmatch_loop.c" - - -# if HANDLE_MULTIBYTE -# define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c)) -# define CHAR wchar_t -# define UCHAR wint_t -# define INT wint_t -# define FCT internal_fnwmatch -# define EXT ext_wmatch -# define END end_wpattern -# define L_(CS) L##CS -# define BTOWC(C) (C) -# ifdef _LIBC -# define STRLEN(S) __wcslen (S) -# define STRCAT(D, S) __wcscat (D, S) -# define MEMPCPY(D, S, N) __wmempcpy (D, S, N) -# else -# define STRLEN(S) wcslen (S) -# define STRCAT(D, S) wcscat (D, S) -# if HAVE_WMEMPCPY -# define MEMPCPY(D, S, N) wmempcpy (D, S, N) -# else -# define MEMPCPY(D, S, N) (wmemcpy (D, S, N) + (N)) -# endif -# endif -# define MEMCHR(S, C, N) wmemchr (S, C, N) -# define WIDE_CHAR_VERSION 1 - -# undef IS_CHAR_CLASS -/* We have to convert the wide character string in a multibyte string. But - we know that the character class names consist of alphanumeric characters - from the portable character set, and since the wide character encoding - for a member of the portable character set is the same code point as - its single-byte encoding, we can use a simplified method to convert the - string to a multibyte character string. */ -static wctype_t -is_char_class (const wchar_t *wcs) -{ - char s[CHAR_CLASS_MAX_LENGTH + 1]; - char *cp = s; - - do - { - /* Test for a printable character from the portable character set. */ -# ifdef _LIBC - if (*wcs < 0x20 || *wcs > 0x7e - || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) - return (wctype_t) 0; -# else - switch (*wcs) - { - case L' ': case L'!': case L'"': case L'#': case L'%': - case L'&': case L'\'': case L'(': case L')': case L'*': - case L'+': case L',': case L'-': case L'.': case L'/': - case L'0': case L'1': case L'2': case L'3': case L'4': - case L'5': case L'6': case L'7': case L'8': case L'9': - case L':': case L';': case L'<': case L'=': case L'>': - case L'?': - case L'A': case L'B': case L'C': case L'D': case L'E': - case L'F': case L'G': case L'H': case L'I': case L'J': - case L'K': case L'L': case L'M': case L'N': case L'O': - case L'P': case L'Q': case L'R': case L'S': case L'T': - case L'U': case L'V': case L'W': case L'X': case L'Y': - case L'Z': - case L'[': case L'\\': case L']': case L'^': case L'_': - case L'a': case L'b': case L'c': case L'd': case L'e': - case L'f': case L'g': case L'h': case L'i': case L'j': - case L'k': case L'l': case L'm': case L'n': case L'o': - case L'p': case L'q': case L'r': case L's': case L't': - case L'u': case L'v': case L'w': case L'x': case L'y': - case L'z': case L'{': case L'|': case L'}': case L'~': - break; - default: - return (wctype_t) 0; - } -# endif - - /* Avoid overrunning the buffer. */ - if (cp == s + CHAR_CLASS_MAX_LENGTH) - return (wctype_t) 0; - - *cp++ = (char) *wcs++; - } - while (*wcs != L'\0'); - - *cp = '\0'; - -# ifdef _LIBC - return __wctype (s); -# else - return wctype (s); -# endif -} -# define IS_CHAR_CLASS(string) is_char_class (string) - -# include "fnmatch_loop.c" -# endif - - -int -fnmatch (const char *pattern, const char *string, int flags) -{ -# if HANDLE_MULTIBYTE -# define ALLOCA_LIMIT 2000 - if (__builtin_expect (MB_CUR_MAX, 1) != 1) - { - mbstate_t ps; - size_t patsize; - size_t strsize; - size_t totsize; - wchar_t *wpattern; - wchar_t *wstring; - int res; - - /* Calculate the size needed to convert the strings to - wide characters. */ - memset (&ps, '\0', sizeof (ps)); - patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1; - if (__builtin_expect (patsize != 0, 1)) - { - assert (mbsinit (&ps)); - strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; - if (__builtin_expect (strsize != 0, 1)) - { - assert (mbsinit (&ps)); - totsize = patsize + strsize; - if (__builtin_expect (! (patsize <= totsize - && totsize <= SIZE_MAX / sizeof (wchar_t)), - 0)) - { - errno = ENOMEM; - return -1; - } - - /* Allocate room for the wide characters. */ - if (__builtin_expect (totsize < ALLOCA_LIMIT, 1)) - wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t)); - else - { - wpattern = malloc (totsize * sizeof (wchar_t)); - if (__builtin_expect (! wpattern, 0)) - { - errno = ENOMEM; - return -1; - } - } - wstring = wpattern + patsize; - - /* Convert the strings into wide characters. */ - mbsrtowcs (wpattern, &pattern, patsize, &ps); - assert (mbsinit (&ps)); - mbsrtowcs (wstring, &string, strsize, &ps); - - res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, - flags & FNM_PERIOD, flags); - - if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0)) - free (wpattern); - return res; - } - } - } - -# endif /* HANDLE_MULTIBYTE */ - - return internal_fnmatch (pattern, string, string + strlen (string), - flags & FNM_PERIOD, flags); -} - -# ifdef _LIBC -# undef fnmatch -versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3); -# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3) -strong_alias (__fnmatch, __fnmatch_old) -compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0); -# endif -libc_hidden_ver (__fnmatch, fnmatch) -# endif - -#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/grub-core/gnulib/fnmatch.in.h b/grub-core/gnulib/fnmatch.in.h deleted file mode 100644 index d39ce2f1c..000000000 --- a/grub-core/gnulib/fnmatch.in.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 1991-1993, 1996-1999, 2001-2003, 2005, 2007, 2009-2013 Free - Software Foundation, Inc. - - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _FNMATCH_H -#define _FNMATCH_H 1 - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* We #undef these before defining them because some losing systems - (HP-UX A.08.07 for example) define these in . */ -#undef FNM_PATHNAME -#undef FNM_NOESCAPE -#undef FNM_PERIOD - -/* Bits set in the FLAGS argument to 'fnmatch'. */ -#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match '/'. */ -#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ -#define FNM_PERIOD (1 << 2) /* Leading '.' is matched only explicitly. */ - -#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE -# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ -# define FNM_LEADING_DIR (1 << 3) /* Ignore '/...' after a match. */ -# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ -# define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ -#endif - -/* Value returned by 'fnmatch' if STRING does not match PATTERN. */ -#define FNM_NOMATCH 1 - -/* This value is returned if the implementation does not support - 'fnmatch'. Since this is not the case here it will never be - returned but the conformance test suites still require the symbol - to be defined. */ -#ifdef _XOPEN_SOURCE -# define FNM_NOSYS (-1) -#endif - -/* Match NAME against the file name pattern PATTERN, - returning zero if it matches, FNM_NOMATCH if not. */ -extern int fnmatch (const char *__pattern, const char *__name, - int __flags) - _GL_ARG_NONNULL ((1, 2)); - -#ifdef __cplusplus -} -#endif - -#endif /* fnmatch.h */ diff --git a/grub-core/gnulib/fnmatch_loop.c b/grub-core/gnulib/fnmatch_loop.c deleted file mode 100644 index f57cd63f9..000000000 --- a/grub-core/gnulib/fnmatch_loop.c +++ /dev/null @@ -1,1219 +0,0 @@ -/* Copyright (C) 1991-1993, 1996-2006, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 . */ - -/* Match STRING against the file name pattern PATTERN, returning zero if - it matches, nonzero if not. */ -static int EXT (INT opt, const CHAR *pattern, const CHAR *string, - const CHAR *string_end, bool no_leading_period, int flags) - internal_function; -static const CHAR *END (const CHAR *patternp) internal_function; - -static int -internal_function -FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, - bool no_leading_period, int flags) -{ - register const CHAR *p = pattern, *n = string; - register UCHAR c; -#ifdef _LIBC -# if WIDE_CHAR_VERSION - const char *collseq = (const char *) - _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC); -# else - const UCHAR *collseq = (const UCHAR *) - _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB); -# endif -#endif - - while ((c = *p++) != L_('\0')) - { - bool new_no_leading_period = false; - c = FOLD (c); - - switch (c) - { - case L_('?'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; - - res = EXT (c, p, n, string_end, no_leading_period, - flags); - if (res != -1) - return res; - } - - if (n == string_end) - return FNM_NOMATCH; - else if (*n == L_('/') && (flags & FNM_FILE_NAME)) - return FNM_NOMATCH; - else if (*n == L_('.') && no_leading_period) - return FNM_NOMATCH; - break; - - case L_('\\'): - if (!(flags & FNM_NOESCAPE)) - { - c = *p++; - if (c == L_('\0')) - /* Trailing \ loses. */ - return FNM_NOMATCH; - c = FOLD (c); - } - if (n == string_end || FOLD ((UCHAR) *n) != c) - return FNM_NOMATCH; - break; - - case L_('*'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; - - res = EXT (c, p, n, string_end, no_leading_period, - flags); - if (res != -1) - return res; - } - - if (n != string_end && *n == L_('.') && no_leading_period) - return FNM_NOMATCH; - - for (c = *p++; c == L_('?') || c == L_('*'); c = *p++) - { - if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0) - { - const CHAR *endp = END (p); - if (endp != p) - { - /* This is a pattern. Skip over it. */ - p = endp; - continue; - } - } - - if (c == L_('?')) - { - /* A ? needs to match one character. */ - if (n == string_end) - /* There isn't another character; no match. */ - return FNM_NOMATCH; - else if (*n == L_('/') - && __builtin_expect (flags & FNM_FILE_NAME, 0)) - /* A slash does not match a wildcard under - FNM_FILE_NAME. */ - return FNM_NOMATCH; - else - /* One character of the string is consumed in matching - this ? wildcard, so *??? won't match if there are - less than three characters. */ - ++n; - } - } - - if (c == L_('\0')) - /* The wildcard(s) is/are the last element of the pattern. - If the name is a file name and contains another slash - this means it cannot match, unless the FNM_LEADING_DIR - flag is set. */ - { - int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH; - - if (flags & FNM_FILE_NAME) - { - if (flags & FNM_LEADING_DIR) - result = 0; - else - { - if (MEMCHR (n, L_('/'), string_end - n) == NULL) - result = 0; - } - } - - return result; - } - else - { - const CHAR *endp; - - endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'), - string_end - n); - if (endp == NULL) - endp = string_end; - - if (c == L_('[') - || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0 - && (c == L_('@') || c == L_('+') || c == L_('!')) - && *p == L_('('))) - { - int flags2 = ((flags & FNM_FILE_NAME) - ? flags : (flags & ~FNM_PERIOD)); - bool no_leading_period2 = no_leading_period; - - for (--p; n < endp; ++n, no_leading_period2 = false) - if (FCT (p, n, string_end, no_leading_period2, flags2) - == 0) - return 0; - } - else if (c == L_('/') && (flags & FNM_FILE_NAME)) - { - while (n < string_end && *n != L_('/')) - ++n; - if (n < string_end && *n == L_('/') - && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags) - == 0)) - return 0; - } - else - { - int flags2 = ((flags & FNM_FILE_NAME) - ? flags : (flags & ~FNM_PERIOD)); - int no_leading_period2 = no_leading_period; - - if (c == L_('\\') && !(flags & FNM_NOESCAPE)) - c = *p; - c = FOLD (c); - for (--p; n < endp; ++n, no_leading_period2 = false) - if (FOLD ((UCHAR) *n) == c - && (FCT (p, n, string_end, no_leading_period2, flags2) - == 0)) - return 0; - } - } - - /* If we come here no match is possible with the wildcard. */ - return FNM_NOMATCH; - - case L_('['): - { - /* Nonzero if the sense of the character class is inverted. */ - const CHAR *p_init = p; - const CHAR *n_init = n; - register bool not; - CHAR cold; - UCHAR fn; - - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - - if (n == string_end) - return FNM_NOMATCH; - - if (*n == L_('.') && no_leading_period) - return FNM_NOMATCH; - - if (*n == L_('/') && (flags & FNM_FILE_NAME)) - /* '/' cannot be matched. */ - return FNM_NOMATCH; - - not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^'))); - if (not) - ++p; - - fn = FOLD ((UCHAR) *n); - - c = *p++; - for (;;) - { - if (!(flags & FNM_NOESCAPE) && c == L_('\\')) - { - if (*p == L_('\0')) - return FNM_NOMATCH; - c = FOLD ((UCHAR) *p); - ++p; - - goto normal_bracket; - } - else if (c == L_('[') && *p == L_(':')) - { - /* Leave room for the null. */ - CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; - size_t c1 = 0; -#if defined _LIBC || WIDE_CHAR_SUPPORT - wctype_t wt; -#endif - const CHAR *startp = p; - - for (;;) - { - if (c1 == CHAR_CLASS_MAX_LENGTH) - /* The name is too long and therefore the pattern - is ill-formed. */ - return FNM_NOMATCH; - - c = *++p; - if (c == L_(':') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c < L_('a') || c >= L_('z')) - { - /* This cannot possibly be a character class name. - Match it as a normal range. */ - p = startp; - c = L_('['); - goto normal_bracket; - } - str[c1++] = c; - } - str[c1] = L_('\0'); - -#if defined _LIBC || WIDE_CHAR_SUPPORT - wt = IS_CHAR_CLASS (str); - if (wt == 0) - /* Invalid character class name. */ - return FNM_NOMATCH; - -# if defined _LIBC && ! WIDE_CHAR_VERSION - /* The following code is glibc specific but does - there a good job in speeding up the code since - we can avoid the btowc() call. */ - if (_ISCTYPE ((UCHAR) *n, wt)) - goto matched; -# else - if (ISWCTYPE (BTOWC ((UCHAR) *n), wt)) - goto matched; -# endif -#else - if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n)) - || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n)) - || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n)) - || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n)) - || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n)) - || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n)) - || (STREQ (str, L_("lower")) && islower ((UCHAR) *n)) - || (STREQ (str, L_("print")) && isprint ((UCHAR) *n)) - || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n)) - || (STREQ (str, L_("space")) && isspace ((UCHAR) *n)) - || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n)) - || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n))) - goto matched; -#endif - c = *p++; - } -#ifdef _LIBC - else if (c == L_('[') && *p == L_('=')) - { - UCHAR str[1]; - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - const CHAR *startp = p; - - c = *++p; - if (c == L_('\0')) - { - p = startp; - c = L_('['); - goto normal_bracket; - } - str[0] = c; - - c = *++p; - if (c != L_('=') || p[1] != L_(']')) - { - p = startp; - c = L_('['); - goto normal_bracket; - } - p += 2; - - if (nrules == 0) - { - if ((UCHAR) *n == str[0]) - goto matched; - } - else - { - const int32_t *table; -# if WIDE_CHAR_VERSION - const int32_t *weights; - const int32_t *extra; -# else - const unsigned char *weights; - const unsigned char *extra; -# endif - const int32_t *indirect; - int32_t idx; - const UCHAR *cp = (const UCHAR *) str; - - /* This #include defines a local function! */ -# if WIDE_CHAR_VERSION -# include -# else -# include -# endif - -# if WIDE_CHAR_VERSION - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); - weights = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); - extra = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); -# else - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); -# endif - - idx = findidx (&cp); - if (idx != 0) - { - /* We found a table entry. Now see whether the - character we are currently at has the same - equivalence class value. */ - int len = weights[idx & 0xffffff]; - int32_t idx2; - const UCHAR *np = (const UCHAR *) n; - - idx2 = findidx (&np); - if (idx2 != 0 - && (idx >> 24) == (idx2 >> 24) - && len == weights[idx2 & 0xffffff]) - { - int cnt = 0; - - idx &= 0xffffff; - idx2 &= 0xffffff; - - while (cnt < len - && (weights[idx + 1 + cnt] - == weights[idx2 + 1 + cnt])) - ++cnt; - - if (cnt == len) - goto matched; - } - } - } - - c = *p++; - } -#endif - else if (c == L_('\0')) - { - /* [ unterminated, treat as normal character. */ - p = p_init; - n = n_init; - c = L_('['); - goto normal_match; - } - else - { - bool is_range = false; - -#ifdef _LIBC - bool is_seqval = false; - - if (c == L_('[') && *p == L_('.')) - { - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - const CHAR *startp = p; - size_t c1 = 0; - - while (1) - { - c = *++p; - if (c == L_('.') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c == '\0') - return FNM_NOMATCH; - ++c1; - } - - /* We have to handling the symbols differently in - ranges since then the collation sequence is - important. */ - is_range = *p == L_('-') && p[1] != L_('\0'); - - if (nrules == 0) - { - /* There are no names defined in the collation - data. Therefore we only accept the trivial - names consisting of the character itself. */ - if (c1 != 1) - return FNM_NOMATCH; - - if (!is_range && *n == startp[1]) - goto matched; - - cold = startp[1]; - c = *p++; - } - else - { - int32_t table_size; - const int32_t *symb_table; -# ifdef WIDE_CHAR_VERSION - char str[c1]; - size_t strcnt; -# else -# define str (startp + 1) -# endif - const unsigned char *extra; - int32_t idx; - int32_t elem; - int32_t second; - int32_t hash; - -# ifdef WIDE_CHAR_VERSION - /* We have to convert the name to a single-byte - string. This is possible since the names - consist of ASCII characters and the internal - representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; -# endif - - table_size = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); - - /* Locate the character in the hashing table. */ - hash = elem_hash (str, c1); - - idx = 0; - elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - second = hash % (table_size - 2) + 1; - - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && (c1 - == extra[symb_table[2 * elem + 1]]) - && memcmp (str, - &extra[symb_table[2 * elem - + 1] - + 1], c1) == 0) - { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; - } - - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } - - if (symb_table[2 * elem] != 0) - { - /* Compare the byte sequence but only if - this is not part of a range. */ -# ifdef WIDE_CHAR_VERSION - int32_t *wextra; - - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - - wextra = (int32_t *) &extra[idx + 4]; -# endif - - if (! is_range) - { -# ifdef WIDE_CHAR_VERSION - for (c1 = 0; - (int32_t) c1 < wextra[idx]; - ++c1) - if (n[c1] != wextra[1 + c1]) - break; - - if ((int32_t) c1 == wextra[idx]) - goto matched; -# else - for (c1 = 0; c1 < extra[idx]; ++c1) - if (n[c1] != extra[1 + c1]) - break; - - if (c1 == extra[idx]) - goto matched; -# endif - } - - /* Get the collation sequence value. */ - is_seqval = true; -# ifdef WIDE_CHAR_VERSION - cold = wextra[1 + wextra[idx]]; -# else - /* Adjust for the alignment. */ - idx += 1 + extra[idx]; - idx = (idx + 3) & ~4; - cold = *((int32_t *) &extra[idx]); -# endif - - c = *p++; - } - else if (c1 == 1) - { - /* No valid character. Match it as a - single byte. */ - if (!is_range && *n == str[0]) - goto matched; - - cold = str[0]; - c = *p++; - } - else - return FNM_NOMATCH; - } - } - else -# undef str -#endif - { - c = FOLD (c); - normal_bracket: - - /* We have to handling the symbols differently in - ranges since then the collation sequence is - important. */ - is_range = (*p == L_('-') && p[1] != L_('\0') - && p[1] != L_(']')); - - if (!is_range && c == fn) - goto matched; - -#if _LIBC - /* This is needed if we goto normal_bracket; from - outside of is_seqval's scope. */ - is_seqval = false; -#endif - - cold = c; - c = *p++; - } - - if (c == L_('-') && *p != L_(']')) - { -#if _LIBC - /* We have to find the collation sequence - value for C. Collation sequence is nothing - we can regularly access. The sequence - value is defined by the order in which the - definitions of the collation values for the - various characters appear in the source - file. A strange concept, nowhere - documented. */ - uint32_t fcollseq; - uint32_t lcollseq; - UCHAR cend = *p++; - -# ifdef WIDE_CHAR_VERSION - /* Search in the 'names' array for the characters. */ - fcollseq = __collseq_table_lookup (collseq, fn); - if (fcollseq == ~((uint32_t) 0)) - /* XXX We don't know anything about the character - we are supposed to match. This means we are - failing. */ - goto range_not_matched; - - if (is_seqval) - lcollseq = cold; - else - lcollseq = __collseq_table_lookup (collseq, cold); -# else - fcollseq = collseq[fn]; - lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; -# endif - - is_seqval = false; - if (cend == L_('[') && *p == L_('.')) - { - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_NRULES); - const CHAR *startp = p; - size_t c1 = 0; - - while (1) - { - c = *++p; - if (c == L_('.') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c == '\0') - return FNM_NOMATCH; - ++c1; - } - - if (nrules == 0) - { - /* There are no names defined in the - collation data. Therefore we only - accept the trivial names consisting - of the character itself. */ - if (c1 != 1) - return FNM_NOMATCH; - - cend = startp[1]; - } - else - { - int32_t table_size; - const int32_t *symb_table; -# ifdef WIDE_CHAR_VERSION - char str[c1]; - size_t strcnt; -# else -# define str (startp + 1) -# endif - const unsigned char *extra; - int32_t idx; - int32_t elem; - int32_t second; - int32_t hash; - -# ifdef WIDE_CHAR_VERSION - /* We have to convert the name to a single-byte - string. This is possible since the names - consist of ASCII characters and the internal - representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; -# endif - - table_size = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); - - /* Locate the character in the hashing - table. */ - hash = elem_hash (str, c1); - - idx = 0; - elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - second = hash % (table_size - 2) + 1; - - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && (c1 - == extra[symb_table[2 * elem + 1]]) - && memcmp (str, - &extra[symb_table[2 * elem + 1] - + 1], c1) == 0) - { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; - } - - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } - - if (symb_table[2 * elem] != 0) - { - /* Compare the byte sequence but only if - this is not part of a range. */ -# ifdef WIDE_CHAR_VERSION - int32_t *wextra; - - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~4; - - wextra = (int32_t *) &extra[idx + 4]; -# endif - /* Get the collation sequence value. */ - is_seqval = true; -# ifdef WIDE_CHAR_VERSION - cend = wextra[1 + wextra[idx]]; -# else - /* Adjust for the alignment. */ - idx += 1 + extra[idx]; - idx = (idx + 3) & ~4; - cend = *((int32_t *) &extra[idx]); -# endif - } - else if (symb_table[2 * elem] != 0 && c1 == 1) - { - cend = str[0]; - c = *p++; - } - else - return FNM_NOMATCH; - } -# undef str - } - else - { - if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) - cend = *p++; - if (cend == L_('\0')) - return FNM_NOMATCH; - cend = FOLD (cend); - } - - /* XXX It is not entirely clear to me how to handle - characters which are not mentioned in the - collation specification. */ - if ( -# ifdef WIDE_CHAR_VERSION - lcollseq == 0xffffffff || -# endif - lcollseq <= fcollseq) - { - /* We have to look at the upper bound. */ - uint32_t hcollseq; - - if (is_seqval) - hcollseq = cend; - else - { -# ifdef WIDE_CHAR_VERSION - hcollseq = - __collseq_table_lookup (collseq, cend); - if (hcollseq == ~((uint32_t) 0)) - { - /* Hum, no information about the upper - bound. The matching succeeds if the - lower bound is matched exactly. */ - if (lcollseq != fcollseq) - goto range_not_matched; - - goto matched; - } -# else - hcollseq = collseq[cend]; -# endif - } - - if (lcollseq <= hcollseq && fcollseq <= hcollseq) - goto matched; - } -# ifdef WIDE_CHAR_VERSION - range_not_matched: -# endif -#else - /* We use a boring value comparison of the character - values. This is better than comparing using - 'strcoll' since the latter would have surprising - and sometimes fatal consequences. */ - UCHAR cend = *p++; - - if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) - cend = *p++; - if (cend == L_('\0')) - return FNM_NOMATCH; - - /* It is a range. */ - if (cold <= fn && fn <= cend) - goto matched; -#endif - - c = *p++; - } - } - - if (c == L_(']')) - break; - } - - if (!not) - return FNM_NOMATCH; - break; - - matched: - /* Skip the rest of the [...] that already matched. */ - do - { - ignore_next: - c = *p++; - - if (c == L_('\0')) - /* [... (unterminated) loses. */ - return FNM_NOMATCH; - - if (!(flags & FNM_NOESCAPE) && c == L_('\\')) - { - if (*p == L_('\0')) - return FNM_NOMATCH; - /* XXX 1003.2d11 is unclear if this is right. */ - ++p; - } - else if (c == L_('[') && *p == L_(':')) - { - int c1 = 0; - const CHAR *startp = p; - - while (1) - { - c = *++p; - if (++c1 == CHAR_CLASS_MAX_LENGTH) - return FNM_NOMATCH; - - if (*p == L_(':') && p[1] == L_(']')) - break; - - if (c < L_('a') || c >= L_('z')) - { - p = startp; - goto ignore_next; - } - } - p += 2; - c = *p++; - } - else if (c == L_('[') && *p == L_('=')) - { - c = *++p; - if (c == L_('\0')) - return FNM_NOMATCH; - c = *++p; - if (c != L_('=') || p[1] != L_(']')) - return FNM_NOMATCH; - p += 2; - c = *p++; - } - else if (c == L_('[') && *p == L_('.')) - { - ++p; - while (1) - { - c = *++p; - if (c == '\0') - return FNM_NOMATCH; - - if (*p == L_('.') && p[1] == L_(']')) - break; - } - p += 2; - c = *p++; - } - } - while (c != L_(']')); - if (not) - return FNM_NOMATCH; - } - break; - - case L_('+'): - case L_('@'): - case L_('!'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; - - res = EXT (c, p, n, string_end, no_leading_period, flags); - if (res != -1) - return res; - } - goto normal_match; - - case L_('/'): - if (NO_LEADING_PERIOD (flags)) - { - if (n == string_end || c != (UCHAR) *n) - return FNM_NOMATCH; - - new_no_leading_period = true; - break; - } - /* FALLTHROUGH */ - default: - normal_match: - if (n == string_end || c != FOLD ((UCHAR) *n)) - return FNM_NOMATCH; - } - - no_leading_period = new_no_leading_period; - ++n; - } - - if (n == string_end) - return 0; - - if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L_('/')) - /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ - return 0; - - return FNM_NOMATCH; -} - - -static const CHAR * -internal_function -END (const CHAR *pattern) -{ - const CHAR *p = pattern; - - while (1) - if (*++p == L_('\0')) - /* This is an invalid pattern. */ - return pattern; - else if (*p == L_('[')) - { - /* Handle brackets special. */ - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - - /* Skip the not sign. We have to recognize it because of a possibly - following ']'. */ - if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) - ++p; - /* A leading ']' is recognized as such. */ - if (*p == L_(']')) - ++p; - /* Skip over all characters of the list. */ - while (*p != L_(']')) - if (*p++ == L_('\0')) - /* This is no valid pattern. */ - return pattern; - } - else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') - || *p == L_('!')) && p[1] == L_('(')) - p = END (p + 1); - else if (*p == L_(')')) - break; - - return p + 1; -} - - -static int -internal_function -EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, - bool no_leading_period, int flags) -{ - const CHAR *startp; - size_t level; - struct patternlist - { - struct patternlist *next; - CHAR str[1]; - } *list = NULL; - struct patternlist **lastp = &list; - size_t pattern_len = STRLEN (pattern); - const CHAR *p; - const CHAR *rs; - enum { ALLOCA_LIMIT = 8000 }; - - /* Parse the pattern. Store the individual parts in the list. */ - level = 0; - for (startp = p = pattern + 1; ; ++p) - if (*p == L_('\0')) - /* This is an invalid pattern. */ - return -1; - else if (*p == L_('[')) - { - /* Handle brackets special. */ - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - - /* Skip the not sign. We have to recognize it because of a possibly - following ']'. */ - if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) - ++p; - /* A leading ']' is recognized as such. */ - if (*p == L_(']')) - ++p; - /* Skip over all characters of the list. */ - while (*p != L_(']')) - if (*p++ == L_('\0')) - /* This is no valid pattern. */ - return -1; - } - else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') - || *p == L_('!')) && p[1] == L_('(')) - /* Remember the nesting level. */ - ++level; - else if (*p == L_(')')) - { - if (level-- == 0) - { - /* This means we found the end of the pattern. */ -#define NEW_PATTERN \ - struct patternlist *newp; \ - size_t plen; \ - size_t plensize; \ - size_t newpsize; \ - \ - plen = (opt == L_('?') || opt == L_('@') \ - ? pattern_len \ - : p - startp + 1UL); \ - plensize = plen * sizeof (CHAR); \ - newpsize = offsetof (struct patternlist, str) + plensize; \ - if ((size_t) -1 / sizeof (CHAR) < plen \ - || newpsize < offsetof (struct patternlist, str) \ - || ALLOCA_LIMIT <= newpsize) \ - return -1; \ - newp = (struct patternlist *) alloca (newpsize); \ - *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ - newp->next = NULL; \ - *lastp = newp; \ - lastp = &newp->next - NEW_PATTERN; - break; - } - } - else if (*p == L_('|')) - { - if (level == 0) - { - NEW_PATTERN; - startp = p + 1; - } - } - assert (list != NULL); - assert (p[-1] == L_(')')); -#undef NEW_PATTERN - - switch (opt) - { - case L_('*'): - if (FCT (p, string, string_end, no_leading_period, flags) == 0) - return 0; - /* FALLTHROUGH */ - - case L_('+'): - do - { - for (rs = string; rs <= string_end; ++rs) - /* First match the prefix with the current pattern with the - current pattern. */ - if (FCT (list->str, string, rs, no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0 - /* This was successful. Now match the rest with the rest - of the pattern. */ - && (FCT (p, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD) == 0 - /* This didn't work. Try the whole pattern. */ - || (rs != string - && FCT (pattern - 1, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD) == 0))) - /* It worked. Signal success. */ - return 0; - } - while ((list = list->next) != NULL); - - /* None of the patterns lead to a match. */ - return FNM_NOMATCH; - - case L_('?'): - if (FCT (p, string, string_end, no_leading_period, flags) == 0) - return 0; - /* FALLTHROUGH */ - - case L_('@'): - do - /* I cannot believe it but 'strcat' is actually acceptable - here. Match the entire string with the prefix from the - pattern list and the rest of the pattern following the - pattern list. */ - if (FCT (STRCAT (list->str, p), string, string_end, - no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) - /* It worked. Signal success. */ - return 0; - while ((list = list->next) != NULL); - - /* None of the patterns lead to a match. */ - return FNM_NOMATCH; - - case L_('!'): - for (rs = string; rs <= string_end; ++rs) - { - struct patternlist *runp; - - for (runp = list; runp != NULL; runp = runp->next) - if (FCT (runp->str, string, rs, no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) - break; - - /* If none of the patterns matched see whether the rest does. */ - if (runp == NULL - && (FCT (p, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) - == 0)) - /* This is successful. */ - return 0; - } - - /* None of the patterns together with the rest of the pattern - lead to a match. */ - return FNM_NOMATCH; - - default: - assert (! "Invalid extended matching operator"); - break; - } - - return -1; -} - - -#undef FOLD -#undef CHAR -#undef UCHAR -#undef INT -#undef FCT -#undef EXT -#undef END -#undef MEMPCPY -#undef MEMCHR -#undef STRLEN -#undef STRCAT -#undef L_ -#undef BTOWC diff --git a/grub-core/gnulib/getdelim.c b/grub-core/gnulib/getdelim.c deleted file mode 100644 index fdbcde2a2..000000000 --- a/grub-core/gnulib/getdelim.c +++ /dev/null @@ -1,135 +0,0 @@ -/* getdelim.c --- Implementation of replacement getdelim function. - Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2013 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3, 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 . */ - -/* Ported from glibc by Simon Josefsson. */ - -/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc - optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below. */ -#define _GL_ARG_NONNULL(params) - -#include - -#include - -#include -#include -#include -#include - -#ifndef SSIZE_MAX -# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) -#endif - -#if USE_UNLOCKED_IO -# include "unlocked-io.h" -# define getc_maybe_unlocked(fp) getc(fp) -#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED -# undef flockfile -# undef funlockfile -# define flockfile(x) ((void) 0) -# define funlockfile(x) ((void) 0) -# define getc_maybe_unlocked(fp) getc(fp) -#else -# define getc_maybe_unlocked(fp) getc_unlocked(fp) -#endif - -/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and - NUL-terminate it). *LINEPTR is a pointer returned from malloc (or - NULL), pointing to *N characters of space. It is realloc'ed as - necessary. Returns the number of characters read (not including - the null terminator), or -1 on error or EOF. */ - -ssize_t -getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) -{ - ssize_t result; - size_t cur_len = 0; - - if (lineptr == NULL || n == NULL || fp == NULL) - { - errno = EINVAL; - return -1; - } - - flockfile (fp); - - if (*lineptr == NULL || *n == 0) - { - char *new_lineptr; - *n = 120; - new_lineptr = (char *) realloc (*lineptr, *n); - if (new_lineptr == NULL) - { - result = -1; - goto unlock_return; - } - *lineptr = new_lineptr; - } - - for (;;) - { - int i; - - i = getc_maybe_unlocked (fp); - if (i == EOF) - { - result = -1; - break; - } - - /* Make enough space for len+1 (for final NUL) bytes. */ - if (cur_len + 1 >= *n) - { - size_t needed_max = - SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; - size_t needed = 2 * *n + 1; /* Be generous. */ - char *new_lineptr; - - if (needed_max < needed) - needed = needed_max; - if (cur_len + 1 >= needed) - { - result = -1; - errno = EOVERFLOW; - goto unlock_return; - } - - new_lineptr = (char *) realloc (*lineptr, needed); - if (new_lineptr == NULL) - { - result = -1; - goto unlock_return; - } - - *lineptr = new_lineptr; - *n = needed; - } - - (*lineptr)[cur_len] = i; - cur_len++; - - if (i == delimiter) - break; - } - (*lineptr)[cur_len] = '\0'; - result = cur_len ? cur_len : result; - - unlock_return: - funlockfile (fp); /* doesn't set errno */ - - return result; -} diff --git a/grub-core/gnulib/getline.c b/grub-core/gnulib/getline.c deleted file mode 100644 index 1aa07b9c7..000000000 --- a/grub-core/gnulib/getline.c +++ /dev/null @@ -1,27 +0,0 @@ -/* getline.c --- Implementation of replacement getline function. - Copyright (C) 2005-2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3, 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 - -ssize_t -getline (char **lineptr, size_t *n, FILE *stream) -{ - return getdelim (lineptr, n, '\n', stream); -} diff --git a/grub-core/gnulib/getopt.c b/grub-core/gnulib/getopt.c deleted file mode 100644 index ef0f4ceec..000000000 --- a/grub-core/gnulib/getopt.c +++ /dev/null @@ -1,1245 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to drepper@gnu.org - before changing it! - Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _LIBC -# include -#endif - -#include "getopt.h" - -#include -#include -#include -#include - -#ifdef _LIBC -# include -#else -# include "gettext.h" -# define _(msgid) gettext (msgid) -#endif - -#if defined _LIBC && defined USE_IN_LIBIO -# include -#endif - -/* This version of 'getopt' appears to the caller like standard Unix 'getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As 'getopt_long' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Using 'getopt' or setting the environment variable POSIXLY_CORRECT - disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt_int.h" - -/* For communication from 'getopt' to the caller. - When 'getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when 'ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to 'getopt'. - - On entry to 'getopt', zero means this is the first call; initialize. - - When 'getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, 'optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Keep a global copy of all internal members of getopt_data. */ - -static struct _getopt_data getopt_data; - - -#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV -extern char *getenv (); -#endif - -#ifdef _LIBC -/* Stored original parameters. - XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ -extern int __libc_argc; -extern char **__libc_argv; - -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -# ifdef USE_NONOPTION_FLAGS -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; -# endif - -# ifdef USE_NONOPTION_FLAGS -# define SWAP_FLAGS(ch1, ch2) \ - if (d->__nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -# else -# define SWAP_FLAGS(ch1, ch2) -# endif -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - 'first_nonopt' and 'last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (char **argv, struct _getopt_data *d) -{ - int bottom = d->__first_nonopt; - int middle = d->__last_nonopt; - int top = d->optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - /* First make sure the handling of the '__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - d->__nonoption_flags_max_len), - '\0', top + 1 - d->__nonoption_flags_max_len); - d->__nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - d->__first_nonopt += (d->optind - d->__last_nonopt); - d->__last_nonopt = d->optind; -} - -/* Initialize the internal data when the first call is made. */ - -static const char * -_getopt_initialize (int argc _GL_UNUSED, - char **argv _GL_UNUSED, const char *optstring, - struct _getopt_data *d, int posixly_correct) -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - d->__first_nonopt = d->__last_nonopt = d->optind; - - d->__nextchar = NULL; - - d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - d->__ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - d->__ordering = REQUIRE_ORDER; - ++optstring; - } - else if (d->__posixly_correct) - d->__ordering = REQUIRE_ORDER; - else - d->__ordering = PERMUTE; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - if (!d->__posixly_correct - && argc == __libc_argc && argv == __libc_argv) - { - if (d->__nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - d->__nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = d->__nonoption_flags_max_len = strlen (orig_str); - if (d->__nonoption_flags_max_len < argc) - d->__nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (d->__nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - d->__nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', d->__nonoption_flags_max_len - len); - } - } - d->__nonoption_flags_len = d->__nonoption_flags_max_len; - } - else - d->__nonoption_flags_len = 0; -#endif - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If 'getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If 'getopt' finds another option character, it returns that character, - updating 'optind' and 'nextchar' so that the next call to 'getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, 'getopt' returns -1. - Then 'optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set 'opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in 'optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in 'optarg', otherwise 'optarg' is set to zero. - - If OPTSTRING starts with '-' or '+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with '--' instead of '-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a '=', or else the in next ARGV-element. - When 'getopt' finds a long-named option, it returns 0 if that option's - 'flag' field is nonzero, the value of the option's 'val' field - if the 'flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of 'struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal_r (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, struct _getopt_data *d, int posixly_correct) -{ - int print_errors = d->opterr; - - if (argc < 1) - return -1; - - d->optarg = NULL; - - if (d->optind == 0 || !d->__initialized) - { - if (d->optind == 0) - d->optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring, d, - posixly_correct); - d->__initialized = 1; - } - else if (optstring[0] == '-' || optstring[0] == '+') - optstring++; - if (optstring[0] == ':') - print_errors = 0; - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ - || (d->optind < d->__nonoption_flags_len \ - && __getopt_nonoption_flags[d->optind] == '1')) -#else -# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') -#endif - - if (d->__nextchar == NULL || *d->__nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (d->__last_nonopt > d->optind) - d->__last_nonopt = d->optind; - if (d->__first_nonopt > d->optind) - d->__first_nonopt = d->optind; - - if (d->__ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__last_nonopt != d->optind) - d->__first_nonopt = d->optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (d->optind < argc && NONOPTION_P) - d->optind++; - d->__last_nonopt = d->optind; - } - - /* The special ARGV-element '--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (d->optind != argc && !strcmp (argv[d->optind], "--")) - { - d->optind++; - - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__first_nonopt == d->__last_nonopt) - d->__first_nonopt = d->optind; - d->__last_nonopt = argc; - - d->optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (d->optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (d->__first_nonopt != d->__last_nonopt) - d->optind = d->__first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (d->__ordering == REQUIRE_ORDER) - return -1; - d->optarg = argv[d->optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - d->__nextchar = (argv[d->optind] + 1 - + (longopts != NULL && argv[d->optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[d->optind][1] == '-' - || (long_only && (argv[d->optind][2] - || !strchr (optstring, argv[d->optind][1]))))) - { - char *nameend; - unsigned int namelen; - const struct option *p; - const struct option *pfound = NULL; - struct option_list - { - const struct option *p; - struct option_list *next; - } *ambig_list = NULL; - int exact = 0; - int indfound = -1; - int option_index; - - for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - namelen = nameend - d->__nextchar; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, namelen)) - { - if (namelen == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - { - /* Second or later nonexact match found. */ - struct option_list *newp = malloc (sizeof (*newp)); - newp->p = p; - newp->next = ambig_list; - ambig_list = newp; - } - } - - if (ambig_list != NULL && !exact) - { - if (print_errors) - { - struct option_list first; - first.p = pfound; - first.next = ambig_list; - ambig_list = &first; - -#if defined _LIBC && defined USE_IN_LIBIO - char *buf = NULL; - size_t buflen = 0; - - FILE *fp = open_memstream (&buf, &buflen); - if (fp != NULL) - { - fprintf (fp, - _("%s: option '%s' is ambiguous; possibilities:"), - argv[0], argv[d->optind]); - - do - { - fprintf (fp, " '--%s'", ambig_list->p->name); - ambig_list = ambig_list->next; - } - while (ambig_list != NULL); - - fputc_unlocked ('\n', fp); - - if (__builtin_expect (fclose (fp) != EOF, 1)) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } - } -#else - fprintf (stderr, - _("%s: option '%s' is ambiguous; possibilities:"), - argv[0], argv[d->optind]); - do - { - fprintf (stderr, " '--%s'", ambig_list->p->name); - ambig_list = ambig_list->next; - } - while (ambig_list != NULL); - - fputc ('\n', stderr); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - d->optopt = 0; - return '?'; - } - - while (ambig_list != NULL) - { - struct option_list *pn = ambig_list->next; - free (ambig_list); - ambig_list = pn; - } - - if (pfound != NULL) - { - option_index = indfound; - d->optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind - 1][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option '--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#else - fprintf (stderr, _("\ -%s: option '--%s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option '%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#else - fprintf (stderr, _("\ -%s: option '%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - - d->__nextchar += strlen (d->__nextchar); - - d->optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '--%s' requires an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option '--%s' requires an argument\n"), - argv[0], pfound->name); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[d->optind][1] == '-' - || strchr (optstring, *d->__nextchar) == NULL) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - - if (argv[d->optind][1] == '-') - { - /* --option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), - argv[0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option '--%s'\n"), - argv[0], d->__nextchar); -#endif - } - else - { - /* +option or -option */ -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#else - fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); -#endif - } - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->__nextchar = (char *) ""; - d->optind++; - d->optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *d->__nextchar++; - const char *temp = strchr (optstring, c); - - /* Increment 'optind' when we start to process its last character. */ - if (*d->__nextchar == '\0') - ++d->optind; - - if (temp == NULL || c == ':' || c == ';') - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; -#endif - -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); -#endif - -#if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#endif - } - d->optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - if (longopts == NULL) - goto no_longs; - - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented 'd->optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; - nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), - argv[0], d->optarg) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), - argv[0], d->optarg); -#endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '-W %s' doesn't allow an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("\ -%s: option '-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); -#endif - } - - d->__nextchar += strlen (d->__nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option '-W %s' requires an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, _("\ -%s: option '-W %s' requires an argument\n"), - argv[0], pfound->name); -#endif - } - d->__nextchar += strlen (d->__nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - else - d->optarg = NULL; - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - no_longs: - d->__nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - d->optind++; - } - else - d->optarg = NULL; - d->__nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { -#if defined _LIBC && defined USE_IN_LIBIO - char *buf; - - if (__asprintf (&buf, _("\ -%s: option requires an argument -- '%c'\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); - - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - - __fxprintf (NULL, "%s", buf); - - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); - - free (buf); - } -#else - fprintf (stderr, - _("%s: option requires an argument -- '%c'\n"), - argv[0], c); -#endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented 'optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - d->__nextchar = NULL; - } - } - return c; - } -} - -int -_getopt_internal (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, int long_only, - int posixly_correct) -{ - int result; - - getopt_data.optind = optind; - getopt_data.opterr = opterr; - - result = _getopt_internal_r (argc, argv, optstring, longopts, - longind, long_only, &getopt_data, - posixly_correct); - - optind = getopt_data.optind; - optarg = getopt_data.optarg; - optopt = getopt_data.optopt; - - return result; -} - -/* glibc gets a LSB-compliant getopt. - Standalone applications get a POSIX-compliant getopt. */ -#if _LIBC -enum { POSIXLY_CORRECT = 0 }; -#else -enum { POSIXLY_CORRECT = 1 }; -#endif - -int -getopt (int argc, char *const *argv, const char *optstring) -{ - return _getopt_internal (argc, (char **) argv, optstring, - (const struct option *) 0, - (int *) 0, - 0, POSIXLY_CORRECT); -} - -#ifdef _LIBC -int -__posix_getopt (int argc, char *const *argv, const char *optstring) -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0, 1); -} -#endif - - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of 'getopt'. */ - -int -main (int argc, char **argv) -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value '%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/grub-core/gnulib/getopt.in.h b/grub-core/gnulib/getopt.in.h deleted file mode 100644 index d9c7d8144..000000000 --- a/grub-core/gnulib/getopt.in.h +++ /dev/null @@ -1,255 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2007, 2009-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _@GUARD_PREFIX@_GETOPT_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* The include_next requires a split double-inclusion guard. We must - also inform the replacement unistd.h to not recursively use - ; our definitions will be present soon enough. */ -#if @HAVE_GETOPT_H@ -# define _GL_SYSTEM_GETOPT -# @INCLUDE_NEXT@ @NEXT_GETOPT_H@ -# undef _GL_SYSTEM_GETOPT -#endif - -#ifndef _@GUARD_PREFIX@_GETOPT_H - -#ifndef __need_getopt -# define _@GUARD_PREFIX@_GETOPT_H 1 -#endif - -/* Standalone applications should #define __GETOPT_PREFIX to an - identifier that prefixes the external functions and variables - defined in this header. When this happens, include the - headers that might declare getopt so that they will not cause - confusion if included after this file (if the system had , - we have already included it). Then systematically rename - identifiers so that they do not collide with the system functions - and variables. Renaming avoids problems with some compilers and - linkers. */ -#if defined __GETOPT_PREFIX && !defined __need_getopt -# if !@HAVE_GETOPT_H@ -# define __need_system_stdlib_h -# include -# undef __need_system_stdlib_h -# include -# include -# endif -# undef __need_getopt -# undef getopt -# undef getopt_long -# undef getopt_long_only -# undef optarg -# undef opterr -# undef optind -# undef optopt -# undef option -# define __GETOPT_CONCAT(x, y) x ## y -# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y) -# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y) -# define getopt __GETOPT_ID (getopt) -# define getopt_long __GETOPT_ID (getopt_long) -# define getopt_long_only __GETOPT_ID (getopt_long_only) -# define optarg __GETOPT_ID (optarg) -# define opterr __GETOPT_ID (opterr) -# define optind __GETOPT_ID (optind) -# define optopt __GETOPT_ID (optopt) -# define option __GETOPT_ID (option) -# define _getopt_internal __GETOPT_ID (getopt_internal) -#endif - -/* Standalone applications get correct prototypes for getopt_long and - getopt_long_only; they declare "char **argv". libc uses prototypes - with "char *const *argv" that are incorrect because getopt_long and - getopt_long_only can permute argv; this is required for backward - compatibility (e.g., for LSB 2.0.1). - - This used to be '#if defined __GETOPT_PREFIX && !defined __need_getopt', - but it caused redefinition warnings if both unistd.h and getopt.h were - included, since unistd.h includes getopt.h having previously defined - __need_getopt. - - The only place where __getopt_argv_const is used is in definitions - of getopt_long and getopt_long_only below, but these are visible - only if __need_getopt is not defined, so it is quite safe to rewrite - the conditional as follows: -*/ -#if !defined __need_getopt -# if defined __GETOPT_PREFIX -# define __getopt_argv_const /* empty */ -# else -# define __getopt_argv_const const -# endif -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifndef __THROW -# ifndef __GNUC_PREREQ -# define __GNUC_PREREQ(maj, min) (0) -# endif -# if defined __cplusplus && __GNUC_PREREQ (2,8) -# define __THROW throw () -# else -# define __THROW -# endif -#endif - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from 'getopt' to the caller. - When 'getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when 'ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to 'getopt'. - - On entry to 'getopt', zero means this is the first call; initialize. - - When 'getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, 'optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message 'getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of 'struct option' terminated by an element containing a name which is - zero. - - The field 'has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field 'flag' is not NULL, it points to a variable that is set - to the value given in the field 'val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an 'int' to - a compiled-in constant, such as set a value from 'optarg', set the - option's 'flag' field to zero and its 'val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero 'flag' field, 'getopt' - returns the contents of the 'val' field. */ - -# if !GNULIB_defined_struct_option -struct option -{ - const char *name; - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; -# define GNULIB_defined_struct_option 1 -# endif - -/* Names for the values of the 'has_arg' field of 'struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, 'optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in 'optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU 'getopt'. - - The argument '--' causes premature termination of argument - scanning, explicitly telling 'getopt' that there are no more - options. - - If OPTS begins with '-', then non-option arguments are treated as - arguments to the option '\1'. This behavior is specific to the GNU - 'getopt'. If OPTS begins with '+', or POSIXLY_CORRECT is set in - the environment, then do not permute arguments. */ - -extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __THROW _GL_ARG_NONNULL ((2, 3)); - -#ifndef __need_getopt -extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW _GL_ARG_NONNULL ((2, 3)); -extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind) - __THROW _GL_ARG_NONNULL ((2, 3)); - -#endif - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* _@GUARD_PREFIX@_GETOPT_H */ -#endif /* _@GUARD_PREFIX@_GETOPT_H */ diff --git a/grub-core/gnulib/getopt1.c b/grub-core/gnulib/getopt1.c deleted file mode 100644 index 55a6b4eae..000000000 --- a/grub-core/gnulib/getopt1.c +++ /dev/null @@ -1,170 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987-1994, 1996-1998, 2004, 2006, 2009-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifdef _LIBC -# include -#else -# include -# include "getopt.h" -#endif -#include "getopt_int.h" - -#include - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (int argc, char *__getopt_argv_const *argv, const char *options, - const struct option *long_options, int *opt_index) -{ - return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 0, 0); -} - -int -_getopt_long_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) -{ - return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 0, d, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (int argc, char *__getopt_argv_const *argv, - const char *options, - const struct option *long_options, int *opt_index) -{ - return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 1, 0); -} - -int -_getopt_long_only_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) -{ - return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 1, d, 0); -} - - -#ifdef TEST - -#include - -int -main (int argc, char **argv) -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static const struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value '%s'\n", optarg); - break; - - case 'd': - printf ("option d with value '%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/grub-core/gnulib/getopt_int.h b/grub-core/gnulib/getopt_int.h deleted file mode 100644 index a6e4b9ea7..000000000 --- a/grub-core/gnulib/getopt_int.h +++ /dev/null @@ -1,135 +0,0 @@ -/* Internal declarations for getopt. - Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _GETOPT_INT_H -#define _GETOPT_INT_H 1 - -#include - -extern int _getopt_internal (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct); - - -/* Reentrant versions which can handle parsing multiple argument - vectors at the same time. */ - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using '+' as the first character - of the list of option characters, or by calling getopt. - - PERMUTE is the default. We permute the contents of ARGV as we - scan, so that eventually all the non-options are at the end. - This allows options to be given in any order, even with programs - that were not written to expect this. - - RETURN_IN_ORDER is an option available to programs that were - written to expect options and other ARGV-elements in any order - and that care about the ordering of the two. We describe each - non-option ARGV-element as if it were the argument of an option - with character code 1. Using '-' as the first character of the - list of option characters selects this mode of operation. - - The special argument '--' forces an end of option-scanning regardless - of the value of 'ordering'. In the case of RETURN_IN_ORDER, only - '--' can cause 'getopt' to return -1 with 'optind' != ARGC. */ - -enum __ord - { - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER - }; - -/* Data type for reentrant functions. */ -struct _getopt_data -{ - /* These have exactly the same meaning as the corresponding global - variables, except that they are used for the reentrant - versions of getopt. */ - int optind; - int opterr; - int optopt; - char *optarg; - - /* Internal members. */ - - /* True if the internal members have been initialized. */ - int __initialized; - - /* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - char *__nextchar; - - /* See __ord above. */ - enum __ord __ordering; - - /* If the POSIXLY_CORRECT environment variable is set - or getopt was called. */ - int __posixly_correct; - - - /* Handle permutation of arguments. */ - - /* Describe the part of ARGV that contains non-options that have - been skipped. 'first_nonopt' is the index in ARGV of the first - of them; 'last_nonopt' is the index after the last of them. */ - - int __first_nonopt; - int __last_nonopt; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - int __nonoption_flags_max_len; - int __nonoption_flags_len; -#endif -}; - -/* The initializer is necessary to set OPTIND and OPTERR to their - default values and to clear the initialization flag. */ -#define _GETOPT_DATA_INITIALIZER { 1, 1 } - -extern int _getopt_internal_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, struct _getopt_data *__data, - int __posixly_correct); - -extern int _getopt_long_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - struct _getopt_data *__data); - -extern int _getopt_long_only_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, - int *__longind, - struct _getopt_data *__data); - -#endif /* getopt_int.h */ diff --git a/grub-core/gnulib/gettext.h b/grub-core/gnulib/gettext.h deleted file mode 100644 index d0215715a..000000000 --- a/grub-core/gnulib/gettext.h +++ /dev/null @@ -1,288 +0,0 @@ -/* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2013 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include - -/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by - the gettext() and ngettext() macros. This is an alternative to calling - textdomain(), and is useful for libraries. */ -# ifdef DEFAULT_TEXT_DOMAIN -# undef gettext -# define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) -# endif - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of a NOP. We don't include - as well because people using "gettext.h" will not include , - and also including would fail on SunOS 4, whereas - is OK. */ -#if defined(__sun) -# include -#endif - -/* Many header files from the libstdc++ coming with g++ 3.3 or newer include - , which chokes if dcgettext is defined as a macro. So include - it now, to make later inclusions of a NOP. */ -#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) -# include -# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H -# include -# endif -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# undef gettext -# define gettext(Msgid) ((const char *) (Msgid)) -# undef dgettext -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) -# undef dcgettext -# define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# undef dngettext -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# undef dcngettext -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) -# undef textdomain -# define textdomain(Domainname) ((const char *) (Domainname)) -# undef bindtextdomain -# define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) -# undef bind_textdomain_codeset -# define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) - -#endif - -/* Prefer gnulib's setlocale override over libintl's setlocale override. */ -#ifdef GNULIB_defined_setlocale -# undef setlocale -# define setlocale rpl_setlocale -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -/* The separator between msgctxt and msgid in a .mo file. */ -#define GETTEXT_CONTEXT_GLUE "\004" - -/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a - MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be - short and rarely need to change. - The letter 'p' stands for 'particular' or 'special'. */ -#ifdef DEFAULT_TEXT_DOMAIN -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#else -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#endif -#define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) -#ifdef DEFAULT_TEXT_DOMAIN -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#else -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#endif -#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) -{ - const char *translation = dcgettext (domain, msg_ctxt_id, category); - if (translation == msg_ctxt_id) - return msgid; - else - return translation; -} - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - const char *translation = - dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); - if (translation == msg_ctxt_id || translation == msgid_plural) - return (n == 1 ? msgid : msgid_plural); - else - return translation; -} - -/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID - can be arbitrary expressions. But for string literals these macros are - less efficient than those above. */ - -#include - -#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ - /* || __STDC_VERSION__ >= 199901L */ ) -# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 -#else -# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 -#endif - -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS -#include -#endif - -#define pgettext_expr(Msgctxt, Msgid) \ - dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) -#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcgettext (domain, msg_ctxt_id, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (translation != msg_ctxt_id) - return translation; - } - return msgid; -} - -#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (!(translation == msg_ctxt_id || translation == msgid_plural)) - return translation; - } - return (n == 1 ? msgid : msgid_plural); -} - -#endif /* _LIBGETTEXT_H */ diff --git a/grub-core/gnulib/intprops.h b/grub-core/gnulib/intprops.h deleted file mode 100644 index b473052d1..000000000 --- a/grub-core/gnulib/intprops.h +++ /dev/null @@ -1,319 +0,0 @@ -/* intprops.h -- properties of integer types - - Copyright (C) 2001-2005, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Paul Eggert. */ - -#ifndef _GL_INTPROPS_H -#define _GL_INTPROPS_H - -#include - -/* Return an integer value, converted to the same type as the integer - expression E after integer type promotion. V is the unconverted value. */ -#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) - -/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see - . */ -#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) - -/* The extra casts in the following macros work around compiler bugs, - e.g., in Cray C 5.0.3.0. */ - -/* True if the arithmetic type T is an integer type. bool counts as - an integer. */ -#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) - -/* True if negative values of the signed integer type T use two's - complement, ones' complement, or signed magnitude representation, - respectively. Much GNU code assumes two's complement, but some - people like to be portable to all possible C hosts. */ -#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) -#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) -#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) - -/* True if the signed integer expression E uses two's complement. */ -#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1) - -/* True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* Return 1 if the integer expression E, after integer promotion, has - a signed type. */ -#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) - - -/* Minimum and maximum values for integer types and expressions. These - macros have undefined behavior if T is signed and has padding bits. - If this is a problem for you, please let us know how to fix it for - your host. */ - -/* The maximum and minimum values for the integer type T. */ -#define TYPE_MINIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) 0 \ - : TYPE_SIGNED_MAGNITUDE (t) \ - ? ~ (t) 0 \ - : ~ TYPE_MAXIMUM (t))) -#define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) - -/* The maximum and minimum values for the type of the expression E, - after integer promotion. E should not have side effects. */ -#define _GL_INT_MINIMUM(e) \ - (_GL_INT_SIGNED (e) \ - ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \ - : _GL_INT_CONVERT (e, 0)) -#define _GL_INT_MAXIMUM(e) \ - (_GL_INT_SIGNED (e) \ - ? _GL_SIGNED_INT_MAXIMUM (e) \ - : _GL_INT_NEGATE_CONVERT (e, 1)) -#define _GL_SIGNED_INT_MAXIMUM(e) \ - (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1) - - -/* Return 1 if the __typeof__ keyword works. This could be done by - 'configure', but for now it's easier to do it by hand. */ -#if 2 <= __GNUC__ || 0x5110 <= __SUNPRO_C -# define _GL_HAVE___TYPEOF__ 1 -#else -# define _GL_HAVE___TYPEOF__ 0 -#endif - -/* Return 1 if the integer type or expression T might be signed. Return 0 - if it is definitely unsigned. This macro does not evaluate its argument, - and expands to an integer constant expression. */ -#if _GL_HAVE___TYPEOF__ -# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) -#else -# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 -#endif - -/* Bound on length of the string representing an unsigned integer - value representable in B bits. log10 (2.0) < 146/485. The - smallest value of B where this bound is not tight is 2621. */ -#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) - -/* Bound on length of the string representing an integer type or expression T. - Subtract 1 for the sign bit if T is signed, and then add 1 more for - a minus sign if needed. - - Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is - signed, this macro may overestimate the true bound by one byte when - applied to unsigned types of size 2, 4, 16, ... bytes. */ -#define INT_STRLEN_BOUND(t) \ - (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT \ - - _GL_SIGNED_TYPE_OR_EXPR (t)) \ - + _GL_SIGNED_TYPE_OR_EXPR (t)) - -/* Bound on buffer size needed to represent an integer type or expression T, - including the terminating null. */ -#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) - - -/* Range overflow checks. - - The INT__RANGE_OVERFLOW macros return 1 if the corresponding C - operators might not yield numerically correct answers due to - arithmetic overflow. They do not rely on undefined or - implementation-defined behavior. Their implementations are simple - and straightforward, but they are a bit harder to use than the - INT__OVERFLOW macros described below. - - Example usage: - - long int i = ...; - long int j = ...; - if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX)) - printf ("multiply would overflow"); - else - printf ("product is %ld", i * j); - - Restrictions on *_RANGE_OVERFLOW macros: - - These macros do not check for all possible numerical problems or - undefined or unspecified behavior: they do not check for division - by zero, for bad shift counts, or for shifting negative numbers. - - These macros may evaluate their arguments zero or multiple times, - so the arguments should not have side effects. The arithmetic - arguments (including the MIN and MAX arguments) must be of the same - integer type after the usual arithmetic conversions, and the type - must have minimum value MIN and maximum MAX. Unsigned types should - use a zero MIN of the proper type. - - These macros are tuned for constant MIN and MAX. For commutative - operations such as A + B, they are also tuned for constant B. */ - -/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. */ -#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \ - ((b) < 0 \ - ? (a) < (min) - (b) \ - : (max) - (b) < (a)) - -/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. */ -#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \ - ((b) < 0 \ - ? (max) + (b) < (a) \ - : (a) < (min) + (b)) - -/* Return 1 if - A would overflow in [MIN,MAX] arithmetic. - See above for restrictions. */ -#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ - ((min) < 0 \ - ? (a) < - (max) \ - : 0 < (a)) - -/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Avoid && and || as they tickle - bugs in Sun C 5.11 2010/08/13 and other compilers; see - . */ -#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ - ((b) < 0 \ - ? ((a) < 0 \ - ? (a) < (max) / (b) \ - : (b) == -1 \ - ? 0 \ - : (min) / (b) < (a)) \ - : (b) == 0 \ - ? 0 \ - : ((a) < 0 \ - ? (a) < (min) / (b) \ - : (max) / (b) < (a))) - -/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Do not check for division by zero. */ -#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \ - ((min) < 0 && (b) == -1 && (a) < - (max)) - -/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Do not check for division by zero. - Mathematically, % should never overflow, but on x86-like hosts - INT_MIN % -1 traps, and the C standard permits this, so treat this - as an overflow too. */ -#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \ - INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max) - -/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Here, MIN and MAX are for A only, and B need - not be of the same type as the other arguments. The C standard says that - behavior is undefined for shifts unless 0 <= B < wordwidth, and that when - A is negative then A << B has undefined behavior and A >> B has - implementation-defined behavior, but do not check these other - restrictions. */ -#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ - ((a) < 0 \ - ? (a) < (min) >> (b) \ - : (max) >> (b) < (a)) - - -/* The _GL*_OVERFLOW macros have the same restrictions as the - *_RANGE_OVERFLOW macros, except that they do not assume that operands - (e.g., A and B) have the same type as MIN and MAX. Instead, they assume - that the result (e.g., A + B) has that type. */ -#define _GL_ADD_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ - : (a) < 0 ? (b) <= (a) + (b) \ - : (b) < 0 ? (a) <= (a) + (b) \ - : (a) + (b) < (b)) -#define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ - : (a) < 0 ? 1 \ - : (b) < 0 ? (a) - (b) <= (a) \ - : (a) < (b)) -#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ - (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ - || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) -#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ - : (a) < 0 ? (b) <= (a) + (b) - 1 \ - : (b) < 0 && (a) + (b) <= (a)) -#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ - : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ - : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) - -/* Return a nonzero value if A is a mathematical multiple of B, where - A is unsigned, B is negative, and MAX is the maximum value of A's - type. A's type must be the same as (A % B)'s type. Normally (A % - -B == 0) suffices, but things get tricky if -B would overflow. */ -#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \ - (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \ - ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \ - ? (a) \ - : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \ - : (a) % - (b)) \ - == 0) - - -/* Integer overflow checks. - - The INT__OVERFLOW macros return 1 if the corresponding C operators - might not yield numerically correct answers due to arithmetic overflow. - They work correctly on all known practical hosts, and do not rely - on undefined behavior due to signed arithmetic overflow. - - Example usage: - - long int i = ...; - long int j = ...; - if (INT_MULTIPLY_OVERFLOW (i, j)) - printf ("multiply would overflow"); - else - printf ("product is %ld", i * j); - - These macros do not check for all possible numerical problems or - undefined or unspecified behavior: they do not check for division - by zero, for bad shift counts, or for shifting negative numbers. - - These macros may evaluate their arguments zero or multiple times, so the - arguments should not have side effects. - - These macros are tuned for their last argument being a constant. - - Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, - A % B, and A << B would overflow, respectively. */ - -#define INT_ADD_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) -#define INT_SUBTRACT_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) -#define INT_NEGATE_OVERFLOW(a) \ - INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) -#define INT_MULTIPLY_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) -#define INT_DIVIDE_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW) -#define INT_REMAINDER_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW) -#define INT_LEFT_SHIFT_OVERFLOW(a, b) \ - INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ - _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) - -/* Return 1 if the expression A B would overflow, - where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, - assuming MIN and MAX are the minimum and maximum for the result type. - Arguments should be free of side effects. */ -#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ - op_result_overflow (a, b, \ - _GL_INT_MINIMUM (0 * (b) + (a)), \ - _GL_INT_MAXIMUM (0 * (b) + (a))) - -#endif /* _GL_INTPROPS_H */ diff --git a/grub-core/gnulib/itold.c b/grub-core/gnulib/itold.c deleted file mode 100644 index 9aabc7e46..000000000 --- a/grub-core/gnulib/itold.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Replacement for 'int' to 'long double' conversion routine. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2011. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -void -_Qp_itoq (long double *result, int a) -{ - /* Convert from 'int' to 'double', then from 'double' to 'long double'. */ - *result = (double) a; -} diff --git a/grub-core/gnulib/langinfo.in.h b/grub-core/gnulib/langinfo.in.h deleted file mode 100644 index 5388ce624..000000000 --- a/grub-core/gnulib/langinfo.in.h +++ /dev/null @@ -1,176 +0,0 @@ -/* Substitute for and wrapper around . - Copyright (C) 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 . */ - -/* - * POSIX for platforms that lack it or have an incomplete one. - * - */ - -#ifndef _@GUARD_PREFIX@_LANGINFO_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_LANGINFO_H@ -# @INCLUDE_NEXT@ @NEXT_LANGINFO_H@ -#endif - -#ifndef _@GUARD_PREFIX@_LANGINFO_H -#define _@GUARD_PREFIX@_LANGINFO_H - - -#if !@HAVE_LANGINFO_H@ - -/* A platform that lacks . */ - -/* Assume that it also lacks and the nl_item type. */ -# if !GNULIB_defined_nl_item -typedef int nl_item; -# define GNULIB_defined_nl_item 1 -# endif - -/* nl_langinfo items of the LC_CTYPE category */ -# define CODESET 10000 -/* nl_langinfo items of the LC_NUMERIC category */ -# define RADIXCHAR 10001 -# define THOUSEP 10002 -/* nl_langinfo items of the LC_TIME category */ -# define D_T_FMT 10003 -# define D_FMT 10004 -# define T_FMT 10005 -# define T_FMT_AMPM 10006 -# define AM_STR 10007 -# define PM_STR 10008 -# define DAY_1 10009 -# define DAY_2 (DAY_1 + 1) -# define DAY_3 (DAY_1 + 2) -# define DAY_4 (DAY_1 + 3) -# define DAY_5 (DAY_1 + 4) -# define DAY_6 (DAY_1 + 5) -# define DAY_7 (DAY_1 + 6) -# define ABDAY_1 10016 -# define ABDAY_2 (ABDAY_1 + 1) -# define ABDAY_3 (ABDAY_1 + 2) -# define ABDAY_4 (ABDAY_1 + 3) -# define ABDAY_5 (ABDAY_1 + 4) -# define ABDAY_6 (ABDAY_1 + 5) -# define ABDAY_7 (ABDAY_1 + 6) -# define MON_1 10023 -# define MON_2 (MON_1 + 1) -# define MON_3 (MON_1 + 2) -# define MON_4 (MON_1 + 3) -# define MON_5 (MON_1 + 4) -# define MON_6 (MON_1 + 5) -# define MON_7 (MON_1 + 6) -# define MON_8 (MON_1 + 7) -# define MON_9 (MON_1 + 8) -# define MON_10 (MON_1 + 9) -# define MON_11 (MON_1 + 10) -# define MON_12 (MON_1 + 11) -# define ABMON_1 10035 -# define ABMON_2 (ABMON_1 + 1) -# define ABMON_3 (ABMON_1 + 2) -# define ABMON_4 (ABMON_1 + 3) -# define ABMON_5 (ABMON_1 + 4) -# define ABMON_6 (ABMON_1 + 5) -# define ABMON_7 (ABMON_1 + 6) -# define ABMON_8 (ABMON_1 + 7) -# define ABMON_9 (ABMON_1 + 8) -# define ABMON_10 (ABMON_1 + 9) -# define ABMON_11 (ABMON_1 + 10) -# define ABMON_12 (ABMON_1 + 11) -# define ERA 10047 -# define ERA_D_FMT 10048 -# define ERA_D_T_FMT 10049 -# define ERA_T_FMT 10050 -# define ALT_DIGITS 10051 -/* nl_langinfo items of the LC_MONETARY category */ -# define CRNCYSTR 10052 -/* nl_langinfo items of the LC_MESSAGES category */ -# define YESEXPR 10053 -# define NOEXPR 10054 - -#else - -/* A platform that has . */ - -# if !@HAVE_LANGINFO_CODESET@ -# define CODESET 10000 -# define GNULIB_defined_CODESET 1 -# endif - -# if !@HAVE_LANGINFO_T_FMT_AMPM@ -# define T_FMT_AMPM 10006 -# define GNULIB_defined_T_FMT_AMPM 1 -# endif - -# if !@HAVE_LANGINFO_ERA@ -# define ERA 10047 -# define ERA_D_FMT 10048 -# define ERA_D_T_FMT 10049 -# define ERA_T_FMT 10050 -# define ALT_DIGITS 10051 -# define GNULIB_defined_ERA 1 -# endif - -# if !@HAVE_LANGINFO_YESEXPR@ -# define YESEXPR 10053 -# define NOEXPR 10054 -# define GNULIB_defined_YESEXPR 1 -# endif - -#endif - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - -/* Declare overridden functions. */ - - -/* Return a piece of locale dependent information. - Note: The difference between nl_langinfo (CODESET) and locale_charset () - is that the latter normalizes the encoding names to GNU conventions. */ - -#if @GNULIB_NL_LANGINFO@ -# if @REPLACE_NL_LANGINFO@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef nl_langinfo -# define nl_langinfo rpl_nl_langinfo -# endif -_GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item)); -_GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item)); -# else -# if !@HAVE_NL_LANGINFO@ -_GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item)); -# endif -_GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item)); -# endif -_GL_CXXALIASWARN (nl_langinfo); -#elif defined GNULIB_POSIXCHECK -# undef nl_langinfo -# if HAVE_RAW_DECL_NL_LANGINFO -_GL_WARN_ON_USE (nl_langinfo, "nl_langinfo is not portable - " - "use gnulib module nl_langinfo for portability"); -# endif -#endif - - -#endif /* _@GUARD_PREFIX@_LANGINFO_H */ -#endif /* _@GUARD_PREFIX@_LANGINFO_H */ diff --git a/grub-core/gnulib/localcharset.c b/grub-core/gnulib/localcharset.c deleted file mode 100644 index 953cc1e70..000000000 --- a/grub-core/gnulib/localcharset.c +++ /dev/null @@ -1,553 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - - Copyright (C) 2000-2006, 2008-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 Bruno Haible . */ - -#include - -/* Specification. */ -#include "localcharset.h" - -#include -#include -#include -#include -#include - -#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET -# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */ -#endif - -#if defined _WIN32 || defined __WIN32__ -# define WINDOWS_NATIVE -#endif - -#if defined __EMX__ -/* Assume EMX program runs on OS/2, even if compiled under DOS. */ -# ifndef OS2 -# define OS2 -# endif -#endif - -#if !defined WINDOWS_NATIVE -# include -# if HAVE_LANGINFO_CODESET -# include -# else -# if 0 /* see comment below */ -# include -# endif -# endif -# ifdef __CYGWIN__ -# define WIN32_LEAN_AND_MEAN -# include -# endif -#elif defined WINDOWS_NATIVE -# define WIN32_LEAN_AND_MEAN -# include -#endif -#if defined OS2 -# define INCL_DOS -# include -#endif - -#if ENABLE_RELOCATABLE -# include "relocatable.h" -#else -# define relocate(pathname) (pathname) -#endif - -/* Get LIBDIR. */ -#ifndef LIBDIR -# include "configmake.h" -#endif - -/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ -#ifndef O_NOFOLLOW -# define O_NOFOLLOW 0 -#endif - -#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ - /* Native Windows, Cygwin, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -#endif - -#ifndef DIRECTORY_SEPARATOR -# define DIRECTORY_SEPARATOR '/' -#endif - -#ifndef ISSLASH -# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) -#endif - -#if HAVE_DECL_GETC_UNLOCKED -# undef getc -# define getc getc_unlocked -#endif - -/* The following static variable is declared 'volatile' to avoid a - possible multithread problem in the function get_charset_aliases. If we - are running in a threaded environment, and if two threads initialize - 'charset_aliases' simultaneously, both will produce the same value, - and everything will be ok if the two assignments to 'charset_aliases' - are atomic. But I don't know what will happen if the two assignments mix. */ -#if __STDC__ != 1 -# define volatile /* empty */ -#endif -/* Pointer to the contents of the charset.alias file, if it has already been - read, else NULL. Its format is: - ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ -static const char * volatile charset_aliases; - -/* Return a pointer to the contents of the charset.alias file. */ -static const char * -get_charset_aliases (void) -{ - const char *cp; - - cp = charset_aliases; - if (cp == NULL) - { -#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__) - const char *dir; - const char *base = "charset.alias"; - char *file_name; - - /* Make it possible to override the charset.alias location. This is - necessary for running the testsuite before "make install". */ - dir = getenv ("CHARSETALIASDIR"); - if (dir == NULL || dir[0] == '\0') - dir = relocate (LIBDIR); - - /* Concatenate dir and base into freshly allocated file_name. */ - { - size_t dir_len = strlen (dir); - size_t base_len = strlen (base); - int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); - file_name = (char *) malloc (dir_len + add_slash + base_len + 1); - if (file_name != NULL) - { - memcpy (file_name, dir, dir_len); - if (add_slash) - file_name[dir_len] = DIRECTORY_SEPARATOR; - memcpy (file_name + dir_len + add_slash, base, base_len + 1); - } - } - - if (file_name == NULL) - /* Out of memory. Treat the file as empty. */ - cp = ""; - else - { - int fd; - - /* Open the file. Reject symbolic links on platforms that support - O_NOFOLLOW. This is a security feature. Without it, an attacker - could retrieve parts of the contents (namely, the tail of the - first line that starts with "* ") of an arbitrary file by placing - a symbolic link to that file under the name "charset.alias" in - some writable directory and defining the environment variable - CHARSETALIASDIR to point to that directory. */ - fd = open (file_name, - O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); - if (fd < 0) - /* File not found. Treat it as empty. */ - cp = ""; - else - { - FILE *fp; - - fp = fdopen (fd, "r"); - if (fp == NULL) - { - /* Out of memory. Treat the file as empty. */ - close (fd); - cp = ""; - } - else - { - /* Parse the file's contents. */ - char *res_ptr = NULL; - size_t res_size = 0; - - for (;;) - { - int c; - char buf1[50+1]; - char buf2[50+1]; - size_t l1, l2; - char *old_res_ptr; - - c = getc (fp); - if (c == EOF) - break; - if (c == '\n' || c == ' ' || c == '\t') - continue; - if (c == '#') - { - /* Skip comment, to end of line. */ - do - c = getc (fp); - while (!(c == EOF || c == '\n')); - if (c == EOF) - break; - continue; - } - ungetc (c, fp); - if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) - break; - l1 = strlen (buf1); - l2 = strlen (buf2); - old_res_ptr = res_ptr; - if (res_size == 0) - { - res_size = l1 + 1 + l2 + 1; - res_ptr = (char *) malloc (res_size + 1); - } - else - { - res_size += l1 + 1 + l2 + 1; - res_ptr = (char *) realloc (res_ptr, res_size + 1); - } - if (res_ptr == NULL) - { - /* Out of memory. */ - res_size = 0; - free (old_res_ptr); - break; - } - strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); - strcpy (res_ptr + res_size - (l2 + 1), buf2); - } - fclose (fp); - if (res_size == 0) - cp = ""; - else - { - *(res_ptr + res_size) = '\0'; - cp = res_ptr; - } - } - } - - free (file_name); - } - -#else - -# if defined DARWIN7 - /* To avoid the trouble of installing a file that is shared by many - GNU packages -- many packaging systems have problems with this --, - simply inline the aliases here. */ - cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" - "ISO8859-2" "\0" "ISO-8859-2" "\0" - "ISO8859-4" "\0" "ISO-8859-4" "\0" - "ISO8859-5" "\0" "ISO-8859-5" "\0" - "ISO8859-7" "\0" "ISO-8859-7" "\0" - "ISO8859-9" "\0" "ISO-8859-9" "\0" - "ISO8859-13" "\0" "ISO-8859-13" "\0" - "ISO8859-15" "\0" "ISO-8859-15" "\0" - "KOI8-R" "\0" "KOI8-R" "\0" - "KOI8-U" "\0" "KOI8-U" "\0" - "CP866" "\0" "CP866" "\0" - "CP949" "\0" "CP949" "\0" - "CP1131" "\0" "CP1131" "\0" - "CP1251" "\0" "CP1251" "\0" - "eucCN" "\0" "GB2312" "\0" - "GB2312" "\0" "GB2312" "\0" - "eucJP" "\0" "EUC-JP" "\0" - "eucKR" "\0" "EUC-KR" "\0" - "Big5" "\0" "BIG5" "\0" - "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" - "GBK" "\0" "GBK" "\0" - "GB18030" "\0" "GB18030" "\0" - "SJIS" "\0" "SHIFT_JIS" "\0" - "ARMSCII-8" "\0" "ARMSCII-8" "\0" - "PT154" "\0" "PT154" "\0" - /*"ISCII-DEV" "\0" "?" "\0"*/ - "*" "\0" "UTF-8" "\0"; -# endif - -# if defined VMS - /* To avoid the troubles of an extra file charset.alias_vms in the - sources of many GNU packages, simply inline the aliases here. */ - /* The list of encodings is taken from the OpenVMS 7.3-1 documentation - "Compaq C Run-Time Library Reference Manual for OpenVMS systems" - section 10.7 "Handling Different Character Sets". */ - cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" - "ISO8859-2" "\0" "ISO-8859-2" "\0" - "ISO8859-5" "\0" "ISO-8859-5" "\0" - "ISO8859-7" "\0" "ISO-8859-7" "\0" - "ISO8859-8" "\0" "ISO-8859-8" "\0" - "ISO8859-9" "\0" "ISO-8859-9" "\0" - /* Japanese */ - "eucJP" "\0" "EUC-JP" "\0" - "SJIS" "\0" "SHIFT_JIS" "\0" - "DECKANJI" "\0" "DEC-KANJI" "\0" - "SDECKANJI" "\0" "EUC-JP" "\0" - /* Chinese */ - "eucTW" "\0" "EUC-TW" "\0" - "DECHANYU" "\0" "DEC-HANYU" "\0" - "DECHANZI" "\0" "GB2312" "\0" - /* Korean */ - "DECKOREAN" "\0" "EUC-KR" "\0"; -# endif - -# if defined WINDOWS_NATIVE || defined __CYGWIN__ - /* To avoid the troubles of installing a separate file in the same - directory as the DLL and of retrieving the DLL's directory at - runtime, simply inline the aliases here. */ - - cp = "CP936" "\0" "GBK" "\0" - "CP1361" "\0" "JOHAB" "\0" - "CP20127" "\0" "ASCII" "\0" - "CP20866" "\0" "KOI8-R" "\0" - "CP20936" "\0" "GB2312" "\0" - "CP21866" "\0" "KOI8-RU" "\0" - "CP28591" "\0" "ISO-8859-1" "\0" - "CP28592" "\0" "ISO-8859-2" "\0" - "CP28593" "\0" "ISO-8859-3" "\0" - "CP28594" "\0" "ISO-8859-4" "\0" - "CP28595" "\0" "ISO-8859-5" "\0" - "CP28596" "\0" "ISO-8859-6" "\0" - "CP28597" "\0" "ISO-8859-7" "\0" - "CP28598" "\0" "ISO-8859-8" "\0" - "CP28599" "\0" "ISO-8859-9" "\0" - "CP28605" "\0" "ISO-8859-15" "\0" - "CP38598" "\0" "ISO-8859-8" "\0" - "CP51932" "\0" "EUC-JP" "\0" - "CP51936" "\0" "GB2312" "\0" - "CP51949" "\0" "EUC-KR" "\0" - "CP51950" "\0" "EUC-TW" "\0" - "CP54936" "\0" "GB18030" "\0" - "CP65001" "\0" "UTF-8" "\0"; -# endif -#endif - - charset_aliases = cp; - } - - return cp; -} - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ - -#ifdef STATIC -STATIC -#endif -const char * -locale_charset (void) -{ - const char *codeset; - const char *aliases; - -#if !(defined WINDOWS_NATIVE || defined OS2) - -# if HAVE_LANGINFO_CODESET - - /* Most systems support nl_langinfo (CODESET) nowadays. */ - codeset = nl_langinfo (CODESET); - -# ifdef __CYGWIN__ - /* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always - returns "US-ASCII". Return the suffix of the locale name from the - environment variables (if present) or the codepage as a number. */ - if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) - { - const char *locale; - static char buf[2 + 10 + 1]; - - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return - it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - } - - /* The Windows API has a function returning the locale's codepage as a - number: GetACP(). This encoding is used by Cygwin, unless the user - has set the environment variable CYGWIN=codepage:oem (which very few - people do). - Output directed to console windows needs to be converted (to - GetOEMCP() if the console is using a raster font, or to - GetConsoleOutputCP() if it is using a TrueType font). Cygwin does - this conversion transparently (see winsup/cygwin/fhandler_console.cc), - converting to GetConsoleOutputCP(). This leads to correct results, - except when SetConsoleOutputCP has been called and a raster font is - in use. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; - } -# endif - -# else - - /* On old systems which lack it, use setlocale or getenv. */ - const char *locale = NULL; - - /* But most old systems don't have a complete set of locales. Some - (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't - use setlocale here; it would return "C" when it doesn't support the - locale name the user has set. */ -# if 0 - locale = setlocale (LC_CTYPE, NULL); -# endif - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - } - - /* On some old systems, one used to set locale = "iso8859_1". On others, - you set it to "language_COUNTRY.charset". In any case, we resolve it - through the charset.alias file. */ - codeset = locale; - -# endif - -#elif defined WINDOWS_NATIVE - - static char buf[2 + 10 + 1]; - - /* The Windows API has a function returning the locale's codepage as a - number: GetACP(). - When the output goes to a console window, it needs to be provided in - GetOEMCP() encoding if the console is using a raster font, or in - GetConsoleOutputCP() encoding if it is using a TrueType font. - But in GUI programs and for output sent to files and pipes, GetACP() - encoding is the best bet. */ - sprintf (buf, "CP%u", GetACP ()); - codeset = buf; - -#elif defined OS2 - - const char *locale; - static char buf[2 + 10 + 1]; - ULONG cp[3]; - ULONG cplen; - - /* Allow user to override the codeset, as set in the operating system, - with standard language environment variables. */ - locale = getenv ("LC_ALL"); - if (locale == NULL || locale[0] == '\0') - { - locale = getenv ("LC_CTYPE"); - if (locale == NULL || locale[0] == '\0') - locale = getenv ("LANG"); - } - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - - /* Resolve through the charset.alias file. */ - codeset = locale; - } - else - { - /* OS/2 has a function returning the locale's codepage as a number. */ - if (DosQueryCp (sizeof (cp), cp, &cplen)) - codeset = ""; - else - { - sprintf (buf, "CP%u", cp[0]); - codeset = buf; - } - } - -#endif - - if (codeset == NULL) - /* The canonical name cannot be determined. */ - codeset = ""; - - /* Resolve alias. */ - for (aliases = get_charset_aliases (); - *aliases != '\0'; - aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) - if (strcmp (codeset, aliases) == 0 - || (aliases[0] == '*' && aliases[1] == '\0')) - { - codeset = aliases + strlen (aliases) + 1; - break; - } - - /* Don't return an empty string. GNU libc and GNU libiconv interpret - the empty string as denoting "the locale's character encoding", - thus GNU libiconv would call this function a second time. */ - if (codeset[0] == '\0') - codeset = "ASCII"; - -#ifdef DARWIN7 - /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8" - (the default codeset) does not work when MB_CUR_MAX is 1. */ - if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX <= 1) - codeset = "ASCII"; -#endif - - return codeset; -} diff --git a/grub-core/gnulib/localcharset.h b/grub-core/gnulib/localcharset.h deleted file mode 100644 index c20982986..000000000 --- a/grub-core/gnulib/localcharset.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Determine a canonical name for the current locale's character encoding. - Copyright (C) 2000-2003, 2009-2013 Free Software Foundation, Inc. - This file is part of the GNU CHARSET Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifndef _LOCALCHARSET_H -#define _LOCALCHARSET_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Determine the current locale's character encoding, and canonicalize it - into one of the canonical names listed in config.charset. - The result must not be freed; it is statically allocated. - If the canonical name cannot be determined, the result is a non-canonical - name. */ -extern const char * locale_charset (void); - - -#ifdef __cplusplus -} -#endif - - -#endif /* _LOCALCHARSET_H */ diff --git a/grub-core/gnulib/locale.in.h b/grub-core/gnulib/locale.in.h deleted file mode 100644 index 264161a6c..000000000 --- a/grub-core/gnulib/locale.in.h +++ /dev/null @@ -1,216 +0,0 @@ -/* A POSIX . - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#ifdef _GL_ALREADY_INCLUDING_LOCALE_H - -/* Special invocation conventions to handle Solaris header files - (through Solaris 10) when combined with gettext's libintl.h. */ - -#@INCLUDE_NEXT@ @NEXT_LOCALE_H@ - -#else -/* Normal invocation convention. */ - -#ifndef _@GUARD_PREFIX@_LOCALE_H - -#define _GL_ALREADY_INCLUDING_LOCALE_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_LOCALE_H@ - -#undef _GL_ALREADY_INCLUDING_LOCALE_H - -#ifndef _@GUARD_PREFIX@_LOCALE_H -#define _@GUARD_PREFIX@_LOCALE_H - -/* NetBSD 5.0 mis-defines NULL. */ -#include - -/* Mac OS X 10.5 defines the locale_t type in . */ -#if @HAVE_XLOCALE_H@ -# include -#endif - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - -/* The LC_MESSAGES locale category is specified in POSIX, but not in ISO C. - On systems that don't define it, use the same value as GNU libintl. */ -#if !defined LC_MESSAGES -# define LC_MESSAGES 1729 -#endif - -/* Bionic libc's 'struct lconv' is just a dummy. */ -#if @REPLACE_STRUCT_LCONV@ -# define lconv rpl_lconv -struct lconv -{ - /* All 'char *' are actually 'const char *'. */ - - /* Members that depend on the LC_NUMERIC category of the locale. See - */ - - /* Symbol used as decimal point. */ - char *decimal_point; - /* Symbol used to separate groups of digits to the left of the decimal - point. */ - char *thousands_sep; - /* Definition of the size of groups of digits to the left of the decimal - point. */ - char *grouping; - - /* Members that depend on the LC_MONETARY category of the locale. See - */ - - /* Symbol used as decimal point. */ - char *mon_decimal_point; - /* Symbol used to separate groups of digits to the left of the decimal - point. */ - char *mon_thousands_sep; - /* Definition of the size of groups of digits to the left of the decimal - point. */ - char *mon_grouping; - /* Sign used to indicate a value >= 0. */ - char *positive_sign; - /* Sign used to indicate a value < 0. */ - char *negative_sign; - - /* For formatting local currency. */ - /* Currency symbol (3 characters) followed by separator (1 character). */ - char *currency_symbol; - /* Number of digits after the decimal point. */ - char frac_digits; - /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it - comes after the number. */ - char p_cs_precedes; - /* For values >= 0: Position of the sign. */ - char p_sign_posn; - /* For values >= 0: Placement of spaces between currency symbol, sign, and - number. */ - char p_sep_by_space; - /* For values < 0: 1 if the currency symbol precedes the number, 0 if it - comes after the number. */ - char n_cs_precedes; - /* For values < 0: Position of the sign. */ - char n_sign_posn; - /* For values < 0: Placement of spaces between currency symbol, sign, and - number. */ - char n_sep_by_space; - - /* For formatting international currency. */ - /* Currency symbol (3 characters) followed by separator (1 character). */ - char *int_curr_symbol; - /* Number of digits after the decimal point. */ - char int_frac_digits; - /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it - comes after the number. */ - char int_p_cs_precedes; - /* For values >= 0: Position of the sign. */ - char int_p_sign_posn; - /* For values >= 0: Placement of spaces between currency symbol, sign, and - number. */ - char int_p_sep_by_space; - /* For values < 0: 1 if the currency symbol precedes the number, 0 if it - comes after the number. */ - char int_n_cs_precedes; - /* For values < 0: Position of the sign. */ - char int_n_sign_posn; - /* For values < 0: Placement of spaces between currency symbol, sign, and - number. */ - char int_n_sep_by_space; -}; -#endif - -#if @GNULIB_LOCALECONV@ -# if @REPLACE_LOCALECONV@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef localeconv -# define localeconv rpl_localeconv -# endif -_GL_FUNCDECL_RPL (localeconv, struct lconv *, (void)); -_GL_CXXALIAS_RPL (localeconv, struct lconv *, (void)); -# else -_GL_CXXALIAS_SYS (localeconv, struct lconv *, (void)); -# endif -_GL_CXXALIASWARN (localeconv); -#elif @REPLACE_STRUCT_LCONV@ -# undef localeconv -# define localeconv localeconv_used_without_requesting_gnulib_module_localeconv -#elif defined GNULIB_POSIXCHECK -# undef localeconv -# if HAVE_RAW_DECL_LOCALECONV -_GL_WARN_ON_USE (localeconv, - "localeconv returns too few information on some platforms - " - "use gnulib module localeconv for portability"); -# endif -#endif - -#if @GNULIB_SETLOCALE@ -# if @REPLACE_SETLOCALE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef setlocale -# define setlocale rpl_setlocale -# define GNULIB_defined_setlocale 1 -# endif -_GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale)); -_GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale)); -# else -_GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale)); -# endif -_GL_CXXALIASWARN (setlocale); -#elif defined GNULIB_POSIXCHECK -# undef setlocale -# if HAVE_RAW_DECL_SETLOCALE -_GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - " - "use gnulib module setlocale for portability"); -# endif -#endif - -#if @GNULIB_DUPLOCALE@ -# if @REPLACE_DUPLOCALE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef duplocale -# define duplocale rpl_duplocale -# endif -_GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale)); -# else -# if @HAVE_DUPLOCALE@ -_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale)); -# endif -# endif -# if @HAVE_DUPLOCALE@ -_GL_CXXALIASWARN (duplocale); -# endif -#elif defined GNULIB_POSIXCHECK -# undef duplocale -# if HAVE_RAW_DECL_DUPLOCALE -_GL_WARN_ON_USE (duplocale, "duplocale is buggy on some glibc systems - " - "use gnulib module duplocale for portability"); -# endif -#endif - -#endif /* _@GUARD_PREFIX@_LOCALE_H */ -#endif /* ! _GL_ALREADY_INCLUDING_LOCALE_H */ -#endif /* _@GUARD_PREFIX@_LOCALE_H */ diff --git a/grub-core/gnulib/localeconv.c b/grub-core/gnulib/localeconv.c deleted file mode 100644 index 7c7c77cfd..000000000 --- a/grub-core/gnulib/localeconv.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Query locale dependent information for formatting numbers. - Copyright (C) 2012-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#if HAVE_STRUCT_LCONV_DECIMAL_POINT - -/* Override for platforms where 'struct lconv' lacks the int_p_*, int_n_* - members. */ - -struct lconv * -localeconv (void) -{ - static struct lconv result; -# undef lconv -# undef localeconv - struct lconv *sys_result = localeconv (); - - result.decimal_point = sys_result->decimal_point; - result.thousands_sep = sys_result->thousands_sep; - result.grouping = sys_result->grouping; - result.mon_decimal_point = sys_result->mon_decimal_point; - result.mon_thousands_sep = sys_result->mon_thousands_sep; - result.mon_grouping = sys_result->mon_grouping; - result.positive_sign = sys_result->positive_sign; - result.negative_sign = sys_result->negative_sign; - result.currency_symbol = sys_result->currency_symbol; - result.frac_digits = sys_result->frac_digits; - result.p_cs_precedes = sys_result->p_cs_precedes; - result.p_sign_posn = sys_result->p_sign_posn; - result.p_sep_by_space = sys_result->p_sep_by_space; - result.n_cs_precedes = sys_result->n_cs_precedes; - result.n_sign_posn = sys_result->n_sign_posn; - result.n_sep_by_space = sys_result->n_sep_by_space; - result.int_curr_symbol = sys_result->int_curr_symbol; - result.int_frac_digits = sys_result->int_frac_digits; - result.int_p_cs_precedes = sys_result->p_cs_precedes; - result.int_p_sign_posn = sys_result->p_sign_posn; - result.int_p_sep_by_space = sys_result->p_sep_by_space; - result.int_n_cs_precedes = sys_result->n_cs_precedes; - result.int_n_sign_posn = sys_result->n_sign_posn; - result.int_n_sep_by_space = sys_result->n_sep_by_space; - - return &result; -} - -#else - -/* Override for platforms where 'struct lconv' is a dummy. */ - -# include - -struct lconv * -localeconv (void) -{ - static /*const*/ struct lconv result = - { - /* decimal_point */ ".", - /* thousands_sep */ "", - /* grouping */ "", - /* mon_decimal_point */ "", - /* mon_thousands_sep */ "", - /* mon_grouping */ "", - /* positive_sign */ "", - /* negative_sign */ "", - /* currency_symbol */ "", - /* frac_digits */ CHAR_MAX, - /* p_cs_precedes */ CHAR_MAX, - /* p_sign_posn */ CHAR_MAX, - /* p_sep_by_space */ CHAR_MAX, - /* n_cs_precedes */ CHAR_MAX, - /* n_sign_posn */ CHAR_MAX, - /* n_sep_by_space */ CHAR_MAX, - /* int_curr_symbol */ "", - /* int_frac_digits */ CHAR_MAX, - /* int_p_cs_precedes */ CHAR_MAX, - /* int_p_sign_posn */ CHAR_MAX, - /* int_p_sep_by_space */ CHAR_MAX, - /* int_n_cs_precedes */ CHAR_MAX, - /* int_n_sign_posn */ CHAR_MAX, - /* int_n_sep_by_space */ CHAR_MAX - }; - - return &result; -} - -#endif diff --git a/grub-core/gnulib/malloc.c b/grub-core/gnulib/malloc.c deleted file mode 100644 index 908735d27..000000000 --- a/grub-core/gnulib/malloc.c +++ /dev/null @@ -1,56 +0,0 @@ -/* malloc() function that is glibc compatible. - - Copyright (C) 1997-1998, 2006-2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 Jim Meyering and Bruno Haible */ - -#define _GL_USE_STDLIB_ALLOC 1 -#include -/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */ -#ifdef malloc -# define NEED_MALLOC_GNU 1 -# undef malloc -/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ -#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU -# define NEED_MALLOC_GNU 1 -#endif - -#include - -#include - -/* Allocate an N-byte block of memory from the heap. - If N is zero, allocate a 1-byte block. */ - -void * -rpl_malloc (size_t n) -{ - void *result; - -#if NEED_MALLOC_GNU - if (n == 0) - n = 1; -#endif - - result = malloc (n); - -#if !HAVE_MALLOC_POSIX - if (result == NULL) - errno = ENOMEM; -#endif - - return result; -} diff --git a/grub-core/gnulib/mbrtowc.c b/grub-core/gnulib/mbrtowc.c deleted file mode 100644 index 5ee44aea4..000000000 --- a/grub-core/gnulib/mbrtowc.c +++ /dev/null @@ -1,402 +0,0 @@ -/* Convert multibyte character to wide character. - Copyright (C) 1999-2002, 2005-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2008. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#if GNULIB_defined_mbstate_t -/* Implement mbrtowc() on top of mbtowc(). */ - -# include -# include - -# include "localcharset.h" -# include "streq.h" -# include "verify.h" - - -verify (sizeof (mbstate_t) >= 4); - -static char internal_state[4]; - -size_t -mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) -{ - char *pstate = (char *)ps; - - if (s == NULL) - { - pwc = NULL; - s = ""; - n = 1; - } - - if (n == 0) - return (size_t)(-2); - - /* Here n > 0. */ - - if (pstate == NULL) - pstate = internal_state; - - { - size_t nstate = pstate[0]; - char buf[4]; - const char *p; - size_t m; - - switch (nstate) - { - case 0: - p = s; - m = n; - break; - case 3: - buf[2] = pstate[3]; - /*FALLTHROUGH*/ - case 2: - buf[1] = pstate[2]; - /*FALLTHROUGH*/ - case 1: - buf[0] = pstate[1]; - p = buf; - m = nstate; - buf[m++] = s[0]; - if (n >= 2 && m < 4) - { - buf[m++] = s[1]; - if (n >= 3 && m < 4) - buf[m++] = s[2]; - } - break; - default: - errno = EINVAL; - return (size_t)(-1); - } - - /* Here m > 0. */ - -# if __GLIBC__ || defined __UCLIBC__ - /* Work around bug */ - mbtowc (NULL, NULL, 0); -# endif - { - int res = mbtowc (pwc, p, m); - - if (res >= 0) - { - if (pwc != NULL && ((*pwc == 0) != (res == 0))) - abort (); - if (nstate >= (res > 0 ? res : 1)) - abort (); - res -= nstate; - pstate[0] = 0; - return res; - } - - /* mbtowc does not distinguish between invalid and incomplete multibyte - sequences. But mbrtowc needs to make this distinction. - There are two possible approaches: - - Use iconv() and its return value. - - Use built-in knowledge about the possible encodings. - Given the low quality of implementation of iconv() on the systems that - lack mbrtowc(), we use the second approach. - The possible encodings are: - - 8-bit encodings, - - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS, - - UTF-8. - Use specialized code for each. */ - if (m >= 4 || m >= MB_CUR_MAX) - goto invalid; - /* Here MB_CUR_MAX > 1 and 0 < m < 4. */ - { - const char *encoding = locale_charset (); - - if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) - { - /* Cf. unistr/u8-mblen.c. */ - unsigned char c = (unsigned char) p[0]; - - if (c >= 0xc2) - { - if (c < 0xe0) - { - if (m == 1) - goto incomplete; - } - else if (c < 0xf0) - { - if (m == 1) - goto incomplete; - if (m == 2) - { - unsigned char c2 = (unsigned char) p[1]; - - if ((c2 ^ 0x80) < 0x40 - && (c >= 0xe1 || c2 >= 0xa0) - && (c != 0xed || c2 < 0xa0)) - goto incomplete; - } - } - else if (c <= 0xf4) - { - if (m == 1) - goto incomplete; - else /* m == 2 || m == 3 */ - { - unsigned char c2 = (unsigned char) p[1]; - - if ((c2 ^ 0x80) < 0x40 - && (c >= 0xf1 || c2 >= 0x90) - && (c < 0xf4 || (c == 0xf4 && c2 < 0x90))) - { - if (m == 2) - goto incomplete; - else /* m == 3 */ - { - unsigned char c3 = (unsigned char) p[2]; - - if ((c3 ^ 0x80) < 0x40) - goto incomplete; - } - } - } - } - } - goto invalid; - } - - /* As a reference for this code, you can use the GNU libiconv - implementation. Look for uses of the RET_TOOFEW macro. */ - - if (STREQ_OPT (encoding, - "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f) - goto incomplete; - } - if (m == 2) - { - unsigned char c = (unsigned char) p[0]; - - if (c == 0x8f) - { - unsigned char c2 = (unsigned char) p[1]; - - if (c2 >= 0xa1 && c2 < 0xff) - goto incomplete; - } - } - goto invalid; - } - if (STREQ_OPT (encoding, - "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) - || STREQ_OPT (encoding, - "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) - || STREQ_OPT (encoding, - "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if (c >= 0xa1 && c < 0xff) - goto incomplete; - } - goto invalid; - } - if (STREQ_OPT (encoding, - "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0xa1 && c < 0xff) || c == 0x8e) - goto incomplete; - } - else /* m == 2 || m == 3 */ - { - unsigned char c = (unsigned char) p[0]; - - if (c == 0x8e) - goto incomplete; - } - goto invalid; - } - if (STREQ_OPT (encoding, - "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe)) - goto incomplete; - } - else /* m == 2 || m == 3 */ - { - unsigned char c = (unsigned char) p[0]; - - if (c >= 0x90 && c <= 0xe3) - { - unsigned char c2 = (unsigned char) p[1]; - - if (c2 >= 0x30 && c2 <= 0x39) - { - if (m == 2) - goto incomplete; - else /* m == 3 */ - { - unsigned char c3 = (unsigned char) p[2]; - - if (c3 >= 0x81 && c3 <= 0xfe) - goto incomplete; - } - } - } - } - goto invalid; - } - if (STREQ_OPT (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) - { - if (m == 1) - { - unsigned char c = (unsigned char) p[0]; - - if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea) - || (c >= 0xf0 && c <= 0xf9)) - goto incomplete; - } - goto invalid; - } - - /* An unknown multibyte encoding. */ - goto incomplete; - } - - incomplete: - { - size_t k = nstate; - /* Here 0 <= k < m < 4. */ - pstate[++k] = s[0]; - if (k < m) - { - pstate[++k] = s[1]; - if (k < m) - pstate[++k] = s[2]; - } - if (k != m) - abort (); - } - pstate[0] = m; - return (size_t)(-2); - - invalid: - errno = EILSEQ; - /* The conversion state is undefined, says POSIX. */ - return (size_t)(-1); - } - } -} - -#else -/* Override the system's mbrtowc() function. */ - -# undef mbrtowc - -size_t -rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) -{ -# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG - if (s == NULL) - { - pwc = NULL; - s = ""; - n = 1; - } -# endif - -# if MBRTOWC_RETVAL_BUG - { - static mbstate_t internal_state; - - /* Override mbrtowc's internal state. We cannot call mbsinit() on the - hidden internal state, but we can call it on our variable. */ - if (ps == NULL) - ps = &internal_state; - - if (!mbsinit (ps)) - { - /* Parse the rest of the multibyte character byte for byte. */ - size_t count = 0; - for (; n > 0; s++, n--) - { - wchar_t wc; - size_t ret = mbrtowc (&wc, s, 1, ps); - - if (ret == (size_t)(-1)) - return (size_t)(-1); - count++; - if (ret != (size_t)(-2)) - { - /* The multibyte character has been completed. */ - if (pwc != NULL) - *pwc = wc; - return (wc == 0 ? 0 : count); - } - } - return (size_t)(-2); - } - } -# endif - -# if MBRTOWC_NUL_RETVAL_BUG - { - wchar_t wc; - size_t ret = mbrtowc (&wc, s, n, ps); - - if (ret != (size_t)(-1) && ret != (size_t)(-2)) - { - if (pwc != NULL) - *pwc = wc; - if (wc == 0) - ret = 0; - } - return ret; - } -# else - { -# if MBRTOWC_NULL_ARG1_BUG - wchar_t dummy; - - if (pwc == NULL) - pwc = &dummy; -# endif - - return mbrtowc (pwc, s, n, ps); - } -# endif -} - -#endif diff --git a/grub-core/gnulib/mbsinit.c b/grub-core/gnulib/mbsinit.c deleted file mode 100644 index 26fbb7fa2..000000000 --- a/grub-core/gnulib/mbsinit.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Test for initial conversion state. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2008. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#include "verify.h" - -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ - -/* On native Windows, 'mbstate_t' is defined as 'int'. */ - -int -mbsinit (const mbstate_t *ps) -{ - return ps == NULL || *ps == 0; -} - -#else - -/* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs() - and wcrtomb(), wcsrtombs(). - We assume that - - sizeof (mbstate_t) >= 4, - - only stateless encodings are supported (such as UTF-8 and EUC-JP, but - not ISO-2022 variants), - - for each encoding, the number of bytes for a wide character is <= 4. - (This maximum is attained for UTF-8, GB18030, EUC-TW.) - We define the meaning of mbstate_t as follows: - - In mb -> wc direction, mbstate_t's first byte contains the number of - buffered bytes (in the range 0..3), followed by up to 3 buffered bytes. - - In wc -> mb direction, mbstate_t contains no information. In other - words, it is always in the initial state. */ - -verify (sizeof (mbstate_t) >= 4); - -int -mbsinit (const mbstate_t *ps) -{ - const char *pstate = (const char *)ps; - - return pstate == NULL || pstate[0] == 0; -} - -#endif diff --git a/grub-core/gnulib/mbsrtowcs-impl.h b/grub-core/gnulib/mbsrtowcs-impl.h deleted file mode 100644 index b50e9739b..000000000 --- a/grub-core/gnulib/mbsrtowcs-impl.h +++ /dev/null @@ -1,122 +0,0 @@ -/* Convert string to wide string. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2008. - - 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 . */ - -size_t -mbsrtowcs (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) -{ - if (ps == NULL) - ps = &_gl_mbsrtowcs_state; - { - const char *src = *srcp; - - if (dest != NULL) - { - wchar_t *destptr = dest; - - for (; len > 0; destptr++, len--) - { - size_t src_avail; - size_t ret; - - /* An optimized variant of - src_avail = strnlen1 (src, MB_LEN_MAX); */ - if (src[0] == '\0') - src_avail = 1; - else if (src[1] == '\0') - src_avail = 2; - else if (src[2] == '\0') - src_avail = 3; - else if (MB_LEN_MAX <= 4 || src[3] == '\0') - src_avail = 4; - else - src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); - - /* Parse the next multibyte character. */ - ret = mbrtowc (destptr, src, src_avail, ps); - - if (ret == (size_t)(-2)) - /* Encountered a multibyte character that extends past a '\0' byte - or that is longer than MB_LEN_MAX bytes. Cannot happen. */ - abort (); - - if (ret == (size_t)(-1)) - goto bad_input; - if (ret == 0) - { - src = NULL; - /* Here mbsinit (ps). */ - break; - } - src += ret; - } - - *srcp = src; - return destptr - dest; - } - else - { - /* Ignore dest and len, don't store *srcp at the end, and - don't clobber *ps. */ - mbstate_t state = *ps; - size_t totalcount = 0; - - for (;; totalcount++) - { - size_t src_avail; - size_t ret; - - /* An optimized variant of - src_avail = strnlen1 (src, MB_LEN_MAX); */ - if (src[0] == '\0') - src_avail = 1; - else if (src[1] == '\0') - src_avail = 2; - else if (src[2] == '\0') - src_avail = 3; - else if (MB_LEN_MAX <= 4 || src[3] == '\0') - src_avail = 4; - else - src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); - - /* Parse the next multibyte character. */ - ret = mbrtowc (NULL, src, src_avail, &state); - - if (ret == (size_t)(-2)) - /* Encountered a multibyte character that extends past a '\0' byte - or that is longer than MB_LEN_MAX bytes. Cannot happen. */ - abort (); - - if (ret == (size_t)(-1)) - goto bad_input2; - if (ret == 0) - { - /* Here mbsinit (&state). */ - break; - } - src += ret; - } - - return totalcount; - } - - bad_input: - *srcp = src; - bad_input2: - errno = EILSEQ; - return (size_t)(-1); - } -} diff --git a/grub-core/gnulib/mbsrtowcs-state.c b/grub-core/gnulib/mbsrtowcs-state.c deleted file mode 100644 index 5a0b8882b..000000000 --- a/grub-core/gnulib/mbsrtowcs-state.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Convert string to wide string. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2008. - - 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 - -/* Internal state used by the functions mbsrtowcs() and mbsnrtowcs(). */ -mbstate_t _gl_mbsrtowcs_state -/* The state must initially be in the "initial state"; so, zero-initialize it. - On most systems, putting it into BSS is sufficient. Not so on Mac OS X 10.3, - see . - When it needs an initializer, use 0 or {0} as initializer? 0 only works - when mbstate_t is a scalar type (such as when gnulib defines it, or on - AIX, IRIX, mingw). {0} works as an initializer in all cases: for a struct - or union type, but also for a scalar type (ISO C 99, 6.7.8.(11)). */ -#if defined __ELF__ - /* On ELF systems, variables in BSS behave well. */ -#else - /* Use braces, to be on the safe side. */ - = { 0 } -#endif - ; diff --git a/grub-core/gnulib/mbsrtowcs.c b/grub-core/gnulib/mbsrtowcs.c deleted file mode 100644 index 116ff493b..000000000 --- a/grub-core/gnulib/mbsrtowcs.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Convert string to wide string. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2008. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#include -#include -#include - -#include "strnlen1.h" - - -extern mbstate_t _gl_mbsrtowcs_state; - -#include "mbsrtowcs-impl.h" diff --git a/grub-core/gnulib/mbswidth.c b/grub-core/gnulib/mbswidth.c deleted file mode 100644 index baa4f2757..000000000 --- a/grub-core/gnulib/mbswidth.c +++ /dev/null @@ -1,199 +0,0 @@ -/* Determine the number of screen columns needed for a string. - Copyright (C) 2000-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Bruno Haible . */ - -#include - -/* Specification. */ -#include "mbswidth.h" - -/* Get MB_CUR_MAX. */ -#include - -#include - -/* Get isprint(). */ -#include - -/* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth(). */ -#include - -/* Get iswcntrl(). */ -#include - -/* Get INT_MAX. */ -#include - -/* Returns the number of columns needed to represent the multibyte - character string pointed to by STRING. If a non-printable character - occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. - With flags = MBSW_REJECT_INVALID | MBSW_REJECT_UNPRINTABLE, this is - the multibyte analogue of the wcswidth function. */ -int -mbswidth (const char *string, int flags) -{ - return mbsnwidth (string, strlen (string), flags); -} - -/* Returns the number of columns needed to represent the multibyte - character string pointed to by STRING of length NBYTES. If a - non-printable character occurs, and MBSW_REJECT_UNPRINTABLE is - specified, -1 is returned. */ -int -mbsnwidth (const char *string, size_t nbytes, int flags) -{ - const char *p = string; - const char *plimit = p + nbytes; - int width; - - width = 0; - if (MB_CUR_MAX > 1) - { - while (p < plimit) - switch (*p) - { - case ' ': case '!': case '"': case '#': case '%': - case '&': case '\'': case '(': case ')': case '*': - case '+': case ',': case '-': case '.': case '/': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case ':': case ';': case '<': case '=': case '>': - case '?': - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case '[': case '\\': case ']': case '^': case '_': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': case '{': case '|': case '}': case '~': - /* These characters are printable ASCII characters. */ - p++; - width++; - break; - case '\0': - if (flags & MBSW_STOP_AT_NUL) - return width; - default: - /* If we have a multibyte sequence, scan it up to its end. */ - { - mbstate_t mbstate; - memset (&mbstate, 0, sizeof mbstate); - do - { - wchar_t wc; - size_t bytes; - int w; - - bytes = mbrtowc (&wc, p, plimit - p, &mbstate); - - if (bytes == (size_t) -1) - /* An invalid multibyte sequence was encountered. */ - { - if (!(flags & MBSW_REJECT_INVALID)) - { - p++; - width++; - break; - } - else - return -1; - } - - if (bytes == (size_t) -2) - /* An incomplete multibyte character at the end. */ - { - if (!(flags & MBSW_REJECT_INVALID)) - { - p = plimit; - width++; - break; - } - else - return -1; - } - - if (bytes == 0) - /* A null wide character was encountered. */ - bytes = 1; - - w = wcwidth (wc); - if (w >= 0) - /* A printable multibyte character. */ - { - if (w > INT_MAX - width) - goto overflow; - width += w; - } - else - /* An unprintable multibyte character. */ - if (!(flags & MBSW_REJECT_UNPRINTABLE)) - { - if (!iswcntrl (wc)) - { - if (width == INT_MAX) - goto overflow; - width++; - } - } - else - return -1; - - p += bytes; - } - while (! mbsinit (&mbstate)); - } - break; - } - return width; - } - - while (p < plimit) - { - unsigned char c = (unsigned char) *p++; - - if (c == 0 && (flags & MBSW_STOP_AT_NUL)) - return width; - - if (isprint (c)) - { - if (width == INT_MAX) - goto overflow; - width++; - } - else if (!(flags & MBSW_REJECT_UNPRINTABLE)) - { - if (!iscntrl (c)) - { - if (width == INT_MAX) - goto overflow; - width++; - } - } - else - return -1; - } - return width; - - overflow: - return INT_MAX; -} diff --git a/grub-core/gnulib/mbswidth.h b/grub-core/gnulib/mbswidth.h deleted file mode 100644 index d7207c58f..000000000 --- a/grub-core/gnulib/mbswidth.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Determine the number of screen columns needed for a string. - Copyright (C) 2000-2004, 2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Avoid a clash of our mbswidth() with a function of the same name defined - in UnixWare 7.1.1 . We need this #include before the #define - below. - However, we don't want to #include on all platforms because - - Tru64 with Desktop Toolkit C has a bug: must be included before - . - - BSD/OS 4.1 has a bug: and must be included before - . */ -#if HAVE_DECL_MBSWIDTH_IN_WCHAR_H -# include -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Optional flags to influence mbswidth/mbsnwidth behavior. */ - -/* If this bit is set, return -1 upon finding an invalid or incomplete - character. Otherwise, assume invalid characters have width 1. */ -#define MBSW_REJECT_INVALID 1 - -/* If this bit is set, return -1 upon finding a non-printable character. - Otherwise, assume unprintable characters have width 0 if they are - control characters and 1 otherwise. */ -#define MBSW_REJECT_UNPRINTABLE 2 - -/* If this bit is set \0 is treated as the end of string. - Otherwise it's treated as a normal one column width character. */ -#define MBSW_STOP_AT_NUL 4 - -/* Returns the number of screen columns needed for STRING. */ -#define mbswidth gnu_mbswidth /* avoid clash with UnixWare 7.1.1 function */ -extern int mbswidth (const char *string, int flags); - -/* Returns the number of screen columns needed for the NBYTES bytes - starting at BUF. */ -extern int mbsnwidth (const char *buf, size_t nbytes, int flags); - - -#ifdef __cplusplus -} -#endif diff --git a/grub-core/gnulib/mbtowc-impl.h b/grub-core/gnulib/mbtowc-impl.h deleted file mode 100644 index 767ab397c..000000000 --- a/grub-core/gnulib/mbtowc-impl.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Convert multibyte character to wide character. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2011. - - 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 . */ - -/* We don't need a static internal state, because the encoding is not state - dependent, and when mbrtowc returns (size_t)(-2). we throw the result - away. */ - -int -mbtowc (wchar_t *pwc, const char *s, size_t n) -{ - if (s == NULL) - return 0; - else - { - mbstate_t state; - wchar_t wc; - size_t result; - - memset (&state, 0, sizeof (mbstate_t)); - result = mbrtowc (&wc, s, n, &state); - if (result == (size_t)-1 || result == (size_t)-2) - { - errno = EILSEQ; - return -1; - } - if (pwc != NULL) - *pwc = wc; - return (wc == 0 ? 0 : result); - } -} diff --git a/grub-core/gnulib/mbtowc.c b/grub-core/gnulib/mbtowc.c deleted file mode 100644 index 632f2e1db..000000000 --- a/grub-core/gnulib/mbtowc.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Convert multibyte character to wide character. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2011. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include - -#include -#include -#include - -#include "mbtowc-impl.h" diff --git a/grub-core/gnulib/memchr.c b/grub-core/gnulib/memchr.c deleted file mode 100644 index 3db38a94c..000000000 --- a/grub-core/gnulib/memchr.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2013 - Free Software Foundation, Inc. - - Based on strlen implementation by Torbjorn Granlund (tege@sics.se), - with help from Dan Sahlin (dan@sics.se) and - commentary by Jim Blandy (jimb@ai.mit.edu); - adaptation to memchr suggested by Dick Karpinski (dick@cca.ucsf.edu), - and implemented by Roland McGrath (roland@ai.mit.edu). - -NOTE: The canonical source of this file is maintained with the GNU C Library. -Bugs can be reported to bug-glibc@prep.ai.mit.edu. - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . */ - -#ifndef _LIBC -# include -#endif - -#include - -#include - -#if defined _LIBC -# include -#else -# define reg_char char -#endif - -#include - -#if HAVE_BP_SYM_H || defined _LIBC -# include -#else -# define BP_SYM(sym) sym -#endif - -#undef __memchr -#ifdef _LIBC -# undef memchr -#endif - -#ifndef weak_alias -# define __memchr memchr -#endif - -/* Search no more than N bytes of S for C. */ -void * -__memchr (void const *s, int c_in, size_t n) -{ - /* On 32-bit hardware, choosing longword to be a 32-bit unsigned - long instead of a 64-bit uintmax_t tends to give better - performance. On 64-bit hardware, unsigned long is generally 64 - bits already. Change this typedef to experiment with - performance. */ - typedef unsigned long int longword; - - const unsigned char *char_ptr; - const longword *longword_ptr; - longword repeated_one; - longword repeated_c; - unsigned reg_char c; - - c = (unsigned char) c_in; - - /* Handle the first few bytes by reading one byte at a time. - Do this until CHAR_PTR is aligned on a longword boundary. */ - for (char_ptr = (const unsigned char *) s; - n > 0 && (size_t) char_ptr % sizeof (longword) != 0; - --n, ++char_ptr) - if (*char_ptr == c) - return (void *) char_ptr; - - longword_ptr = (const longword *) char_ptr; - - /* All these elucidatory comments refer to 4-byte longwords, - but the theory applies equally well to any size longwords. */ - - /* Compute auxiliary longword values: - repeated_one is a value which has a 1 in every byte. - repeated_c has c in every byte. */ - repeated_one = 0x01010101; - repeated_c = c | (c << 8); - repeated_c |= repeated_c << 16; - if (0xffffffffU < (longword) -1) - { - repeated_one |= repeated_one << 31 << 1; - repeated_c |= repeated_c << 31 << 1; - if (8 < sizeof (longword)) - { - size_t i; - - for (i = 64; i < sizeof (longword) * 8; i *= 2) - { - repeated_one |= repeated_one << i; - repeated_c |= repeated_c << i; - } - } - } - - /* Instead of the traditional loop which tests each byte, we will test a - longword at a time. The tricky part is testing if *any of the four* - bytes in the longword in question are equal to c. We first use an xor - with repeated_c. This reduces the task to testing whether *any of the - four* bytes in longword1 is zero. - - We compute tmp = - ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). - That is, we perform the following operations: - 1. Subtract repeated_one. - 2. & ~longword1. - 3. & a mask consisting of 0x80 in every byte. - Consider what happens in each byte: - - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, - and step 3 transforms it into 0x80. A carry can also be propagated - to more significant bytes. - - If a byte of longword1 is nonzero, let its lowest 1 bit be at - position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, - the byte ends in a single bit of value 0 and k bits of value 1. - After step 2, the result is just k bits of value 1: 2^k - 1. After - step 3, the result is 0. And no carry is produced. - So, if longword1 has only non-zero bytes, tmp is zero. - Whereas if longword1 has a zero byte, call j the position of the least - significant zero byte. Then the result has a zero at positions 0, ..., - j-1 and a 0x80 at position j. We cannot predict the result at the more - significant bytes (positions j+1..3), but it does not matter since we - already have a non-zero bit at position 8*j+7. - - So, the test whether any byte in longword1 is zero is equivalent to - testing whether tmp is nonzero. */ - - while (n >= sizeof (longword)) - { - longword longword1 = *longword_ptr ^ repeated_c; - - if ((((longword1 - repeated_one) & ~longword1) - & (repeated_one << 7)) != 0) - break; - longword_ptr++; - n -= sizeof (longword); - } - - char_ptr = (const unsigned char *) longword_ptr; - - /* At this point, we know that either n < sizeof (longword), or one of the - sizeof (longword) bytes starting at char_ptr is == c. On little-endian - machines, we could determine the first such byte without any further - memory accesses, just by looking at the tmp result from the last loop - iteration. But this does not work on big-endian machines. Choose code - that works in both cases. */ - - for (; n > 0; --n, ++char_ptr) - { - if (*char_ptr == c) - return (void *) char_ptr; - } - - return NULL; -} -#ifdef weak_alias -weak_alias (__memchr, BP_SYM (memchr)) -#endif diff --git a/grub-core/gnulib/memchr.valgrind b/grub-core/gnulib/memchr.valgrind deleted file mode 100644 index 60f247e10..000000000 --- a/grub-core/gnulib/memchr.valgrind +++ /dev/null @@ -1,14 +0,0 @@ -# Suppress a valgrind message about use of uninitialized memory in memchr(). -# POSIX states that when the character is found, memchr must not read extra -# bytes in an overestimated length (for example, where memchr is used to -# implement strnlen). However, we use a safe word read to provide a speedup. -{ - memchr-value4 - Memcheck:Value4 - fun:rpl_memchr -} -{ - memchr-value8 - Memcheck:Value8 - fun:rpl_memchr -} diff --git a/grub-core/gnulib/mempcpy.c b/grub-core/gnulib/mempcpy.c deleted file mode 100644 index 5582368ed..000000000 --- a/grub-core/gnulib/mempcpy.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copy memory area and return pointer after last written byte. - Copyright (C) 2003, 2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#include - -/* Specification. */ -#include - -/* Copy N bytes of SRC to DEST, return pointer to bytes after the - last written byte. */ -void * -mempcpy (void *dest, const void *src, size_t n) -{ - return (char *) memcpy (dest, src, n) + n; -} diff --git a/grub-core/gnulib/msvc-inval.c b/grub-core/gnulib/msvc-inval.c deleted file mode 100644 index 7e57731eb..000000000 --- a/grub-core/gnulib/msvc-inval.c +++ /dev/null @@ -1,129 +0,0 @@ -/* Invalid parameter handler for MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#include - -/* Specification. */ -#include "msvc-inval.h" - -#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \ - && !(MSVC_INVALID_PARAMETER_HANDLING == SANE_LIBRARY_HANDLING) - -/* Get _invalid_parameter_handler type and _set_invalid_parameter_handler - declaration. */ -# include - -# if MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING - -static void __cdecl -gl_msvc_invalid_parameter_handler (const wchar_t *expression, - const wchar_t *function, - const wchar_t *file, - unsigned int line, - uintptr_t dummy) -{ -} - -# else - -/* Get declarations of the native Windows API functions. */ -# define WIN32_LEAN_AND_MEAN -# include - -# if defined _MSC_VER - -static void cdecl -gl_msvc_invalid_parameter_handler (const wchar_t *expression, - const wchar_t *function, - const wchar_t *file, - unsigned int line, - uintptr_t dummy) -{ - RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); -} - -# else - -/* An index to thread-local storage. */ -static DWORD tls_index; -static int tls_initialized /* = 0 */; - -/* Used as a fallback only. */ -static struct gl_msvc_inval_per_thread not_per_thread; - -struct gl_msvc_inval_per_thread * -gl_msvc_inval_current (void) -{ - if (!tls_initialized) - { - tls_index = TlsAlloc (); - tls_initialized = 1; - } - if (tls_index == TLS_OUT_OF_INDEXES) - /* TlsAlloc had failed. */ - return ¬_per_thread; - else - { - struct gl_msvc_inval_per_thread *pointer = - (struct gl_msvc_inval_per_thread *) TlsGetValue (tls_index); - if (pointer == NULL) - { - /* First call. Allocate a new 'struct gl_msvc_inval_per_thread'. */ - pointer = - (struct gl_msvc_inval_per_thread *) - malloc (sizeof (struct gl_msvc_inval_per_thread)); - if (pointer == NULL) - /* Could not allocate memory. Use the global storage. */ - pointer = ¬_per_thread; - TlsSetValue (tls_index, pointer); - } - return pointer; - } -} - -static void cdecl -gl_msvc_invalid_parameter_handler (const wchar_t *expression, - const wchar_t *function, - const wchar_t *file, - unsigned int line, - uintptr_t dummy) -{ - struct gl_msvc_inval_per_thread *current = gl_msvc_inval_current (); - if (current->restart_valid) - longjmp (current->restart, 1); - else - /* An invalid parameter notification from outside the gnulib code. - Give the caller a chance to intervene. */ - RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); -} - -# endif - -# endif - -static int gl_msvc_inval_initialized /* = 0 */; - -void -gl_msvc_inval_ensure_handler (void) -{ - if (gl_msvc_inval_initialized == 0) - { - _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler); - gl_msvc_inval_initialized = 1; - } -} - -#endif diff --git a/grub-core/gnulib/msvc-inval.h b/grub-core/gnulib/msvc-inval.h deleted file mode 100644 index dcb0353dc..000000000 --- a/grub-core/gnulib/msvc-inval.h +++ /dev/null @@ -1,222 +0,0 @@ -/* Invalid parameter handler for MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifndef _MSVC_INVAL_H -#define _MSVC_INVAL_H - -/* With MSVC runtime libraries with the "invalid parameter handler" concept, - functions like fprintf(), dup2(), or close() crash when the caller passes - an invalid argument. But POSIX wants error codes (such as EINVAL or EBADF) - instead. - This file defines macros that turn such an invalid parameter notification - into a non-local exit. An error code can then be produced at the target - of this exit. You can thus write code like - - TRY_MSVC_INVAL - { - - } - CATCH_MSVC_INVAL - { - - } - DONE_MSVC_INVAL; - - This entire block expands to a single statement. - - The handling of invalid parameters can be done in three ways: - - * The default way, which is reasonable for programs (not libraries): - AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [DEFAULT_HANDLING]) - - * The way for libraries that make "hairy" calls (like close(-1), or - fclose(fp) where fileno(fp) is closed, or simply getdtablesize()): - AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [HAIRY_LIBRARY_HANDLING]) - - * The way for libraries that make no "hairy" calls: - AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [SANE_LIBRARY_HANDLING]) - */ - -#define DEFAULT_HANDLING 0 -#define HAIRY_LIBRARY_HANDLING 1 -#define SANE_LIBRARY_HANDLING 2 - -#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \ - && !(MSVC_INVALID_PARAMETER_HANDLING == SANE_LIBRARY_HANDLING) -/* A native Windows platform with the "invalid parameter handler" concept, - and either DEFAULT_HANDLING or HAIRY_LIBRARY_HANDLING. */ - -# if MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING -/* Default handling. */ - -# ifdef __cplusplus -extern "C" { -# endif - -/* Ensure that the invalid parameter handler in installed that just returns. - Because we assume no other part of the program installs a different - invalid parameter handler, this solution is multithread-safe. */ -extern void gl_msvc_inval_ensure_handler (void); - -# ifdef __cplusplus -} -# endif - -# define TRY_MSVC_INVAL \ - do \ - { \ - gl_msvc_inval_ensure_handler (); \ - if (1) -# define CATCH_MSVC_INVAL \ - else -# define DONE_MSVC_INVAL \ - } \ - while (0) - -# else -/* Handling for hairy libraries. */ - -# include - -/* Gnulib can define its own status codes, as described in the page - "Raising Software Exceptions" on microsoft.com - . - Our status codes are composed of - - 0xE0000000, mandatory for all user-defined status codes, - - 0x474E550, a API identifier ("GNU"), - - 0, 1, 2, ..., used to distinguish different status codes from the - same API. */ -# define STATUS_GNULIB_INVALID_PARAMETER (0xE0000000 + 0x474E550 + 0) - -# if defined _MSC_VER -/* A compiler that supports __try/__except, as described in the page - "try-except statement" on microsoft.com - . - With __try/__except, we can use the multithread-safe exception handling. */ - -# ifdef __cplusplus -extern "C" { -# endif - -/* Ensure that the invalid parameter handler in installed that raises a - software exception with code STATUS_GNULIB_INVALID_PARAMETER. - Because we assume no other part of the program installs a different - invalid parameter handler, this solution is multithread-safe. */ -extern void gl_msvc_inval_ensure_handler (void); - -# ifdef __cplusplus -} -# endif - -# define TRY_MSVC_INVAL \ - do \ - { \ - gl_msvc_inval_ensure_handler (); \ - __try -# define CATCH_MSVC_INVAL \ - __except (GetExceptionCode () == STATUS_GNULIB_INVALID_PARAMETER \ - ? EXCEPTION_EXECUTE_HANDLER \ - : EXCEPTION_CONTINUE_SEARCH) -# define DONE_MSVC_INVAL \ - } \ - while (0) - -# else -/* Any compiler. - We can only use setjmp/longjmp. */ - -# include - -# ifdef __cplusplus -extern "C" { -# endif - -struct gl_msvc_inval_per_thread -{ - /* The restart that will resume execution at the code between - CATCH_MSVC_INVAL and DONE_MSVC_INVAL. It is enabled only between - TRY_MSVC_INVAL and CATCH_MSVC_INVAL. */ - jmp_buf restart; - - /* Tells whether the contents of restart is valid. */ - int restart_valid; -}; - -/* Ensure that the invalid parameter handler in installed that passes - control to the gl_msvc_inval_restart if it is valid, or raises a - software exception with code STATUS_GNULIB_INVALID_PARAMETER otherwise. - Because we assume no other part of the program installs a different - invalid parameter handler, this solution is multithread-safe. */ -extern void gl_msvc_inval_ensure_handler (void); - -/* Return a pointer to the per-thread data for the current thread. */ -extern struct gl_msvc_inval_per_thread *gl_msvc_inval_current (void); - -# ifdef __cplusplus -} -# endif - -# define TRY_MSVC_INVAL \ - do \ - { \ - struct gl_msvc_inval_per_thread *msvc_inval_current; \ - gl_msvc_inval_ensure_handler (); \ - msvc_inval_current = gl_msvc_inval_current (); \ - /* First, initialize gl_msvc_inval_restart. */ \ - if (setjmp (msvc_inval_current->restart) == 0) \ - { \ - /* Then, mark it as valid. */ \ - msvc_inval_current->restart_valid = 1; -# define CATCH_MSVC_INVAL \ - /* Execution completed. \ - Mark gl_msvc_inval_restart as invalid. */ \ - msvc_inval_current->restart_valid = 0; \ - } \ - else \ - { \ - /* Execution triggered an invalid parameter notification. \ - Mark gl_msvc_inval_restart as invalid. */ \ - msvc_inval_current->restart_valid = 0; -# define DONE_MSVC_INVAL \ - } \ - } \ - while (0) - -# endif - -# endif - -#else -/* A platform that does not need to the invalid parameter handler, - or when SANE_LIBRARY_HANDLING is desired. */ - -/* The braces here avoid GCC warnings like - "warning: suggest explicit braces to avoid ambiguous 'else'". */ -# define TRY_MSVC_INVAL \ - do \ - { \ - if (1) -# define CATCH_MSVC_INVAL \ - else -# define DONE_MSVC_INVAL \ - } \ - while (0) - -#endif - -#endif /* _MSVC_INVAL_H */ diff --git a/grub-core/gnulib/msvc-nothrow.c b/grub-core/gnulib/msvc-nothrow.c deleted file mode 100644 index 8d65472a8..000000000 --- a/grub-core/gnulib/msvc-nothrow.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Wrappers that don't throw invalid parameter notifications - with MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#include - -/* Specification. */ -#include "msvc-nothrow.h" - -/* Get declarations of the native Windows API functions. */ -#define WIN32_LEAN_AND_MEAN -#include - -#include "msvc-inval.h" - -#undef _get_osfhandle - -#if HAVE_MSVC_INVALID_PARAMETER_HANDLER -intptr_t -_gl_nothrow_get_osfhandle (int fd) -{ - intptr_t result; - - TRY_MSVC_INVAL - { - result = _get_osfhandle (fd); - } - CATCH_MSVC_INVAL - { - result = (intptr_t) INVALID_HANDLE_VALUE; - } - DONE_MSVC_INVAL; - - return result; -} -#endif diff --git a/grub-core/gnulib/msvc-nothrow.h b/grub-core/gnulib/msvc-nothrow.h deleted file mode 100644 index 5f521813d..000000000 --- a/grub-core/gnulib/msvc-nothrow.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Wrappers that don't throw invalid parameter notifications - with MSVC runtime libraries. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifndef _MSVC_NOTHROW_H -#define _MSVC_NOTHROW_H - -/* With MSVC runtime libraries with the "invalid parameter handler" concept, - functions like fprintf(), dup2(), or close() crash when the caller passes - an invalid argument. But POSIX wants error codes (such as EINVAL or EBADF) - instead. - This file defines wrappers that turn such an invalid parameter notification - into an error code. */ - -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - -/* Get original declaration of _get_osfhandle. */ -# include - -# if HAVE_MSVC_INVALID_PARAMETER_HANDLER - -/* Override _get_osfhandle. */ -extern intptr_t _gl_nothrow_get_osfhandle (int fd); -# define _get_osfhandle _gl_nothrow_get_osfhandle - -# endif - -#endif - -#endif /* _MSVC_NOTHROW_H */ diff --git a/grub-core/gnulib/nl_langinfo.c b/grub-core/gnulib/nl_langinfo.c deleted file mode 100644 index 771c9533a..000000000 --- a/grub-core/gnulib/nl_langinfo.c +++ /dev/null @@ -1,271 +0,0 @@ -/* nl_langinfo() replacement: query locale dependent information. - - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#if REPLACE_NL_LANGINFO - -/* Override nl_langinfo with support for added nl_item values. */ - -# include -# include - -# undef nl_langinfo - -char * -rpl_nl_langinfo (nl_item item) -{ - switch (item) - { -# if GNULIB_defined_CODESET - case CODESET: - { - const char *locale; - static char buf[2 + 10 + 1]; - - locale = setlocale (LC_CTYPE, NULL); - if (locale != NULL && locale[0] != '\0') - { - /* If the locale name contains an encoding after the dot, return - it. */ - const char *dot = strchr (locale, '.'); - - if (dot != NULL) - { - const char *modifier; - - dot++; - /* Look for the possible @... trailer and remove it, if any. */ - modifier = strchr (dot, '@'); - if (modifier == NULL) - return dot; - if (modifier - dot < sizeof (buf)) - { - memcpy (buf, dot, modifier - dot); - buf [modifier - dot] = '\0'; - return buf; - } - } - } - return ""; - } -# endif -# if GNULIB_defined_T_FMT_AMPM - case T_FMT_AMPM: - return "%I:%M:%S %p"; -# endif -# if GNULIB_defined_ERA - case ERA: - /* The format is not standardized. In glibc it is a sequence of strings - of the form "direction:offset:start_date:end_date:era_name:era_format" - with an empty string at the end. */ - return ""; - case ERA_D_FMT: - /* The %Ex conversion in strftime behaves like %x if the locale does not - have an alternative time format. */ - item = D_FMT; - break; - case ERA_D_T_FMT: - /* The %Ec conversion in strftime behaves like %c if the locale does not - have an alternative time format. */ - item = D_T_FMT; - break; - case ERA_T_FMT: - /* The %EX conversion in strftime behaves like %X if the locale does not - have an alternative time format. */ - item = T_FMT; - break; - case ALT_DIGITS: - /* The format is not standardized. In glibc it is a sequence of 10 - strings, appended in memory. */ - return "\0\0\0\0\0\0\0\0\0\0"; -# endif -# if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS - case YESEXPR: - return "^[yY]"; - case NOEXPR: - return "^[nN]"; -# endif - default: - break; - } - return nl_langinfo (item); -} - -#else - -/* Provide nl_langinfo from scratch. */ - -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - -/* Native Windows platforms. */ - -# define WIN32_LEAN_AND_MEAN /* avoid including junk */ -# include - -# include - -# else - -/* An old Unix platform without locales, such as Linux libc5 or BeOS. */ - -# endif - -# include - -char * -nl_langinfo (nl_item item) -{ - switch (item) - { - /* nl_langinfo items of the LC_CTYPE category */ - case CODESET: -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - { - static char buf[2 + 10 + 1]; - - /* The Windows API has a function returning the locale's codepage as - a number. */ - sprintf (buf, "CP%u", GetACP ()); - return buf; - } -# elif defined __BEOS__ - return "UTF-8"; -# else - return "ISO-8859-1"; -# endif - /* nl_langinfo items of the LC_NUMERIC category */ - case RADIXCHAR: - return localeconv () ->decimal_point; - case THOUSEP: - return localeconv () ->thousands_sep; - /* nl_langinfo items of the LC_TIME category. - TODO: Really use the locale. */ - case D_T_FMT: - case ERA_D_T_FMT: - return "%a %b %e %H:%M:%S %Y"; - case D_FMT: - case ERA_D_FMT: - return "%m/%d/%y"; - case T_FMT: - case ERA_T_FMT: - return "%H:%M:%S"; - case T_FMT_AMPM: - return "%I:%M:%S %p"; - case AM_STR: - return "AM"; - case PM_STR: - return "PM"; - case DAY_1: - return "Sunday"; - case DAY_2: - return "Monday"; - case DAY_3: - return "Tuesday"; - case DAY_4: - return "Wednesday"; - case DAY_5: - return "Thursday"; - case DAY_6: - return "Friday"; - case DAY_7: - return "Saturday"; - case ABDAY_1: - return "Sun"; - case ABDAY_2: - return "Mon"; - case ABDAY_3: - return "Tue"; - case ABDAY_4: - return "Wed"; - case ABDAY_5: - return "Thu"; - case ABDAY_6: - return "Fri"; - case ABDAY_7: - return "Sat"; - case MON_1: - return "January"; - case MON_2: - return "February"; - case MON_3: - return "March"; - case MON_4: - return "April"; - case MON_5: - return "May"; - case MON_6: - return "June"; - case MON_7: - return "July"; - case MON_8: - return "August"; - case MON_9: - return "September"; - case MON_10: - return "October"; - case MON_11: - return "November"; - case MON_12: - return "December"; - case ABMON_1: - return "Jan"; - case ABMON_2: - return "Feb"; - case ABMON_3: - return "Mar"; - case ABMON_4: - return "Apr"; - case ABMON_5: - return "May"; - case ABMON_6: - return "Jun"; - case ABMON_7: - return "Jul"; - case ABMON_8: - return "Aug"; - case ABMON_9: - return "Sep"; - case ABMON_10: - return "Oct"; - case ABMON_11: - return "Nov"; - case ABMON_12: - return "Dec"; - case ERA: - return ""; - case ALT_DIGITS: - return "\0\0\0\0\0\0\0\0\0\0"; - /* nl_langinfo items of the LC_MONETARY category - TODO: Really use the locale. */ - case CRNCYSTR: - return "-"; - /* nl_langinfo items of the LC_MESSAGES category - TODO: Really use the locale. */ - case YESEXPR: - return "^[yY]"; - case NOEXPR: - return "^[nN]"; - default: - return ""; - } -} - -#endif diff --git a/grub-core/gnulib/printf-args.c b/grub-core/gnulib/printf-args.c deleted file mode 100644 index c27e6bc6b..000000000 --- a/grub-core/gnulib/printf-args.c +++ /dev/null @@ -1,187 +0,0 @@ -/* Decomposed printf argument list. - Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2013 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 . */ - -/* This file can be parametrized with the following macros: - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. - PRINTF_FETCHARGS Name of the function to be defined. - STATIC Set to 'static' to declare the function static. */ - -#ifndef PRINTF_FETCHARGS -# include -#endif - -/* Specification. */ -#ifndef PRINTF_FETCHARGS -# include "printf-args.h" -#endif - -#ifdef STATIC -STATIC -#endif -int -PRINTF_FETCHARGS (va_list args, arguments *a) -{ - size_t i; - argument *ap; - - for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++) - switch (ap->type) - { - case TYPE_SCHAR: - ap->a.a_schar = va_arg (args, /*signed char*/ int); - break; - case TYPE_UCHAR: - ap->a.a_uchar = va_arg (args, /*unsigned char*/ int); - break; - case TYPE_SHORT: - ap->a.a_short = va_arg (args, /*short*/ int); - break; - case TYPE_USHORT: - ap->a.a_ushort = va_arg (args, /*unsigned short*/ int); - break; - case TYPE_INT: - ap->a.a_int = va_arg (args, int); - break; - case TYPE_UINT: - ap->a.a_uint = va_arg (args, unsigned int); - break; - case TYPE_LONGINT: - ap->a.a_longint = va_arg (args, long int); - break; - case TYPE_ULONGINT: - ap->a.a_ulongint = va_arg (args, unsigned long int); - break; -#if HAVE_LONG_LONG_INT - case TYPE_LONGLONGINT: - ap->a.a_longlongint = va_arg (args, long long int); - break; - case TYPE_ULONGLONGINT: - ap->a.a_ulonglongint = va_arg (args, unsigned long long int); - break; -#endif - case TYPE_DOUBLE: - ap->a.a_double = va_arg (args, double); - break; - case TYPE_LONGDOUBLE: - ap->a.a_longdouble = va_arg (args, long double); - break; - case TYPE_CHAR: - ap->a.a_char = va_arg (args, int); - break; -#if HAVE_WINT_T - case TYPE_WIDE_CHAR: - /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by - default argument promotions", this is not the case in mingw32, - where wint_t is 'unsigned short'. */ - ap->a.a_wide_char = - (sizeof (wint_t) < sizeof (int) - ? (wint_t) va_arg (args, int) - : va_arg (args, wint_t)); - break; -#endif - case TYPE_STRING: - ap->a.a_string = va_arg (args, const char *); - /* A null pointer is an invalid argument for "%s", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_string == NULL) - ap->a.a_string = "(NULL)"; - break; -#if HAVE_WCHAR_T - case TYPE_WIDE_STRING: - ap->a.a_wide_string = va_arg (args, const wchar_t *); - /* A null pointer is an invalid argument for "%ls", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_wide_string == NULL) - { - static const wchar_t wide_null_string[] = - { - (wchar_t)'(', - (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L', - (wchar_t)')', - (wchar_t)0 - }; - ap->a.a_wide_string = wide_null_string; - } - break; -#endif - case TYPE_POINTER: - ap->a.a_pointer = va_arg (args, void *); - break; - case TYPE_COUNT_SCHAR_POINTER: - ap->a.a_count_schar_pointer = va_arg (args, signed char *); - break; - case TYPE_COUNT_SHORT_POINTER: - ap->a.a_count_short_pointer = va_arg (args, short *); - break; - case TYPE_COUNT_INT_POINTER: - ap->a.a_count_int_pointer = va_arg (args, int *); - break; - case TYPE_COUNT_LONGINT_POINTER: - ap->a.a_count_longint_pointer = va_arg (args, long int *); - break; -#if HAVE_LONG_LONG_INT - case TYPE_COUNT_LONGLONGINT_POINTER: - ap->a.a_count_longlongint_pointer = va_arg (args, long long int *); - break; -#endif -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - case TYPE_U8_STRING: - ap->a.a_u8_string = va_arg (args, const uint8_t *); - /* A null pointer is an invalid argument for "%U", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_u8_string == NULL) - { - static const uint8_t u8_null_string[] = - { '(', 'N', 'U', 'L', 'L', ')', 0 }; - ap->a.a_u8_string = u8_null_string; - } - break; - case TYPE_U16_STRING: - ap->a.a_u16_string = va_arg (args, const uint16_t *); - /* A null pointer is an invalid argument for "%lU", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_u16_string == NULL) - { - static const uint16_t u16_null_string[] = - { '(', 'N', 'U', 'L', 'L', ')', 0 }; - ap->a.a_u16_string = u16_null_string; - } - break; - case TYPE_U32_STRING: - ap->a.a_u32_string = va_arg (args, const uint32_t *); - /* A null pointer is an invalid argument for "%llU", but in practice - it occurs quite frequently in printf statements that produce - debug output. Use a fallback in this case. */ - if (ap->a.a_u32_string == NULL) - { - static const uint32_t u32_null_string[] = - { '(', 'N', 'U', 'L', 'L', ')', 0 }; - ap->a.a_u32_string = u32_null_string; - } - break; -#endif - default: - /* Unknown type. */ - return -1; - } - return 0; -} diff --git a/grub-core/gnulib/printf-args.h b/grub-core/gnulib/printf-args.h deleted file mode 100644 index 2a9c2a3f8..000000000 --- a/grub-core/gnulib/printf-args.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Decomposed printf argument list. - Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2013 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifndef _PRINTF_ARGS_H -#define _PRINTF_ARGS_H - -/* This file can be parametrized with the following macros: - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. - PRINTF_FETCHARGS Name of the function to be declared. - STATIC Set to 'static' to declare the function static. */ - -/* Default parameters. */ -#ifndef PRINTF_FETCHARGS -# define PRINTF_FETCHARGS printf_fetchargs -#endif - -/* Get size_t. */ -#include - -/* Get wchar_t. */ -#if HAVE_WCHAR_T -# include -#endif - -/* Get wint_t. */ -#if HAVE_WINT_T -# include -#endif - -/* Get va_list. */ -#include - - -/* Argument types */ -typedef enum -{ - TYPE_NONE, - TYPE_SCHAR, - TYPE_UCHAR, - TYPE_SHORT, - TYPE_USHORT, - TYPE_INT, - TYPE_UINT, - TYPE_LONGINT, - TYPE_ULONGINT, -#if HAVE_LONG_LONG_INT - TYPE_LONGLONGINT, - TYPE_ULONGLONGINT, -#endif - TYPE_DOUBLE, - TYPE_LONGDOUBLE, - TYPE_CHAR, -#if HAVE_WINT_T - TYPE_WIDE_CHAR, -#endif - TYPE_STRING, -#if HAVE_WCHAR_T - TYPE_WIDE_STRING, -#endif - TYPE_POINTER, - TYPE_COUNT_SCHAR_POINTER, - TYPE_COUNT_SHORT_POINTER, - TYPE_COUNT_INT_POINTER, - TYPE_COUNT_LONGINT_POINTER -#if HAVE_LONG_LONG_INT -, TYPE_COUNT_LONGLONGINT_POINTER -#endif -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ -, TYPE_U8_STRING -, TYPE_U16_STRING -, TYPE_U32_STRING -#endif -} arg_type; - -/* Polymorphic argument */ -typedef struct -{ - arg_type type; - union - { - signed char a_schar; - unsigned char a_uchar; - short a_short; - unsigned short a_ushort; - int a_int; - unsigned int a_uint; - long int a_longint; - unsigned long int a_ulongint; -#if HAVE_LONG_LONG_INT - long long int a_longlongint; - unsigned long long int a_ulonglongint; -#endif - float a_float; - double a_double; - long double a_longdouble; - int a_char; -#if HAVE_WINT_T - wint_t a_wide_char; -#endif - const char* a_string; -#if HAVE_WCHAR_T - const wchar_t* a_wide_string; -#endif - void* a_pointer; - signed char * a_count_schar_pointer; - short * a_count_short_pointer; - int * a_count_int_pointer; - long int * a_count_longint_pointer; -#if HAVE_LONG_LONG_INT - long long int * a_count_longlongint_pointer; -#endif -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - const uint8_t * a_u8_string; - const uint16_t * a_u16_string; - const uint32_t * a_u32_string; -#endif - } - a; -} -argument; - -/* Number of directly allocated arguments (no malloc() needed). */ -#define N_DIRECT_ALLOC_ARGUMENTS 7 - -typedef struct -{ - size_t count; - argument *arg; - argument direct_alloc_arg[N_DIRECT_ALLOC_ARGUMENTS]; -} -arguments; - - -/* Fetch the arguments, putting them into a. */ -#ifdef STATIC -STATIC -#else -extern -#endif -int PRINTF_FETCHARGS (va_list args, arguments *a); - -#endif /* _PRINTF_ARGS_H */ diff --git a/grub-core/gnulib/printf-parse.c b/grub-core/gnulib/printf-parse.c deleted file mode 100644 index 23cacc1da..000000000 --- a/grub-core/gnulib/printf-parse.c +++ /dev/null @@ -1,638 +0,0 @@ -/* Formatted output to strings. - Copyright (C) 1999-2000, 2002-2003, 2006-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 . */ - -/* This file can be parametrized with the following macros: - CHAR_T The element type of the format string. - CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters - in the format string are ASCII. - DIRECTIVE Structure denoting a format directive. - Depends on CHAR_T. - DIRECTIVES Structure denoting the set of format directives of a - format string. Depends on CHAR_T. - PRINTF_PARSE Function that parses a format string. - Depends on CHAR_T. - STATIC Set to 'static' to declare the function static. - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */ - -#ifndef PRINTF_PARSE -# include -#endif - -/* Specification. */ -#ifndef PRINTF_PARSE -# include "printf-parse.h" -#endif - -/* Default parameters. */ -#ifndef PRINTF_PARSE -# define PRINTF_PARSE printf_parse -# define CHAR_T char -# define DIRECTIVE char_directive -# define DIRECTIVES char_directives -#endif - -/* Get size_t, NULL. */ -#include - -/* Get intmax_t. */ -#if defined IN_LIBINTL || defined IN_LIBASPRINTF -# if HAVE_STDINT_H_WITH_UINTMAX -# include -# endif -# if HAVE_INTTYPES_H_WITH_UINTMAX -# include -# endif -#else -# include -#endif - -/* malloc(), realloc(), free(). */ -#include - -/* memcpy(). */ -#include - -/* errno. */ -#include - -/* Checked size_t computations. */ -#include "xsize.h" - -#if CHAR_T_ONLY_ASCII -/* c_isascii(). */ -# include "c-ctype.h" -#endif - -#ifdef STATIC -STATIC -#endif -int -PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) -{ - const CHAR_T *cp = format; /* pointer into format */ - size_t arg_posn = 0; /* number of regular arguments consumed */ - size_t d_allocated; /* allocated elements of d->dir */ - size_t a_allocated; /* allocated elements of a->arg */ - size_t max_width_length = 0; - size_t max_precision_length = 0; - - d->count = 0; - d_allocated = N_DIRECT_ALLOC_DIRECTIVES; - d->dir = d->direct_alloc_dir; - - a->count = 0; - a_allocated = N_DIRECT_ALLOC_ARGUMENTS; - a->arg = a->direct_alloc_arg; - -#define REGISTER_ARG(_index_,_type_) \ - { \ - size_t n = (_index_); \ - if (n >= a_allocated) \ - { \ - size_t memory_size; \ - argument *memory; \ - \ - a_allocated = xtimes (a_allocated, 2); \ - if (a_allocated <= n) \ - a_allocated = xsum (n, 1); \ - memory_size = xtimes (a_allocated, sizeof (argument)); \ - if (size_overflow_p (memory_size)) \ - /* Overflow, would lead to out of memory. */ \ - goto out_of_memory; \ - memory = (argument *) (a->arg != a->direct_alloc_arg \ - ? realloc (a->arg, memory_size) \ - : malloc (memory_size)); \ - if (memory == NULL) \ - /* Out of memory. */ \ - goto out_of_memory; \ - if (a->arg == a->direct_alloc_arg) \ - memcpy (memory, a->arg, a->count * sizeof (argument)); \ - a->arg = memory; \ - } \ - while (a->count <= n) \ - a->arg[a->count++].type = TYPE_NONE; \ - if (a->arg[n].type == TYPE_NONE) \ - a->arg[n].type = (_type_); \ - else if (a->arg[n].type != (_type_)) \ - /* Ambiguous type for positional argument. */ \ - goto error; \ - } - - while (*cp != '\0') - { - CHAR_T c = *cp++; - if (c == '%') - { - size_t arg_index = ARG_NONE; - DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */ - - /* Initialize the next directive. */ - dp->dir_start = cp - 1; - dp->flags = 0; - dp->width_start = NULL; - dp->width_end = NULL; - dp->width_arg_index = ARG_NONE; - dp->precision_start = NULL; - dp->precision_end = NULL; - dp->precision_arg_index = ARG_NONE; - dp->arg_index = ARG_NONE; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - n = xsum (xtimes (n, 10), *np - '0'); - if (n == 0) - /* Positional argument 0. */ - goto error; - if (size_overflow_p (n)) - /* n too large, would lead to out of memory later. */ - goto error; - arg_index = n - 1; - cp = np + 1; - } - } - - /* Read the flags. */ - for (;;) - { - if (*cp == '\'') - { - dp->flags |= FLAG_GROUP; - cp++; - } - else if (*cp == '-') - { - dp->flags |= FLAG_LEFT; - cp++; - } - else if (*cp == '+') - { - dp->flags |= FLAG_SHOWSIGN; - cp++; - } - else if (*cp == ' ') - { - dp->flags |= FLAG_SPACE; - cp++; - } - else if (*cp == '#') - { - dp->flags |= FLAG_ALT; - cp++; - } - else if (*cp == '0') - { - dp->flags |= FLAG_ZERO; - cp++; - } -#if __GLIBC__ >= 2 && !defined __UCLIBC__ - else if (*cp == 'I') - { - dp->flags |= FLAG_LOCALIZED; - cp++; - } -#endif - else - break; - } - - /* Parse the field width. */ - if (*cp == '*') - { - dp->width_start = cp; - cp++; - dp->width_end = cp; - if (max_width_length < 1) - max_width_length = 1; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - n = xsum (xtimes (n, 10), *np - '0'); - if (n == 0) - /* Positional argument 0. */ - goto error; - if (size_overflow_p (n)) - /* n too large, would lead to out of memory later. */ - goto error; - dp->width_arg_index = n - 1; - cp = np + 1; - } - } - if (dp->width_arg_index == ARG_NONE) - { - dp->width_arg_index = arg_posn++; - if (dp->width_arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->width_arg_index, TYPE_INT); - } - else if (*cp >= '0' && *cp <= '9') - { - size_t width_length; - - dp->width_start = cp; - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - dp->width_end = cp; - width_length = dp->width_end - dp->width_start; - if (max_width_length < width_length) - max_width_length = width_length; - } - - /* Parse the precision. */ - if (*cp == '.') - { - cp++; - if (*cp == '*') - { - dp->precision_start = cp - 1; - cp++; - dp->precision_end = cp; - if (max_precision_length < 2) - max_precision_length = 2; - - /* Test for positional argument. */ - if (*cp >= '0' && *cp <= '9') - { - const CHAR_T *np; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - ; - if (*np == '$') - { - size_t n = 0; - - for (np = cp; *np >= '0' && *np <= '9'; np++) - n = xsum (xtimes (n, 10), *np - '0'); - if (n == 0) - /* Positional argument 0. */ - goto error; - if (size_overflow_p (n)) - /* n too large, would lead to out of memory - later. */ - goto error; - dp->precision_arg_index = n - 1; - cp = np + 1; - } - } - if (dp->precision_arg_index == ARG_NONE) - { - dp->precision_arg_index = arg_posn++; - if (dp->precision_arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->precision_arg_index, TYPE_INT); - } - else - { - size_t precision_length; - - dp->precision_start = cp - 1; - for (; *cp >= '0' && *cp <= '9'; cp++) - ; - dp->precision_end = cp; - precision_length = dp->precision_end - dp->precision_start; - if (max_precision_length < precision_length) - max_precision_length = precision_length; - } - } - - { - arg_type type; - - /* Parse argument type/size specifiers. */ - { - int flags = 0; - - for (;;) - { - if (*cp == 'h') - { - flags |= (1 << (flags & 1)); - cp++; - } - else if (*cp == 'L') - { - flags |= 4; - cp++; - } - else if (*cp == 'l') - { - flags += 8; - cp++; - } - else if (*cp == 'j') - { - if (sizeof (intmax_t) > sizeof (long)) - { - /* intmax_t = long long */ - flags += 16; - } - else if (sizeof (intmax_t) > sizeof (int)) - { - /* intmax_t = long */ - flags += 8; - } - cp++; - } - else if (*cp == 'z' || *cp == 'Z') - { - /* 'z' is standardized in ISO C 99, but glibc uses 'Z' - because the warning facility in gcc-2.95.2 understands - only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */ - if (sizeof (size_t) > sizeof (long)) - { - /* size_t = long long */ - flags += 16; - } - else if (sizeof (size_t) > sizeof (int)) - { - /* size_t = long */ - flags += 8; - } - cp++; - } - else if (*cp == 't') - { - if (sizeof (ptrdiff_t) > sizeof (long)) - { - /* ptrdiff_t = long long */ - flags += 16; - } - else if (sizeof (ptrdiff_t) > sizeof (int)) - { - /* ptrdiff_t = long */ - flags += 8; - } - cp++; - } -#if defined __APPLE__ && defined __MACH__ - /* On Mac OS X 10.3, PRIdMAX is defined as "qd". - We cannot change it to "lld" because PRIdMAX must also - be understood by the system's printf routines. */ - else if (*cp == 'q') - { - if (64 / 8 > sizeof (long)) - { - /* int64_t = long long */ - flags += 16; - } - else - { - /* int64_t = long */ - flags += 8; - } - cp++; - } -#endif -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - /* On native Windows, PRIdMAX is defined as "I64d". - We cannot change it to "lld" because PRIdMAX must also - be understood by the system's printf routines. */ - else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') - { - if (64 / 8 > sizeof (long)) - { - /* __int64 = long long */ - flags += 16; - } - else - { - /* __int64 = long */ - flags += 8; - } - cp += 3; - } -#endif - else - break; - } - - /* Read the conversion character. */ - c = *cp++; - switch (c) - { - case 'd': case 'i': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ - if (flags >= 16 || (flags & 4)) - type = TYPE_LONGLONGINT; - else -#endif - /* If 'long long' exists and is the same as 'long', we parse - "lld" into TYPE_LONGINT. */ - if (flags >= 8) - type = TYPE_LONGINT; - else if (flags & 2) - type = TYPE_SCHAR; - else if (flags & 1) - type = TYPE_SHORT; - else - type = TYPE_INT; - break; - case 'o': case 'u': case 'x': case 'X': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ - if (flags >= 16 || (flags & 4)) - type = TYPE_ULONGLONGINT; - else -#endif - /* If 'unsigned long long' exists and is the same as - 'unsigned long', we parse "llu" into TYPE_ULONGINT. */ - if (flags >= 8) - type = TYPE_ULONGINT; - else if (flags & 2) - type = TYPE_UCHAR; - else if (flags & 1) - type = TYPE_USHORT; - else - type = TYPE_UINT; - break; - case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': - case 'a': case 'A': - if (flags >= 16 || (flags & 4)) - type = TYPE_LONGDOUBLE; - else - type = TYPE_DOUBLE; - break; - case 'c': - if (flags >= 8) -#if HAVE_WINT_T - type = TYPE_WIDE_CHAR; -#else - goto error; -#endif - else - type = TYPE_CHAR; - break; -#if HAVE_WINT_T - case 'C': - type = TYPE_WIDE_CHAR; - c = 'c'; - break; -#endif - case 's': - if (flags >= 8) -#if HAVE_WCHAR_T - type = TYPE_WIDE_STRING; -#else - goto error; -#endif - else - type = TYPE_STRING; - break; -#if HAVE_WCHAR_T - case 'S': - type = TYPE_WIDE_STRING; - c = 's'; - break; -#endif - case 'p': - type = TYPE_POINTER; - break; - case 'n': -#if HAVE_LONG_LONG_INT - /* If 'long long' exists and is larger than 'long': */ - if (flags >= 16 || (flags & 4)) - type = TYPE_COUNT_LONGLONGINT_POINTER; - else -#endif - /* If 'long long' exists and is the same as 'long', we parse - "lln" into TYPE_COUNT_LONGINT_POINTER. */ - if (flags >= 8) - type = TYPE_COUNT_LONGINT_POINTER; - else if (flags & 2) - type = TYPE_COUNT_SCHAR_POINTER; - else if (flags & 1) - type = TYPE_COUNT_SHORT_POINTER; - else - type = TYPE_COUNT_INT_POINTER; - break; -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - case 'U': - if (flags >= 16) - type = TYPE_U32_STRING; - else if (flags >= 8) - type = TYPE_U16_STRING; - else - type = TYPE_U8_STRING; - break; -#endif - case '%': - type = TYPE_NONE; - break; - default: - /* Unknown conversion character. */ - goto error; - } - } - - if (type != TYPE_NONE) - { - dp->arg_index = arg_index; - if (dp->arg_index == ARG_NONE) - { - dp->arg_index = arg_posn++; - if (dp->arg_index == ARG_NONE) - /* arg_posn wrapped around. */ - goto error; - } - REGISTER_ARG (dp->arg_index, type); - } - dp->conversion = c; - dp->dir_end = cp; - } - - d->count++; - if (d->count >= d_allocated) - { - size_t memory_size; - DIRECTIVE *memory; - - d_allocated = xtimes (d_allocated, 2); - memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); - if (size_overflow_p (memory_size)) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir - ? realloc (d->dir, memory_size) - : malloc (memory_size)); - if (memory == NULL) - /* Out of memory. */ - goto out_of_memory; - if (d->dir == d->direct_alloc_dir) - memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE)); - d->dir = memory; - } - } -#if CHAR_T_ONLY_ASCII - else if (!c_isascii (c)) - { - /* Non-ASCII character. Not supported. */ - goto error; - } -#endif - } - d->dir[d->count].dir_start = cp; - - d->max_width_length = max_width_length; - d->max_precision_length = max_precision_length; - return 0; - -error: - if (a->arg != a->direct_alloc_arg) - free (a->arg); - if (d->dir != d->direct_alloc_dir) - free (d->dir); - errno = EINVAL; - return -1; - -out_of_memory: - if (a->arg != a->direct_alloc_arg) - free (a->arg); - if (d->dir != d->direct_alloc_dir) - free (d->dir); - errno = ENOMEM; - return -1; -} - -#undef PRINTF_PARSE -#undef DIRECTIVES -#undef DIRECTIVE -#undef CHAR_T_ONLY_ASCII -#undef CHAR_T diff --git a/grub-core/gnulib/printf-parse.h b/grub-core/gnulib/printf-parse.h deleted file mode 100644 index d8474bee1..000000000 --- a/grub-core/gnulib/printf-parse.h +++ /dev/null @@ -1,193 +0,0 @@ -/* Parse printf format string. - Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2013 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifndef _PRINTF_PARSE_H -#define _PRINTF_PARSE_H - -/* This file can be parametrized with the following macros: - ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. - STATIC Set to 'static' to declare the function static. */ - -#if HAVE_FEATURES_H -# include /* for __GLIBC__, __UCLIBC__ */ -#endif - -#include "printf-args.h" - - -/* Flags */ -#define FLAG_GROUP 1 /* ' flag */ -#define FLAG_LEFT 2 /* - flag */ -#define FLAG_SHOWSIGN 4 /* + flag */ -#define FLAG_SPACE 8 /* space flag */ -#define FLAG_ALT 16 /* # flag */ -#define FLAG_ZERO 32 -#if __GLIBC__ >= 2 && !defined __UCLIBC__ -# define FLAG_LOCALIZED 64 /* I flag, uses localized digits */ -#endif - -/* arg_index value indicating that no argument is consumed. */ -#define ARG_NONE (~(size_t)0) - -/* xxx_directive: A parsed directive. - xxx_directives: A parsed format string. */ - -/* Number of directly allocated directives (no malloc() needed). */ -#define N_DIRECT_ALLOC_DIRECTIVES 7 - -/* A parsed directive. */ -typedef struct -{ - const char* dir_start; - const char* dir_end; - int flags; - const char* width_start; - const char* width_end; - size_t width_arg_index; - const char* precision_start; - const char* precision_end; - size_t precision_arg_index; - char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -char_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - char_directive *dir; - size_t max_width_length; - size_t max_precision_length; - char_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; -} -char_directives; - -#if ENABLE_UNISTDIO - -/* A parsed directive. */ -typedef struct -{ - const uint8_t* dir_start; - const uint8_t* dir_end; - int flags; - const uint8_t* width_start; - const uint8_t* width_end; - size_t width_arg_index; - const uint8_t* precision_start; - const uint8_t* precision_end; - size_t precision_arg_index; - uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -u8_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - u8_directive *dir; - size_t max_width_length; - size_t max_precision_length; - u8_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; -} -u8_directives; - -/* A parsed directive. */ -typedef struct -{ - const uint16_t* dir_start; - const uint16_t* dir_end; - int flags; - const uint16_t* width_start; - const uint16_t* width_end; - size_t width_arg_index; - const uint16_t* precision_start; - const uint16_t* precision_end; - size_t precision_arg_index; - uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -u16_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - u16_directive *dir; - size_t max_width_length; - size_t max_precision_length; - u16_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; -} -u16_directives; - -/* A parsed directive. */ -typedef struct -{ - const uint32_t* dir_start; - const uint32_t* dir_end; - int flags; - const uint32_t* width_start; - const uint32_t* width_end; - size_t width_arg_index; - const uint32_t* precision_start; - const uint32_t* precision_end; - size_t precision_arg_index; - uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */ - size_t arg_index; -} -u32_directive; - -/* A parsed format string. */ -typedef struct -{ - size_t count; - u32_directive *dir; - size_t max_width_length; - size_t max_precision_length; - u32_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; -} -u32_directives; - -#endif - - -/* Parses the format string. Fills in the number N of directives, and fills - in directives[0], ..., directives[N-1], and sets directives[N].dir_start - to the end of the format string. Also fills in the arg_type fields of the - arguments and the needed count of arguments. */ -#if ENABLE_UNISTDIO -extern int - ulc_printf_parse (const char *format, char_directives *d, arguments *a); -extern int - u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a); -extern int - u16_printf_parse (const uint16_t *format, u16_directives *d, - arguments *a); -extern int - u32_printf_parse (const uint32_t *format, u32_directives *d, - arguments *a); -#else -# ifdef STATIC -STATIC -# else -extern -# endif -int printf_parse (const char *format, char_directives *d, arguments *a); -#endif - -#endif /* _PRINTF_PARSE_H */ diff --git a/grub-core/gnulib/progname.c b/grub-core/gnulib/progname.c deleted file mode 100644 index 0c195e521..000000000 --- a/grub-core/gnulib/progname.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Program name management. - Copyright (C) 2001-2003, 2005-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2001. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - - -#include - -/* Specification. */ -#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */ -#include "progname.h" - -#include /* get program_invocation_name declaration */ -#include -#include -#include - - -/* String containing name the program is called with. - To be initialized by main(). */ -const char *program_name = NULL; - -/* Set program_name, based on argv[0]. - argv0 must be a string allocated with indefinite extent, and must not be - modified after this call. */ -void -set_program_name (const char *argv0) -{ - /* libtool creates a temporary executable whose name is sometimes prefixed - with "lt-" (depends on the platform). It also makes argv[0] absolute. - But the name of the temporary executable is a detail that should not be - visible to the end user and to the test suite. - Remove this "/.libs/" or "/.libs/lt-" prefix here. */ - const char *slash; - const char *base; - - /* Sanity check. POSIX requires the invoking process to pass a non-NULL - argv[0]. */ - if (argv0 == NULL) - { - /* It's a bug in the invoking program. Help diagnosing it. */ - fputs ("A NULL argv[0] was passed through an exec system call.\n", - stderr); - abort (); - } - - slash = strrchr (argv0, '/'); - base = (slash != NULL ? slash + 1 : argv0); - if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0) - { - argv0 = base; - if (strncmp (base, "lt-", 3) == 0) - { - argv0 = base + 3; - /* On glibc systems, remove the "lt-" prefix from the variable - program_invocation_short_name. */ -#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - program_invocation_short_name = (char *) argv0; -#endif - } - } - - /* But don't strip off a leading / in general, because when the user - runs - /some/hidden/place/bin/cp foo foo - he should get the error message - /some/hidden/place/bin/cp: `foo' and `foo' are the same file - not - cp: `foo' and `foo' are the same file - */ - - program_name = argv0; - - /* On glibc systems, the error() function comes from libc and uses the - variable program_invocation_name, not program_name. So set this variable - as well. */ -#if HAVE_DECL_PROGRAM_INVOCATION_NAME - program_invocation_name = (char *) argv0; -#endif -} diff --git a/grub-core/gnulib/progname.h b/grub-core/gnulib/progname.h deleted file mode 100644 index b4f3c2778..000000000 --- a/grub-core/gnulib/progname.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Program name management. - Copyright (C) 2001-2004, 2006, 2009-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2001. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _PROGNAME_H -#define _PROGNAME_H - -/* Programs using this file should do the following in main(): - set_program_name (argv[0]); - */ - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* String containing name the program is called with. */ -extern const char *program_name; - -/* Set program_name, based on argv[0]. - argv0 must be a string allocated with indefinite extent, and must not be - modified after this call. */ -extern void set_program_name (const char *argv0); - -#if ENABLE_RELOCATABLE - -/* Set program_name, based on argv[0], and original installation prefix and - directory, for relocatability. */ -extern void set_program_name_and_installdir (const char *argv0, - const char *orig_installprefix, - const char *orig_installdir); -#undef set_program_name -#define set_program_name(ARG0) \ - set_program_name_and_installdir (ARG0, INSTALLPREFIX, INSTALLDIR) - -/* Return the full pathname of the current executable, based on the earlier - call to set_program_name_and_installdir. Return NULL if unknown. */ -extern char *get_full_program_name (void); - -#endif - - -#ifdef __cplusplus -} -#endif - - -#endif /* _PROGNAME_H */ diff --git a/grub-core/gnulib/rawmemchr.c b/grub-core/gnulib/rawmemchr.c deleted file mode 100644 index a0298ce64..000000000 --- a/grub-core/gnulib/rawmemchr.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Searching in a string. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -/* Find the first occurrence of C in S. */ -void * -rawmemchr (const void *s, int c_in) -{ - /* On 32-bit hardware, choosing longword to be a 32-bit unsigned - long instead of a 64-bit uintmax_t tends to give better - performance. On 64-bit hardware, unsigned long is generally 64 - bits already. Change this typedef to experiment with - performance. */ - typedef unsigned long int longword; - - const unsigned char *char_ptr; - const longword *longword_ptr; - longword repeated_one; - longword repeated_c; - unsigned char c; - - c = (unsigned char) c_in; - - /* Handle the first few bytes by reading one byte at a time. - Do this until CHAR_PTR is aligned on a longword boundary. */ - for (char_ptr = (const unsigned char *) s; - (size_t) char_ptr % sizeof (longword) != 0; - ++char_ptr) - if (*char_ptr == c) - return (void *) char_ptr; - - longword_ptr = (const longword *) char_ptr; - - /* All these elucidatory comments refer to 4-byte longwords, - but the theory applies equally well to any size longwords. */ - - /* Compute auxiliary longword values: - repeated_one is a value which has a 1 in every byte. - repeated_c has c in every byte. */ - repeated_one = 0x01010101; - repeated_c = c | (c << 8); - repeated_c |= repeated_c << 16; - if (0xffffffffU < (longword) -1) - { - repeated_one |= repeated_one << 31 << 1; - repeated_c |= repeated_c << 31 << 1; - if (8 < sizeof (longword)) - { - size_t i; - - for (i = 64; i < sizeof (longword) * 8; i *= 2) - { - repeated_one |= repeated_one << i; - repeated_c |= repeated_c << i; - } - } - } - - /* Instead of the traditional loop which tests each byte, we will - test a longword at a time. The tricky part is testing if *any of - the four* bytes in the longword in question are equal to NUL or - c. We first use an xor with repeated_c. This reduces the task - to testing whether *any of the four* bytes in longword1 is zero. - - We compute tmp = - ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). - That is, we perform the following operations: - 1. Subtract repeated_one. - 2. & ~longword1. - 3. & a mask consisting of 0x80 in every byte. - Consider what happens in each byte: - - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, - and step 3 transforms it into 0x80. A carry can also be propagated - to more significant bytes. - - If a byte of longword1 is nonzero, let its lowest 1 bit be at - position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, - the byte ends in a single bit of value 0 and k bits of value 1. - After step 2, the result is just k bits of value 1: 2^k - 1. After - step 3, the result is 0. And no carry is produced. - So, if longword1 has only non-zero bytes, tmp is zero. - Whereas if longword1 has a zero byte, call j the position of the least - significant zero byte. Then the result has a zero at positions 0, ..., - j-1 and a 0x80 at position j. We cannot predict the result at the more - significant bytes (positions j+1..3), but it does not matter since we - already have a non-zero bit at position 8*j+7. - - The test whether any byte in longword1 is zero is equivalent - to testing whether tmp is nonzero. - - This test can read beyond the end of a string, depending on where - C_IN is encountered. However, this is considered safe since the - initialization phase ensured that the read will be aligned, - therefore, the read will not cross page boundaries and will not - cause a fault. */ - - while (1) - { - longword longword1 = *longword_ptr ^ repeated_c; - - if ((((longword1 - repeated_one) & ~longword1) - & (repeated_one << 7)) != 0) - break; - longword_ptr++; - } - - char_ptr = (const unsigned char *) longword_ptr; - - /* At this point, we know that one of the sizeof (longword) bytes - starting at char_ptr is == c. On little-endian machines, we - could determine the first such byte without any further memory - accesses, just by looking at the tmp result from the last loop - iteration. But this does not work on big-endian machines. - Choose code that works in both cases. */ - - char_ptr = (unsigned char *) longword_ptr; - while (*char_ptr != c) - char_ptr++; - return (void *) char_ptr; -} diff --git a/grub-core/gnulib/rawmemchr.valgrind b/grub-core/gnulib/rawmemchr.valgrind deleted file mode 100644 index 636392368..000000000 --- a/grub-core/gnulib/rawmemchr.valgrind +++ /dev/null @@ -1,12 +0,0 @@ -# Suppress a valgrind message about use of uninitialized memory in rawmemchr(). -# This use is OK because it provides only a speedup. -{ - rawmemchr-value4 - Memcheck:Value4 - fun:rawmemchr -} -{ - rawmemchr-value8 - Memcheck:Value8 - fun:rawmemchr -} diff --git a/grub-core/gnulib/realloc.c b/grub-core/gnulib/realloc.c deleted file mode 100644 index b51010a62..000000000 --- a/grub-core/gnulib/realloc.c +++ /dev/null @@ -1,79 +0,0 @@ -/* realloc() function that is glibc compatible. - - Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2013 Free Software - Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* written by Jim Meyering and Bruno Haible */ - -#define _GL_USE_STDLIB_ALLOC 1 -#include - -/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */ -#ifdef realloc -# define NEED_REALLOC_GNU 1 -/* Whereas the gnulib module 'realloc-gnu' defines HAVE_REALLOC_GNU. */ -#elif GNULIB_REALLOC_GNU && !HAVE_REALLOC_GNU -# define NEED_REALLOC_GNU 1 -#endif - -/* Infer the properties of the system's malloc function. - The gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */ -#if GNULIB_MALLOC_GNU && HAVE_MALLOC_GNU -# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1 -#endif - -#include - -#include - -/* Change the size of an allocated block of memory P to N bytes, - with error checking. If N is zero, change it to 1. If P is NULL, - use malloc. */ - -void * -rpl_realloc (void *p, size_t n) -{ - void *result; - -#if NEED_REALLOC_GNU - if (n == 0) - { - n = 1; - - /* In theory realloc might fail, so don't rely on it to free. */ - free (p); - p = NULL; - } -#endif - - if (p == NULL) - { -#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE - if (n == 0) - n = 1; -#endif - result = malloc (n); - } - else - result = realloc (p, n); - -#if !HAVE_REALLOC_POSIX - if (result == NULL) - errno = ENOMEM; -#endif - - return result; -} diff --git a/grub-core/gnulib/ref-add.sin b/grub-core/gnulib/ref-add.sin deleted file mode 100644 index 112bcdc64..000000000 --- a/grub-core/gnulib/ref-add.sin +++ /dev/null @@ -1,29 +0,0 @@ -# Add this package to a list of references stored in a text file. -# -# Copyright (C) 2000, 2009-2013 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, 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 Bruno Haible . -# -/^# Packages using this file: / { - s/# Packages using this file:// - ta - :a - s/ @PACKAGE@ / @PACKAGE@ / - tb - s/ $/ @PACKAGE@ / - :b - s/^/# Packages using this file:/ -} diff --git a/grub-core/gnulib/ref-del.sin b/grub-core/gnulib/ref-del.sin deleted file mode 100644 index 6f7386847..000000000 --- a/grub-core/gnulib/ref-del.sin +++ /dev/null @@ -1,24 +0,0 @@ -# Remove this package from a list of references stored in a text file. -# -# Copyright (C) 2000, 2009-2013 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, 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 Bruno Haible . -# -/^# Packages using this file: / { - s/# Packages using this file:// - s/ @PACKAGE@ / / - s/^/# Packages using this file:/ -} diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c deleted file mode 100644 index 596e0cf3e..000000000 --- a/grub-core/gnulib/regcomp.c +++ /dev/null @@ -1,3913 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with the GNU C Library; if not, see - . */ - -static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, - size_t length, reg_syntax_t syntax); -static void re_compile_fastmap_iter (regex_t *bufp, - const re_dfastate_t *init_state, - char *fastmap); -static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len); -#ifdef RE_ENABLE_I18N -static void free_charset (re_charset_t *cset); -#endif /* RE_ENABLE_I18N */ -static void free_workarea_compile (regex_t *preg); -static reg_errcode_t create_initial_state (re_dfa_t *dfa); -#ifdef RE_ENABLE_I18N -static void optimize_utf8 (re_dfa_t *dfa); -#endif -static reg_errcode_t analyze (regex_t *preg); -static reg_errcode_t preorder (bin_tree_t *root, - reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra); -static reg_errcode_t postorder (bin_tree_t *root, - reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra); -static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node); -static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node); -static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg, - bin_tree_t *node); -static reg_errcode_t calc_first (void *extra, bin_tree_t *node); -static reg_errcode_t calc_next (void *extra, bin_tree_t *node); -static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node); -static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint); -static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node, - unsigned int constraint); -static reg_errcode_t calc_eclosure (re_dfa_t *dfa); -static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, - Idx node, bool root); -static reg_errcode_t calc_inveclosure (re_dfa_t *dfa); -static Idx fetch_number (re_string_t *input, re_token_t *token, - reg_syntax_t syntax); -static int peek_token (re_token_t *token, re_string_t *input, - reg_syntax_t syntax) internal_function; -static bin_tree_t *parse (re_string_t *regexp, regex_t *preg, - reg_syntax_t syntax, reg_errcode_t *err); -static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - Idx nest, reg_errcode_t *err); -static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp, - re_dfa_t *dfa, re_token_t *token, - reg_syntax_t syntax, reg_errcode_t *err); -static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, - re_token_t *token, reg_syntax_t syntax, - reg_errcode_t *err); -static reg_errcode_t parse_bracket_element (bracket_elem_t *elem, - re_string_t *regexp, - re_token_t *token, int token_len, - re_dfa_t *dfa, - reg_syntax_t syntax, - bool accept_hyphen); -static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, - re_string_t *regexp, - re_token_t *token); -#ifdef RE_ENABLE_I18N -static reg_errcode_t build_equiv_class (bitset_t sbcset, - re_charset_t *mbcset, - Idx *equiv_class_alloc, - const unsigned char *name); -static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, - bitset_t sbcset, - re_charset_t *mbcset, - Idx *char_class_alloc, - const char *class_name, - reg_syntax_t syntax); -#else /* not RE_ENABLE_I18N */ -static reg_errcode_t build_equiv_class (bitset_t sbcset, - const unsigned char *name); -static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, - bitset_t sbcset, - const char *class_name, - reg_syntax_t syntax); -#endif /* not RE_ENABLE_I18N */ -static bin_tree_t *build_charclass_op (re_dfa_t *dfa, - RE_TRANSLATE_TYPE trans, - const char *class_name, - const char *extra, - bool non_match, reg_errcode_t *err); -static bin_tree_t *create_tree (re_dfa_t *dfa, - bin_tree_t *left, bin_tree_t *right, - re_token_type_t type); -static bin_tree_t *create_token_tree (re_dfa_t *dfa, - bin_tree_t *left, bin_tree_t *right, - const re_token_t *token); -static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa); -static void free_token (re_token_t *node); -static reg_errcode_t free_tree (void *extra, bin_tree_t *node); -static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node); - -/* This table gives an error message for each of the error codes listed - in regex.h. Obviously the order here has to be same as there. - POSIX doesn't require that we do anything for REG_NOERROR, - but why not be nice? */ - -static const char __re_error_msgid[] = - { -#define REG_NOERROR_IDX 0 - gettext_noop ("Success") /* REG_NOERROR */ - "\0" -#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success") - gettext_noop ("No match") /* REG_NOMATCH */ - "\0" -#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match") - gettext_noop ("Invalid regular expression") /* REG_BADPAT */ - "\0" -#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression") - gettext_noop ("Invalid collation character") /* REG_ECOLLATE */ - "\0" -#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character") - gettext_noop ("Invalid character class name") /* REG_ECTYPE */ - "\0" -#define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name") - gettext_noop ("Trailing backslash") /* REG_EESCAPE */ - "\0" -#define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash") - gettext_noop ("Invalid back reference") /* REG_ESUBREG */ - "\0" -#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference") - gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */ - "\0" -#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^") - gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */ - "\0" -#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(") - gettext_noop ("Unmatched \\{") /* REG_EBRACE */ - "\0" -#define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{") - gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */ - "\0" -#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}") - gettext_noop ("Invalid range end") /* REG_ERANGE */ - "\0" -#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end") - gettext_noop ("Memory exhausted") /* REG_ESPACE */ - "\0" -#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted") - gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */ - "\0" -#define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression") - gettext_noop ("Premature end of regular expression") /* REG_EEND */ - "\0" -#define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression") - gettext_noop ("Regular expression too big") /* REG_ESIZE */ - "\0" -#define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big") - gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */ - }; - -static const size_t __re_error_msgid_idx[] = - { - REG_NOERROR_IDX, - REG_NOMATCH_IDX, - REG_BADPAT_IDX, - REG_ECOLLATE_IDX, - REG_ECTYPE_IDX, - REG_EESCAPE_IDX, - REG_ESUBREG_IDX, - REG_EBRACK_IDX, - REG_EPAREN_IDX, - REG_EBRACE_IDX, - REG_BADBR_IDX, - REG_ERANGE_IDX, - REG_ESPACE_IDX, - REG_BADRPT_IDX, - REG_EEND_IDX, - REG_ESIZE_IDX, - REG_ERPAREN_IDX - }; - -/* Entry points for GNU code. */ - -/* re_compile_pattern is the GNU regular expression compiler: it - compiles PATTERN (of length LENGTH) and puts the result in BUFP. - Returns 0 if the pattern was valid, otherwise an error string. - - Assumes the 'allocated' (and perhaps 'buffer') and 'translate' fields - are set in BUFP on entry. */ - -#ifdef _LIBC -const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - size_t length; - struct re_pattern_buffer *bufp; -#else /* size_t might promote */ -const char * -re_compile_pattern (const char *pattern, size_t length, - struct re_pattern_buffer *bufp) -#endif -{ - reg_errcode_t ret; - - /* And GNU code determines whether or not to get register information - by passing null for the REGS argument to re_match, etc., not by - setting no_sub, unless RE_NO_SUB is set. */ - bufp->no_sub = !!(re_syntax_options & RE_NO_SUB); - - /* Match anchors at newline. */ - bufp->newline_anchor = 1; - - ret = re_compile_internal (bufp, pattern, length, re_syntax_options); - - if (!ret) - return NULL; - return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); -} -#ifdef _LIBC -weak_alias (__re_compile_pattern, re_compile_pattern) -#endif - -/* Set by 're_set_syntax' to the current regexp syntax to recognize. Can - also be assigned to arbitrarily: each pattern buffer stores its own - syntax, so it can be changed between regex compilations. */ -/* This has no initializer because initialized variables in Emacs - become read-only after dumping. */ -reg_syntax_t re_syntax_options; - - -/* Specify the precise syntax of regexps for compilation. This provides - for compatibility for various utilities which historically have - different, incompatible syntaxes. - - The argument SYNTAX is a bit mask comprised of the various bits - defined in regex.h. We return the old syntax. */ - -reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; -{ - reg_syntax_t ret = re_syntax_options; - - re_syntax_options = syntax; - return ret; -} -#ifdef _LIBC -weak_alias (__re_set_syntax, re_set_syntax) -#endif - -int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; -{ - re_dfa_t *dfa = bufp->buffer; - char *fastmap = bufp->fastmap; - - memset (fastmap, '\0', sizeof (char) * SBC_MAX); - re_compile_fastmap_iter (bufp, dfa->init_state, fastmap); - if (dfa->init_state != dfa->init_state_word) - re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap); - if (dfa->init_state != dfa->init_state_nl) - re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap); - if (dfa->init_state != dfa->init_state_begbuf) - re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap); - bufp->fastmap_accurate = 1; - return 0; -} -#ifdef _LIBC -weak_alias (__re_compile_fastmap, re_compile_fastmap) -#endif - -static inline void -__attribute__ ((always_inline)) -re_set_fastmap (char *fastmap, bool icase, int ch) -{ - fastmap[ch] = 1; - if (icase) - fastmap[tolower (ch)] = 1; -} - -/* Helper function for re_compile_fastmap. - Compile fastmap for the initial_state INIT_STATE. */ - -static void -re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, - char *fastmap) -{ - re_dfa_t *dfa = bufp->buffer; - Idx node_cnt; - bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); - for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) - { - Idx node = init_state->nodes.elems[node_cnt]; - re_token_type_t type = dfa->nodes[node].type; - - if (type == CHARACTER) - { - re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); -#ifdef RE_ENABLE_I18N - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) - { - unsigned char buf[MB_LEN_MAX]; - unsigned char *p; - wchar_t wc; - mbstate_t state; - - p = buf; - *p++ = dfa->nodes[node].opr.c; - while (++node < dfa->nodes_len - && dfa->nodes[node].type == CHARACTER - && dfa->nodes[node].mb_partial) - *p++ = dfa->nodes[node].opr.c; - memset (&state, '\0', sizeof (state)); - if (__mbrtowc (&wc, (const char *) buf, p - buf, - &state) == p - buf - && (__wcrtomb ((char *) buf, towlower (wc), &state) - != (size_t) -1)) - re_set_fastmap (fastmap, false, buf[0]); - } -#endif - } - else if (type == SIMPLE_BRACKET) - { - int i, ch; - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - { - int j; - bitset_word_t w = dfa->nodes[node].opr.sbcset[i]; - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - if (w & ((bitset_word_t) 1 << j)) - re_set_fastmap (fastmap, icase, ch); - } - } -#ifdef RE_ENABLE_I18N - else if (type == COMPLEX_BRACKET) - { - re_charset_t *cset = dfa->nodes[node].opr.mbcset; - Idx i; - -# ifdef _LIBC - /* See if we have to try all bytes which start multiple collation - elements. - e.g. In da_DK, we want to catch 'a' since "aa" is a valid - collation element, and don't catch 'b' since 'b' is - the only collation element which starts from 'b' (and - it is caught by SIMPLE_BRACKET). */ - if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0 - && (cset->ncoll_syms || cset->nranges)) - { - const int32_t *table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - for (i = 0; i < SBC_MAX; ++i) - if (table[i] < 0) - re_set_fastmap (fastmap, icase, i); - } -# endif /* _LIBC */ - - /* See if we have to start the match at all multibyte characters, - i.e. where we would not find an invalid sequence. This only - applies to multibyte character sets; for single byte character - sets, the SIMPLE_BRACKET again suffices. */ - if (dfa->mb_cur_max > 1 - && (cset->nchar_classes || cset->non_match || cset->nranges -# ifdef _LIBC - || cset->nequiv_classes -# endif /* _LIBC */ - )) - { - unsigned char c = 0; - do - { - mbstate_t mbs; - memset (&mbs, 0, sizeof (mbs)); - if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2) - re_set_fastmap (fastmap, false, (int) c); - } - while (++c != 0); - } - - else - { - /* ... Else catch all bytes which can start the mbchars. */ - for (i = 0; i < cset->nmbchars; ++i) - { - char buf[256]; - mbstate_t state; - memset (&state, '\0', sizeof (state)); - if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) - re_set_fastmap (fastmap, icase, *(unsigned char *) buf); - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) - { - if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) - != (size_t) -1) - re_set_fastmap (fastmap, false, *(unsigned char *) buf); - } - } - } - } -#endif /* RE_ENABLE_I18N */ - else if (type == OP_PERIOD -#ifdef RE_ENABLE_I18N - || type == OP_UTF8_PERIOD -#endif /* RE_ENABLE_I18N */ - || type == END_OF_RE) - { - memset (fastmap, '\1', sizeof (char) * SBC_MAX); - if (type == END_OF_RE) - bufp->can_be_null = 1; - return; - } - } -} - -/* Entry point for POSIX code. */ -/* regcomp takes a regular expression as a string and compiles it. - - PREG is a regex_t *. We do not expect any fields to be initialized, - since POSIX says we shouldn't. Thus, we set - - 'buffer' to the compiled pattern; - 'used' to the length of the compiled pattern; - 'syntax' to RE_SYNTAX_POSIX_EXTENDED if the - REG_EXTENDED bit in CFLAGS is set; otherwise, to - RE_SYNTAX_POSIX_BASIC; - 'newline_anchor' to REG_NEWLINE being set in CFLAGS; - 'fastmap' to an allocated space for the fastmap; - 'fastmap_accurate' to zero; - 're_nsub' to the number of subexpressions in PATTERN. - - PATTERN is the address of the pattern string. - - CFLAGS is a series of bits which affect compilation. - - If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we - use POSIX basic syntax. - - If REG_NEWLINE is set, then . and [^...] don't match newline. - Also, regexec will try a match beginning after every newline. - - If REG_ICASE is set, then we considers upper- and lowercase - versions of letters to be equivalent when matching. - - If REG_NOSUB is set, then when PREG is passed to regexec, that - routine will report only success or failure, and nothing about the - registers. - - It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for - the return codes and their meanings.) */ - -int -regcomp (preg, pattern, cflags) - regex_t *_Restrict_ preg; - const char *_Restrict_ pattern; - int cflags; -{ - reg_errcode_t ret; - reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED - : RE_SYNTAX_POSIX_BASIC); - - preg->buffer = NULL; - preg->allocated = 0; - preg->used = 0; - - /* Try to allocate space for the fastmap. */ - preg->fastmap = re_malloc (char, SBC_MAX); - if (BE (preg->fastmap == NULL, 0)) - return REG_ESPACE; - - syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0; - - /* If REG_NEWLINE is set, newlines are treated differently. */ - if (cflags & REG_NEWLINE) - { /* REG_NEWLINE implies neither . nor [^...] match newline. */ - syntax &= ~RE_DOT_NEWLINE; - syntax |= RE_HAT_LISTS_NOT_NEWLINE; - /* It also changes the matching behavior. */ - preg->newline_anchor = 1; - } - else - preg->newline_anchor = 0; - preg->no_sub = !!(cflags & REG_NOSUB); - preg->translate = NULL; - - ret = re_compile_internal (preg, pattern, strlen (pattern), syntax); - - /* POSIX doesn't distinguish between an unmatched open-group and an - unmatched close-group: both are REG_EPAREN. */ - if (ret == REG_ERPAREN) - ret = REG_EPAREN; - - /* We have already checked preg->fastmap != NULL. */ - if (BE (ret == REG_NOERROR, 1)) - /* Compute the fastmap now, since regexec cannot modify the pattern - buffer. This function never fails in this implementation. */ - (void) re_compile_fastmap (preg); - else - { - /* Some error occurred while compiling the expression. */ - re_free (preg->fastmap); - preg->fastmap = NULL; - } - - return (int) ret; -} -#ifdef _LIBC -weak_alias (__regcomp, regcomp) -#endif - -/* Returns a message corresponding to an error code, ERRCODE, returned - from either regcomp or regexec. We don't use PREG here. */ - -#ifdef _LIBC -size_t -regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *_Restrict_ preg; - char *_Restrict_ errbuf; - size_t errbuf_size; -#else /* size_t might promote */ -size_t -regerror (int errcode, const regex_t *_Restrict_ preg, - char *_Restrict_ errbuf, size_t errbuf_size) -#endif -{ - const char *msg; - size_t msg_size; - - if (BE (errcode < 0 - || errcode >= (int) (sizeof (__re_error_msgid_idx) - / sizeof (__re_error_msgid_idx[0])), 0)) - msg = gettext ("unknown regexp error"); - else - msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); - - msg_size = strlen (msg) + 1; /* Includes the null. */ - - if (BE (errbuf_size != 0, 1)) - { - size_t cpy_size = msg_size; - if (BE (msg_size > errbuf_size, 0)) - { - cpy_size = errbuf_size - 1; - errbuf[cpy_size] = '\0'; - } - memcpy (errbuf, msg, cpy_size); - } - - return msg_size; -} -#ifdef _LIBC -weak_alias (__regerror, regerror) -#endif - - -#ifdef RE_ENABLE_I18N -/* This static array is used for the map to single-byte characters when - UTF-8 is used. Otherwise we would allocate memory just to initialize - it the same all the time. UTF-8 is the preferred encoding so this is - a worthwhile optimization. */ -static const bitset_t utf8_sb_map = -{ - /* Set the first 128 bits. */ -# ifdef __GNUC__ - [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX -# else -# if 4 * BITSET_WORD_BITS < ASCII_CHARS -# error "bitset_word_t is narrower than 32 bits" -# elif 3 * BITSET_WORD_BITS < ASCII_CHARS - BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, -# elif 2 * BITSET_WORD_BITS < ASCII_CHARS - BITSET_WORD_MAX, BITSET_WORD_MAX, -# elif 1 * BITSET_WORD_BITS < ASCII_CHARS - BITSET_WORD_MAX, -# endif - (BITSET_WORD_MAX - >> (SBC_MAX % BITSET_WORD_BITS == 0 - ? 0 - : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS)) -# endif -}; -#endif - - -static void -free_dfa_content (re_dfa_t *dfa) -{ - Idx i, j; - - if (dfa->nodes) - for (i = 0; i < dfa->nodes_len; ++i) - free_token (dfa->nodes + i); - re_free (dfa->nexts); - for (i = 0; i < dfa->nodes_len; ++i) - { - if (dfa->eclosures != NULL) - re_node_set_free (dfa->eclosures + i); - if (dfa->inveclosures != NULL) - re_node_set_free (dfa->inveclosures + i); - if (dfa->edests != NULL) - re_node_set_free (dfa->edests + i); - } - re_free (dfa->edests); - re_free (dfa->eclosures); - re_free (dfa->inveclosures); - re_free (dfa->nodes); - - if (dfa->state_table) - for (i = 0; i <= dfa->state_hash_mask; ++i) - { - struct re_state_table_entry *entry = dfa->state_table + i; - for (j = 0; j < entry->num; ++j) - { - re_dfastate_t *state = entry->array[j]; - free_state (state); - } - re_free (entry->array); - } - re_free (dfa->state_table); -#ifdef RE_ENABLE_I18N - if (dfa->sb_char != utf8_sb_map) - re_free (dfa->sb_char); -#endif - re_free (dfa->subexp_map); -#ifdef DEBUG - re_free (dfa->re_str); -#endif - - re_free (dfa); -} - - -/* Free dynamically allocated space used by PREG. */ - -void -regfree (preg) - regex_t *preg; -{ - re_dfa_t *dfa = preg->buffer; - if (BE (dfa != NULL, 1)) - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - - re_free (preg->fastmap); - preg->fastmap = NULL; - - re_free (preg->translate); - preg->translate = NULL; -} -#ifdef _LIBC -weak_alias (__regfree, regfree) -#endif - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined _REGEX_RE_COMP || defined _LIBC - -/* BSD has one and only one pattern buffer. */ -static struct re_pattern_buffer re_comp_buf; - -char * -# ifdef _LIBC -/* Make these definitions weak in libc, so POSIX programs can redefine - these names if they don't use our functions, and still use - regcomp/regexec above without link errors. */ -weak_function -# endif -re_comp (s) - const char *s; -{ - reg_errcode_t ret; - char *fastmap; - - if (!s) - { - if (!re_comp_buf.buffer) - return gettext ("No previous regular expression"); - return 0; - } - - if (re_comp_buf.buffer) - { - fastmap = re_comp_buf.fastmap; - re_comp_buf.fastmap = NULL; - __regfree (&re_comp_buf); - memset (&re_comp_buf, '\0', sizeof (re_comp_buf)); - re_comp_buf.fastmap = fastmap; - } - - if (re_comp_buf.fastmap == NULL) - { - re_comp_buf.fastmap = (char *) malloc (SBC_MAX); - if (re_comp_buf.fastmap == NULL) - return (char *) gettext (__re_error_msgid - + __re_error_msgid_idx[(int) REG_ESPACE]); - } - - /* Since 're_exec' always passes NULL for the 'regs' argument, we - don't need to initialize the pattern buffer fields which affect it. */ - - /* Match anchors at newlines. */ - re_comp_buf.newline_anchor = 1; - - ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options); - - if (!ret) - return NULL; - - /* Yes, we're discarding 'const' here if !HAVE_LIBINTL. */ - return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); -} - -#ifdef _LIBC -libc_freeres_fn (free_mem) -{ - __regfree (&re_comp_buf); -} -#endif - -#endif /* _REGEX_RE_COMP */ - -/* Internal entry point. - Compile the regular expression PATTERN, whose length is LENGTH. - SYNTAX indicate regular expression's syntax. */ - -static reg_errcode_t -re_compile_internal (regex_t *preg, const char * pattern, size_t length, - reg_syntax_t syntax) -{ - reg_errcode_t err = REG_NOERROR; - re_dfa_t *dfa; - re_string_t regexp; - - /* Initialize the pattern buffer. */ - preg->fastmap_accurate = 0; - preg->syntax = syntax; - preg->not_bol = preg->not_eol = 0; - preg->used = 0; - preg->re_nsub = 0; - preg->can_be_null = 0; - preg->regs_allocated = REGS_UNALLOCATED; - - /* Initialize the dfa. */ - dfa = preg->buffer; - if (BE (preg->allocated < sizeof (re_dfa_t), 0)) - { - /* If zero allocated, but buffer is non-null, try to realloc - enough space. This loses if buffer's address is bogus, but - that is the user's responsibility. If ->buffer is NULL this - is a simple allocation. */ - dfa = re_realloc (preg->buffer, re_dfa_t, 1); - if (dfa == NULL) - return REG_ESPACE; - preg->allocated = sizeof (re_dfa_t); - preg->buffer = dfa; - } - preg->used = sizeof (re_dfa_t); - - err = init_dfa (dfa, length); - if (BE (err != REG_NOERROR, 0)) - { - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - return err; - } -#ifdef DEBUG - /* Note: length+1 will not overflow since it is checked in init_dfa. */ - dfa->re_str = re_malloc (char, length + 1); - strncpy (dfa->re_str, pattern, length + 1); -#endif - - __libc_lock_init (dfa->lock); - - err = re_string_construct (®exp, pattern, length, preg->translate, - (syntax & RE_ICASE) != 0, dfa); - if (BE (err != REG_NOERROR, 0)) - { - re_compile_internal_free_return: - free_workarea_compile (preg); - re_string_destruct (®exp); - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - return err; - } - - /* Parse the regular expression, and build a structure tree. */ - preg->re_nsub = 0; - dfa->str_tree = parse (®exp, preg, syntax, &err); - if (BE (dfa->str_tree == NULL, 0)) - goto re_compile_internal_free_return; - - /* Analyze the tree and create the nfa. */ - err = analyze (preg); - if (BE (err != REG_NOERROR, 0)) - goto re_compile_internal_free_return; - -#ifdef RE_ENABLE_I18N - /* If possible, do searching in single byte encoding to speed things up. */ - if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL) - optimize_utf8 (dfa); -#endif - - /* Then create the initial state of the dfa. */ - err = create_initial_state (dfa); - - /* Release work areas. */ - free_workarea_compile (preg); - re_string_destruct (®exp); - - if (BE (err != REG_NOERROR, 0)) - { - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - } - - return err; -} - -/* Initialize DFA. We use the length of the regular expression PAT_LEN - as the initial length of some arrays. */ - -static reg_errcode_t -init_dfa (re_dfa_t *dfa, size_t pat_len) -{ - __re_size_t table_size; -#ifndef _LIBC - const char *codeset_name; -#endif -#ifdef RE_ENABLE_I18N - size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); -#else - size_t max_i18n_object_size = 0; -#endif - size_t max_object_size = - MAX (sizeof (struct re_state_table_entry), - MAX (sizeof (re_token_t), - MAX (sizeof (re_node_set), - MAX (sizeof (regmatch_t), - max_i18n_object_size)))); - - memset (dfa, '\0', sizeof (re_dfa_t)); - - /* Force allocation of str_tree_storage the first time. */ - dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; - - /* Avoid overflows. The extra "/ 2" is for the table_size doubling - calculation below, and for similar doubling calculations - elsewhere. And it's <= rather than <, because some of the - doubling calculations add 1 afterwards. */ - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2 <= pat_len, 0)) - return REG_ESPACE; - - dfa->nodes_alloc = pat_len + 1; - dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc); - - /* table_size = 2 ^ ceil(log pat_len) */ - for (table_size = 1; ; table_size <<= 1) - if (table_size > pat_len) - break; - - dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); - dfa->state_hash_mask = table_size - 1; - - dfa->mb_cur_max = MB_CUR_MAX; -#ifdef _LIBC - if (dfa->mb_cur_max == 6 - && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0) - dfa->is_utf8 = 1; - dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII) - != 0); -#else - codeset_name = nl_langinfo (CODESET); - if ((codeset_name[0] == 'U' || codeset_name[0] == 'u') - && (codeset_name[1] == 'T' || codeset_name[1] == 't') - && (codeset_name[2] == 'F' || codeset_name[2] == 'f') - && strcmp (codeset_name + 3 + (codeset_name[3] == '-'), "8") == 0) - dfa->is_utf8 = 1; - - /* We check exhaustively in the loop below if this charset is a - superset of ASCII. */ - dfa->map_notascii = 0; -#endif - -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - if (dfa->is_utf8) - dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map; - else - { - int i, j, ch; - - dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); - if (BE (dfa->sb_char == NULL, 0)) - return REG_ESPACE; - - /* Set the bits corresponding to single byte chars. */ - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - { - wint_t wch = __btowc (ch); - if (wch != WEOF) - dfa->sb_char[i] |= (bitset_word_t) 1 << j; -# ifndef _LIBC - if (isascii (ch) && wch != ch) - dfa->map_notascii = 1; -# endif - } - } - } -#endif - - if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0)) - return REG_ESPACE; - return REG_NOERROR; -} - -/* Initialize WORD_CHAR table, which indicate which character is - "word". In this case "word" means that it is the word construction - character used by some operators like "\<", "\>", etc. */ - -static void -internal_function -init_word_char (re_dfa_t *dfa) -{ - int i = 0; - int j; - int ch = 0; - dfa->word_ops_used = 1; - if (BE (dfa->map_notascii == 0, 1)) - { - bitset_word_t bits0 = 0x00000000; - bitset_word_t bits1 = 0x03ff0000; - bitset_word_t bits2 = 0x87fffffe; - bitset_word_t bits3 = 0x07fffffe; - if (BITSET_WORD_BITS == 64) - { - dfa->word_char[0] = bits1 << 31 << 1 | bits0; - dfa->word_char[1] = bits3 << 31 << 1 | bits2; - i = 2; - } - else if (BITSET_WORD_BITS == 32) - { - dfa->word_char[0] = bits0; - dfa->word_char[1] = bits1; - dfa->word_char[2] = bits2; - dfa->word_char[3] = bits3; - i = 4; - } - else - goto general_case; - ch = 128; - - if (BE (dfa->is_utf8, 1)) - { - memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8); - return; - } - } - - general_case: - for (; i < BITSET_WORDS; ++i) - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - if (isalnum (ch) || ch == '_') - dfa->word_char[i] |= (bitset_word_t) 1 << j; -} - -/* Free the work area which are only used while compiling. */ - -static void -free_workarea_compile (regex_t *preg) -{ - re_dfa_t *dfa = preg->buffer; - bin_tree_storage_t *storage, *next; - for (storage = dfa->str_tree_storage; storage; storage = next) - { - next = storage->next; - re_free (storage); - } - dfa->str_tree_storage = NULL; - dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; - dfa->str_tree = NULL; - re_free (dfa->org_indices); - dfa->org_indices = NULL; -} - -/* Create initial states for all contexts. */ - -static reg_errcode_t -create_initial_state (re_dfa_t *dfa) -{ - Idx first, i; - reg_errcode_t err; - re_node_set init_nodes; - - /* Initial states have the epsilon closure of the node which is - the first node of the regular expression. */ - first = dfa->str_tree->first->node_idx; - dfa->init_node = first; - err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* The back-references which are in initial states can epsilon transit, - since in this case all of the subexpressions can be null. - Then we add epsilon closures of the nodes which are the next nodes of - the back-references. */ - if (dfa->nbackref > 0) - for (i = 0; i < init_nodes.nelem; ++i) - { - Idx node_idx = init_nodes.elems[i]; - re_token_type_t type = dfa->nodes[node_idx].type; - - Idx clexp_idx; - if (type != OP_BACK_REF) - continue; - for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx) - { - re_token_t *clexp_node; - clexp_node = dfa->nodes + init_nodes.elems[clexp_idx]; - if (clexp_node->type == OP_CLOSE_SUBEXP - && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx) - break; - } - if (clexp_idx == init_nodes.nelem) - continue; - - if (type == OP_BACK_REF) - { - Idx dest_idx = dfa->edests[node_idx].elems[0]; - if (!re_node_set_contains (&init_nodes, dest_idx)) - { - reg_errcode_t merge_err - = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); - if (merge_err != REG_NOERROR) - return merge_err; - i = 0; - } - } - } - - /* It must be the first time to invoke acquire_state. */ - dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); - /* We don't check ERR here, since the initial state must not be NULL. */ - if (BE (dfa->init_state == NULL, 0)) - return err; - if (dfa->init_state->has_constraint) - { - dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, - CONTEXT_WORD); - dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes, - CONTEXT_NEWLINE); - dfa->init_state_begbuf = re_acquire_state_context (&err, dfa, - &init_nodes, - CONTEXT_NEWLINE - | CONTEXT_BEGBUF); - if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) - return err; - } - else - dfa->init_state_word = dfa->init_state_nl - = dfa->init_state_begbuf = dfa->init_state; - - re_node_set_free (&init_nodes); - return REG_NOERROR; -} - -#ifdef RE_ENABLE_I18N -/* If it is possible to do searching in single byte encoding instead of UTF-8 - to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change - DFA nodes where needed. */ - -static void -optimize_utf8 (re_dfa_t *dfa) -{ - Idx node; - int i; - bool mb_chars = false; - bool has_period = false; - - for (node = 0; node < dfa->nodes_len; ++node) - switch (dfa->nodes[node].type) - { - case CHARACTER: - if (dfa->nodes[node].opr.c >= ASCII_CHARS) - mb_chars = true; - break; - case ANCHOR: - switch (dfa->nodes[node].opr.ctx_type) - { - case LINE_FIRST: - case LINE_LAST: - case BUF_FIRST: - case BUF_LAST: - break; - default: - /* Word anchors etc. cannot be handled. It's okay to test - opr.ctx_type since constraints (for all DFA nodes) are - created by ORing one or more opr.ctx_type values. */ - return; - } - break; - case OP_PERIOD: - has_period = true; - break; - case OP_BACK_REF: - case OP_ALT: - case END_OF_RE: - case OP_DUP_ASTERISK: - case OP_OPEN_SUBEXP: - case OP_CLOSE_SUBEXP: - break; - case COMPLEX_BRACKET: - return; - case SIMPLE_BRACKET: - /* Just double check. */ - { - int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0 - ? 0 - : BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS); - for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i) - { - if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0) - return; - rshift = 0; - } - } - break; - default: - break; - } - - if (mb_chars || has_period) - for (node = 0; node < dfa->nodes_len; ++node) - { - if (dfa->nodes[node].type == CHARACTER - && dfa->nodes[node].opr.c >= ASCII_CHARS) - dfa->nodes[node].mb_partial = 0; - else if (dfa->nodes[node].type == OP_PERIOD) - dfa->nodes[node].type = OP_UTF8_PERIOD; - } - - /* The search can be in single byte locale. */ - dfa->mb_cur_max = 1; - dfa->is_utf8 = 0; - dfa->has_mb_node = dfa->nbackref > 0 || has_period; -} -#endif - -/* Analyze the structure tree, and calculate "first", "next", "edest", - "eclosure", and "inveclosure". */ - -static reg_errcode_t -analyze (regex_t *preg) -{ - re_dfa_t *dfa = preg->buffer; - reg_errcode_t ret; - - /* Allocate arrays. */ - dfa->nexts = re_malloc (Idx, dfa->nodes_alloc); - dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc); - dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc); - dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc); - if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL - || dfa->eclosures == NULL, 0)) - return REG_ESPACE; - - dfa->subexp_map = re_malloc (Idx, preg->re_nsub); - if (dfa->subexp_map != NULL) - { - Idx i; - for (i = 0; i < preg->re_nsub; i++) - dfa->subexp_map[i] = i; - preorder (dfa->str_tree, optimize_subexps, dfa); - for (i = 0; i < preg->re_nsub; i++) - if (dfa->subexp_map[i] != i) - break; - if (i == preg->re_nsub) - { - free (dfa->subexp_map); - dfa->subexp_map = NULL; - } - } - - ret = postorder (dfa->str_tree, lower_subexps, preg); - if (BE (ret != REG_NOERROR, 0)) - return ret; - ret = postorder (dfa->str_tree, calc_first, dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - preorder (dfa->str_tree, calc_next, dfa); - ret = preorder (dfa->str_tree, link_nfa_nodes, dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - ret = calc_eclosure (dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - /* We only need this during the prune_impossible_nodes pass in regexec.c; - skip it if p_i_n will not run, as calc_inveclosure can be quadratic. */ - if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match) - || dfa->nbackref) - { - dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); - if (BE (dfa->inveclosures == NULL, 0)) - return REG_ESPACE; - ret = calc_inveclosure (dfa); - } - - return ret; -} - -/* Our parse trees are very unbalanced, so we cannot use a stack to - implement parse tree visits. Instead, we use parent pointers and - some hairy code in these two functions. */ -static reg_errcode_t -postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra) -{ - bin_tree_t *node, *prev; - - for (node = root; ; ) - { - /* Descend down the tree, preferably to the left (or to the right - if that's the only child). */ - while (node->left || node->right) - if (node->left) - node = node->left; - else - node = node->right; - - do - { - reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) - return err; - if (node->parent == NULL) - return REG_NOERROR; - prev = node; - node = node->parent; - } - /* Go up while we have a node that is reached from the right. */ - while (node->right == prev || node->right == NULL); - node = node->right; - } -} - -static reg_errcode_t -preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra) -{ - bin_tree_t *node; - - for (node = root; ; ) - { - reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* Go to the left node, or up and to the right. */ - if (node->left) - node = node->left; - else - { - bin_tree_t *prev = NULL; - while (node->right == prev || node->right == NULL) - { - prev = node; - node = node->parent; - if (!node) - return REG_NOERROR; - } - node = node->right; - } - } -} - -/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell - re_search_internal to map the inner one's opr.idx to this one's. Adjust - backreferences as well. Requires a preorder visit. */ -static reg_errcode_t -optimize_subexps (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - - if (node->token.type == OP_BACK_REF && dfa->subexp_map) - { - int idx = node->token.opr.idx; - node->token.opr.idx = dfa->subexp_map[idx]; - dfa->used_bkref_map |= 1 << node->token.opr.idx; - } - - else if (node->token.type == SUBEXP - && node->left && node->left->token.type == SUBEXP) - { - Idx other_idx = node->left->token.opr.idx; - - node->left = node->left->left; - if (node->left) - node->left->parent = node; - - dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx]; - if (other_idx < BITSET_WORD_BITS) - dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx); - } - - return REG_NOERROR; -} - -/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation - of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP. */ -static reg_errcode_t -lower_subexps (void *extra, bin_tree_t *node) -{ - regex_t *preg = (regex_t *) extra; - reg_errcode_t err = REG_NOERROR; - - if (node->left && node->left->token.type == SUBEXP) - { - node->left = lower_subexp (&err, preg, node->left); - if (node->left) - node->left->parent = node; - } - if (node->right && node->right->token.type == SUBEXP) - { - node->right = lower_subexp (&err, preg, node->right); - if (node->right) - node->right->parent = node; - } - - return err; -} - -static bin_tree_t * -lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node) -{ - re_dfa_t *dfa = preg->buffer; - bin_tree_t *body = node->left; - bin_tree_t *op, *cls, *tree1, *tree; - - if (preg->no_sub - /* We do not optimize empty subexpressions, because otherwise we may - have bad CONCAT nodes with NULL children. This is obviously not - very common, so we do not lose much. An example that triggers - this case is the sed "script" /\(\)/x. */ - && node->left != NULL - && (node->token.opr.idx >= BITSET_WORD_BITS - || !(dfa->used_bkref_map - & ((bitset_word_t) 1 << node->token.opr.idx)))) - return node->left; - - /* Convert the SUBEXP node to the concatenation of an - OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP. */ - op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP); - cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP); - tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls; - tree = create_tree (dfa, op, tree1, CONCAT); - if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - - op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx; - op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp; - return tree; -} - -/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton - nodes. Requires a postorder visit. */ -static reg_errcode_t -calc_first (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - if (node->token.type == CONCAT) - { - node->first = node->left->first; - node->node_idx = node->left->node_idx; - } - else - { - node->first = node; - node->node_idx = re_dfa_add_node (dfa, node->token); - if (BE (node->node_idx == REG_MISSING, 0)) - return REG_ESPACE; - if (node->token.type == ANCHOR) - dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type; - } - return REG_NOERROR; -} - -/* Pass 2: compute NEXT on the tree. Preorder visit. */ -static reg_errcode_t -calc_next (void *extra, bin_tree_t *node) -{ - switch (node->token.type) - { - case OP_DUP_ASTERISK: - node->left->next = node; - break; - case CONCAT: - node->left->next = node->right->first; - node->right->next = node->next; - break; - default: - if (node->left) - node->left->next = node->next; - if (node->right) - node->right->next = node->next; - break; - } - return REG_NOERROR; -} - -/* Pass 3: link all DFA nodes to their NEXT node (any order will do). */ -static reg_errcode_t -link_nfa_nodes (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - Idx idx = node->node_idx; - reg_errcode_t err = REG_NOERROR; - - switch (node->token.type) - { - case CONCAT: - break; - - case END_OF_RE: - assert (node->next == NULL); - break; - - case OP_DUP_ASTERISK: - case OP_ALT: - { - Idx left, right; - dfa->has_plural_match = 1; - if (node->left != NULL) - left = node->left->first->node_idx; - else - left = node->next->node_idx; - if (node->right != NULL) - right = node->right->first->node_idx; - else - right = node->next->node_idx; - assert (REG_VALID_INDEX (left)); - assert (REG_VALID_INDEX (right)); - err = re_node_set_init_2 (dfa->edests + idx, left, right); - } - break; - - case ANCHOR: - case OP_OPEN_SUBEXP: - case OP_CLOSE_SUBEXP: - err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx); - break; - - case OP_BACK_REF: - dfa->nexts[idx] = node->next->node_idx; - if (node->token.type == OP_BACK_REF) - err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); - break; - - default: - assert (!IS_EPSILON_NODE (node->token.type)); - dfa->nexts[idx] = node->next->node_idx; - break; - } - - return err; -} - -/* Duplicate the epsilon closure of the node ROOT_NODE. - Note that duplicated nodes have constraint INIT_CONSTRAINT in addition - to their own constraint. */ - -static reg_errcode_t -internal_function -duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, - Idx root_node, unsigned int init_constraint) -{ - Idx org_node, clone_node; - bool ok; - unsigned int constraint = init_constraint; - for (org_node = top_org_node, clone_node = top_clone_node;;) - { - Idx org_dest, clone_dest; - if (dfa->nodes[org_node].type == OP_BACK_REF) - { - /* If the back reference epsilon-transit, its destination must - also have the constraint. Then duplicate the epsilon closure - of the destination of the back reference, and store it in - edests of the back reference. */ - org_dest = dfa->nexts[org_node]; - re_node_set_empty (dfa->edests + clone_node); - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - dfa->nexts[clone_node] = dfa->nexts[org_node]; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - else if (dfa->edests[org_node].nelem == 0) - { - /* In case of the node can't epsilon-transit, don't duplicate the - destination and store the original destination as the - destination of the node. */ - dfa->nexts[clone_node] = dfa->nexts[org_node]; - break; - } - else if (dfa->edests[org_node].nelem == 1) - { - /* In case of the node can epsilon-transit, and it has only one - destination. */ - org_dest = dfa->edests[org_node].elems[0]; - re_node_set_empty (dfa->edests + clone_node); - /* If the node is root_node itself, it means the epsilon closure - has a loop. Then tie it to the destination of the root_node. */ - if (org_node == root_node && clone_node != org_node) - { - ok = re_node_set_insert (dfa->edests + clone_node, org_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - break; - } - /* In case the node has another constraint, append it. */ - constraint |= dfa->nodes[org_node].constraint; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - else /* dfa->edests[org_node].nelem == 2 */ - { - /* In case of the node can epsilon-transit, and it has two - destinations. In the bin_tree_t and DFA, that's '|' and '*'. */ - org_dest = dfa->edests[org_node].elems[0]; - re_node_set_empty (dfa->edests + clone_node); - /* Search for a duplicated node which satisfies the constraint. */ - clone_dest = search_duplicated_node (dfa, org_dest, constraint); - if (clone_dest == REG_MISSING) - { - /* There is no such duplicated node, create a new one. */ - reg_errcode_t err; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - err = duplicate_node_closure (dfa, org_dest, clone_dest, - root_node, constraint); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - { - /* There is a duplicated node which satisfies the constraint, - use it to avoid infinite loop. */ - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - - org_dest = dfa->edests[org_node].elems[1]; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == REG_MISSING, 0)) - return REG_ESPACE; - ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (! ok, 0)) - return REG_ESPACE; - } - org_node = org_dest; - clone_node = clone_dest; - } - return REG_NOERROR; -} - -/* Search for a node which is duplicated from the node ORG_NODE, and - satisfies the constraint CONSTRAINT. */ - -static Idx -search_duplicated_node (const re_dfa_t *dfa, Idx org_node, - unsigned int constraint) -{ - Idx idx; - for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx) - { - if (org_node == dfa->org_indices[idx] - && constraint == dfa->nodes[idx].constraint) - return idx; /* Found. */ - } - return REG_MISSING; /* Not found. */ -} - -/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT. - Return the index of the new node, or REG_MISSING if insufficient storage is - available. */ - -static Idx -duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint) -{ - Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]); - if (BE (dup_idx != REG_MISSING, 1)) - { - dfa->nodes[dup_idx].constraint = constraint; - dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint; - dfa->nodes[dup_idx].duplicated = 1; - - /* Store the index of the original node. */ - dfa->org_indices[dup_idx] = org_idx; - } - return dup_idx; -} - -static reg_errcode_t -calc_inveclosure (re_dfa_t *dfa) -{ - Idx src, idx; - bool ok; - for (idx = 0; idx < dfa->nodes_len; ++idx) - re_node_set_init_empty (dfa->inveclosures + idx); - - for (src = 0; src < dfa->nodes_len; ++src) - { - Idx *elems = dfa->eclosures[src].elems; - for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) - { - ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); - if (BE (! ok, 0)) - return REG_ESPACE; - } - } - - return REG_NOERROR; -} - -/* Calculate "eclosure" for all the node in DFA. */ - -static reg_errcode_t -calc_eclosure (re_dfa_t *dfa) -{ - Idx node_idx; - bool incomplete; -#ifdef DEBUG - assert (dfa->nodes_len > 0); -#endif - incomplete = false; - /* For each nodes, calculate epsilon closure. */ - for (node_idx = 0; ; ++node_idx) - { - reg_errcode_t err; - re_node_set eclosure_elem; - if (node_idx == dfa->nodes_len) - { - if (!incomplete) - break; - incomplete = false; - node_idx = 0; - } - -#ifdef DEBUG - assert (dfa->eclosures[node_idx].nelem != REG_MISSING); -#endif - - /* If we have already calculated, skip it. */ - if (dfa->eclosures[node_idx].nelem != 0) - continue; - /* Calculate epsilon closure of 'node_idx'. */ - err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (dfa->eclosures[node_idx].nelem == 0) - { - incomplete = true; - re_node_set_free (&eclosure_elem); - } - } - return REG_NOERROR; -} - -/* Calculate epsilon closure of NODE. */ - -static reg_errcode_t -calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) -{ - reg_errcode_t err; - Idx i; - re_node_set eclosure; - bool ok; - bool incomplete = false; - err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* This indicates that we are calculating this node now. - We reference this value to avoid infinite loop. */ - dfa->eclosures[node].nelem = REG_MISSING; - - /* If the current node has constraints, duplicate all nodes - since they must inherit the constraints. */ - if (dfa->nodes[node].constraint - && dfa->edests[node].nelem - && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) - { - err = duplicate_node_closure (dfa, node, node, node, - dfa->nodes[node].constraint); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - /* Expand each epsilon destination nodes. */ - if (IS_EPSILON_NODE(dfa->nodes[node].type)) - for (i = 0; i < dfa->edests[node].nelem; ++i) - { - re_node_set eclosure_elem; - Idx edest = dfa->edests[node].elems[i]; - /* If calculating the epsilon closure of 'edest' is in progress, - return intermediate result. */ - if (dfa->eclosures[edest].nelem == REG_MISSING) - { - incomplete = true; - continue; - } - /* If we haven't calculated the epsilon closure of 'edest' yet, - calculate now. Otherwise use calculated epsilon closure. */ - if (dfa->eclosures[edest].nelem == 0) - { - err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - eclosure_elem = dfa->eclosures[edest]; - /* Merge the epsilon closure of 'edest'. */ - err = re_node_set_merge (&eclosure, &eclosure_elem); - if (BE (err != REG_NOERROR, 0)) - return err; - /* If the epsilon closure of 'edest' is incomplete, - the epsilon closure of this node is also incomplete. */ - if (dfa->eclosures[edest].nelem == 0) - { - incomplete = true; - re_node_set_free (&eclosure_elem); - } - } - - /* An epsilon closure includes itself. */ - ok = re_node_set_insert (&eclosure, node); - if (BE (! ok, 0)) - return REG_ESPACE; - if (incomplete && !root) - dfa->eclosures[node].nelem = 0; - else - dfa->eclosures[node] = eclosure; - *new_set = eclosure; - return REG_NOERROR; -} - -/* Functions for token which are used in the parser. */ - -/* Fetch a token from INPUT. - We must not use this function inside bracket expressions. */ - -static void -internal_function -fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) -{ - re_string_skip_bytes (input, peek_token (result, input, syntax)); -} - -/* Peek a token from INPUT, and return the length of the token. - We must not use this function inside bracket expressions. */ - -static int -internal_function -peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) -{ - unsigned char c; - - if (re_string_eoi (input)) - { - token->type = END_OF_RE; - return 0; - } - - c = re_string_peek_byte (input, 0); - token->opr.c = c; - - token->word_char = 0; -#ifdef RE_ENABLE_I18N - token->mb_partial = 0; - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) - { - token->type = CHARACTER; - token->mb_partial = 1; - return 1; - } -#endif - if (c == '\\') - { - unsigned char c2; - if (re_string_cur_idx (input) + 1 >= re_string_length (input)) - { - token->type = BACK_SLASH; - return 1; - } - - c2 = re_string_peek_byte_case (input, 1); - token->opr.c = c2; - token->type = CHARACTER; -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc = re_string_wchar_at (input, - re_string_cur_idx (input) + 1); - token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; - } - else -#endif - token->word_char = IS_WORD_CHAR (c2) != 0; - - switch (c2) - { - case '|': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR)) - token->type = OP_ALT; - break; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - if (!(syntax & RE_NO_BK_REFS)) - { - token->type = OP_BACK_REF; - token->opr.idx = c2 - '1'; - } - break; - case '<': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_FIRST; - } - break; - case '>': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_LAST; - } - break; - case 'b': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_DELIM; - } - break; - case 'B': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = NOT_WORD_DELIM; - } - break; - case 'w': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_WORD; - break; - case 'W': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_NOTWORD; - break; - case 's': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_SPACE; - break; - case 'S': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_NOTSPACE; - break; - case '`': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = BUF_FIRST; - } - break; - case '\'': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = BUF_LAST; - } - break; - case '(': - if (!(syntax & RE_NO_BK_PARENS)) - token->type = OP_OPEN_SUBEXP; - break; - case ')': - if (!(syntax & RE_NO_BK_PARENS)) - token->type = OP_CLOSE_SUBEXP; - break; - case '+': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_PLUS; - break; - case '?': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_QUESTION; - break; - case '{': - if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) - token->type = OP_OPEN_DUP_NUM; - break; - case '}': - if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) - token->type = OP_CLOSE_DUP_NUM; - break; - default: - break; - } - return 2; - } - - token->type = CHARACTER; -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input)); - token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; - } - else -#endif - token->word_char = IS_WORD_CHAR (token->opr.c); - - switch (c) - { - case '\n': - if (syntax & RE_NEWLINE_ALT) - token->type = OP_ALT; - break; - case '|': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR)) - token->type = OP_ALT; - break; - case '*': - token->type = OP_DUP_ASTERISK; - break; - case '+': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_PLUS; - break; - case '?': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_QUESTION; - break; - case '{': - if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - token->type = OP_OPEN_DUP_NUM; - break; - case '}': - if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - token->type = OP_CLOSE_DUP_NUM; - break; - case '(': - if (syntax & RE_NO_BK_PARENS) - token->type = OP_OPEN_SUBEXP; - break; - case ')': - if (syntax & RE_NO_BK_PARENS) - token->type = OP_CLOSE_SUBEXP; - break; - case '[': - token->type = OP_OPEN_BRACKET; - break; - case '.': - token->type = OP_PERIOD; - break; - case '^': - if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) && - re_string_cur_idx (input) != 0) - { - char prev = re_string_peek_byte (input, -1); - if (!(syntax & RE_NEWLINE_ALT) || prev != '\n') - break; - } - token->type = ANCHOR; - token->opr.ctx_type = LINE_FIRST; - break; - case '$': - if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) && - re_string_cur_idx (input) + 1 != re_string_length (input)) - { - re_token_t next; - re_string_skip_bytes (input, 1); - peek_token (&next, input, syntax); - re_string_skip_bytes (input, -1); - if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP) - break; - } - token->type = ANCHOR; - token->opr.ctx_type = LINE_LAST; - break; - default: - break; - } - return 1; -} - -/* Peek a token from INPUT, and return the length of the token. - We must not use this function out of bracket expressions. */ - -static int -internal_function -peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) -{ - unsigned char c; - if (re_string_eoi (input)) - { - token->type = END_OF_RE; - return 0; - } - c = re_string_peek_byte (input, 0); - token->opr.c = c; - -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) - { - token->type = CHARACTER; - return 1; - } -#endif /* RE_ENABLE_I18N */ - - if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) - && re_string_cur_idx (input) + 1 < re_string_length (input)) - { - /* In this case, '\' escape a character. */ - unsigned char c2; - re_string_skip_bytes (input, 1); - c2 = re_string_peek_byte (input, 0); - token->opr.c = c2; - token->type = CHARACTER; - return 1; - } - if (c == '[') /* '[' is a special char in a bracket exps. */ - { - unsigned char c2; - int token_len; - if (re_string_cur_idx (input) + 1 < re_string_length (input)) - c2 = re_string_peek_byte (input, 1); - else - c2 = 0; - token->opr.c = c2; - token_len = 2; - switch (c2) - { - case '.': - token->type = OP_OPEN_COLL_ELEM; - break; - case '=': - token->type = OP_OPEN_EQUIV_CLASS; - break; - case ':': - if (syntax & RE_CHAR_CLASSES) - { - token->type = OP_OPEN_CHAR_CLASS; - break; - } - /* else fall through. */ - default: - token->type = CHARACTER; - token->opr.c = c; - token_len = 1; - break; - } - return token_len; - } - switch (c) - { - case '-': - token->type = OP_CHARSET_RANGE; - break; - case ']': - token->type = OP_CLOSE_BRACKET; - break; - case '^': - token->type = OP_NON_MATCH_LIST; - break; - default: - token->type = CHARACTER; - } - return 1; -} - -/* Functions for parser. */ - -/* Entry point of the parser. - Parse the regular expression REGEXP and return the structure tree. - If an error occurs, ERR is set by error code, and return NULL. - This function build the following tree, from regular expression : - CAT - / \ - / \ - EOR - - CAT means concatenation. - EOR means end of regular expression. */ - -static bin_tree_t * -parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, - reg_errcode_t *err) -{ - re_dfa_t *dfa = preg->buffer; - bin_tree_t *tree, *eor, *root; - re_token_t current_token; - dfa->syntax = syntax; - fetch_token (¤t_token, regexp, syntax | RE_CARET_ANCHORS_HERE); - tree = parse_reg_exp (regexp, preg, ¤t_token, syntax, 0, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - eor = create_tree (dfa, NULL, NULL, END_OF_RE); - if (tree != NULL) - root = create_tree (dfa, tree, eor, CONCAT); - else - root = eor; - if (BE (eor == NULL || root == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - return root; -} - -/* This function build the following tree, from regular expression - |: - ALT - / \ - / \ - - - ALT means alternative, which represents the operator '|'. */ - -static bin_tree_t * -parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = preg->buffer; - bin_tree_t *tree, *branch = NULL; - tree = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - - while (token->type == OP_ALT) - { - fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); - if (token->type != OP_ALT && token->type != END_OF_RE - && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) - { - branch = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && branch == NULL, 0)) - return NULL; - } - else - branch = NULL; - tree = create_tree (dfa, tree, branch, OP_ALT); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - return tree; -} - -/* This function build the following tree, from regular expression - : - CAT - / \ - / \ - - - CAT means concatenation. */ - -static bin_tree_t * -parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - bin_tree_t *tree, *expr; - re_dfa_t *dfa = preg->buffer; - tree = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - - while (token->type != OP_ALT && token->type != END_OF_RE - && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) - { - expr = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && expr == NULL, 0)) - { - if (tree != NULL) - postorder (tree, free_tree, NULL); - return NULL; - } - if (tree != NULL && expr != NULL) - { - bin_tree_t *newtree = create_tree (dfa, tree, expr, CONCAT); - if (newtree == NULL) - { - postorder (expr, free_tree, NULL); - postorder (tree, free_tree, NULL); - *err = REG_ESPACE; - return NULL; - } - tree = newtree; - } - else if (tree == NULL) - tree = expr; - /* Otherwise expr == NULL, we don't need to create new tree. */ - } - return tree; -} - -/* This function build the following tree, from regular expression a*: - * - | - a -*/ - -static bin_tree_t * -parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = preg->buffer; - bin_tree_t *tree; - switch (token->type) - { - case CHARACTER: - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - while (!re_string_eoi (regexp) - && !re_string_first_byte (regexp, re_string_cur_idx (regexp))) - { - bin_tree_t *mbc_remain; - fetch_token (token, regexp, syntax); - mbc_remain = create_token_tree (dfa, NULL, NULL, token); - tree = create_tree (dfa, tree, mbc_remain, CONCAT); - if (BE (mbc_remain == NULL || tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - } -#endif - break; - case OP_OPEN_SUBEXP: - tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_OPEN_BRACKET: - tree = parse_bracket_exp (regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_BACK_REF: - if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1)) - { - *err = REG_ESUBREG; - return NULL; - } - dfa->used_bkref_map |= 1 << token->opr.idx; - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - ++dfa->nbackref; - dfa->has_mb_node = 1; - break; - case OP_OPEN_DUP_NUM: - if (syntax & RE_CONTEXT_INVALID_DUP) - { - *err = REG_BADRPT; - return NULL; - } - /* FALLTHROUGH */ - case OP_DUP_ASTERISK: - case OP_DUP_PLUS: - case OP_DUP_QUESTION: - if (syntax & RE_CONTEXT_INVALID_OPS) - { - *err = REG_BADRPT; - return NULL; - } - else if (syntax & RE_CONTEXT_INDEP_OPS) - { - fetch_token (token, regexp, syntax); - return parse_expression (regexp, preg, token, syntax, nest, err); - } - /* else fall through */ - case OP_CLOSE_SUBEXP: - if ((token->type == OP_CLOSE_SUBEXP) && - !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) - { - *err = REG_ERPAREN; - return NULL; - } - /* else fall through */ - case OP_CLOSE_DUP_NUM: - /* We treat it as a normal character. */ - - /* Then we can these characters as normal characters. */ - token->type = CHARACTER; - /* mb_partial and word_char bits should be initialized already - by peek_token. */ - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - break; - case ANCHOR: - if ((token->opr.ctx_type - & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST)) - && dfa->word_ops_used == 0) - init_word_char (dfa); - if (token->opr.ctx_type == WORD_DELIM - || token->opr.ctx_type == NOT_WORD_DELIM) - { - bin_tree_t *tree_first, *tree_last; - if (token->opr.ctx_type == WORD_DELIM) - { - token->opr.ctx_type = WORD_FIRST; - tree_first = create_token_tree (dfa, NULL, NULL, token); - token->opr.ctx_type = WORD_LAST; - } - else - { - token->opr.ctx_type = INSIDE_WORD; - tree_first = create_token_tree (dfa, NULL, NULL, token); - token->opr.ctx_type = INSIDE_NOTWORD; - } - tree_last = create_token_tree (dfa, NULL, NULL, token); - tree = create_tree (dfa, tree_first, tree_last, OP_ALT); - if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - else - { - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - /* We must return here, since ANCHORs can't be followed - by repetition operators. - eg. RE"^*" is invalid or "", - it must not be "". */ - fetch_token (token, regexp, syntax); - return tree; - case OP_PERIOD: - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - if (dfa->mb_cur_max > 1) - dfa->has_mb_node = 1; - break; - case OP_WORD: - case OP_NOTWORD: - tree = build_charclass_op (dfa, regexp->trans, - "alnum", - "_", - token->type == OP_NOTWORD, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_SPACE: - case OP_NOTSPACE: - tree = build_charclass_op (dfa, regexp->trans, - "space", - "", - token->type == OP_NOTSPACE, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_ALT: - case END_OF_RE: - return NULL; - case BACK_SLASH: - *err = REG_EESCAPE; - return NULL; - default: - /* Must not happen? */ -#ifdef DEBUG - assert (0); -#endif - return NULL; - } - fetch_token (token, regexp, syntax); - - while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS - || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) - { - tree = parse_dup_op (tree, regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - /* In BRE consecutive duplications are not allowed. */ - if ((syntax & RE_CONTEXT_INVALID_DUP) - && (token->type == OP_DUP_ASTERISK - || token->type == OP_OPEN_DUP_NUM)) - { - *err = REG_BADRPT; - return NULL; - } - } - - return tree; -} - -/* This function build the following tree, from regular expression - (): - SUBEXP - | - -*/ - -static bin_tree_t * -parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, Idx nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = preg->buffer; - bin_tree_t *tree; - size_t cur_nsub; - cur_nsub = preg->re_nsub++; - - fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); - - /* The subexpression may be a null string. */ - if (token->type == OP_CLOSE_SUBEXP) - tree = NULL; - else - { - tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); - if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) - { - if (tree != NULL) - postorder (tree, free_tree, NULL); - *err = REG_EPAREN; - } - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } - - if (cur_nsub <= '9' - '1') - dfa->completed_bkref_map |= 1 << cur_nsub; - - tree = create_tree (dfa, tree, NULL, SUBEXP); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - tree->token.opr.idx = cur_nsub; - return tree; -} - -/* This function parse repetition operators like "*", "+", "{1,3}" etc. */ - -static bin_tree_t * -parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, - re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err) -{ - bin_tree_t *tree = NULL, *old_tree = NULL; - Idx i, start, end, start_idx = re_string_cur_idx (regexp); - re_token_t start_token = *token; - - if (token->type == OP_OPEN_DUP_NUM) - { - end = 0; - start = fetch_number (regexp, token, syntax); - if (start == REG_MISSING) - { - if (token->type == CHARACTER && token->opr.c == ',') - start = 0; /* We treat "{,m}" as "{0,m}". */ - else - { - *err = REG_BADBR; /* {} is invalid. */ - return NULL; - } - } - if (BE (start != REG_ERROR, 1)) - { - /* We treat "{n}" as "{n,n}". */ - end = ((token->type == OP_CLOSE_DUP_NUM) ? start - : ((token->type == CHARACTER && token->opr.c == ',') - ? fetch_number (regexp, token, syntax) : REG_ERROR)); - } - if (BE (start == REG_ERROR || end == REG_ERROR, 0)) - { - /* Invalid sequence. */ - if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0)) - { - if (token->type == END_OF_RE) - *err = REG_EBRACE; - else - *err = REG_BADBR; - - return NULL; - } - - /* If the syntax bit is set, rollback. */ - re_string_set_index (regexp, start_idx); - *token = start_token; - token->type = CHARACTER; - /* mb_partial and word_char bits should be already initialized by - peek_token. */ - return elem; - } - - if (BE ((end != REG_MISSING && start > end) - || token->type != OP_CLOSE_DUP_NUM, 0)) - { - /* First number greater than second. */ - *err = REG_BADBR; - return NULL; - } - - if (BE (RE_DUP_MAX < (end == REG_MISSING ? start : end), 0)) - { - *err = REG_ESIZE; - return NULL; - } - } - else - { - start = (token->type == OP_DUP_PLUS) ? 1 : 0; - end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING; - } - - fetch_token (token, regexp, syntax); - - if (BE (elem == NULL, 0)) - return NULL; - if (BE (start == 0 && end == 0, 0)) - { - postorder (elem, free_tree, NULL); - return NULL; - } - - /* Extract "{n,m}" to "...{0,}". */ - if (BE (start > 0, 0)) - { - tree = elem; - for (i = 2; i <= start; ++i) - { - elem = duplicate_tree (elem, dfa); - tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) - goto parse_dup_op_espace; - } - - if (start == end) - return tree; - - /* Duplicate ELEM before it is marked optional. */ - elem = duplicate_tree (elem, dfa); - old_tree = tree; - } - else - old_tree = NULL; - - if (elem->token.type == SUBEXP) - { - uintptr_t subidx = elem->token.opr.idx; - postorder (elem, mark_opt_subexp, (void *) subidx); - } - - tree = create_tree (dfa, elem, NULL, - (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT)); - if (BE (tree == NULL, 0)) - goto parse_dup_op_espace; - -/* From gnulib's "intprops.h": - True if the arithmetic type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - - /* This loop is actually executed only when end != REG_MISSING, - to rewrite {0,n} as ((...?)?)?... We have - already created the start+1-th copy. */ - if (TYPE_SIGNED (Idx) || end != REG_MISSING) - for (i = start + 2; i <= end; ++i) - { - elem = duplicate_tree (elem, dfa); - tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) - goto parse_dup_op_espace; - - tree = create_tree (dfa, tree, NULL, OP_ALT); - if (BE (tree == NULL, 0)) - goto parse_dup_op_espace; - } - - if (old_tree) - tree = create_tree (dfa, old_tree, tree, CONCAT); - - return tree; - - parse_dup_op_espace: - *err = REG_ESPACE; - return NULL; -} - -/* Size of the names for collating symbol/equivalence_class/character_class. - I'm not sure, but maybe enough. */ -#define BRACKET_NAME_BUF_SIZE 32 - -#ifndef _LIBC - /* Local function for parse_bracket_exp only used in case of NOT _LIBC. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument since we may - update it. */ - -static reg_errcode_t -internal_function -# ifdef RE_ENABLE_I18N -build_range_exp (const reg_syntax_t syntax, - bitset_t sbcset, - re_charset_t *mbcset, - Idx *range_alloc, - const bracket_elem_t *start_elem, - const bracket_elem_t *end_elem) -# else /* not RE_ENABLE_I18N */ -build_range_exp (const reg_syntax_t syntax, - bitset_t sbcset, - const bracket_elem_t *start_elem, - const bracket_elem_t *end_elem) -# endif /* not RE_ENABLE_I18N */ -{ - unsigned int start_ch, end_ch; - /* Equivalence Classes and Character Classes can't be a range start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) - return REG_ERANGE; - - /* We can handle no multi character collating elements without libc - support. */ - if (BE ((start_elem->type == COLL_SYM - && strlen ((char *) start_elem->opr.name) > 1) - || (end_elem->type == COLL_SYM - && strlen ((char *) end_elem->opr.name) > 1), 0)) - return REG_ECOLLATE; - -# ifdef RE_ENABLE_I18N - { - wchar_t wc; - wint_t start_wc; - wint_t end_wc; - - start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch - : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); - end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch - : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] - : 0)); - start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) - ? __btowc (start_ch) : start_elem->opr.wch); - end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) - ? __btowc (end_ch) : end_elem->opr.wch); - if (start_wc == WEOF || end_wc == WEOF) - return REG_ECOLLATE; - else if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_wc > end_wc, 0)) - return REG_ERANGE; - - /* Got valid collation sequence values, add them as a new entry. - However, for !_LIBC we have no collation elements: if the - character set is single byte, the single byte character set - that we build below suffices. parse_bracket_exp passes - no MBCSET if dfa->mb_cur_max == 1. */ - if (mbcset) - { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - wchar_t *new_array_start, *new_array_end; - Idx new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - /* Use realloc since mbcset->range_starts and mbcset->range_ends - are NULL if *range_alloc == 0. */ - new_array_start = re_realloc (mbcset->range_starts, wchar_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, wchar_t, - new_nranges); - - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; - - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } - - mbcset->range_starts[mbcset->nranges] = start_wc; - mbcset->range_ends[mbcset->nranges++] = end_wc; - } - - /* Build the table for single byte characters. */ - for (wc = 0; wc < SBC_MAX; ++wc) - { - if (start_wc <= wc && wc <= end_wc) - bitset_set (sbcset, wc); - } - } -# else /* not RE_ENABLE_I18N */ - { - unsigned int ch; - start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch - : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); - end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch - : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] - : 0)); - if (start_ch > end_ch) - return REG_ERANGE; - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ++ch) - if (start_ch <= ch && ch <= end_ch) - bitset_set (sbcset, ch); - } -# endif /* not RE_ENABLE_I18N */ - return REG_NOERROR; -} -#endif /* not _LIBC */ - -#ifndef _LIBC -/* Helper function for parse_bracket_exp only used in case of NOT _LIBC.. - Build the collating element which is represented by NAME. - The result are written to MBCSET and SBCSET. - COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a - pointer argument since we may update it. */ - -static reg_errcode_t -internal_function -# ifdef RE_ENABLE_I18N -build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, - Idx *coll_sym_alloc, const unsigned char *name) -# else /* not RE_ENABLE_I18N */ -build_collating_symbol (bitset_t sbcset, const unsigned char *name) -# endif /* not RE_ENABLE_I18N */ -{ - size_t name_len = strlen ((const char *) name); - if (BE (name_len != 1, 0)) - return REG_ECOLLATE; - else - { - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } -} -#endif /* not _LIBC */ - -/* This function parse bracket expression like "[abc]", "[a-c]", - "[[.a-a.]]" etc. */ - -static bin_tree_t * -parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, - reg_syntax_t syntax, reg_errcode_t *err) -{ -#ifdef _LIBC - const unsigned char *collseqmb; - const char *collseqwc; - uint32_t nrules; - int32_t table_size; - const int32_t *symb_table; - const unsigned char *extra; - - /* Local function for parse_bracket_exp used in _LIBC environment. - Seek the collating symbol entry corresponding to NAME. - Return the index of the symbol in the SYMB_TABLE, - or -1 if not found. */ - - auto inline int32_t - __attribute__ ((always_inline)) - seek_collating_symbol_entry (const unsigned char *name, size_t name_len) - { - int32_t elem; - - for (elem = 0; elem < table_size; elem++) - if (symb_table[2 * elem] != 0) - { - int32_t idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - if (/* Compare the length of the name. */ - name_len == extra[idx] - /* Compare the name. */ - && memcmp (name, &extra[idx + 1], name_len) == 0) - /* Yep, this is the entry. */ - return elem; - } - return -1; - } - - /* Local function for parse_bracket_exp used in _LIBC environment. - Look up the collation sequence value of BR_ELEM. - Return the value if succeeded, UINT_MAX otherwise. */ - - auto inline unsigned int - __attribute__ ((always_inline)) - lookup_collation_sequence_value (bracket_elem_t *br_elem) - { - if (br_elem->type == SB_CHAR) - { - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - return collseqmb[br_elem->opr.ch]; - else - { - wint_t wc = __btowc (br_elem->opr.ch); - return __collseq_table_lookup (collseqwc, wc); - } - } - else if (br_elem->type == MB_CHAR) - { - if (nrules != 0) - return __collseq_table_lookup (collseqwc, br_elem->opr.wch); - } - else if (br_elem->type == COLL_SYM) - { - size_t sym_name_len = strlen ((char *) br_elem->opr.name); - if (nrules != 0) - { - int32_t elem, idx; - elem = seek_collating_symbol_entry (br_elem->opr.name, - sym_name_len); - if (elem != -1) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - /* Skip the byte sequence of the collating element. */ - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - /* Skip the multibyte collation sequence value. */ - idx += sizeof (unsigned int); - /* Skip the wide char sequence of the collating element. */ - idx += sizeof (unsigned int) * - (1 + *(unsigned int *) (extra + idx)); - /* Return the collation sequence value. */ - return *(unsigned int *) (extra + idx); - } - else if (sym_name_len == 1) - { - /* No valid character. Match it as a single byte - character. */ - return collseqmb[br_elem->opr.name[0]]; - } - } - else if (sym_name_len == 1) - return collseqmb[br_elem->opr.name[0]]; - } - return UINT_MAX; - } - - /* Local function for parse_bracket_exp used in _LIBC environment. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument since we may - update it. */ - - auto inline reg_errcode_t - __attribute__ ((always_inline)) - build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc, - bracket_elem_t *start_elem, bracket_elem_t *end_elem) - { - unsigned int ch; - uint32_t start_collseq; - uint32_t end_collseq; - - /* Equivalence Classes and Character Classes can't be a range - start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) - return REG_ERANGE; - - /* FIXME: Implement rational ranges here, too. */ - start_collseq = lookup_collation_sequence_value (start_elem); - end_collseq = lookup_collation_sequence_value (end_elem); - /* Check start/end collation sequence values. */ - if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0)) - return REG_ECOLLATE; - if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0)) - return REG_ERANGE; - - /* Got valid collation sequence values, add them as a new entry. - However, if we have no collation elements, and the character set - is single byte, the single byte character set that we - build below suffices. */ - if (nrules > 0 || dfa->mb_cur_max > 1) - { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - uint32_t *new_array_start; - uint32_t *new_array_end; - Idx new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - new_array_start = re_realloc (mbcset->range_starts, uint32_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, uint32_t, - new_nranges); - - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; - - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } - - mbcset->range_starts[mbcset->nranges] = start_collseq; - mbcset->range_ends[mbcset->nranges++] = end_collseq; - } - - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ch++) - { - uint32_t ch_collseq; - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - ch_collseq = collseqmb[ch]; - else - ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); - if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) - bitset_set (sbcset, ch); - } - return REG_NOERROR; - } - - /* Local function for parse_bracket_exp used in _LIBC environment. - Build the collating element which is represented by NAME. - The result are written to MBCSET and SBCSET. - COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a - pointer argument since we may update it. */ - - auto inline reg_errcode_t - __attribute__ ((always_inline)) - build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, - Idx *coll_sym_alloc, const unsigned char *name) - { - int32_t elem, idx; - size_t name_len = strlen ((const char *) name); - if (nrules != 0) - { - elem = seek_collating_symbol_entry (name, name_len); - if (elem != -1) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - } - else if (name_len == 1) - { - /* No valid character, treat it as a normal - character. */ - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } - else - return REG_ECOLLATE; - - /* Got valid collation sequence, add it as a new entry. */ - /* Check the space of the arrays. */ - if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->ncoll_syms is 0. */ - Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; - /* Use realloc since mbcset->coll_syms is NULL - if *alloc == 0. */ - int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, - new_coll_sym_alloc); - if (BE (new_coll_syms == NULL, 0)) - return REG_ESPACE; - mbcset->coll_syms = new_coll_syms; - *coll_sym_alloc = new_coll_sym_alloc; - } - mbcset->coll_syms[mbcset->ncoll_syms++] = idx; - return REG_NOERROR; - } - else - { - if (BE (name_len != 1, 0)) - return REG_ECOLLATE; - else - { - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } - } - } -#endif - - re_token_t br_token; - re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; - Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; - Idx equiv_class_alloc = 0, char_class_alloc = 0; -#endif /* not RE_ENABLE_I18N */ - bool non_match = false; - bin_tree_t *work_tree; - int token_len; - bool first_round = true; -#ifdef _LIBC - collseqmb = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); - nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules) - { - /* - if (MB_CUR_MAX > 1) - */ - collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); - table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); - } -#endif - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else - if (BE (sbcset == NULL, 0)) -#endif /* RE_ENABLE_I18N */ - { - re_free (sbcset); -#ifdef RE_ENABLE_I18N - re_free (mbcset); -#endif - *err = REG_ESPACE; - return NULL; - } - - token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_BADPAT; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_NON_MATCH_LIST) - { -#ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ - non_match = true; - if (syntax & RE_HAT_LISTS_NOT_NEWLINE) - bitset_set (sbcset, '\n'); - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_BADPAT; - goto parse_bracket_exp_free_return; - } - } - - /* We treat the first ']' as a normal character. */ - if (token->type == OP_CLOSE_BRACKET) - token->type = CHARACTER; - - while (1) - { - bracket_elem_t start_elem, end_elem; - unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE]; - unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE]; - reg_errcode_t ret; - int token_len2 = 0; - bool is_range_exp = false; - re_token_t token2; - - start_elem.opr.name = start_name_buf; - ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa, - syntax, first_round); - if (BE (ret != REG_NOERROR, 0)) - { - *err = ret; - goto parse_bracket_exp_free_return; - } - first_round = false; - - /* Get information about the next token. We need it in any case. */ - token_len = peek_token_bracket (token, regexp, syntax); - - /* Do not check for ranges if we know they are not allowed. */ - if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) - { - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_CHARSET_RANGE) - { - re_string_skip_bytes (regexp, token_len); /* Skip '-'. */ - token_len2 = peek_token_bracket (&token2, regexp, syntax); - if (BE (token2.type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token2.type == OP_CLOSE_BRACKET) - { - /* We treat the last '-' as a normal character. */ - re_string_skip_bytes (regexp, -token_len); - token->type = CHARACTER; - } - else - is_range_exp = true; - } - } - - if (is_range_exp == true) - { - end_elem.opr.name = end_name_buf; - ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2, - dfa, syntax, true); - if (BE (ret != REG_NOERROR, 0)) - { - *err = ret; - goto parse_bracket_exp_free_return; - } - - token_len = peek_token_bracket (token, regexp, syntax); - -#ifdef _LIBC - *err = build_range_exp (sbcset, mbcset, &range_alloc, - &start_elem, &end_elem); -#else -# ifdef RE_ENABLE_I18N - *err = build_range_exp (syntax, sbcset, - dfa->mb_cur_max > 1 ? mbcset : NULL, - &range_alloc, &start_elem, &end_elem); -# else - *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem); -# endif -#endif /* RE_ENABLE_I18N */ - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - } - else - { - switch (start_elem.type) - { - case SB_CHAR: - bitset_set (sbcset, start_elem.opr.ch); - break; -#ifdef RE_ENABLE_I18N - case MB_CHAR: - /* Check whether the array has enough space. */ - if (BE (mbchar_alloc == mbcset->nmbchars, 0)) - { - wchar_t *new_mbchars; - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nmbchars is 0. */ - mbchar_alloc = 2 * mbcset->nmbchars + 1; - /* Use realloc since array is NULL if *alloc == 0. */ - new_mbchars = re_realloc (mbcset->mbchars, wchar_t, - mbchar_alloc); - if (BE (new_mbchars == NULL, 0)) - goto parse_bracket_exp_espace; - mbcset->mbchars = new_mbchars; - } - mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; - break; -#endif /* RE_ENABLE_I18N */ - case EQUIV_CLASS: - *err = build_equiv_class (sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &equiv_class_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - case COLL_SYM: - *err = build_collating_symbol (sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &coll_sym_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - case CHAR_CLASS: - *err = build_charclass (regexp->trans, sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &char_class_alloc, -#endif /* RE_ENABLE_I18N */ - (const char *) start_elem.opr.name, - syntax); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - default: - assert (0); - break; - } - } - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_CLOSE_BRACKET) - break; - } - - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - - /* If it is non-matching list. */ - if (non_match) - bitset_not (sbcset); - -#ifdef RE_ENABLE_I18N - /* Ensure only single byte characters are set. */ - if (dfa->mb_cur_max > 1) - bitset_mask (sbcset, dfa->sb_char); - - if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes - || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes - || mbcset->non_match))) - { - bin_tree_t *mbc_tree; - int sbc_idx; - /* Build a tree for complex bracket. */ - dfa->has_mb_node = 1; - br_token.type = COMPLEX_BRACKET; - br_token.opr.mbcset = mbcset; - mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) - goto parse_bracket_exp_espace; - for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx) - if (sbcset[sbc_idx]) - break; - /* If there are no bits set in sbcset, there is no point - of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */ - if (sbc_idx < BITSET_WORDS) - { - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - - /* Then join them by ALT node. */ - work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - } - else - { - re_free (sbcset); - work_tree = mbc_tree; - } - } - else -#endif /* not RE_ENABLE_I18N */ - { -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - } - return work_tree; - - parse_bracket_exp_espace: - *err = REG_ESPACE; - parse_bracket_exp_free_return: - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - return NULL; -} - -/* Parse an element in the bracket expression. */ - -static reg_errcode_t -parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp, - re_token_t *token, int token_len, re_dfa_t *dfa, - reg_syntax_t syntax, bool accept_hyphen) -{ -#ifdef RE_ENABLE_I18N - int cur_char_size; - cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); - if (cur_char_size > 1) - { - elem->type = MB_CHAR; - elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp)); - re_string_skip_bytes (regexp, cur_char_size); - return REG_NOERROR; - } -#endif /* RE_ENABLE_I18N */ - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS - || token->type == OP_OPEN_EQUIV_CLASS) - return parse_bracket_symbol (elem, regexp, token); - if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen) - { - /* A '-' must only appear as anything but a range indicator before - the closing bracket. Everything else is an error. */ - re_token_t token2; - (void) peek_token_bracket (&token2, regexp, syntax); - if (token2.type != OP_CLOSE_BRACKET) - /* The actual error value is not standardized since this whole - case is undefined. But ERANGE makes good sense. */ - return REG_ERANGE; - } - elem->type = SB_CHAR; - elem->opr.ch = token->opr.c; - return REG_NOERROR; -} - -/* Parse a bracket symbol in the bracket expression. Bracket symbols are - such as [::], [..], and - [==]. */ - -static reg_errcode_t -parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, - re_token_t *token) -{ - unsigned char ch, delim = token->opr.c; - int i = 0; - if (re_string_eoi(regexp)) - return REG_EBRACK; - for (;; ++i) - { - if (i >= BRACKET_NAME_BUF_SIZE) - return REG_EBRACK; - if (token->type == OP_OPEN_CHAR_CLASS) - ch = re_string_fetch_byte_case (regexp); - else - ch = re_string_fetch_byte (regexp); - if (re_string_eoi(regexp)) - return REG_EBRACK; - if (ch == delim && re_string_peek_byte (regexp, 0) == ']') - break; - elem->opr.name[i] = ch; - } - re_string_skip_bytes (regexp, 1); - elem->opr.name[i] = '\0'; - switch (token->type) - { - case OP_OPEN_COLL_ELEM: - elem->type = COLL_SYM; - break; - case OP_OPEN_EQUIV_CLASS: - elem->type = EQUIV_CLASS; - break; - case OP_OPEN_CHAR_CLASS: - elem->type = CHAR_CLASS; - break; - default: - break; - } - return REG_NOERROR; -} - - /* Helper function for parse_bracket_exp. - Build the equivalence class which is represented by NAME. - The result are written to MBCSET and SBCSET. - EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes, - is a pointer argument since we may update it. */ - -static reg_errcode_t -#ifdef RE_ENABLE_I18N -build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, - Idx *equiv_class_alloc, const unsigned char *name) -#else /* not RE_ENABLE_I18N */ -build_equiv_class (bitset_t sbcset, const unsigned char *name) -#endif /* not RE_ENABLE_I18N */ -{ -#ifdef _LIBC - uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules != 0) - { - const int32_t *table, *indirect; - const unsigned char *weights, *extra, *cp; - unsigned char char_buf[2]; - int32_t idx1, idx2; - unsigned int ch; - size_t len; - /* This #include defines a local function! */ -# include - /* Calculate the index for equivalence class. */ - cp = name; - table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_INDIRECTMB); - idx1 = findidx (&cp, -1); - if (BE (idx1 == 0 || *cp != '\0', 0)) - /* This isn't a valid character. */ - return REG_ECOLLATE; - - /* Build single byte matching table for this equivalence class. */ - len = weights[idx1 & 0xffffff]; - for (ch = 0; ch < SBC_MAX; ++ch) - { - char_buf[0] = ch; - cp = char_buf; - idx2 = findidx (&cp, 1); -/* - idx2 = table[ch]; -*/ - if (idx2 == 0) - /* This isn't a valid character. */ - continue; - /* Compare only if the length matches and the collation rule - index is the same. */ - if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)) - { - int cnt = 0; - - while (cnt <= len && - weights[(idx1 & 0xffffff) + 1 + cnt] - == weights[(idx2 & 0xffffff) + 1 + cnt]) - ++cnt; - - if (cnt > len) - bitset_set (sbcset, ch); - } - } - /* Check whether the array has enough space. */ - if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nequiv_classes is 0. */ - Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1; - /* Use realloc since the array is NULL if *alloc == 0. */ - int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes, - int32_t, - new_equiv_class_alloc); - if (BE (new_equiv_classes == NULL, 0)) - return REG_ESPACE; - mbcset->equiv_classes = new_equiv_classes; - *equiv_class_alloc = new_equiv_class_alloc; - } - mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1; - } - else -#endif /* _LIBC */ - { - if (BE (strlen ((const char *) name) != 1, 0)) - return REG_ECOLLATE; - bitset_set (sbcset, *name); - } - return REG_NOERROR; -} - - /* Helper function for parse_bracket_exp. - Build the character class which is represented by NAME. - The result are written to MBCSET and SBCSET. - CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes, - is a pointer argument since we may update it. */ - -static reg_errcode_t -#ifdef RE_ENABLE_I18N -build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, - re_charset_t *mbcset, Idx *char_class_alloc, - const char *class_name, reg_syntax_t syntax) -#else /* not RE_ENABLE_I18N */ -build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, - const char *class_name, reg_syntax_t syntax) -#endif /* not RE_ENABLE_I18N */ -{ - int i; - const char *name = class_name; - - /* In case of REG_ICASE "upper" and "lower" match the both of - upper and lower cases. */ - if ((syntax & RE_ICASE) - && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0)) - name = "alpha"; - -#ifdef RE_ENABLE_I18N - /* Check the space of the arrays. */ - if (BE (*char_class_alloc == mbcset->nchar_classes, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nchar_classes is 0. */ - Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1; - /* Use realloc since array is NULL if *alloc == 0. */ - wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t, - new_char_class_alloc); - if (BE (new_char_classes == NULL, 0)) - return REG_ESPACE; - mbcset->char_classes = new_char_classes; - *char_class_alloc = new_char_class_alloc; - } - mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name); -#endif /* RE_ENABLE_I18N */ - -#define BUILD_CHARCLASS_LOOP(ctype_func) \ - do { \ - if (BE (trans != NULL, 0)) \ - { \ - for (i = 0; i < SBC_MAX; ++i) \ - if (ctype_func (i)) \ - bitset_set (sbcset, trans[i]); \ - } \ - else \ - { \ - for (i = 0; i < SBC_MAX; ++i) \ - if (ctype_func (i)) \ - bitset_set (sbcset, i); \ - } \ - } while (0) - - if (strcmp (name, "alnum") == 0) - BUILD_CHARCLASS_LOOP (isalnum); - else if (strcmp (name, "cntrl") == 0) - BUILD_CHARCLASS_LOOP (iscntrl); - else if (strcmp (name, "lower") == 0) - BUILD_CHARCLASS_LOOP (islower); - else if (strcmp (name, "space") == 0) - BUILD_CHARCLASS_LOOP (isspace); - else if (strcmp (name, "alpha") == 0) - BUILD_CHARCLASS_LOOP (isalpha); - else if (strcmp (name, "digit") == 0) - BUILD_CHARCLASS_LOOP (isdigit); - else if (strcmp (name, "print") == 0) - BUILD_CHARCLASS_LOOP (isprint); - else if (strcmp (name, "upper") == 0) - BUILD_CHARCLASS_LOOP (isupper); - else if (strcmp (name, "blank") == 0) - BUILD_CHARCLASS_LOOP (isblank); - else if (strcmp (name, "graph") == 0) - BUILD_CHARCLASS_LOOP (isgraph); - else if (strcmp (name, "punct") == 0) - BUILD_CHARCLASS_LOOP (ispunct); - else if (strcmp (name, "xdigit") == 0) - BUILD_CHARCLASS_LOOP (isxdigit); - else - return REG_ECTYPE; - - return REG_NOERROR; -} - -static bin_tree_t * -build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, - const char *class_name, - const char *extra, bool non_match, - reg_errcode_t *err) -{ - re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; - Idx alloc = 0; -#endif /* not RE_ENABLE_I18N */ - reg_errcode_t ret; - re_token_t br_token; - bin_tree_t *tree; - - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ - -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else /* not RE_ENABLE_I18N */ - if (BE (sbcset == NULL, 0)) -#endif /* not RE_ENABLE_I18N */ - { - *err = REG_ESPACE; - return NULL; - } - - if (non_match) - { -#ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ - } - - /* We don't care the syntax in this case. */ - ret = build_charclass (trans, sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &alloc, -#endif /* RE_ENABLE_I18N */ - class_name, 0); - - if (BE (ret != REG_NOERROR, 0)) - { - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - *err = ret; - return NULL; - } - /* \w match '_' also. */ - for (; *extra; extra++) - bitset_set (sbcset, *extra); - - /* If it is non-matching list. */ - if (non_match) - bitset_not (sbcset); - -#ifdef RE_ENABLE_I18N - /* Ensure only single byte characters are set. */ - if (dfa->mb_cur_max > 1) - bitset_mask (sbcset, dfa->sb_char); -#endif - - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (tree == NULL, 0)) - goto build_word_op_espace; - -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - bin_tree_t *mbc_tree; - /* Build a tree for complex bracket. */ - br_token.type = COMPLEX_BRACKET; - br_token.opr.mbcset = mbcset; - dfa->has_mb_node = 1; - mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) - goto build_word_op_espace; - /* Then join them by ALT node. */ - tree = create_tree (dfa, tree, mbc_tree, OP_ALT); - if (BE (mbc_tree != NULL, 1)) - return tree; - } - else - { - free_charset (mbcset); - return tree; - } -#else /* not RE_ENABLE_I18N */ - return tree; -#endif /* not RE_ENABLE_I18N */ - - build_word_op_espace: - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - *err = REG_ESPACE; - return NULL; -} - -/* This is intended for the expressions like "a{1,3}". - Fetch a number from 'input', and return the number. - Return REG_MISSING if the number field is empty like "{,1}". - Return RE_DUP_MAX + 1 if the number field is too large. - Return REG_ERROR if an error occurred. */ - -static Idx -fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) -{ - Idx num = REG_MISSING; - unsigned char c; - while (1) - { - fetch_token (token, input, syntax); - c = token->opr.c; - if (BE (token->type == END_OF_RE, 0)) - return REG_ERROR; - if (token->type == OP_CLOSE_DUP_NUM || c == ',') - break; - num = ((token->type != CHARACTER || c < '0' || '9' < c - || num == REG_ERROR) - ? REG_ERROR - : num == REG_MISSING - ? c - '0' - : MIN (RE_DUP_MAX + 1, num * 10 + c - '0')); - } - return num; -} - -#ifdef RE_ENABLE_I18N -static void -free_charset (re_charset_t *cset) -{ - re_free (cset->mbchars); -# ifdef _LIBC - re_free (cset->coll_syms); - re_free (cset->equiv_classes); - re_free (cset->range_starts); - re_free (cset->range_ends); -# endif - re_free (cset->char_classes); - re_free (cset); -} -#endif /* RE_ENABLE_I18N */ - -/* Functions for binary tree operation. */ - -/* Create a tree node. */ - -static bin_tree_t * -create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, - re_token_type_t type) -{ - re_token_t t; - t.type = type; - return create_token_tree (dfa, left, right, &t); -} - -static bin_tree_t * -create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, - const re_token_t *token) -{ - bin_tree_t *tree; - if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0)) - { - bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1); - - if (storage == NULL) - return NULL; - storage->next = dfa->str_tree_storage; - dfa->str_tree_storage = storage; - dfa->str_tree_storage_idx = 0; - } - tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++]; - - tree->parent = NULL; - tree->left = left; - tree->right = right; - tree->token = *token; - tree->token.duplicated = 0; - tree->token.opt_subexp = 0; - tree->first = NULL; - tree->next = NULL; - tree->node_idx = REG_MISSING; - - if (left != NULL) - left->parent = tree; - if (right != NULL) - right->parent = tree; - return tree; -} - -/* Mark the tree SRC as an optional subexpression. - To be called from preorder or postorder. */ - -static reg_errcode_t -mark_opt_subexp (void *extra, bin_tree_t *node) -{ - Idx idx = (uintptr_t) extra; - if (node->token.type == SUBEXP && node->token.opr.idx == idx) - node->token.opt_subexp = 1; - - return REG_NOERROR; -} - -/* Free the allocated memory inside NODE. */ - -static void -free_token (re_token_t *node) -{ -#ifdef RE_ENABLE_I18N - if (node->type == COMPLEX_BRACKET && node->duplicated == 0) - free_charset (node->opr.mbcset); - else -#endif /* RE_ENABLE_I18N */ - if (node->type == SIMPLE_BRACKET && node->duplicated == 0) - re_free (node->opr.sbcset); -} - -/* Worker function for tree walking. Free the allocated memory inside NODE - and its children. */ - -static reg_errcode_t -free_tree (void *extra, bin_tree_t *node) -{ - free_token (&node->token); - return REG_NOERROR; -} - - -/* Duplicate the node SRC, and return new node. This is a preorder - visit similar to the one implemented by the generic visitor, but - we need more infrastructure to maintain two parallel trees --- so, - it's easier to duplicate. */ - -static bin_tree_t * -duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa) -{ - const bin_tree_t *node; - bin_tree_t *dup_root; - bin_tree_t **p_new = &dup_root, *dup_node = root->parent; - - for (node = root; ; ) - { - /* Create a new tree and link it back to the current parent. */ - *p_new = create_token_tree (dfa, NULL, NULL, &node->token); - if (*p_new == NULL) - return NULL; - (*p_new)->parent = dup_node; - (*p_new)->token.duplicated = 1; - dup_node = *p_new; - - /* Go to the left node, or up and to the right. */ - if (node->left) - { - node = node->left; - p_new = &dup_node->left; - } - else - { - const bin_tree_t *prev = NULL; - while (node->right == prev || node->right == NULL) - { - prev = node; - node = node->parent; - dup_node = dup_node->parent; - if (!node) - return dup_root; - } - node = node->right; - p_new = &dup_node->right; - } - } -} diff --git a/grub-core/gnulib/regex.c b/grub-core/gnulib/regex.c deleted file mode 100644 index 5a0332e00..000000000 --- a/grub-core/gnulib/regex.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _LIBC -# include - -# if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ -# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" -# endif -# if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__ -# pragma GCC diagnostic ignored "-Wold-style-definition" -# pragma GCC diagnostic ignored "-Wtype-limits" -# endif -#endif - -/* Make sure no one compiles this code with a C++ compiler. */ -#if defined __cplusplus && defined _LIBC -# error "This is C code, use a C compiler" -#endif - -#ifdef _LIBC -/* We have to keep the namespace clean. */ -# define regfree(preg) __regfree (preg) -# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) -# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) -# define regerror(errcode, preg, errbuf, errbuf_size) \ - __regerror(errcode, preg, errbuf, errbuf_size) -# define re_set_registers(bu, re, nu, st, en) \ - __re_set_registers (bu, re, nu, st, en) -# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ - __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) -# define re_match(bufp, string, size, pos, regs) \ - __re_match (bufp, string, size, pos, regs) -# define re_search(bufp, string, size, startpos, range, regs) \ - __re_search (bufp, string, size, startpos, range, regs) -# define re_compile_pattern(pattern, length, bufp) \ - __re_compile_pattern (pattern, length, bufp) -# define re_set_syntax(syntax) __re_set_syntax (syntax) -# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ - __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) -# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) - -# include "../locale/localeinfo.h" -#endif - -/* On some systems, limits.h sets RE_DUP_MAX to a lower value than - GNU regex allows. Include it before , which correctly - #undefs RE_DUP_MAX and sets it to the right value. */ -#include - -#include -#include "regex_internal.h" - -#include "regex_internal.c" -#include "regcomp.c" -#include "regexec.c" - -/* Binary backward compatibility. */ -#if _LIBC -# include -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) -link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.") -int re_max_failures = 2000; -# endif -#endif diff --git a/grub-core/gnulib/regex.h b/grub-core/gnulib/regex.h deleted file mode 100644 index 854c6edaf..000000000 --- a/grub-core/gnulib/regex.h +++ /dev/null @@ -1,667 +0,0 @@ -/* Definitions for data structures and routines for the regular - expression library. - Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2013 Free Software - Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _REGEX_H -#define _REGEX_H 1 - -#include - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Define __USE_GNU to declare GNU extensions that violate the - POSIX name space rules. */ -#ifdef _GNU_SOURCE -# define __USE_GNU 1 -#endif - -#ifdef _REGEX_LARGE_OFFSETS - -/* Use types and values that are wide enough to represent signed and - unsigned byte offsets in memory. This currently works only when - the regex code is used outside of the GNU C library; it is not yet - supported within glibc itself, and glibc users should not define - _REGEX_LARGE_OFFSETS. */ - -/* The type of nonnegative object indexes. Traditionally, GNU regex - uses 'int' for these. Code that uses __re_idx_t should work - regardless of whether the type is signed. */ -typedef size_t __re_idx_t; - -/* The type of object sizes. */ -typedef size_t __re_size_t; - -/* The type of object sizes, in places where the traditional code - uses unsigned long int. */ -typedef size_t __re_long_size_t; - -#else - -/* The traditional GNU regex implementation mishandles strings longer - than INT_MAX. */ -typedef int __re_idx_t; -typedef unsigned int __re_size_t; -typedef unsigned long int __re_long_size_t; - -#endif - -/* The following two types have to be signed and unsigned integer type - wide enough to hold a value of a pointer. For most ANSI compilers - ptrdiff_t and size_t should be likely OK. Still size of these two - types is 2 for Microsoft C. Ugh... */ -typedef long int s_reg_t; -typedef unsigned long int active_reg_t; - -/* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ -typedef unsigned long int reg_syntax_t; - -#ifdef __USE_GNU -/* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) - -/* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - -/* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - -/* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - -/* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - -/* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - -/* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - -/* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - -/* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - -/* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - -/* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -# define RE_LIMITED_OPS (RE_INTERVALS << 1) - -/* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - -/* If this bit is set, then '{...}' defines an interval, and \{ and \} - are literals. - If not set, then '\{...\}' defines an interval. */ -# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - -/* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - -/* If this bit is set, then \ matches . - If not set, then \ is a back-reference. */ -# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - -/* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - -/* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - -/* If this bit is set, then an unmatched ) is ordinary. - If not set, then an unmatched ) is invalid. */ -# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) - -/* If this bit is set, succeed as soon as we match the whole pattern, - without further backtracking. */ -# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) - -/* If this bit is set, do not process the GNU regex operators. - If not set, then the GNU regex operators are recognized. */ -# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) - -/* If this bit is set, turn on internal regex debugging. - If not set, and debugging was on, turn it off. - This only works if regex.c is compiled -DDEBUG. - We define this bit always, so that all that's needed to turn on - debugging is to recompile regex.c; the calling code can always have - this bit set, and it won't affect anything in the normal case. */ -# define RE_DEBUG (RE_NO_GNU_OPS << 1) - -/* If this bit is set, a syntactically invalid interval is treated as - a string of ordinary characters. For example, the ERE 'a{1' is - treated as 'a\{1'. */ -# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) - -/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only - for ^, because it is difficult to scan the regex backwards to find - whether ^ should be special. */ -# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1) - -/* If this bit is set, then \{ cannot be first in a regex or - immediately after an alternation, open-group or \} operator. */ -# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1) - -/* If this bit is set, then no_sub will be set to 1 during - re_compile_pattern. */ -# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1) -#endif - -/* This global variable defines the particular regexp syntax to use (for - some interfaces). When a regexp is compiled, the syntax used is - stored in the pattern buffer, so changing this does not affect - already-compiled regexps. */ -extern reg_syntax_t re_syntax_options; - -#ifdef __USE_GNU -/* Define combinations of the above bits for the standard possibilities. - (The [[[ comments delimit what gets put into the Texinfo file, so - don't delete them!) */ -/* [[[begin syntaxes]]] */ -# define RE_SYNTAX_EMACS 0 - -# define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CHAR_CLASSES \ - | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) - -# define RE_SYNTAX_GNU_AWK \ - ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INVALID_INTERVAL_ORD) \ - & ~(RE_DOT_NOT_NULL | RE_CONTEXT_INDEP_OPS \ - | RE_CONTEXT_INVALID_OPS )) - -# define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INTERVALS | RE_NO_GNU_OPS \ - | RE_INVALID_INTERVAL_ORD) - -# define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -# define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -# define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ - | RE_INVALID_INTERVAL_ORD) - -/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - -/* Syntax bits common to both basic and extended POSIX regex syntax. */ -# define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -# define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP) - -/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -# define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -# define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is - removed and RE_NO_BK_REFS is added. */ -# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) -/* [[[end syntaxes]]] */ - -/* Maximum number of duplicates an interval can allow. POSIX-conforming - systems might define this in , but we want our - value, so remove any previous define. */ -# ifdef _REGEX_INCLUDE_LIMITS_H -# include -# endif -# ifdef RE_DUP_MAX -# undef RE_DUP_MAX -# endif - -/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored - the counter as a 2-byte signed integer. This is no longer true, so - RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to - ((SIZE_MAX - 9) / 10) if _REGEX_LARGE_OFFSETS is defined. - However, there would be a huge performance problem if someone - actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains - its historical value. */ -# define RE_DUP_MAX (0x7fff) -#endif - - -/* POSIX 'cflags' bits (i.e., information for 'regcomp'). */ - -/* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (1 << 1) - -/* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (1 << 2) - -/* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (1 << 3) - - -/* POSIX 'eflags' bits (i.e., information for regexec). */ - -/* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - -/* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - -/* Use PMATCH[0] to delimit the start and end of the search in the - buffer. */ -#define REG_STARTEND (1 << 2) - - -/* If any error codes are removed, changed, or added, update the - '__re_error_msgid' table in regcomp.c. */ - -typedef enum -{ - _REG_ENOSYS = -1, /* This will never happen for this implementation. */ - _REG_NOERROR = 0, /* Success. */ - _REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - _REG_BADPAT, /* Invalid pattern. */ - _REG_ECOLLATE, /* Invalid collating element. */ - _REG_ECTYPE, /* Invalid character class name. */ - _REG_EESCAPE, /* Trailing backslash. */ - _REG_ESUBREG, /* Invalid back reference. */ - _REG_EBRACK, /* Unmatched left bracket. */ - _REG_EPAREN, /* Parenthesis imbalance. */ - _REG_EBRACE, /* Unmatched \{. */ - _REG_BADBR, /* Invalid contents of \{\}. */ - _REG_ERANGE, /* Invalid range end. */ - _REG_ESPACE, /* Ran out of memory. */ - _REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - _REG_EEND, /* Premature end. */ - _REG_ESIZE, /* Too large (e.g., repeat count too large). */ - _REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ -} reg_errcode_t; - -#if defined _XOPEN_SOURCE || defined __USE_XOPEN2K -# define REG_ENOSYS _REG_ENOSYS -#endif -#define REG_NOERROR _REG_NOERROR -#define REG_NOMATCH _REG_NOMATCH -#define REG_BADPAT _REG_BADPAT -#define REG_ECOLLATE _REG_ECOLLATE -#define REG_ECTYPE _REG_ECTYPE -#define REG_EESCAPE _REG_EESCAPE -#define REG_ESUBREG _REG_ESUBREG -#define REG_EBRACK _REG_EBRACK -#define REG_EPAREN _REG_EPAREN -#define REG_EBRACE _REG_EBRACE -#define REG_BADBR _REG_BADBR -#define REG_ERANGE _REG_ERANGE -#define REG_ESPACE _REG_ESPACE -#define REG_BADRPT _REG_BADRPT -#define REG_EEND _REG_EEND -#define REG_ESIZE _REG_ESIZE -#define REG_ERPAREN _REG_ERPAREN - -/* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields 'buffer', 'allocated', 'fastmap', - and 'translate' can be set. After the pattern has been compiled, - the fields 're_nsub', 'not_bol' and 'not_eol' are available. All - other fields are private to the regex routines. */ - -#ifndef RE_TRANSLATE_TYPE -# define __RE_TRANSLATE_TYPE unsigned char * -# ifdef __USE_GNU -# define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE -# endif -#endif - -#ifdef __USE_GNU -# define __REPB_PREFIX(name) name -#else -# define __REPB_PREFIX(name) __##name -#endif - -struct re_pattern_buffer -{ - /* Space that holds the compiled pattern. The type - 'struct re_dfa_t' is private and is not declared here. */ - struct re_dfa_t *__REPB_PREFIX(buffer); - - /* Number of bytes to which 'buffer' points. */ - __re_long_size_t __REPB_PREFIX(allocated); - - /* Number of bytes actually used in 'buffer'. */ - __re_long_size_t __REPB_PREFIX(used); - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t __REPB_PREFIX(syntax); - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses the - fastmap, if there is one, to skip over impossible starting points - for matches. */ - char *__REPB_PREFIX(fastmap); - - /* Either a translate table to apply to all characters before - comparing them, or zero for no translation. The translation is - applied to a pattern when it is compiled and to a string when it - is matched. */ - __RE_TRANSLATE_TYPE __REPB_PREFIX(translate); - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in 're_search_2', to see whether or - not we should use the fastmap, so we don't set this absolutely - perfectly; see 're_compile_fastmap' (the "duplicate" case). */ - unsigned __REPB_PREFIX(can_be_null) : 1; - - /* If REGS_UNALLOCATED, allocate space in the 'regs' structure - for 'max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#ifdef __USE_GNU -# define REGS_UNALLOCATED 0 -# define REGS_REALLOCATE 1 -# define REGS_FIXED 2 -#endif - unsigned __REPB_PREFIX(regs_allocated) : 2; - - /* Set to zero when 're_compile_pattern' compiles a pattern; set to - one by 're_compile_fastmap' if it updates the fastmap. */ - unsigned __REPB_PREFIX(fastmap_accurate) : 1; - - /* If set, 're_match_2' does not return information about - subexpressions. */ - unsigned __REPB_PREFIX(no_sub) : 1; - - /* If set, a beginning-of-line anchor doesn't match at the beginning - of the string. */ - unsigned __REPB_PREFIX(not_bol) : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned __REPB_PREFIX(not_eol) : 1; - - /* If true, an anchor at a newline matches. */ - unsigned __REPB_PREFIX(newline_anchor) : 1; -}; - -typedef struct re_pattern_buffer regex_t; - -/* Type for byte offsets within the string. POSIX mandates this. */ -#ifdef _REGEX_LARGE_OFFSETS -/* POSIX 1003.1-2008 requires that regoff_t be at least as wide as - ptrdiff_t and ssize_t. We don't know of any hosts where ptrdiff_t - is wider than ssize_t, so ssize_t is safe. */ -typedef ssize_t regoff_t; -#else -/* The traditional GNU regex implementation mishandles strings longer - than INT_MAX. */ -typedef int regoff_t; -#endif - - -#ifdef __USE_GNU -/* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ -struct re_registers -{ - __re_size_t num_regs; - regoff_t *start; - regoff_t *end; -}; - - -/* If 'regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - 're_match_2' returns information about at least this many registers - the first time a 'regs' structure is passed. */ -# ifndef RE_NREGS -# define RE_NREGS 30 -# endif -#endif - - -/* POSIX specification for registers. Aside from the different names than - 're_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ -typedef struct -{ - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ -} regmatch_t; - -/* Declarations for routines. */ - -#ifdef __USE_GNU -/* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the 're_syntax_options' variable. */ -extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); - -/* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global 're_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. - - To free the allocated storage, you must call 'regfree' on BUFFER. - Note that the translate table must either have been initialised by - 'regcomp', with a malloc'ed value, or set to NULL before calling - 'regfree'. */ -extern const char *re_compile_pattern (const char *__pattern, size_t __length, - struct re_pattern_buffer *__buffer); - - -/* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ -extern int re_compile_fastmap (struct re_pattern_buffer *__buffer); - - -/* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern regoff_t re_search (struct re_pattern_buffer *__buffer, - const char *__string, __re_idx_t __length, - __re_idx_t __start, regoff_t __range, - struct re_registers *__regs); - - -/* Like 're_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ -extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, - const char *__string1, __re_idx_t __length1, - const char *__string2, __re_idx_t __length2, - __re_idx_t __start, regoff_t __range, - struct re_registers *__regs, - __re_idx_t __stop); - - -/* Like 're_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern regoff_t re_match (struct re_pattern_buffer *__buffer, - const char *__string, __re_idx_t __length, - __re_idx_t __start, struct re_registers *__regs); - - -/* Relates to 're_match' as 're_search_2' relates to 're_search'. */ -extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, - const char *__string1, __re_idx_t __length1, - const char *__string2, __re_idx_t __length2, - __re_idx_t __start, struct re_registers *__regs, - __re_idx_t __stop); - - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least 'NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - BUFFER will allocate its own register data, without - freeing the old data. */ -extern void re_set_registers (struct re_pattern_buffer *__buffer, - struct re_registers *__regs, - __re_size_t __num_regs, - regoff_t *__starts, regoff_t *__ends); -#endif /* Use GNU */ - -#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_BSD) -# ifndef _CRAY -/* 4.2 bsd compatibility. */ -extern char *re_comp (const char *); -extern int re_exec (const char *); -# endif -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". - Other compilers use __restrict, __restrict__, and _Restrict, and - 'configure' might #define 'restrict' to those words, so pick a - different name. */ -#ifndef _Restrict_ -# if 199901L <= __STDC_VERSION__ -# define _Restrict_ restrict -# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__) -# define _Restrict_ __restrict -# else -# define _Restrict_ -# endif -#endif -/* gcc 3.1 and up support the [restrict] syntax. Don't trust - sys/cdefs.h's definition of __restrict_arr, though, as it - mishandles gcc -ansi -pedantic. */ -#ifndef _Restrict_arr_ -# if ((199901L <= __STDC_VERSION__ \ - || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ - && !defined __STRICT_ANSI__)) \ - && !defined __GNUG__) -# define _Restrict_arr_ _Restrict_ -# else -# define _Restrict_arr_ -# endif -#endif - -/* POSIX compatibility. */ -extern int regcomp (regex_t *_Restrict_ __preg, - const char *_Restrict_ __pattern, - int __cflags); - -extern int regexec (const regex_t *_Restrict_ __preg, - const char *_Restrict_ __string, size_t __nmatch, - regmatch_t __pmatch[_Restrict_arr_], - int __eflags); - -extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, - char *_Restrict_ __errbuf, size_t __errbuf_size); - -extern void regfree (regex_t *__preg); - - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif /* regex.h */ diff --git a/grub-core/gnulib/regex_internal.c b/grub-core/gnulib/regex_internal.c deleted file mode 100644 index 899b0ae67..000000000 --- a/grub-core/gnulib/regex_internal.c +++ /dev/null @@ -1,1741 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with the GNU C Library; if not, see - . */ - -static void re_string_construct_common (const char *str, Idx len, - re_string_t *pstr, - RE_TRANSLATE_TYPE trans, bool icase, - const re_dfa_t *dfa) internal_function; -static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, - const re_node_set *nodes, - re_hashval_t hash) internal_function; -static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, - const re_node_set *nodes, - unsigned int context, - re_hashval_t hash) internal_function; - -/* Functions for string operation. */ - -/* This function allocate the buffers. It is necessary to call - re_string_reconstruct before using the object. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, - RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) -{ - reg_errcode_t ret; - Idx init_buf_len; - - /* Ensure at least one character fits into the buffers. */ - if (init_len < dfa->mb_cur_max) - init_len = dfa->mb_cur_max; - init_buf_len = (len + 1 < init_len) ? len + 1: init_len; - re_string_construct_common (str, len, pstr, trans, icase, dfa); - - ret = re_string_realloc_buffers (pstr, init_buf_len); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - pstr->word_char = dfa->word_char; - pstr->word_ops_used = dfa->word_ops_used; - pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; - pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len; - pstr->valid_raw_len = pstr->valid_len; - return REG_NOERROR; -} - -/* This function allocate the buffers, and initialize them. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_string_construct (re_string_t *pstr, const char *str, Idx len, - RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) -{ - reg_errcode_t ret; - memset (pstr, '\0', sizeof (re_string_t)); - re_string_construct_common (str, len, pstr, trans, icase, dfa); - - if (len > 0) - { - ret = re_string_realloc_buffers (pstr, len + 1); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; - - if (icase) - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - while (1) - { - ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - if (pstr->valid_raw_len >= len) - break; - if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) - break; - ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - } - else -#endif /* RE_ENABLE_I18N */ - build_upper_buffer (pstr); - } - else - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - build_wcs_buffer (pstr); - else -#endif /* RE_ENABLE_I18N */ - { - if (trans != NULL) - re_string_translate_buffer (pstr); - else - { - pstr->valid_len = pstr->bufs_len; - pstr->valid_raw_len = pstr->bufs_len; - } - } - } - - return REG_NOERROR; -} - -/* Helper functions for re_string_allocate, and re_string_construct. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) -{ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - wint_t *new_wcs; - - /* Avoid overflow in realloc. */ - const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_buf_len, 0)) - return REG_ESPACE; - - new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); - if (BE (new_wcs == NULL, 0)) - return REG_ESPACE; - pstr->wcs = new_wcs; - if (pstr->offsets != NULL) - { - Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len); - if (BE (new_offsets == NULL, 0)) - return REG_ESPACE; - pstr->offsets = new_offsets; - } - } -#endif /* RE_ENABLE_I18N */ - if (pstr->mbs_allocated) - { - unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, - new_buf_len); - if (BE (new_mbs == NULL, 0)) - return REG_ESPACE; - pstr->mbs = new_mbs; - } - pstr->bufs_len = new_buf_len; - return REG_NOERROR; -} - - -static void -internal_function -re_string_construct_common (const char *str, Idx len, re_string_t *pstr, - RE_TRANSLATE_TYPE trans, bool icase, - const re_dfa_t *dfa) -{ - pstr->raw_mbs = (const unsigned char *) str; - pstr->len = len; - pstr->raw_len = len; - pstr->trans = trans; - pstr->icase = icase; - pstr->mbs_allocated = (trans != NULL || icase); - pstr->mb_cur_max = dfa->mb_cur_max; - pstr->is_utf8 = dfa->is_utf8; - pstr->map_notascii = dfa->map_notascii; - pstr->stop = pstr->len; - pstr->raw_stop = pstr->stop; -} - -#ifdef RE_ENABLE_I18N - -/* Build wide character buffer PSTR->WCS. - If the byte sequence of the string are: - (0), (1), (0), (1), - Then wide character buffer will be: - , WEOF , , WEOF , - We use WEOF for padding, they indicate that the position isn't - a first byte of a multibyte character. - - Note that this function assumes PSTR->VALID_LEN elements are already - built and starts from PSTR->VALID_LEN. */ - -static void -internal_function -build_wcs_buffer (re_string_t *pstr) -{ -#ifdef _LIBC - unsigned char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); -#else - unsigned char buf[64]; -#endif - mbstate_t prev_st; - Idx byte_idx, end_idx, remain_len; - size_t mbclen; - - /* Build the buffers from pstr->valid_len to either pstr->len or - pstr->bufs_len. */ - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - for (byte_idx = pstr->valid_len; byte_idx < end_idx;) - { - wchar_t wc; - const char *p; - - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - /* Apply the translation if we need. */ - if (BE (pstr->trans != NULL, 0)) - { - int i, ch; - - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) - { - ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i]; - buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch]; - } - p = (const char *) buf; - } - else - p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; - mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -1 || mbclen == 0 - || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0)) - { - /* We treat these cases as a singlebyte character. */ - mbclen = 1; - wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - if (BE (pstr->trans != NULL, 0)) - wc = pstr->trans[wc]; - pstr->cur_state = prev_st; - } - else if (BE (mbclen == (size_t) -2, 0)) - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - - /* Write wide character and padding. */ - pstr->wcs[byte_idx++] = wc; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = byte_idx; -} - -/* Build wide character buffer PSTR->WCS like build_wcs_buffer, - but for REG_ICASE. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -build_wcs_upper_buffer (re_string_t *pstr) -{ - mbstate_t prev_st; - Idx src_idx, byte_idx, end_idx, remain_len; - size_t mbclen; -#ifdef _LIBC - char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); -#else - char buf[64]; -#endif - - byte_idx = pstr->valid_len; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - /* The following optimization assumes that ASCII characters can be - mapped to wide characters with a simple cast. */ - if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed) - { - while (byte_idx < end_idx) - { - wchar_t wc; - - if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) - && mbsinit (&pstr->cur_state)) - { - /* In case of a singlebyte character. */ - pstr->mbs[byte_idx] - = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]); - /* The next step uses the assumption that wchar_t is encoded - ASCII-safe: all ASCII values can be converted like this. */ - pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; - ++byte_idx; - continue; - } - - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - mbclen = __mbrtowc (&wc, - ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx - + byte_idx), remain_len, &pstr->cur_state); - if (BE (mbclen < (size_t) -2, 1)) - { - wchar_t wcu = wc; - if (iswlower (wc)) - { - size_t mbcdlen; - - wcu = towupper (wc); - mbcdlen = wcrtomb (buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) - memcpy (pstr->mbs + byte_idx, buf, mbclen); - else - { - src_idx = byte_idx; - goto offsets_needed; - } - } - else - memcpy (pstr->mbs + byte_idx, - pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen); - pstr->wcs[byte_idx++] = wcu; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - else if (mbclen == (size_t) -1 || mbclen == 0 - || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) - { - /* It is an invalid character, an incomplete character - at the end of the string, or '\0'. Just use the byte. */ - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - pstr->mbs[byte_idx] = ch; - /* And also cast it to wide char. */ - pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) - pstr->cur_state = prev_st; - } - else - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = byte_idx; - return REG_NOERROR; - } - else - for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;) - { - wchar_t wc; - const char *p; - offsets_needed: - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - if (BE (pstr->trans != NULL, 0)) - { - int i, ch; - - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) - { - ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i]; - buf[i] = pstr->trans[ch]; - } - p = (const char *) buf; - } - else - p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; - mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen < (size_t) -2, 1)) - { - wchar_t wcu = wc; - if (iswlower (wc)) - { - size_t mbcdlen; - - wcu = towupper (wc); - mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) - memcpy (pstr->mbs + byte_idx, buf, mbclen); - else if (mbcdlen != (size_t) -1) - { - size_t i; - - if (byte_idx + mbcdlen > pstr->bufs_len) - { - pstr->cur_state = prev_st; - break; - } - - if (pstr->offsets == NULL) - { - pstr->offsets = re_malloc (Idx, pstr->bufs_len); - - if (pstr->offsets == NULL) - return REG_ESPACE; - } - if (!pstr->offsets_needed) - { - for (i = 0; i < (size_t) byte_idx; ++i) - pstr->offsets[i] = i; - pstr->offsets_needed = 1; - } - - memcpy (pstr->mbs + byte_idx, buf, mbcdlen); - pstr->wcs[byte_idx] = wcu; - pstr->offsets[byte_idx] = src_idx; - for (i = 1; i < mbcdlen; ++i) - { - pstr->offsets[byte_idx + i] - = src_idx + (i < mbclen ? i : mbclen - 1); - pstr->wcs[byte_idx + i] = WEOF; - } - pstr->len += mbcdlen - mbclen; - if (pstr->raw_stop > src_idx) - pstr->stop += mbcdlen - mbclen; - end_idx = (pstr->bufs_len > pstr->len) - ? pstr->len : pstr->bufs_len; - byte_idx += mbcdlen; - src_idx += mbclen; - continue; - } - else - memcpy (pstr->mbs + byte_idx, p, mbclen); - } - else - memcpy (pstr->mbs + byte_idx, p, mbclen); - - if (BE (pstr->offsets_needed != 0, 0)) - { - size_t i; - for (i = 0; i < mbclen; ++i) - pstr->offsets[byte_idx + i] = src_idx + i; - } - src_idx += mbclen; - - pstr->wcs[byte_idx++] = wcu; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - else if (mbclen == (size_t) -1 || mbclen == 0 - || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) - { - /* It is an invalid character or '\0'. Just use the byte. */ - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; - - if (BE (pstr->trans != NULL, 0)) - ch = pstr->trans [ch]; - pstr->mbs[byte_idx] = ch; - - if (BE (pstr->offsets_needed != 0, 0)) - pstr->offsets[byte_idx] = src_idx; - ++src_idx; - - /* And also cast it to wide char. */ - pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) - pstr->cur_state = prev_st; - } - else - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = src_idx; - return REG_NOERROR; -} - -/* Skip characters until the index becomes greater than NEW_RAW_IDX. - Return the index. */ - -static Idx -internal_function -re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) -{ - mbstate_t prev_st; - Idx rawbuf_idx; - size_t mbclen; - wint_t wc = WEOF; - - /* Skip the characters which are not necessary to check. */ - for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len; - rawbuf_idx < new_raw_idx;) - { - wchar_t wc2; - Idx remain_len = pstr->raw_len - rawbuf_idx; - prev_st = pstr->cur_state; - mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, - remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) - { - /* We treat these cases as a single byte character. */ - if (mbclen == 0 || remain_len == 0) - wc = L'\0'; - else - wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx); - mbclen = 1; - pstr->cur_state = prev_st; - } - else - wc = wc2; - /* Then proceed the next character. */ - rawbuf_idx += mbclen; - } - *last_wc = wc; - return rawbuf_idx; -} -#endif /* RE_ENABLE_I18N */ - -/* Build the buffer PSTR->MBS, and apply the translation if we need. - This function is used in case of REG_ICASE. */ - -static void -internal_function -build_upper_buffer (re_string_t *pstr) -{ - Idx char_idx, end_idx; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) - { - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; - if (BE (pstr->trans != NULL, 0)) - ch = pstr->trans[ch]; - if (islower (ch)) - pstr->mbs[char_idx] = toupper (ch); - else - pstr->mbs[char_idx] = ch; - } - pstr->valid_len = char_idx; - pstr->valid_raw_len = char_idx; -} - -/* Apply TRANS to the buffer in PSTR. */ - -static void -internal_function -re_string_translate_buffer (re_string_t *pstr) -{ - Idx buf_idx, end_idx; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) - { - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx]; - pstr->mbs[buf_idx] = pstr->trans[ch]; - } - - pstr->valid_len = buf_idx; - pstr->valid_raw_len = buf_idx; -} - -/* This function re-construct the buffers. - Concretely, convert to wide character in case of pstr->mb_cur_max > 1, - convert to upper case in case of REG_ICASE, apply translation. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) -{ - Idx offset; - - if (BE (pstr->raw_mbs_idx <= idx, 0)) - offset = idx - pstr->raw_mbs_idx; - else - { - /* Reset buffer. */ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); -#endif /* RE_ENABLE_I18N */ - pstr->len = pstr->raw_len; - pstr->stop = pstr->raw_stop; - pstr->valid_len = 0; - pstr->raw_mbs_idx = 0; - pstr->valid_raw_len = 0; - pstr->offsets_needed = 0; - pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF - : CONTEXT_NEWLINE | CONTEXT_BEGBUF); - if (!pstr->mbs_allocated) - pstr->mbs = (unsigned char *) pstr->raw_mbs; - offset = idx; - } - - if (BE (offset != 0, 1)) - { - /* Should the already checked characters be kept? */ - if (BE (offset < pstr->valid_raw_len, 1)) - { - /* Yes, move them to the front of the buffer. */ -#ifdef RE_ENABLE_I18N - if (BE (pstr->offsets_needed, 0)) - { - Idx low = 0, high = pstr->valid_len, mid; - do - { - mid = (high + low) / 2; - if (pstr->offsets[mid] > offset) - high = mid; - else if (pstr->offsets[mid] < offset) - low = mid + 1; - else - break; - } - while (low < high); - if (pstr->offsets[mid] < offset) - ++mid; - pstr->tip_context = re_string_context_at (pstr, mid - 1, - eflags); - /* This can be quite complicated, so handle specially - only the common and easy case where the character with - different length representation of lower and upper - case is present at or after offset. */ - if (pstr->valid_len > offset - && mid == offset && pstr->offsets[mid] == offset) - { - memmove (pstr->wcs, pstr->wcs + offset, - (pstr->valid_len - offset) * sizeof (wint_t)); - memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset); - pstr->valid_len -= offset; - pstr->valid_raw_len -= offset; - for (low = 0; low < pstr->valid_len; low++) - pstr->offsets[low] = pstr->offsets[low + offset] - offset; - } - else - { - /* Otherwise, just find out how long the partial multibyte - character at offset is and fill it with WEOF/255. */ - pstr->len = pstr->raw_len - idx + offset; - pstr->stop = pstr->raw_stop - idx + offset; - pstr->offsets_needed = 0; - while (mid > 0 && pstr->offsets[mid - 1] == offset) - --mid; - while (mid < pstr->valid_len) - if (pstr->wcs[mid] != WEOF) - break; - else - ++mid; - if (mid == pstr->valid_len) - pstr->valid_len = 0; - else - { - pstr->valid_len = pstr->offsets[mid] - offset; - if (pstr->valid_len) - { - for (low = 0; low < pstr->valid_len; ++low) - pstr->wcs[low] = WEOF; - memset (pstr->mbs, 255, pstr->valid_len); - } - } - pstr->valid_raw_len = pstr->valid_len; - } - } - else -#endif - { - pstr->tip_context = re_string_context_at (pstr, offset - 1, - eflags); -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - memmove (pstr->wcs, pstr->wcs + offset, - (pstr->valid_len - offset) * sizeof (wint_t)); -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) - memmove (pstr->mbs, pstr->mbs + offset, - pstr->valid_len - offset); - pstr->valid_len -= offset; - pstr->valid_raw_len -= offset; -#if DEBUG - assert (pstr->valid_len > 0); -#endif - } - } - else - { -#ifdef RE_ENABLE_I18N - /* No, skip all characters until IDX. */ - Idx prev_valid_len = pstr->valid_len; - - if (BE (pstr->offsets_needed, 0)) - { - pstr->len = pstr->raw_len - idx + offset; - pstr->stop = pstr->raw_stop - idx + offset; - pstr->offsets_needed = 0; - } -#endif - pstr->valid_len = 0; -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - Idx wcs_idx; - wint_t wc = WEOF; - - if (pstr->is_utf8) - { - const unsigned char *raw, *p, *end; - - /* Special case UTF-8. Multi-byte chars start with any - byte other than 0x80 - 0xbf. */ - raw = pstr->raw_mbs + pstr->raw_mbs_idx; - end = raw + (offset - pstr->mb_cur_max); - if (end < pstr->raw_mbs) - end = pstr->raw_mbs; - p = raw + offset - 1; -#ifdef _LIBC - /* We know the wchar_t encoding is UCS4, so for the simple - case, ASCII characters, skip the conversion step. */ - if (isascii (*p) && BE (pstr->trans == NULL, 1)) - { - memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); - /* pstr->valid_len = 0; */ - wc = (wchar_t) *p; - } - else -#endif - for (; p >= end; --p) - if ((*p & 0xc0) != 0x80) - { - mbstate_t cur_state; - wchar_t wc2; - Idx mlen = raw + pstr->len - p; - unsigned char buf[6]; - size_t mbclen; - - const unsigned char *pp = p; - if (BE (pstr->trans != NULL, 0)) - { - int i = mlen < 6 ? mlen : 6; - while (--i >= 0) - buf[i] = pstr->trans[p[i]]; - pp = buf; - } - /* XXX Don't use mbrtowc, we know which conversion - to use (UTF-8 -> UCS4). */ - memset (&cur_state, 0, sizeof (cur_state)); - mbclen = __mbrtowc (&wc2, (const char *) pp, mlen, - &cur_state); - if (raw + offset - p <= mbclen - && mbclen < (size_t) -2) - { - memset (&pstr->cur_state, '\0', - sizeof (mbstate_t)); - pstr->valid_len = mbclen - (raw + offset - p); - wc = wc2; - } - break; - } - } - - if (wc == WEOF) - pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx; - if (wc == WEOF) - pstr->tip_context - = re_string_context_at (pstr, prev_valid_len - 1, eflags); - else - pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) - && IS_WIDE_WORD_CHAR (wc)) - ? CONTEXT_WORD - : ((IS_WIDE_NEWLINE (wc) - && pstr->newline_anchor) - ? CONTEXT_NEWLINE : 0)); - if (BE (pstr->valid_len, 0)) - { - for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) - pstr->wcs[wcs_idx] = WEOF; - if (pstr->mbs_allocated) - memset (pstr->mbs, 255, pstr->valid_len); - } - pstr->valid_raw_len = pstr->valid_len; - } - else -#endif /* RE_ENABLE_I18N */ - { - int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; - pstr->valid_raw_len = 0; - if (pstr->trans) - c = pstr->trans[c]; - pstr->tip_context = (bitset_contain (pstr->word_char, c) - ? CONTEXT_WORD - : ((IS_NEWLINE (c) && pstr->newline_anchor) - ? CONTEXT_NEWLINE : 0)); - } - } - if (!BE (pstr->mbs_allocated, 0)) - pstr->mbs += offset; - } - pstr->raw_mbs_idx = idx; - pstr->len -= offset; - pstr->stop -= offset; - - /* Then build the buffers. */ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - if (pstr->icase) - { - reg_errcode_t ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - else - build_wcs_buffer (pstr); - } - else -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) - { - if (pstr->icase) - build_upper_buffer (pstr); - else if (pstr->trans != NULL) - re_string_translate_buffer (pstr); - } - else - pstr->valid_len = pstr->len; - - pstr->cur_idx = 0; - return REG_NOERROR; -} - -static unsigned char -internal_function __attribute__ ((pure)) -re_string_peek_byte_case (const re_string_t *pstr, Idx idx) -{ - int ch; - Idx off; - - /* Handle the common (easiest) cases first. */ - if (BE (!pstr->mbs_allocated, 1)) - return re_string_peek_byte (pstr, idx); - -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1 - && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) - return re_string_peek_byte (pstr, idx); -#endif - - off = pstr->cur_idx + idx; -#ifdef RE_ENABLE_I18N - if (pstr->offsets_needed) - off = pstr->offsets[off]; -#endif - - ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; - -#ifdef RE_ENABLE_I18N - /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I - this function returns CAPITAL LETTER I instead of first byte of - DOTLESS SMALL LETTER I. The latter would confuse the parser, - since peek_byte_case doesn't advance cur_idx in any way. */ - if (pstr->offsets_needed && !isascii (ch)) - return re_string_peek_byte (pstr, idx); -#endif - - return ch; -} - -static unsigned char -internal_function -re_string_fetch_byte_case (re_string_t *pstr) -{ - if (BE (!pstr->mbs_allocated, 1)) - return re_string_fetch_byte (pstr); - -#ifdef RE_ENABLE_I18N - if (pstr->offsets_needed) - { - Idx off; - int ch; - - /* For tr_TR.UTF-8 [[:islower:]] there is - [[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip - in that case the whole multi-byte character and return - the original letter. On the other side, with - [[: DOTLESS SMALL LETTER I return [[:I, as doing - anything else would complicate things too much. */ - - if (!re_string_first_byte (pstr, pstr->cur_idx)) - return re_string_fetch_byte (pstr); - - off = pstr->offsets[pstr->cur_idx]; - ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; - - if (! isascii (ch)) - return re_string_fetch_byte (pstr); - - re_string_skip_bytes (pstr, - re_string_char_size_at (pstr, pstr->cur_idx)); - return ch; - } -#endif - - return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; -} - -static void -internal_function -re_string_destruct (re_string_t *pstr) -{ -#ifdef RE_ENABLE_I18N - re_free (pstr->wcs); - re_free (pstr->offsets); -#endif /* RE_ENABLE_I18N */ - if (pstr->mbs_allocated) - re_free (pstr->mbs); -} - -/* Return the context at IDX in INPUT. */ - -static unsigned int -internal_function -re_string_context_at (const re_string_t *input, Idx idx, int eflags) -{ - int c; - if (BE (! REG_VALID_INDEX (idx), 0)) - /* In this case, we use the value stored in input->tip_context, - since we can't know the character in input->mbs[-1] here. */ - return input->tip_context; - if (BE (idx == input->len, 0)) - return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF - : CONTEXT_NEWLINE | CONTEXT_ENDBUF); -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc; - Idx wc_idx = idx; - while(input->wcs[wc_idx] == WEOF) - { -#ifdef DEBUG - /* It must not happen. */ - assert (REG_VALID_INDEX (wc_idx)); -#endif - --wc_idx; - if (! REG_VALID_INDEX (wc_idx)) - return input->tip_context; - } - wc = input->wcs[wc_idx]; - if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) - return CONTEXT_WORD; - return (IS_WIDE_NEWLINE (wc) && input->newline_anchor - ? CONTEXT_NEWLINE : 0); - } - else -#endif - { - c = re_string_byte_at (input, idx); - if (bitset_contain (input->word_char, c)) - return CONTEXT_WORD; - return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0; - } -} - -/* Functions for set operation. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_node_set_alloc (re_node_set *set, Idx size) -{ - set->alloc = size; - set->nelem = 0; - set->elems = re_malloc (Idx, size); - if (BE (set->elems == NULL, 0) && (MALLOC_0_IS_NONNULL || size != 0)) - return REG_ESPACE; - return REG_NOERROR; -} - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_node_set_init_1 (re_node_set *set, Idx elem) -{ - set->alloc = 1; - set->nelem = 1; - set->elems = re_malloc (Idx, 1); - if (BE (set->elems == NULL, 0)) - { - set->alloc = set->nelem = 0; - return REG_ESPACE; - } - set->elems[0] = elem; - return REG_NOERROR; -} - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) -{ - set->alloc = 2; - set->elems = re_malloc (Idx, 2); - if (BE (set->elems == NULL, 0)) - return REG_ESPACE; - if (elem1 == elem2) - { - set->nelem = 1; - set->elems[0] = elem1; - } - else - { - set->nelem = 2; - if (elem1 < elem2) - { - set->elems[0] = elem1; - set->elems[1] = elem2; - } - else - { - set->elems[0] = elem2; - set->elems[1] = elem1; - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_node_set_init_copy (re_node_set *dest, const re_node_set *src) -{ - dest->nelem = src->nelem; - if (src->nelem > 0) - { - dest->alloc = dest->nelem; - dest->elems = re_malloc (Idx, dest->alloc); - if (BE (dest->elems == NULL, 0)) - { - dest->alloc = dest->nelem = 0; - return REG_ESPACE; - } - memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); - } - else - re_node_set_init_empty (dest); - return REG_NOERROR; -} - -/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. - Note: We assume dest->elems is NULL, when dest->alloc is 0. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, - const re_node_set *src2) -{ - Idx i1, i2, is, id, delta, sbase; - if (src1->nelem == 0 || src2->nelem == 0) - return REG_NOERROR; - - /* We need dest->nelem + 2 * elems_in_intersection; this is a - conservative estimate. */ - if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) - { - Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; - Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); - if (BE (new_elems == NULL, 0)) - return REG_ESPACE; - dest->elems = new_elems; - dest->alloc = new_alloc; - } - - /* Find the items in the intersection of SRC1 and SRC2, and copy - into the top of DEST those that are not already in DEST itself. */ - sbase = dest->nelem + src1->nelem + src2->nelem; - i1 = src1->nelem - 1; - i2 = src2->nelem - 1; - id = dest->nelem - 1; - for (;;) - { - if (src1->elems[i1] == src2->elems[i2]) - { - /* Try to find the item in DEST. Maybe we could binary search? */ - while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) - --id; - - if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) - dest->elems[--sbase] = src1->elems[i1]; - - if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) - break; - } - - /* Lower the highest of the two items. */ - else if (src1->elems[i1] < src2->elems[i2]) - { - if (! REG_VALID_INDEX (--i2)) - break; - } - else - { - if (! REG_VALID_INDEX (--i1)) - break; - } - } - - id = dest->nelem - 1; - is = dest->nelem + src1->nelem + src2->nelem - 1; - delta = is - sbase + 1; - - /* Now copy. When DELTA becomes zero, the remaining - DEST elements are already in place; this is more or - less the same loop that is in re_node_set_merge. */ - dest->nelem += delta; - if (delta > 0 && REG_VALID_INDEX (id)) - for (;;) - { - if (dest->elems[is] > dest->elems[id]) - { - /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; - if (delta == 0) - break; - } - else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; - if (! REG_VALID_INDEX (--id)) - break; - } - } - - /* Copy remaining SRC elements. */ - memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx)); - - return REG_NOERROR; -} - -/* Calculate the union set of the sets SRC1 and SRC2. And store it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_node_set_init_union (re_node_set *dest, const re_node_set *src1, - const re_node_set *src2) -{ - Idx i1, i2, id; - if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) - { - dest->alloc = src1->nelem + src2->nelem; - dest->elems = re_malloc (Idx, dest->alloc); - if (BE (dest->elems == NULL, 0)) - return REG_ESPACE; - } - else - { - if (src1 != NULL && src1->nelem > 0) - return re_node_set_init_copy (dest, src1); - else if (src2 != NULL && src2->nelem > 0) - return re_node_set_init_copy (dest, src2); - else - re_node_set_init_empty (dest); - return REG_NOERROR; - } - for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;) - { - if (src1->elems[i1] > src2->elems[i2]) - { - dest->elems[id++] = src2->elems[i2++]; - continue; - } - if (src1->elems[i1] == src2->elems[i2]) - ++i2; - dest->elems[id++] = src1->elems[i1++]; - } - if (i1 < src1->nelem) - { - memcpy (dest->elems + id, src1->elems + i1, - (src1->nelem - i1) * sizeof (Idx)); - id += src1->nelem - i1; - } - else if (i2 < src2->nelem) - { - memcpy (dest->elems + id, src2->elems + i2, - (src2->nelem - i2) * sizeof (Idx)); - id += src2->nelem - i2; - } - dest->nelem = id; - return REG_NOERROR; -} - -/* Calculate the union set of the sets DEST and SRC. And store it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -re_node_set_merge (re_node_set *dest, const re_node_set *src) -{ - Idx is, id, sbase, delta; - if (src == NULL || src->nelem == 0) - return REG_NOERROR; - if (dest->alloc < 2 * src->nelem + dest->nelem) - { - Idx new_alloc = 2 * (src->nelem + dest->alloc); - Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc); - if (BE (new_buffer == NULL, 0)) - return REG_ESPACE; - dest->elems = new_buffer; - dest->alloc = new_alloc; - } - - if (BE (dest->nelem == 0, 0)) - { - dest->nelem = src->nelem; - memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); - return REG_NOERROR; - } - - /* Copy into the top of DEST the items of SRC that are not - found in DEST. Maybe we could binary search in DEST? */ - for (sbase = dest->nelem + 2 * src->nelem, - is = src->nelem - 1, id = dest->nelem - 1; - REG_VALID_INDEX (is) && REG_VALID_INDEX (id); ) - { - if (dest->elems[id] == src->elems[is]) - is--, id--; - else if (dest->elems[id] < src->elems[is]) - dest->elems[--sbase] = src->elems[is--]; - else /* if (dest->elems[id] > src->elems[is]) */ - --id; - } - - if (REG_VALID_INDEX (is)) - { - /* If DEST is exhausted, the remaining items of SRC must be unique. */ - sbase -= is + 1; - memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx)); - } - - id = dest->nelem - 1; - is = dest->nelem + 2 * src->nelem - 1; - delta = is - sbase + 1; - if (delta == 0) - return REG_NOERROR; - - /* Now copy. When DELTA becomes zero, the remaining - DEST elements are already in place. */ - dest->nelem += delta; - for (;;) - { - if (dest->elems[is] > dest->elems[id]) - { - /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; - if (delta == 0) - break; - } - else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; - if (! REG_VALID_INDEX (--id)) - { - /* Copy remaining SRC elements. */ - memcpy (dest->elems, dest->elems + sbase, - delta * sizeof (Idx)); - break; - } - } - } - - return REG_NOERROR; -} - -/* Insert the new element ELEM to the re_node_set* SET. - SET should not already have ELEM. - Return true if successful. */ - -static bool -internal_function __attribute_warn_unused_result__ -re_node_set_insert (re_node_set *set, Idx elem) -{ - Idx idx; - /* In case the set is empty. */ - if (set->alloc == 0) - return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1); - - if (BE (set->nelem, 0) == 0) - { - /* We already guaranteed above that set->alloc != 0. */ - set->elems[0] = elem; - ++set->nelem; - return true; - } - - /* Realloc if we need. */ - if (set->alloc == set->nelem) - { - Idx *new_elems; - set->alloc = set->alloc * 2; - new_elems = re_realloc (set->elems, Idx, set->alloc); - if (BE (new_elems == NULL, 0)) - return false; - set->elems = new_elems; - } - - /* Move the elements which follows the new element. Test the - first element separately to skip a check in the inner loop. */ - if (elem < set->elems[0]) - { - idx = 0; - for (idx = set->nelem; idx > 0; idx--) - set->elems[idx] = set->elems[idx - 1]; - } - else - { - for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) - set->elems[idx] = set->elems[idx - 1]; - } - - /* Insert the new element. */ - set->elems[idx] = elem; - ++set->nelem; - return true; -} - -/* Insert the new element ELEM to the re_node_set* SET. - SET should not already have any element greater than or equal to ELEM. - Return true if successful. */ - -static bool -internal_function __attribute_warn_unused_result__ -re_node_set_insert_last (re_node_set *set, Idx elem) -{ - /* Realloc if we need. */ - if (set->alloc == set->nelem) - { - Idx *new_elems; - set->alloc = (set->alloc + 1) * 2; - new_elems = re_realloc (set->elems, Idx, set->alloc); - if (BE (new_elems == NULL, 0)) - return false; - set->elems = new_elems; - } - - /* Insert the new element. */ - set->elems[set->nelem++] = elem; - return true; -} - -/* Compare two node sets SET1 and SET2. - Return true if SET1 and SET2 are equivalent. */ - -static bool -internal_function __attribute__ ((pure)) -re_node_set_compare (const re_node_set *set1, const re_node_set *set2) -{ - Idx i; - if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) - return false; - for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) - if (set1->elems[i] != set2->elems[i]) - return false; - return true; -} - -/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ - -static Idx -internal_function __attribute__ ((pure)) -re_node_set_contains (const re_node_set *set, Idx elem) -{ - __re_size_t idx, right, mid; - if (! REG_VALID_NONZERO_INDEX (set->nelem)) - return 0; - - /* Binary search the element. */ - idx = 0; - right = set->nelem - 1; - while (idx < right) - { - mid = (idx + right) / 2; - if (set->elems[mid] < elem) - idx = mid + 1; - else - right = mid; - } - return set->elems[idx] == elem ? idx + 1 : 0; -} - -static void -internal_function -re_node_set_remove_at (re_node_set *set, Idx idx) -{ - if (idx < 0 || idx >= set->nelem) - return; - --set->nelem; - for (; idx < set->nelem; idx++) - set->elems[idx] = set->elems[idx + 1]; -} - - -/* Add the token TOKEN to dfa->nodes, and return the index of the token. - Or return REG_MISSING if an error occurred. */ - -static Idx -internal_function -re_dfa_add_node (re_dfa_t *dfa, re_token_t token) -{ - if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) - { - size_t new_nodes_alloc = dfa->nodes_alloc * 2; - Idx *new_nexts, *new_indices; - re_node_set *new_edests, *new_eclosures; - re_token_t *new_nodes; - - /* Avoid overflows in realloc. */ - const size_t max_object_size = MAX (sizeof (re_token_t), - MAX (sizeof (re_node_set), - sizeof (Idx))); - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_nodes_alloc, 0)) - return REG_MISSING; - - new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); - if (BE (new_nodes == NULL, 0)) - return REG_MISSING; - dfa->nodes = new_nodes; - new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); - new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); - new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); - new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); - if (BE (new_nexts == NULL || new_indices == NULL - || new_edests == NULL || new_eclosures == NULL, 0)) - return REG_MISSING; - dfa->nexts = new_nexts; - dfa->org_indices = new_indices; - dfa->edests = new_edests; - dfa->eclosures = new_eclosures; - dfa->nodes_alloc = new_nodes_alloc; - } - dfa->nodes[dfa->nodes_len] = token; - dfa->nodes[dfa->nodes_len].constraint = 0; -#ifdef RE_ENABLE_I18N - dfa->nodes[dfa->nodes_len].accept_mb = - ((token.type == OP_PERIOD && dfa->mb_cur_max > 1) - || token.type == COMPLEX_BRACKET); -#endif - dfa->nexts[dfa->nodes_len] = REG_MISSING; - re_node_set_init_empty (dfa->edests + dfa->nodes_len); - re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); - return dfa->nodes_len++; -} - -static re_hashval_t -internal_function -calc_state_hash (const re_node_set *nodes, unsigned int context) -{ - re_hashval_t hash = nodes->nelem + context; - Idx i; - for (i = 0 ; i < nodes->nelem ; i++) - hash += nodes->elems[i]; - return hash; -} - -/* Search for the state whose node_set is equivalent to NODES. - Return the pointer to the state, if we found it in the DFA. - Otherwise create the new one and return it. In case of an error - return NULL and set the error code in ERR. - Note: - We assume NULL as the invalid state, then it is possible that - return value is NULL and ERR is REG_NOERROR. - - We never return non-NULL value in case of any errors, it is for - optimization. */ - -static re_dfastate_t * -internal_function __attribute_warn_unused_result__ -re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, - const re_node_set *nodes) -{ - re_hashval_t hash; - re_dfastate_t *new_state; - struct re_state_table_entry *spot; - Idx i; -#ifdef lint - /* Suppress bogus uninitialized-variable warnings. */ - *err = REG_NOERROR; -#endif - if (BE (nodes->nelem == 0, 0)) - { - *err = REG_NOERROR; - return NULL; - } - hash = calc_state_hash (nodes, 0); - spot = dfa->state_table + (hash & dfa->state_hash_mask); - - for (i = 0 ; i < spot->num ; i++) - { - re_dfastate_t *state = spot->array[i]; - if (hash != state->hash) - continue; - if (re_node_set_compare (&state->nodes, nodes)) - return state; - } - - /* There are no appropriate state in the dfa, create the new one. */ - new_state = create_ci_newstate (dfa, nodes, hash); - if (BE (new_state == NULL, 0)) - *err = REG_ESPACE; - - return new_state; -} - -/* Search for the state whose node_set is equivalent to NODES and - whose context is equivalent to CONTEXT. - Return the pointer to the state, if we found it in the DFA. - Otherwise create the new one and return it. In case of an error - return NULL and set the error code in ERR. - Note: - We assume NULL as the invalid state, then it is possible that - return value is NULL and ERR is REG_NOERROR. - - We never return non-NULL value in case of any errors, it is for - optimization. */ - -static re_dfastate_t * -internal_function __attribute_warn_unused_result__ -re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, - const re_node_set *nodes, unsigned int context) -{ - re_hashval_t hash; - re_dfastate_t *new_state; - struct re_state_table_entry *spot; - Idx i; -#ifdef lint - /* Suppress bogus uninitialized-variable warnings. */ - *err = REG_NOERROR; -#endif - if (nodes->nelem == 0) - { - *err = REG_NOERROR; - return NULL; - } - hash = calc_state_hash (nodes, context); - spot = dfa->state_table + (hash & dfa->state_hash_mask); - - for (i = 0 ; i < spot->num ; i++) - { - re_dfastate_t *state = spot->array[i]; - if (state->hash == hash - && state->context == context - && re_node_set_compare (state->entrance_nodes, nodes)) - return state; - } - /* There are no appropriate state in 'dfa', create the new one. */ - new_state = create_cd_newstate (dfa, nodes, context, hash); - if (BE (new_state == NULL, 0)) - *err = REG_ESPACE; - - return new_state; -} - -/* Finish initialization of the new state NEWSTATE, and using its hash value - HASH put in the appropriate bucket of DFA's state table. Return value - indicates the error code if failed. */ - -static reg_errcode_t -__attribute_warn_unused_result__ -register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, - re_hashval_t hash) -{ - struct re_state_table_entry *spot; - reg_errcode_t err; - Idx i; - - newstate->hash = hash; - err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - for (i = 0; i < newstate->nodes.nelem; i++) - { - Idx elem = newstate->nodes.elems[i]; - if (!IS_EPSILON_NODE (dfa->nodes[elem].type)) - if (! re_node_set_insert_last (&newstate->non_eps_nodes, elem)) - return REG_ESPACE; - } - - spot = dfa->state_table + (hash & dfa->state_hash_mask); - if (BE (spot->alloc <= spot->num, 0)) - { - Idx new_alloc = 2 * spot->num + 2; - re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, - new_alloc); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - spot->array = new_array; - spot->alloc = new_alloc; - } - spot->array[spot->num++] = newstate; - return REG_NOERROR; -} - -static void -free_state (re_dfastate_t *state) -{ - re_node_set_free (&state->non_eps_nodes); - re_node_set_free (&state->inveclosure); - if (state->entrance_nodes != &state->nodes) - { - re_node_set_free (state->entrance_nodes); - re_free (state->entrance_nodes); - } - re_node_set_free (&state->nodes); - re_free (state->word_trtable); - re_free (state->trtable); - re_free (state); -} - -/* Create the new state which is independent of contexts. - Return the new state if succeeded, otherwise return NULL. */ - -static re_dfastate_t * -internal_function __attribute_warn_unused_result__ -create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, - re_hashval_t hash) -{ - Idx i; - reg_errcode_t err; - re_dfastate_t *newstate; - - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) - return NULL; - err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_free (newstate); - return NULL; - } - - newstate->entrance_nodes = &newstate->nodes; - for (i = 0 ; i < nodes->nelem ; i++) - { - re_token_t *node = dfa->nodes + nodes->elems[i]; - re_token_type_t type = node->type; - if (type == CHARACTER && !node->constraint) - continue; -#ifdef RE_ENABLE_I18N - newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ - - /* If the state has the halt node, the state is a halt state. */ - if (type == END_OF_RE) - newstate->halt = 1; - else if (type == OP_BACK_REF) - newstate->has_backref = 1; - else if (type == ANCHOR || node->constraint) - newstate->has_constraint = 1; - } - err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) - { - free_state (newstate); - newstate = NULL; - } - return newstate; -} - -/* Create the new state which is depend on the context CONTEXT. - Return the new state if succeeded, otherwise return NULL. */ - -static re_dfastate_t * -internal_function __attribute_warn_unused_result__ -create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, - unsigned int context, re_hashval_t hash) -{ - Idx i, nctx_nodes = 0; - reg_errcode_t err; - re_dfastate_t *newstate; - - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) - return NULL; - err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_free (newstate); - return NULL; - } - - newstate->context = context; - newstate->entrance_nodes = &newstate->nodes; - - for (i = 0 ; i < nodes->nelem ; i++) - { - re_token_t *node = dfa->nodes + nodes->elems[i]; - re_token_type_t type = node->type; - unsigned int constraint = node->constraint; - - if (type == CHARACTER && !constraint) - continue; -#ifdef RE_ENABLE_I18N - newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ - - /* If the state has the halt node, the state is a halt state. */ - if (type == END_OF_RE) - newstate->halt = 1; - else if (type == OP_BACK_REF) - newstate->has_backref = 1; - - if (constraint) - { - if (newstate->entrance_nodes == &newstate->nodes) - { - newstate->entrance_nodes = re_malloc (re_node_set, 1); - if (BE (newstate->entrance_nodes == NULL, 0)) - { - free_state (newstate); - return NULL; - } - if (re_node_set_init_copy (newstate->entrance_nodes, nodes) - != REG_NOERROR) - return NULL; - nctx_nodes = 0; - newstate->has_constraint = 1; - } - - if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context)) - { - re_node_set_remove_at (&newstate->nodes, i - nctx_nodes); - ++nctx_nodes; - } - } - } - err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) - { - free_state (newstate); - newstate = NULL; - } - return newstate; -} diff --git a/grub-core/gnulib/regex_internal.h b/grub-core/gnulib/regex_internal.h deleted file mode 100644 index c467b2907..000000000 --- a/grub-core/gnulib/regex_internal.h +++ /dev/null @@ -1,873 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _REGEX_INTERNAL_H -#define _REGEX_INTERNAL_H 1 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#if defined _LIBC -# include -#else -# define __libc_lock_init(NAME) do { } while (0) -# define __libc_lock_lock(NAME) do { } while (0) -# define __libc_lock_unlock(NAME) do { } while (0) -#endif - -/* In case that the system doesn't have isblank(). */ -#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) -# define isblank(ch) ((ch) == ' ' || (ch) == '\t') -#endif - -#ifdef _LIBC -# ifndef _RE_DEFINE_LOCALE_FUNCTIONS -# define _RE_DEFINE_LOCALE_FUNCTIONS 1 -# include -# include -# include -# endif -#endif - -/* This is for other GNU distributions with internationalized messages. */ -#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC -# include -# ifdef _LIBC -# undef gettext -# define gettext(msgid) \ - __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) -# endif -#else -# define gettext(msgid) (msgid) -#endif - -#ifndef gettext_noop -/* This define is so xgettext can find the internationalizable - strings. */ -# define gettext_noop(String) String -#endif - -#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC -# define RE_ENABLE_I18N -#endif - -#if __GNUC__ >= 3 -# define BE(expr, val) __builtin_expect (expr, val) -#else -# define BE(expr, val) (expr) -#endif - -/* Number of ASCII characters. */ -#define ASCII_CHARS 0x80 - -/* Number of single byte characters. */ -#define SBC_MAX (UCHAR_MAX + 1) - -#define COLL_ELEM_LEN_MAX 8 - -/* The character which represents newline. */ -#define NEWLINE_CHAR '\n' -#define WIDE_NEWLINE_CHAR L'\n' - -/* Rename to standard API for using out of glibc. */ -#ifndef _LIBC -# undef __wctype -# undef __iswctype -# define __wctype wctype -# define __iswctype iswctype -# define __btowc btowc -# define __mbrtowc mbrtowc -# define __wcrtomb wcrtomb -# define __regfree regfree -# define attribute_hidden -#endif /* not _LIBC */ - -#if __GNUC__ < 3 + (__GNUC_MINOR__ < 1) -# define __attribute__(arg) -#endif - -typedef __re_idx_t Idx; -#ifdef _REGEX_LARGE_OFFSETS -# define IDX_MAX (SIZE_MAX - 2) -#else -# define IDX_MAX INT_MAX -#endif - -/* Special return value for failure to match. */ -#define REG_MISSING ((Idx) -1) - -/* Special return value for internal error. */ -#define REG_ERROR ((Idx) -2) - -/* Test whether N is a valid index, and is not one of the above. */ -#ifdef _REGEX_LARGE_OFFSETS -# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR) -#else -# define REG_VALID_INDEX(n) (0 <= (n)) -#endif - -/* Test whether N is a valid nonzero index. */ -#ifdef _REGEX_LARGE_OFFSETS -# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1)) -#else -# define REG_VALID_NONZERO_INDEX(n) (0 < (n)) -#endif - -/* A hash value, suitable for computing hash tables. */ -typedef __re_size_t re_hashval_t; - -/* An integer used to represent a set of bits. It must be unsigned, - and must be at least as wide as unsigned int. */ -typedef unsigned long int bitset_word_t; -/* All bits set in a bitset_word_t. */ -#define BITSET_WORD_MAX ULONG_MAX - -/* Number of bits in a bitset_word_t. For portability to hosts with - padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)'; - instead, deduce it directly from BITSET_WORD_MAX. Avoid - greater-than-32-bit integers and unconditional shifts by more than - 31 bits, as they're not portable. */ -#if BITSET_WORD_MAX == 0xffffffffUL -# define BITSET_WORD_BITS 32 -#elif BITSET_WORD_MAX >> 31 >> 4 == 1 -# define BITSET_WORD_BITS 36 -#elif BITSET_WORD_MAX >> 31 >> 16 == 1 -# define BITSET_WORD_BITS 48 -#elif BITSET_WORD_MAX >> 31 >> 28 == 1 -# define BITSET_WORD_BITS 60 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1 -# define BITSET_WORD_BITS 64 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1 -# define BITSET_WORD_BITS 72 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1 -# define BITSET_WORD_BITS 128 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1 -# define BITSET_WORD_BITS 256 -#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1 -# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */ -# if BITSET_WORD_BITS <= SBC_MAX -# error "Invalid SBC_MAX" -# endif -#else -# error "Add case for new bitset_word_t size" -#endif - -/* Number of bitset_word_t values in a bitset_t. */ -#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS) - -typedef bitset_word_t bitset_t[BITSET_WORDS]; -typedef bitset_word_t *re_bitset_ptr_t; -typedef const bitset_word_t *re_const_bitset_ptr_t; - -#define PREV_WORD_CONSTRAINT 0x0001 -#define PREV_NOTWORD_CONSTRAINT 0x0002 -#define NEXT_WORD_CONSTRAINT 0x0004 -#define NEXT_NOTWORD_CONSTRAINT 0x0008 -#define PREV_NEWLINE_CONSTRAINT 0x0010 -#define NEXT_NEWLINE_CONSTRAINT 0x0020 -#define PREV_BEGBUF_CONSTRAINT 0x0040 -#define NEXT_ENDBUF_CONSTRAINT 0x0080 -#define WORD_DELIM_CONSTRAINT 0x0100 -#define NOT_WORD_DELIM_CONSTRAINT 0x0200 - -typedef enum -{ - INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, - WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, - WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, - INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, - LINE_FIRST = PREV_NEWLINE_CONSTRAINT, - LINE_LAST = NEXT_NEWLINE_CONSTRAINT, - BUF_FIRST = PREV_BEGBUF_CONSTRAINT, - BUF_LAST = NEXT_ENDBUF_CONSTRAINT, - WORD_DELIM = WORD_DELIM_CONSTRAINT, - NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT -} re_context_type; - -typedef struct -{ - Idx alloc; - Idx nelem; - Idx *elems; -} re_node_set; - -typedef enum -{ - NON_TYPE = 0, - - /* Node type, These are used by token, node, tree. */ - CHARACTER = 1, - END_OF_RE = 2, - SIMPLE_BRACKET = 3, - OP_BACK_REF = 4, - OP_PERIOD = 5, -#ifdef RE_ENABLE_I18N - COMPLEX_BRACKET = 6, - OP_UTF8_PERIOD = 7, -#endif /* RE_ENABLE_I18N */ - - /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used - when the debugger shows values of this enum type. */ -#define EPSILON_BIT 8 - OP_OPEN_SUBEXP = EPSILON_BIT | 0, - OP_CLOSE_SUBEXP = EPSILON_BIT | 1, - OP_ALT = EPSILON_BIT | 2, - OP_DUP_ASTERISK = EPSILON_BIT | 3, - ANCHOR = EPSILON_BIT | 4, - - /* Tree type, these are used only by tree. */ - CONCAT = 16, - SUBEXP = 17, - - /* Token type, these are used only by token. */ - OP_DUP_PLUS = 18, - OP_DUP_QUESTION, - OP_OPEN_BRACKET, - OP_CLOSE_BRACKET, - OP_CHARSET_RANGE, - OP_OPEN_DUP_NUM, - OP_CLOSE_DUP_NUM, - OP_NON_MATCH_LIST, - OP_OPEN_COLL_ELEM, - OP_CLOSE_COLL_ELEM, - OP_OPEN_EQUIV_CLASS, - OP_CLOSE_EQUIV_CLASS, - OP_OPEN_CHAR_CLASS, - OP_CLOSE_CHAR_CLASS, - OP_WORD, - OP_NOTWORD, - OP_SPACE, - OP_NOTSPACE, - BACK_SLASH - -} re_token_type_t; - -#ifdef RE_ENABLE_I18N -typedef struct -{ - /* Multibyte characters. */ - wchar_t *mbchars; - - /* Collating symbols. */ -# ifdef _LIBC - int32_t *coll_syms; -# endif - - /* Equivalence classes. */ -# ifdef _LIBC - int32_t *equiv_classes; -# endif - - /* Range expressions. */ -# ifdef _LIBC - uint32_t *range_starts; - uint32_t *range_ends; -# else /* not _LIBC */ - wchar_t *range_starts; - wchar_t *range_ends; -# endif /* not _LIBC */ - - /* Character classes. */ - wctype_t *char_classes; - - /* If this character set is the non-matching list. */ - unsigned int non_match : 1; - - /* # of multibyte characters. */ - Idx nmbchars; - - /* # of collating symbols. */ - Idx ncoll_syms; - - /* # of equivalence classes. */ - Idx nequiv_classes; - - /* # of range expressions. */ - Idx nranges; - - /* # of character classes. */ - Idx nchar_classes; -} re_charset_t; -#endif /* RE_ENABLE_I18N */ - -typedef struct -{ - union - { - unsigned char c; /* for CHARACTER */ - re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; /* for COMPLEX_BRACKET */ -#endif /* RE_ENABLE_I18N */ - Idx idx; /* for BACK_REF */ - re_context_type ctx_type; /* for ANCHOR */ - } opr; -#if __GNUC__ >= 2 && !defined __STRICT_ANSI__ - re_token_type_t type : 8; -#else - re_token_type_t type; -#endif - unsigned int constraint : 10; /* context constraint */ - unsigned int duplicated : 1; - unsigned int opt_subexp : 1; -#ifdef RE_ENABLE_I18N - unsigned int accept_mb : 1; - /* These 2 bits can be moved into the union if needed (e.g. if running out - of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */ - unsigned int mb_partial : 1; -#endif - unsigned int word_char : 1; -} re_token_t; - -#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT) - -struct re_string_t -{ - /* Indicate the raw buffer which is the original string passed as an - argument of regexec(), re_search(), etc.. */ - const unsigned char *raw_mbs; - /* Store the multibyte string. In case of "case insensitive mode" like - REG_ICASE, upper cases of the string are stored, otherwise MBS points - the same address that RAW_MBS points. */ - unsigned char *mbs; -#ifdef RE_ENABLE_I18N - /* Store the wide character string which is corresponding to MBS. */ - wint_t *wcs; - Idx *offsets; - mbstate_t cur_state; -#endif - /* Index in RAW_MBS. Each character mbs[i] corresponds to - raw_mbs[raw_mbs_idx + i]. */ - Idx raw_mbs_idx; - /* The length of the valid characters in the buffers. */ - Idx valid_len; - /* The corresponding number of bytes in raw_mbs array. */ - Idx valid_raw_len; - /* The length of the buffers MBS and WCS. */ - Idx bufs_len; - /* The index in MBS, which is updated by re_string_fetch_byte. */ - Idx cur_idx; - /* length of RAW_MBS array. */ - Idx raw_len; - /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */ - Idx len; - /* End of the buffer may be shorter than its length in the cases such - as re_match_2, re_search_2. Then, we use STOP for end of the buffer - instead of LEN. */ - Idx raw_stop; - /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */ - Idx stop; - - /* The context of mbs[0]. We store the context independently, since - the context of mbs[0] may be different from raw_mbs[0], which is - the beginning of the input string. */ - unsigned int tip_context; - /* The translation passed as a part of an argument of re_compile_pattern. */ - RE_TRANSLATE_TYPE trans; - /* Copy of re_dfa_t's word_char. */ - re_const_bitset_ptr_t word_char; - /* true if REG_ICASE. */ - unsigned char icase; - unsigned char is_utf8; - unsigned char map_notascii; - unsigned char mbs_allocated; - unsigned char offsets_needed; - unsigned char newline_anchor; - unsigned char word_ops_used; - int mb_cur_max; -}; -typedef struct re_string_t re_string_t; - - -struct re_dfa_t; -typedef struct re_dfa_t re_dfa_t; - -#ifndef _LIBC -# define internal_function -#endif - -#ifndef NOT_IN_libc -static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, - Idx new_buf_len) - internal_function; -# ifdef RE_ENABLE_I18N -static void build_wcs_buffer (re_string_t *pstr) internal_function; -static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr) - internal_function; -# endif /* RE_ENABLE_I18N */ -static void build_upper_buffer (re_string_t *pstr) internal_function; -static void re_string_translate_buffer (re_string_t *pstr) internal_function; -static unsigned int re_string_context_at (const re_string_t *input, Idx idx, - int eflags) - internal_function __attribute__ ((pure)); -#endif -#define re_string_peek_byte(pstr, offset) \ - ((pstr)->mbs[(pstr)->cur_idx + offset]) -#define re_string_fetch_byte(pstr) \ - ((pstr)->mbs[(pstr)->cur_idx++]) -#define re_string_first_byte(pstr, idx) \ - ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF) -#define re_string_is_single_byte_char(pstr, idx) \ - ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \ - || (pstr)->wcs[(idx) + 1] != WEOF)) -#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx) -#define re_string_cur_idx(pstr) ((pstr)->cur_idx) -#define re_string_get_buffer(pstr) ((pstr)->mbs) -#define re_string_length(pstr) ((pstr)->len) -#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx]) -#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) -#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) - -#if defined _LIBC || HAVE_ALLOCA -# include -#endif - -#ifndef _LIBC -# if HAVE_ALLOCA -/* The OS usually guarantees only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - allocate anything larger than 4096 bytes. Also care for the possibility - of a few compiler-allocated temporary stack slots. */ -# define __libc_use_alloca(n) ((n) < 4032) -# else -/* alloca is implemented with malloc, so just use malloc. */ -# define __libc_use_alloca(n) 0 -# undef alloca -# define alloca(n) malloc (n) -# endif -#endif - -#ifdef _LIBC -# define MALLOC_0_IS_NONNULL 1 -#elif !defined MALLOC_0_IS_NONNULL -# define MALLOC_0_IS_NONNULL 0 -#endif - -#ifndef MAX -# define MAX(a,b) ((a) < (b) ? (b) : (a)) -#endif -#ifndef MIN -# define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) -#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) -#define re_free(p) free (p) - -struct bin_tree_t -{ - struct bin_tree_t *parent; - struct bin_tree_t *left; - struct bin_tree_t *right; - struct bin_tree_t *first; - struct bin_tree_t *next; - - re_token_t token; - - /* 'node_idx' is the index in dfa->nodes, if 'type' == 0. - Otherwise 'type' indicate the type of this node. */ - Idx node_idx; -}; -typedef struct bin_tree_t bin_tree_t; - -#define BIN_TREE_STORAGE_SIZE \ - ((1024 - sizeof (void *)) / sizeof (bin_tree_t)) - -struct bin_tree_storage_t -{ - struct bin_tree_storage_t *next; - bin_tree_t data[BIN_TREE_STORAGE_SIZE]; -}; -typedef struct bin_tree_storage_t bin_tree_storage_t; - -#define CONTEXT_WORD 1 -#define CONTEXT_NEWLINE (CONTEXT_WORD << 1) -#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1) -#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1) - -#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD) -#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE) -#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF) -#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF) -#define IS_ORDINARY_CONTEXT(c) ((c) == 0) - -#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_') -#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR) -#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_') -#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR) - -#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \ - ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ - || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ - || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\ - || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context))) - -#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \ - ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ - || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ - || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \ - || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context))) - -struct re_dfastate_t -{ - re_hashval_t hash; - re_node_set nodes; - re_node_set non_eps_nodes; - re_node_set inveclosure; - re_node_set *entrance_nodes; - struct re_dfastate_t **trtable, **word_trtable; - unsigned int context : 4; - unsigned int halt : 1; - /* If this state can accept "multi byte". - Note that we refer to multibyte characters, and multi character - collating elements as "multi byte". */ - unsigned int accept_mb : 1; - /* If this state has backreference node(s). */ - unsigned int has_backref : 1; - unsigned int has_constraint : 1; -}; -typedef struct re_dfastate_t re_dfastate_t; - -struct re_state_table_entry -{ - Idx num; - Idx alloc; - re_dfastate_t **array; -}; - -/* Array type used in re_sub_match_last_t and re_sub_match_top_t. */ - -typedef struct -{ - Idx next_idx; - Idx alloc; - re_dfastate_t **array; -} state_array_t; - -/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */ - -typedef struct -{ - Idx node; - Idx str_idx; /* The position NODE match at. */ - state_array_t path; -} re_sub_match_last_t; - -/* Store information about the node NODE whose type is OP_OPEN_SUBEXP. - And information about the node, whose type is OP_CLOSE_SUBEXP, - corresponding to NODE is stored in LASTS. */ - -typedef struct -{ - Idx str_idx; - Idx node; - state_array_t *path; - Idx alasts; /* Allocation size of LASTS. */ - Idx nlasts; /* The number of LASTS. */ - re_sub_match_last_t **lasts; -} re_sub_match_top_t; - -struct re_backref_cache_entry -{ - Idx node; - Idx str_idx; - Idx subexp_from; - Idx subexp_to; - char more; - char unused; - unsigned short int eps_reachable_subexps_map; -}; - -typedef struct -{ - /* The string object corresponding to the input string. */ - re_string_t input; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - const re_dfa_t *const dfa; -#else - const re_dfa_t *dfa; -#endif - /* EFLAGS of the argument of regexec. */ - int eflags; - /* Where the matching ends. */ - Idx match_last; - Idx last_node; - /* The state log used by the matcher. */ - re_dfastate_t **state_log; - Idx state_log_top; - /* Back reference cache. */ - Idx nbkref_ents; - Idx abkref_ents; - struct re_backref_cache_entry *bkref_ents; - int max_mb_elem_len; - Idx nsub_tops; - Idx asub_tops; - re_sub_match_top_t **sub_tops; -} re_match_context_t; - -typedef struct -{ - re_dfastate_t **sifted_states; - re_dfastate_t **limited_states; - Idx last_node; - Idx last_str_idx; - re_node_set limits; -} re_sift_context_t; - -struct re_fail_stack_ent_t -{ - Idx idx; - Idx node; - regmatch_t *regs; - re_node_set eps_via_nodes; -}; - -struct re_fail_stack_t -{ - Idx num; - Idx alloc; - struct re_fail_stack_ent_t *stack; -}; - -struct re_dfa_t -{ - re_token_t *nodes; - size_t nodes_alloc; - size_t nodes_len; - Idx *nexts; - Idx *org_indices; - re_node_set *edests; - re_node_set *eclosures; - re_node_set *inveclosures; - struct re_state_table_entry *state_table; - re_dfastate_t *init_state; - re_dfastate_t *init_state_word; - re_dfastate_t *init_state_nl; - re_dfastate_t *init_state_begbuf; - bin_tree_t *str_tree; - bin_tree_storage_t *str_tree_storage; - re_bitset_ptr_t sb_char; - int str_tree_storage_idx; - - /* number of subexpressions 're_nsub' is in regex_t. */ - re_hashval_t state_hash_mask; - Idx init_node; - Idx nbackref; /* The number of backreference in this dfa. */ - - /* Bitmap expressing which backreference is used. */ - bitset_word_t used_bkref_map; - bitset_word_t completed_bkref_map; - - unsigned int has_plural_match : 1; - /* If this dfa has "multibyte node", which is a backreference or - a node which can accept multibyte character or multi character - collating element. */ - unsigned int has_mb_node : 1; - unsigned int is_utf8 : 1; - unsigned int map_notascii : 1; - unsigned int word_ops_used : 1; - int mb_cur_max; - bitset_t word_char; - reg_syntax_t syntax; - Idx *subexp_map; -#ifdef DEBUG - char* re_str; -#endif -#ifdef _LIBC - __libc_lock_define (, lock) -#endif -}; - -#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set)) -#define re_node_set_remove(set,id) \ - (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1)) -#define re_node_set_empty(p) ((p)->nelem = 0) -#define re_node_set_free(set) re_free ((set)->elems) - - -typedef enum -{ - SB_CHAR, - MB_CHAR, - EQUIV_CLASS, - COLL_SYM, - CHAR_CLASS -} bracket_elem_type; - -typedef struct -{ - bracket_elem_type type; - union - { - unsigned char ch; - unsigned char *name; - wchar_t wch; - } opr; -} bracket_elem_t; - - -/* Functions for bitset_t operation. */ - -static void -bitset_set (bitset_t set, Idx i) -{ - set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; -} - -static void -bitset_clear (bitset_t set, Idx i) -{ - set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); -} - -static bool -bitset_contain (const bitset_t set, Idx i) -{ - return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; -} - -static void -bitset_empty (bitset_t set) -{ - memset (set, '\0', sizeof (bitset_t)); -} - -static void -bitset_set_all (bitset_t set) -{ - memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); - if (SBC_MAX % BITSET_WORD_BITS != 0) - set[BITSET_WORDS - 1] = - ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; -} - -static void -bitset_copy (bitset_t dest, const bitset_t src) -{ - memcpy (dest, src, sizeof (bitset_t)); -} - -static void __attribute__ ((unused)) -bitset_not (bitset_t set) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i) - set[bitset_i] = ~set[bitset_i]; - if (SBC_MAX % BITSET_WORD_BITS != 0) - set[BITSET_WORDS - 1] = - ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1) - & ~set[BITSET_WORDS - 1]); -} - -static void __attribute__ ((unused)) -bitset_merge (bitset_t dest, const bitset_t src) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) - dest[bitset_i] |= src[bitset_i]; -} - -static void __attribute__ ((unused)) -bitset_mask (bitset_t dest, const bitset_t src) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) - dest[bitset_i] &= src[bitset_i]; -} - -#ifdef RE_ENABLE_I18N -/* Functions for re_string. */ -static int -internal_function __attribute__ ((pure, unused)) -re_string_char_size_at (const re_string_t *pstr, Idx idx) -{ - int byte_idx; - if (pstr->mb_cur_max == 1) - return 1; - for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx) - if (pstr->wcs[idx + byte_idx] != WEOF) - break; - return byte_idx; -} - -static wint_t -internal_function __attribute__ ((pure, unused)) -re_string_wchar_at (const re_string_t *pstr, Idx idx) -{ - if (pstr->mb_cur_max == 1) - return (wint_t) pstr->mbs[idx]; - return (wint_t) pstr->wcs[idx]; -} - -# ifndef NOT_IN_libc -static int -internal_function __attribute__ ((pure, unused)) -re_string_elem_size_at (const re_string_t *pstr, Idx idx) -{ -# ifdef _LIBC - const unsigned char *p, *extra; - const int32_t *table, *indirect; -# include - uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - - if (nrules != 0) - { - table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_INDIRECTMB); - p = pstr->mbs + idx; - findidx (&p, pstr->len - idx); - return p - pstr->mbs - idx; - } - else -# endif /* _LIBC */ - return 1; -} -# endif -#endif /* RE_ENABLE_I18N */ - -#ifndef __GNUC_PREREQ -# if defined __GNUC__ && defined __GNUC_MINOR__ -# define __GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -# else -# define __GNUC_PREREQ(maj, min) 0 -# endif -#endif - -#if __GNUC_PREREQ (3,4) -# undef __attribute_warn_unused_result__ -# define __attribute_warn_unused_result__ \ - __attribute__ ((__warn_unused_result__)) -#else -# define __attribute_warn_unused_result__ /* empty */ -#endif - -#endif /* _REGEX_INTERNAL_H */ diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c deleted file mode 100644 index f632cd47b..000000000 --- a/grub-core/gnulib/regexec.c +++ /dev/null @@ -1,4414 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with the GNU C Library; if not, see - . */ - -static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, - Idx n) internal_function; -static void match_ctx_clean (re_match_context_t *mctx) internal_function; -static void match_ctx_free (re_match_context_t *cache) internal_function; -static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node, - Idx str_idx, Idx from, Idx to) - internal_function; -static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) - internal_function; -static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node, - Idx str_idx) internal_function; -static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop, - Idx node, Idx str_idx) - internal_function; -static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, - re_dfastate_t **limited_sts, Idx last_node, - Idx last_str_idx) - internal_function; -static reg_errcode_t re_search_internal (const regex_t *preg, - const char *string, Idx length, - Idx start, Idx last_start, Idx stop, - size_t nmatch, regmatch_t pmatch[], - int eflags) internal_function; -static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp, - const char *string1, Idx length1, - const char *string2, Idx length2, - Idx start, regoff_t range, - struct re_registers *regs, - Idx stop, bool ret_len) internal_function; -static regoff_t re_search_stub (struct re_pattern_buffer *bufp, - const char *string, Idx length, Idx start, - regoff_t range, Idx stop, - struct re_registers *regs, - bool ret_len) internal_function; -static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, - Idx nregs, int regs_allocated) internal_function; -static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx) - internal_function; -static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match, - Idx *p_match_first) internal_function; -static Idx check_halt_state_context (const re_match_context_t *mctx, - const re_dfastate_t *state, Idx idx) - internal_function; -static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, - regmatch_t *prev_idx_match, Idx cur_node, - Idx cur_idx, Idx nmatch) internal_function; -static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, - Idx str_idx, Idx dest_node, Idx nregs, - regmatch_t *regs, - re_node_set *eps_via_nodes) - internal_function; -static reg_errcode_t set_regs (const regex_t *preg, - const re_match_context_t *mctx, - size_t nmatch, regmatch_t *pmatch, - bool fl_backtrack) internal_function; -static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) - internal_function; - -#ifdef RE_ENABLE_I18N -static int sift_states_iter_mb (const re_match_context_t *mctx, - re_sift_context_t *sctx, - Idx node_idx, Idx str_idx, Idx max_str_idx) - internal_function; -#endif /* RE_ENABLE_I18N */ -static reg_errcode_t sift_states_backward (const re_match_context_t *mctx, - re_sift_context_t *sctx) - internal_function; -static reg_errcode_t build_sifted_states (const re_match_context_t *mctx, - re_sift_context_t *sctx, Idx str_idx, - re_node_set *cur_dest) - internal_function; -static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx, - re_sift_context_t *sctx, - Idx str_idx, - re_node_set *dest_nodes) - internal_function; -static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa, - re_node_set *dest_nodes, - const re_node_set *candidates) - internal_function; -static bool check_dst_limits (const re_match_context_t *mctx, - const re_node_set *limits, - Idx dst_node, Idx dst_idx, Idx src_node, - Idx src_idx) internal_function; -static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, - int boundaries, Idx subexp_idx, - Idx from_node, Idx bkref_idx) - internal_function; -static int check_dst_limits_calc_pos (const re_match_context_t *mctx, - Idx limit, Idx subexp_idx, - Idx node, Idx str_idx, - Idx bkref_idx) internal_function; -static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa, - re_node_set *dest_nodes, - const re_node_set *candidates, - re_node_set *limits, - struct re_backref_cache_entry *bkref_ents, - Idx str_idx) internal_function; -static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx, - re_sift_context_t *sctx, - Idx str_idx, const re_node_set *candidates) - internal_function; -static reg_errcode_t merge_state_array (const re_dfa_t *dfa, - re_dfastate_t **dst, - re_dfastate_t **src, Idx num) - internal_function; -static re_dfastate_t *find_recover_state (reg_errcode_t *err, - re_match_context_t *mctx) internal_function; -static re_dfastate_t *transit_state (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *state) internal_function; -static re_dfastate_t *merge_state_with_log (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *next_state) - internal_function; -static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx, - re_node_set *cur_nodes, - Idx str_idx) internal_function; -#if 0 -static re_dfastate_t *transit_state_sb (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; -#endif -#ifdef RE_ENABLE_I18N -static reg_errcode_t transit_state_mb (re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; -#endif /* RE_ENABLE_I18N */ -static reg_errcode_t transit_state_bkref (re_match_context_t *mctx, - const re_node_set *nodes) - internal_function; -static reg_errcode_t get_subexp (re_match_context_t *mctx, - Idx bkref_node, Idx bkref_str_idx) - internal_function; -static reg_errcode_t get_subexp_sub (re_match_context_t *mctx, - const re_sub_match_top_t *sub_top, - re_sub_match_last_t *sub_last, - Idx bkref_node, Idx bkref_str) - internal_function; -static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, - Idx subexp_idx, int type) internal_function; -static reg_errcode_t check_arrival (re_match_context_t *mctx, - state_array_t *path, Idx top_node, - Idx top_str, Idx last_node, Idx last_str, - int type) internal_function; -static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx, - Idx str_idx, - re_node_set *cur_nodes, - re_node_set *next_nodes) - internal_function; -static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa, - re_node_set *cur_nodes, - Idx ex_subexp, int type) - internal_function; -static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa, - re_node_set *dst_nodes, - Idx target, Idx ex_subexp, - int type) internal_function; -static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx, - re_node_set *cur_nodes, Idx cur_str, - Idx subexp_num, int type) - internal_function; -static bool build_trtable (const re_dfa_t *dfa, - re_dfastate_t *state) internal_function; -#ifdef RE_ENABLE_I18N -static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, - const re_string_t *input, Idx idx) - internal_function; -# ifdef _LIBC -static unsigned int find_collation_sequence_value (const unsigned char *mbs, - size_t name_len) - internal_function; -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ -static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa, - const re_dfastate_t *state, - re_node_set *states_node, - bitset_t *states_ch) internal_function; -static bool check_node_accept (const re_match_context_t *mctx, - const re_token_t *node, Idx idx) - internal_function; -static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len) - internal_function; - -/* Entry point for POSIX code. */ - -/* regexec searches for a given pattern, specified by PREG, in the - string STRING. - - If NMATCH is zero or REG_NOSUB was set in the cflags argument to - 'regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at - least NMATCH elements, and we set them to the offsets of the - corresponding matched substrings. - - EFLAGS specifies "execution flags" which affect matching: if - REG_NOTBOL is set, then ^ does not match at the beginning of the - string; if REG_NOTEOL is set, then $ does not match at the end. - - We return 0 if we find a match and REG_NOMATCH if not. */ - -int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *_Restrict_ preg; - const char *_Restrict_ string; - size_t nmatch; - regmatch_t pmatch[_Restrict_arr_]; - int eflags; -{ - reg_errcode_t err; - Idx start, length; -#ifdef _LIBC - re_dfa_t *dfa = preg->buffer; -#endif - - if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND)) - return REG_BADPAT; - - if (eflags & REG_STARTEND) - { - start = pmatch[0].rm_so; - length = pmatch[0].rm_eo; - } - else - { - start = 0; - length = strlen (string); - } - - __libc_lock_lock (dfa->lock); - if (preg->no_sub) - err = re_search_internal (preg, string, length, start, length, - length, 0, NULL, eflags); - else - err = re_search_internal (preg, string, length, start, length, - length, nmatch, pmatch, eflags); - __libc_lock_unlock (dfa->lock); - return err != REG_NOERROR; -} - -#ifdef _LIBC -# include -versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); - -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) -__typeof__ (__regexec) __compat_regexec; - -int -attribute_compat_text_section -__compat_regexec (const regex_t *_Restrict_ preg, - const char *_Restrict_ string, size_t nmatch, - regmatch_t pmatch[], int eflags) -{ - return regexec (preg, string, nmatch, pmatch, - eflags & (REG_NOTBOL | REG_NOTEOL)); -} -compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); -# endif -#endif - -/* Entry points for GNU code. */ - -/* re_match, re_search, re_match_2, re_search_2 - - The former two functions operate on STRING with length LENGTH, - while the later two operate on concatenation of STRING1 and STRING2 - with lengths LENGTH1 and LENGTH2, respectively. - - re_match() matches the compiled pattern in BUFP against the string, - starting at index START. - - re_search() first tries matching at index START, then it tries to match - starting from index START + 1, and so on. The last start position tried - is START + RANGE. (Thus RANGE = 0 forces re_search to operate the same - way as re_match().) - - The parameter STOP of re_{match,search}_2 specifies that no match exceeding - the first STOP characters of the concatenation of the strings should be - concerned. - - If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match - and all groups is stored in REGS. (For the "_2" variants, the offsets are - computed relative to the concatenation, not relative to the individual - strings.) - - On success, re_match* functions return the length of the match, re_search* - return the position of the start of the match. Return value -1 means no - match was found and -2 indicates an internal error. */ - -regoff_t -re_match (bufp, string, length, start, regs) - struct re_pattern_buffer *bufp; - const char *string; - Idx length, start; - struct re_registers *regs; -{ - return re_search_stub (bufp, string, length, start, 0, length, regs, true); -} -#ifdef _LIBC -weak_alias (__re_match, re_match) -#endif - -regoff_t -re_search (bufp, string, length, start, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - Idx length, start; - regoff_t range; - struct re_registers *regs; -{ - return re_search_stub (bufp, string, length, start, range, length, regs, - false); -} -#ifdef _LIBC -weak_alias (__re_search, re_search) -#endif - -regoff_t -re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - Idx length1, length2, start, stop; - struct re_registers *regs; -{ - return re_search_2_stub (bufp, string1, length1, string2, length2, - start, 0, regs, stop, true); -} -#ifdef _LIBC -weak_alias (__re_match_2, re_match_2) -#endif - -regoff_t -re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - Idx length1, length2, start, stop; - regoff_t range; - struct re_registers *regs; -{ - return re_search_2_stub (bufp, string1, length1, string2, length2, - start, range, regs, stop, false); -} -#ifdef _LIBC -weak_alias (__re_search_2, re_search_2) -#endif - -static regoff_t -re_search_2_stub (struct re_pattern_buffer *bufp, - const char *string1, Idx length1, - const char *string2, Idx length2, - Idx start, regoff_t range, struct re_registers *regs, - Idx stop, bool ret_len) -{ - const char *str; - regoff_t rval; - Idx len = length1 + length2; - char *s = NULL; - - if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0)) - return -2; - - /* Concatenate the strings. */ - if (length2 > 0) - if (length1 > 0) - { - s = re_malloc (char, len); - - if (BE (s == NULL, 0)) - return -2; -#ifdef _LIBC - memcpy (__mempcpy (s, string1, length1), string2, length2); -#else - memcpy (s, string1, length1); - memcpy (s + length1, string2, length2); -#endif - str = s; - } - else - str = string2; - else - str = string1; - - rval = re_search_stub (bufp, str, len, start, range, stop, regs, - ret_len); - re_free (s); - return rval; -} - -/* The parameters have the same meaning as those of re_search. - Additional parameters: - If RET_LEN is true the length of the match is returned (re_match style); - otherwise the position of the match is returned. */ - -static regoff_t -re_search_stub (struct re_pattern_buffer *bufp, - const char *string, Idx length, - Idx start, regoff_t range, Idx stop, struct re_registers *regs, - bool ret_len) -{ - reg_errcode_t result; - regmatch_t *pmatch; - Idx nregs; - regoff_t rval; - int eflags = 0; -#ifdef _LIBC - re_dfa_t *dfa = bufp->buffer; -#endif - Idx last_start = start + range; - - /* Check for out-of-range. */ - if (BE (start < 0 || start > length, 0)) - return -1; - if (BE (length < last_start || (0 <= range && last_start < start), 0)) - last_start = length; - else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0)) - last_start = 0; - - __libc_lock_lock (dfa->lock); - - eflags |= (bufp->not_bol) ? REG_NOTBOL : 0; - eflags |= (bufp->not_eol) ? REG_NOTEOL : 0; - - /* Compile fastmap if we haven't yet. */ - if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate) - re_compile_fastmap (bufp); - - if (BE (bufp->no_sub, 0)) - regs = NULL; - - /* We need at least 1 register. */ - if (regs == NULL) - nregs = 1; - else if (BE (bufp->regs_allocated == REGS_FIXED - && regs->num_regs <= bufp->re_nsub, 0)) - { - nregs = regs->num_regs; - if (BE (nregs < 1, 0)) - { - /* Nothing can be copied to regs. */ - regs = NULL; - nregs = 1; - } - } - else - nregs = bufp->re_nsub + 1; - pmatch = re_malloc (regmatch_t, nregs); - if (BE (pmatch == NULL, 0)) - { - rval = -2; - goto out; - } - - result = re_search_internal (bufp, string, length, start, last_start, stop, - nregs, pmatch, eflags); - - rval = 0; - - /* I hope we needn't fill their regs with -1's when no match was found. */ - if (result != REG_NOERROR) - rval = result == REG_NOMATCH ? -1 : -2; - else if (regs != NULL) - { - /* If caller wants register contents data back, copy them. */ - bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs, - bufp->regs_allocated); - if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0)) - rval = -2; - } - - if (BE (rval == 0, 1)) - { - if (ret_len) - { - assert (pmatch[0].rm_so == start); - rval = pmatch[0].rm_eo - start; - } - else - rval = pmatch[0].rm_so; - } - re_free (pmatch); - out: - __libc_lock_unlock (dfa->lock); - return rval; -} - -static unsigned -re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, - int regs_allocated) -{ - int rval = REGS_REALLOCATE; - Idx i; - Idx need_regs = nregs + 1; - /* We need one extra element beyond 'num_regs' for the '-1' marker GNU code - uses. */ - - /* Have the register data arrays been allocated? */ - if (regs_allocated == REGS_UNALLOCATED) - { /* No. So allocate them with malloc. */ - regs->start = re_malloc (regoff_t, need_regs); - if (BE (regs->start == NULL, 0)) - return REGS_UNALLOCATED; - regs->end = re_malloc (regoff_t, need_regs); - if (BE (regs->end == NULL, 0)) - { - re_free (regs->start); - return REGS_UNALLOCATED; - } - regs->num_regs = need_regs; - } - else if (regs_allocated == REGS_REALLOCATE) - { /* Yes. If we need more elements than were already - allocated, reallocate them. If we need fewer, just - leave it alone. */ - if (BE (need_regs > regs->num_regs, 0)) - { - regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs); - regoff_t *new_end; - if (BE (new_start == NULL, 0)) - return REGS_UNALLOCATED; - new_end = re_realloc (regs->end, regoff_t, need_regs); - if (BE (new_end == NULL, 0)) - { - re_free (new_start); - return REGS_UNALLOCATED; - } - regs->start = new_start; - regs->end = new_end; - regs->num_regs = need_regs; - } - } - else - { - assert (regs_allocated == REGS_FIXED); - /* This function may not be called with REGS_FIXED and nregs too big. */ - assert (regs->num_regs >= nregs); - rval = REGS_FIXED; - } - - /* Copy the regs. */ - for (i = 0; i < nregs; ++i) - { - regs->start[i] = pmatch[i].rm_so; - regs->end[i] = pmatch[i].rm_eo; - } - for ( ; i < regs->num_regs; ++i) - regs->start[i] = regs->end[i] = -1; - - return rval; -} - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use - this memory for recording register information. STARTS and ENDS - must be allocated using the malloc library routine, and must each - be at least NUM_REGS * sizeof (regoff_t) bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ - -void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - __re_size_t num_regs; - regoff_t *starts, *ends; -{ - if (num_regs) - { - bufp->regs_allocated = REGS_REALLOCATE; - regs->num_regs = num_regs; - regs->start = starts; - regs->end = ends; - } - else - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; - regs->start = regs->end = NULL; - } -} -#ifdef _LIBC -weak_alias (__re_set_registers, re_set_registers) -#endif - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined _REGEX_RE_COMP || defined _LIBC -int -# ifdef _LIBC -weak_function -# endif -re_exec (s) - const char *s; -{ - return 0 == regexec (&re_comp_buf, s, 0, NULL, 0); -} -#endif /* _REGEX_RE_COMP */ - -/* Internal entry point. */ - -/* Searches for a compiled pattern PREG in the string STRING, whose - length is LENGTH. NMATCH, PMATCH, and EFLAGS have the same - meaning as with regexec. LAST_START is START + RANGE, where - START and RANGE have the same meaning as with re_search. - Return REG_NOERROR if we find a match, and REG_NOMATCH if not, - otherwise return the error code. - Note: We assume front end functions already check ranges. - (0 <= LAST_START && LAST_START <= LENGTH) */ - -static reg_errcode_t -__attribute_warn_unused_result__ -re_search_internal (const regex_t *preg, - const char *string, Idx length, - Idx start, Idx last_start, Idx stop, - size_t nmatch, regmatch_t pmatch[], - int eflags) -{ - reg_errcode_t err; - const re_dfa_t *dfa = preg->buffer; - Idx left_lim, right_lim; - int incr; - bool fl_longest_match; - int match_kind; - Idx match_first; - Idx match_last = REG_MISSING; - Idx extra_nmatch; - bool sb; - int ch; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - re_match_context_t mctx = { .dfa = dfa }; -#else - re_match_context_t mctx; -#endif - char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate - && start != last_start && !preg->can_be_null) - ? preg->fastmap : NULL); - RE_TRANSLATE_TYPE t = preg->translate; - -#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) - memset (&mctx, '\0', sizeof (re_match_context_t)); - mctx.dfa = dfa; -#endif - - extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0; - nmatch -= extra_nmatch; - - /* Check if the DFA haven't been compiled. */ - if (BE (preg->used == 0 || dfa->init_state == NULL - || dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) - return REG_NOMATCH; - -#ifdef DEBUG - /* We assume front-end functions already check them. */ - assert (0 <= last_start && last_start <= length); -#endif - - /* If initial states with non-begbuf contexts have no elements, - the regex must be anchored. If preg->newline_anchor is set, - we'll never use init_state_nl, so do not check it. */ - if (dfa->init_state->nodes.nelem == 0 - && dfa->init_state_word->nodes.nelem == 0 - && (dfa->init_state_nl->nodes.nelem == 0 - || !preg->newline_anchor)) - { - if (start != 0 && last_start != 0) - return REG_NOMATCH; - start = last_start = 0; - } - - /* We must check the longest matching, if nmatch > 0. */ - fl_longest_match = (nmatch != 0 || dfa->nbackref); - - err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1, - preg->translate, (preg->syntax & RE_ICASE) != 0, - dfa); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - mctx.input.stop = stop; - mctx.input.raw_stop = stop; - mctx.input.newline_anchor = preg->newline_anchor; - - err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* We will log all the DFA states through which the dfa pass, - if nmatch > 1, or this dfa has "multibyte node", which is a - back-reference or a node which can accept multibyte character or - multi character collating element. */ - if (nmatch > 1 || dfa->has_mb_node) - { - /* Avoid overflow. */ - if (BE ((MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) - <= mctx.input.bufs_len), 0)) - { - err = REG_ESPACE; - goto free_return; - } - - mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1); - if (BE (mctx.state_log == NULL, 0)) - { - err = REG_ESPACE; - goto free_return; - } - } - else - mctx.state_log = NULL; - - match_first = start; - mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF - : CONTEXT_NEWLINE | CONTEXT_BEGBUF; - - /* Check incrementally whether the input string matches. */ - incr = (last_start < start) ? -1 : 1; - left_lim = (last_start < start) ? last_start : start; - right_lim = (last_start < start) ? start : last_start; - sb = dfa->mb_cur_max == 1; - match_kind = - (fastmap - ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0) - | (start <= last_start ? 2 : 0) - | (t != NULL ? 1 : 0)) - : 8); - - for (;; match_first += incr) - { - err = REG_NOMATCH; - if (match_first < left_lim || right_lim < match_first) - goto free_return; - - /* Advance as rapidly as possible through the string, until we - find a plausible place to start matching. This may be done - with varying efficiency, so there are various possibilities: - only the most common of them are specialized, in order to - save on code size. We use a switch statement for speed. */ - switch (match_kind) - { - case 8: - /* No fastmap. */ - break; - - case 7: - /* Fastmap with single-byte translation, match forward. */ - while (BE (match_first < right_lim, 1) - && !fastmap[t[(unsigned char) string[match_first]]]) - ++match_first; - goto forward_match_found_start_or_reached_end; - - case 6: - /* Fastmap without translation, match forward. */ - while (BE (match_first < right_lim, 1) - && !fastmap[(unsigned char) string[match_first]]) - ++match_first; - - forward_match_found_start_or_reached_end: - if (BE (match_first == right_lim, 0)) - { - ch = match_first >= length - ? 0 : (unsigned char) string[match_first]; - if (!fastmap[t ? t[ch] : ch]) - goto free_return; - } - break; - - case 4: - case 5: - /* Fastmap without multi-byte translation, match backwards. */ - while (match_first >= left_lim) - { - ch = match_first >= length - ? 0 : (unsigned char) string[match_first]; - if (fastmap[t ? t[ch] : ch]) - break; - --match_first; - } - if (match_first < left_lim) - goto free_return; - break; - - default: - /* In this case, we can't determine easily the current byte, - since it might be a component byte of a multibyte - character. Then we use the constructed buffer instead. */ - for (;;) - { - /* If MATCH_FIRST is out of the valid range, reconstruct the - buffers. */ - __re_size_t offset = match_first - mctx.input.raw_mbs_idx; - if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0)) - { - err = re_string_reconstruct (&mctx.input, match_first, - eflags); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - offset = match_first - mctx.input.raw_mbs_idx; - } - /* If MATCH_FIRST is out of the buffer, leave it as '\0'. - Note that MATCH_FIRST must not be smaller than 0. */ - ch = (match_first >= length - ? 0 : re_string_byte_at (&mctx.input, offset)); - if (fastmap[ch]) - break; - match_first += incr; - if (match_first < left_lim || match_first > right_lim) - { - err = REG_NOMATCH; - goto free_return; - } - } - break; - } - - /* Reconstruct the buffers so that the matcher can assume that - the matching starts from the beginning of the buffer. */ - err = re_string_reconstruct (&mctx.input, match_first, eflags); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - -#ifdef RE_ENABLE_I18N - /* Don't consider this char as a possible match start if it part, - yet isn't the head, of a multibyte character. */ - if (!sb && !re_string_first_byte (&mctx.input, 0)) - continue; -#endif - - /* It seems to be appropriate one, then use the matcher. */ - /* We assume that the matching starts from 0. */ - mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0; - match_last = check_matching (&mctx, fl_longest_match, - start <= last_start ? &match_first : NULL); - if (match_last != REG_MISSING) - { - if (BE (match_last == REG_ERROR, 0)) - { - err = REG_ESPACE; - goto free_return; - } - else - { - mctx.match_last = match_last; - if ((!preg->no_sub && nmatch > 1) || dfa->nbackref) - { - re_dfastate_t *pstate = mctx.state_log[match_last]; - mctx.last_node = check_halt_state_context (&mctx, pstate, - match_last); - } - if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match) - || dfa->nbackref) - { - err = prune_impossible_nodes (&mctx); - if (err == REG_NOERROR) - break; - if (BE (err != REG_NOMATCH, 0)) - goto free_return; - match_last = REG_MISSING; - } - else - break; /* We found a match. */ - } - } - - match_ctx_clean (&mctx); - } - -#ifdef DEBUG - assert (match_last != REG_MISSING); - assert (err == REG_NOERROR); -#endif - - /* Set pmatch[] if we need. */ - if (nmatch > 0) - { - Idx reg_idx; - - /* Initialize registers. */ - for (reg_idx = 1; reg_idx < nmatch; ++reg_idx) - pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1; - - /* Set the points where matching start/end. */ - pmatch[0].rm_so = 0; - pmatch[0].rm_eo = mctx.match_last; - /* FIXME: This function should fail if mctx.match_last exceeds - the maximum possible regoff_t value. We need a new error - code REG_OVERFLOW. */ - - if (!preg->no_sub && nmatch > 1) - { - err = set_regs (preg, &mctx, nmatch, pmatch, - dfa->has_plural_match && dfa->nbackref > 0); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - - /* At last, add the offset to each register, since we slid - the buffers so that we could assume that the matching starts - from 0. */ - for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) - if (pmatch[reg_idx].rm_so != -1) - { -#ifdef RE_ENABLE_I18N - if (BE (mctx.input.offsets_needed != 0, 0)) - { - pmatch[reg_idx].rm_so = - (pmatch[reg_idx].rm_so == mctx.input.valid_len - ? mctx.input.valid_raw_len - : mctx.input.offsets[pmatch[reg_idx].rm_so]); - pmatch[reg_idx].rm_eo = - (pmatch[reg_idx].rm_eo == mctx.input.valid_len - ? mctx.input.valid_raw_len - : mctx.input.offsets[pmatch[reg_idx].rm_eo]); - } -#else - assert (mctx.input.offsets_needed == 0); -#endif - pmatch[reg_idx].rm_so += match_first; - pmatch[reg_idx].rm_eo += match_first; - } - for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx) - { - pmatch[nmatch + reg_idx].rm_so = -1; - pmatch[nmatch + reg_idx].rm_eo = -1; - } - - if (dfa->subexp_map) - for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++) - if (dfa->subexp_map[reg_idx] != reg_idx) - { - pmatch[reg_idx + 1].rm_so - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so; - pmatch[reg_idx + 1].rm_eo - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo; - } - } - - free_return: - re_free (mctx.state_log); - if (dfa->nbackref) - match_ctx_free (&mctx); - re_string_destruct (&mctx.input); - return err; -} - -static reg_errcode_t -__attribute_warn_unused_result__ -prune_impossible_nodes (re_match_context_t *mctx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx halt_node, match_last; - reg_errcode_t ret; - re_dfastate_t **sifted_states; - re_dfastate_t **lim_states = NULL; - re_sift_context_t sctx; -#ifdef DEBUG - assert (mctx->state_log != NULL); -#endif - match_last = mctx->match_last; - halt_node = mctx->last_node; - - /* Avoid overflow. */ - if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) <= match_last, 0)) - return REG_ESPACE; - - sifted_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (sifted_states == NULL, 0)) - { - ret = REG_ESPACE; - goto free_return; - } - if (dfa->nbackref) - { - lim_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (lim_states == NULL, 0)) - { - ret = REG_ESPACE; - goto free_return; - } - while (1) - { - memset (lim_states, '\0', - sizeof (re_dfastate_t *) * (match_last + 1)); - sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, - match_last); - ret = sift_states_backward (mctx, &sctx); - re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - if (sifted_states[0] != NULL || lim_states[0] != NULL) - break; - do - { - --match_last; - if (! REG_VALID_INDEX (match_last)) - { - ret = REG_NOMATCH; - goto free_return; - } - } while (mctx->state_log[match_last] == NULL - || !mctx->state_log[match_last]->halt); - halt_node = check_halt_state_context (mctx, - mctx->state_log[match_last], - match_last); - } - ret = merge_state_array (dfa, sifted_states, lim_states, - match_last + 1); - re_free (lim_states); - lim_states = NULL; - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - } - else - { - sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last); - ret = sift_states_backward (mctx, &sctx); - re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - if (sifted_states[0] == NULL) - { - ret = REG_NOMATCH; - goto free_return; - } - } - re_free (mctx->state_log); - mctx->state_log = sifted_states; - sifted_states = NULL; - mctx->last_node = halt_node; - mctx->match_last = match_last; - ret = REG_NOERROR; - free_return: - re_free (sifted_states); - re_free (lim_states); - return ret; -} - -/* Acquire an initial state and return it. - We must select appropriate initial state depending on the context, - since initial states may have constraints like "\<", "^", etc.. */ - -static inline re_dfastate_t * -__attribute__ ((always_inline)) internal_function -acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, - Idx idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - if (dfa->init_state->has_constraint) - { - unsigned int context; - context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags); - if (IS_WORD_CONTEXT (context)) - return dfa->init_state_word; - else if (IS_ORDINARY_CONTEXT (context)) - return dfa->init_state; - else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context)) - return dfa->init_state_begbuf; - else if (IS_NEWLINE_CONTEXT (context)) - return dfa->init_state_nl; - else if (IS_BEGBUF_CONTEXT (context)) - { - /* It is relatively rare case, then calculate on demand. */ - return re_acquire_state_context (err, dfa, - dfa->init_state->entrance_nodes, - context); - } - else - /* Must not happen? */ - return dfa->init_state; - } - else - return dfa->init_state; -} - -/* Check whether the regular expression match input string INPUT or not, - and return the index where the matching end. Return REG_MISSING if - there is no match, and return REG_ERROR in case of an error. - FL_LONGEST_MATCH means we want the POSIX longest matching. - If P_MATCH_FIRST is not NULL, and the match fails, it is set to the - next place where we may want to try matching. - Note that the matcher assumes that the matching starts from the current - index of the buffer. */ - -static Idx -internal_function __attribute_warn_unused_result__ -check_matching (re_match_context_t *mctx, bool fl_longest_match, - Idx *p_match_first) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx match = 0; - Idx match_last = REG_MISSING; - Idx cur_str_idx = re_string_cur_idx (&mctx->input); - re_dfastate_t *cur_state; - bool at_init_state = p_match_first != NULL; - Idx next_start_idx = cur_str_idx; - - err = REG_NOERROR; - cur_state = acquire_init_state_context (&err, mctx, cur_str_idx); - /* An initial state must not be NULL (invalid). */ - if (BE (cur_state == NULL, 0)) - { - assert (err == REG_ESPACE); - return REG_ERROR; - } - - if (mctx->state_log != NULL) - { - mctx->state_log[cur_str_idx] = cur_state; - - /* Check OP_OPEN_SUBEXP in the initial state in case that we use them - later. E.g. Processing back references. */ - if (BE (dfa->nbackref, 0)) - { - at_init_state = false; - err = check_subexp_matching_top (mctx, &cur_state->nodes, 0); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (cur_state->has_backref) - { - err = transit_state_bkref (mctx, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - } - - /* If the RE accepts NULL string. */ - if (BE (cur_state->halt, 0)) - { - if (!cur_state->has_constraint - || check_halt_state_context (mctx, cur_state, cur_str_idx)) - { - if (!fl_longest_match) - return cur_str_idx; - else - { - match_last = cur_str_idx; - match = 1; - } - } - } - - while (!re_string_eoi (&mctx->input)) - { - re_dfastate_t *old_state = cur_state; - Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1; - - if ((BE (next_char_idx >= mctx->input.bufs_len, 0) - && mctx->input.bufs_len < mctx->input.len) - || (BE (next_char_idx >= mctx->input.valid_len, 0) - && mctx->input.valid_len < mctx->input.len)) - { - err = extend_buffers (mctx, next_char_idx + 1); - if (BE (err != REG_NOERROR, 0)) - { - assert (err == REG_ESPACE); - return REG_ERROR; - } - } - - cur_state = transit_state (&err, mctx, cur_state); - if (mctx->state_log != NULL) - cur_state = merge_state_with_log (&err, mctx, cur_state); - - if (cur_state == NULL) - { - /* Reached the invalid state or an error. Try to recover a valid - state using the state log, if available and if we have not - already found a valid (even if not the longest) match. */ - if (BE (err != REG_NOERROR, 0)) - return REG_ERROR; - - if (mctx->state_log == NULL - || (match && !fl_longest_match) - || (cur_state = find_recover_state (&err, mctx)) == NULL) - break; - } - - if (BE (at_init_state, 0)) - { - if (old_state == cur_state) - next_start_idx = next_char_idx; - else - at_init_state = false; - } - - if (cur_state->halt) - { - /* Reached a halt state. - Check the halt state can satisfy the current context. */ - if (!cur_state->has_constraint - || check_halt_state_context (mctx, cur_state, - re_string_cur_idx (&mctx->input))) - { - /* We found an appropriate halt state. */ - match_last = re_string_cur_idx (&mctx->input); - match = 1; - - /* We found a match, do not modify match_first below. */ - p_match_first = NULL; - if (!fl_longest_match) - break; - } - } - } - - if (p_match_first) - *p_match_first += next_start_idx; - - return match_last; -} - -/* Check NODE match the current context. */ - -static bool -internal_function -check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context) -{ - re_token_type_t type = dfa->nodes[node].type; - unsigned int constraint = dfa->nodes[node].constraint; - if (type != END_OF_RE) - return false; - if (!constraint) - return true; - if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context)) - return false; - return true; -} - -/* Check the halt state STATE match the current context. - Return 0 if not match, if the node, STATE has, is a halt node and - match the context, return the node. */ - -static Idx -internal_function -check_halt_state_context (const re_match_context_t *mctx, - const re_dfastate_t *state, Idx idx) -{ - Idx i; - unsigned int context; -#ifdef DEBUG - assert (state->halt); -#endif - context = re_string_context_at (&mctx->input, idx, mctx->eflags); - for (i = 0; i < state->nodes.nelem; ++i) - if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context)) - return state->nodes.elems[i]; - return 0; -} - -/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA - corresponding to the DFA). - Return the destination node, and update EPS_VIA_NODES; - return REG_MISSING in case of errors. */ - -static Idx -internal_function -proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, - Idx *pidx, Idx node, re_node_set *eps_via_nodes, - struct re_fail_stack_t *fs) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx i; - bool ok; - if (IS_EPSILON_NODE (dfa->nodes[node].type)) - { - re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; - re_node_set *edests = &dfa->edests[node]; - Idx dest_node; - ok = re_node_set_insert (eps_via_nodes, node); - if (BE (! ok, 0)) - return REG_ERROR; - /* Pick up a valid destination, or return REG_MISSING if none - is found. */ - for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i) - { - Idx candidate = edests->elems[i]; - if (!re_node_set_contains (cur_nodes, candidate)) - continue; - if (dest_node == REG_MISSING) - dest_node = candidate; - - else - { - /* In order to avoid infinite loop like "(a*)*", return the second - epsilon-transition if the first was already considered. */ - if (re_node_set_contains (eps_via_nodes, dest_node)) - return candidate; - - /* Otherwise, push the second epsilon-transition on the fail stack. */ - else if (fs != NULL - && push_fail_stack (fs, *pidx, candidate, nregs, regs, - eps_via_nodes)) - return REG_ERROR; - - /* We know we are going to exit. */ - break; - } - } - return dest_node; - } - else - { - Idx naccepted = 0; - re_token_type_t type = dfa->nodes[node].type; - -#ifdef RE_ENABLE_I18N - if (dfa->nodes[node].accept_mb) - naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx); - else -#endif /* RE_ENABLE_I18N */ - if (type == OP_BACK_REF) - { - Idx subexp_idx = dfa->nodes[node].opr.idx + 1; - naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; - if (fs != NULL) - { - if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1) - return REG_MISSING; - else if (naccepted) - { - char *buf = (char *) re_string_get_buffer (&mctx->input); - if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, - naccepted) != 0) - return REG_MISSING; - } - } - - if (naccepted == 0) - { - Idx dest_node; - ok = re_node_set_insert (eps_via_nodes, node); - if (BE (! ok, 0)) - return REG_ERROR; - dest_node = dfa->edests[node].elems[0]; - if (re_node_set_contains (&mctx->state_log[*pidx]->nodes, - dest_node)) - return dest_node; - } - } - - if (naccepted != 0 - || check_node_accept (mctx, dfa->nodes + node, *pidx)) - { - Idx dest_node = dfa->nexts[node]; - *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted; - if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL - || !re_node_set_contains (&mctx->state_log[*pidx]->nodes, - dest_node))) - return REG_MISSING; - re_node_set_empty (eps_via_nodes); - return dest_node; - } - } - return REG_MISSING; -} - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, - Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) -{ - reg_errcode_t err; - Idx num = fs->num++; - if (fs->num == fs->alloc) - { - struct re_fail_stack_ent_t *new_array; - new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) - * fs->alloc * 2)); - if (new_array == NULL) - return REG_ESPACE; - fs->alloc *= 2; - fs->stack = new_array; - } - fs->stack[num].idx = str_idx; - fs->stack[num].node = dest_node; - fs->stack[num].regs = re_malloc (regmatch_t, nregs); - if (fs->stack[num].regs == NULL) - return REG_ESPACE; - memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); - err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); - return err; -} - -static Idx -internal_function -pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, - regmatch_t *regs, re_node_set *eps_via_nodes) -{ - Idx num = --fs->num; - assert (REG_VALID_INDEX (num)); - *pidx = fs->stack[num].idx; - memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); - re_node_set_free (eps_via_nodes); - re_free (fs->stack[num].regs); - *eps_via_nodes = fs->stack[num].eps_via_nodes; - return fs->stack[num].node; -} - -/* Set the positions where the subexpressions are starts/ends to registers - PMATCH. - Note: We assume that pmatch[0] is already set, and - pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, - regmatch_t *pmatch, bool fl_backtrack) -{ - const re_dfa_t *dfa = preg->buffer; - Idx idx, cur_node; - re_node_set eps_via_nodes; - struct re_fail_stack_t *fs; - struct re_fail_stack_t fs_body = { 0, 2, NULL }; - regmatch_t *prev_idx_match; - bool prev_idx_match_malloced = false; - -#ifdef DEBUG - assert (nmatch > 1); - assert (mctx->state_log != NULL); -#endif - if (fl_backtrack) - { - fs = &fs_body; - fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc); - if (fs->stack == NULL) - return REG_ESPACE; - } - else - fs = NULL; - - cur_node = dfa->init_node; - re_node_set_init_empty (&eps_via_nodes); - - if (__libc_use_alloca (nmatch * sizeof (regmatch_t))) - prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t)); - else - { - prev_idx_match = re_malloc (regmatch_t, nmatch); - if (prev_idx_match == NULL) - { - free_fail_stack_return (fs); - return REG_ESPACE; - } - prev_idx_match_malloced = true; - } - memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); - - for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) - { - update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); - - if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) - { - Idx reg_idx; - if (fs) - { - for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) - if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) - break; - if (reg_idx == nmatch) - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return free_fail_stack_return (fs); - } - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); - } - else - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return REG_NOERROR; - } - } - - /* Proceed to next node. */ - cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, - &eps_via_nodes, fs); - - if (BE (! REG_VALID_INDEX (cur_node), 0)) - { - if (BE (cur_node == REG_ERROR, 0)) - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - free_fail_stack_return (fs); - return REG_ESPACE; - } - if (fs) - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); - else - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return REG_NOMATCH; - } - } - } - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return free_fail_stack_return (fs); -} - -static reg_errcode_t -internal_function -free_fail_stack_return (struct re_fail_stack_t *fs) -{ - if (fs) - { - Idx fs_idx; - for (fs_idx = 0; fs_idx < fs->num; ++fs_idx) - { - re_node_set_free (&fs->stack[fs_idx].eps_via_nodes); - re_free (fs->stack[fs_idx].regs); - } - re_free (fs->stack); - } - return REG_NOERROR; -} - -static void -internal_function -update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, - regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch) -{ - int type = dfa->nodes[cur_node].type; - if (type == OP_OPEN_SUBEXP) - { - Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; - - /* We are at the first node of this sub expression. */ - if (reg_num < nmatch) - { - pmatch[reg_num].rm_so = cur_idx; - pmatch[reg_num].rm_eo = -1; - } - } - else if (type == OP_CLOSE_SUBEXP) - { - Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; - if (reg_num < nmatch) - { - /* We are at the last node of this sub expression. */ - if (pmatch[reg_num].rm_so < cur_idx) - { - pmatch[reg_num].rm_eo = cur_idx; - /* This is a non-empty match or we are not inside an optional - subexpression. Accept this right away. */ - memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); - } - else - { - if (dfa->nodes[cur_node].opt_subexp - && prev_idx_match[reg_num].rm_so != -1) - /* We transited through an empty match for an optional - subexpression, like (a?)*, and this is not the subexp's - first match. Copy back the old content of the registers - so that matches of an inner subexpression are undone as - well, like in ((a?))*. */ - memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch); - else - /* We completed a subexpression, but it may be part of - an optional one, so do not update PREV_IDX_MATCH. */ - pmatch[reg_num].rm_eo = cur_idx; - } - } - } -} - -/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0 - and sift the nodes in each states according to the following rules. - Updated state_log will be wrote to STATE_LOG. - - Rules: We throw away the Node 'a' in the STATE_LOG[STR_IDX] if... - 1. When STR_IDX == MATCH_LAST(the last index in the state_log): - If 'a' isn't the LAST_NODE and 'a' can't epsilon transit to - the LAST_NODE, we throw away the node 'a'. - 2. When 0 <= STR_IDX < MATCH_LAST and 'a' accepts - string 's' and transit to 'b': - i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw - away the node 'a'. - ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is - thrown away, we throw away the node 'a'. - 3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b': - i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the - node 'a'. - ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away, - we throw away the node 'a'. */ - -#define STATE_NODE_CONTAINS(state,node) \ - ((state) != NULL && re_node_set_contains (&(state)->nodes, node)) - -static reg_errcode_t -internal_function -sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) -{ - reg_errcode_t err; - int null_cnt = 0; - Idx str_idx = sctx->last_str_idx; - re_node_set cur_dest; - -#ifdef DEBUG - assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL); -#endif - - /* Build sifted state_log[str_idx]. It has the nodes which can epsilon - transit to the last_node and the last_node itself. */ - err = re_node_set_init_1 (&cur_dest, sctx->last_node); - if (BE (err != REG_NOERROR, 0)) - return err; - err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* Then check each states in the state_log. */ - while (str_idx > 0) - { - /* Update counters. */ - null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0; - if (null_cnt > mctx->max_mb_elem_len) - { - memset (sctx->sifted_states, '\0', - sizeof (re_dfastate_t *) * str_idx); - re_node_set_free (&cur_dest); - return REG_NOERROR; - } - re_node_set_empty (&cur_dest); - --str_idx; - - if (mctx->state_log[str_idx]) - { - err = build_sifted_states (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - - /* Add all the nodes which satisfy the following conditions: - - It can epsilon transit to a node in CUR_DEST. - - It is in CUR_SRC. - And update state_log. */ - err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - err = REG_NOERROR; - free_return: - re_node_set_free (&cur_dest); - return err; -} - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx str_idx, re_node_set *cur_dest) -{ - const re_dfa_t *const dfa = mctx->dfa; - const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes; - Idx i; - - /* Then build the next sifted state. - We build the next sifted state on 'cur_dest', and update - 'sifted_states[str_idx]' with 'cur_dest'. - Note: - 'cur_dest' is the sifted state from 'state_log[str_idx + 1]'. - 'cur_src' points the node_set of the old 'state_log[str_idx]' - (with the epsilon nodes pre-filtered out). */ - for (i = 0; i < cur_src->nelem; i++) - { - Idx prev_node = cur_src->elems[i]; - int naccepted = 0; - bool ok; - -#ifdef DEBUG - re_token_type_t type = dfa->nodes[prev_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N - /* If the node may accept "multi byte". */ - if (dfa->nodes[prev_node].accept_mb) - naccepted = sift_states_iter_mb (mctx, sctx, prev_node, - str_idx, sctx->last_str_idx); -#endif /* RE_ENABLE_I18N */ - - /* We don't check backreferences here. - See update_cur_sifted_state(). */ - if (!naccepted - && check_node_accept (mctx, dfa->nodes + prev_node, str_idx) - && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1], - dfa->nexts[prev_node])) - naccepted = 1; - - if (naccepted == 0) - continue; - - if (sctx->limits.nelem) - { - Idx to_idx = str_idx + naccepted; - if (check_dst_limits (mctx, &sctx->limits, - dfa->nexts[prev_node], to_idx, - prev_node, str_idx)) - continue; - } - ok = re_node_set_insert (cur_dest, prev_node); - if (BE (! ok, 0)) - return REG_ESPACE; - } - - return REG_NOERROR; -} - -/* Helper functions. */ - -static reg_errcode_t -internal_function -clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) -{ - Idx top = mctx->state_log_top; - - if ((next_state_log_idx >= mctx->input.bufs_len - && mctx->input.bufs_len < mctx->input.len) - || (next_state_log_idx >= mctx->input.valid_len - && mctx->input.valid_len < mctx->input.len)) - { - reg_errcode_t err; - err = extend_buffers (mctx, next_state_log_idx + 1); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (top < next_state_log_idx) - { - memset (mctx->state_log + top + 1, '\0', - sizeof (re_dfastate_t *) * (next_state_log_idx - top)); - mctx->state_log_top = next_state_log_idx; - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, - re_dfastate_t **src, Idx num) -{ - Idx st_idx; - reg_errcode_t err; - for (st_idx = 0; st_idx < num; ++st_idx) - { - if (dst[st_idx] == NULL) - dst[st_idx] = src[st_idx]; - else if (src[st_idx] != NULL) - { - re_node_set merged_set; - err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes, - &src[st_idx]->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - dst[st_idx] = re_acquire_state (&err, dfa, &merged_set); - re_node_set_free (&merged_set); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -update_cur_sifted_state (const re_match_context_t *mctx, - re_sift_context_t *sctx, Idx str_idx, - re_node_set *dest_nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err = REG_NOERROR; - const re_node_set *candidates; - candidates = ((mctx->state_log[str_idx] == NULL) ? NULL - : &mctx->state_log[str_idx]->nodes); - - if (dest_nodes->nelem == 0) - sctx->sifted_states[str_idx] = NULL; - else - { - if (candidates) - { - /* At first, add the nodes which can epsilon transit to a node in - DEST_NODE. */ - err = add_epsilon_src_nodes (dfa, dest_nodes, candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* Then, check the limitations in the current sift_context. */ - if (sctx->limits.nelem) - { - err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits, - mctx->bkref_ents, str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - - sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (candidates && mctx->state_log[str_idx]->has_backref) - { - err = sift_states_bkref (mctx, sctx, str_idx, candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, - const re_node_set *candidates) -{ - reg_errcode_t err = REG_NOERROR; - Idx i; - - re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (!state->inveclosure.alloc) - { - err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - for (i = 0; i < dest_nodes->nelem; i++) - { - err = re_node_set_merge (&state->inveclosure, - dfa->inveclosures + dest_nodes->elems[i]); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - } - } - return re_node_set_add_intersect (dest_nodes, candidates, - &state->inveclosure); -} - -static reg_errcode_t -internal_function -sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, - const re_node_set *candidates) -{ - Idx ecl_idx; - reg_errcode_t err; - re_node_set *inv_eclosure = dfa->inveclosures + node; - re_node_set except_nodes; - re_node_set_init_empty (&except_nodes); - for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) - { - Idx cur_node = inv_eclosure->elems[ecl_idx]; - if (cur_node == node) - continue; - if (IS_EPSILON_NODE (dfa->nodes[cur_node].type)) - { - Idx edst1 = dfa->edests[cur_node].elems[0]; - Idx edst2 = ((dfa->edests[cur_node].nelem > 1) - ? dfa->edests[cur_node].elems[1] : REG_MISSING); - if ((!re_node_set_contains (inv_eclosure, edst1) - && re_node_set_contains (dest_nodes, edst1)) - || (REG_VALID_NONZERO_INDEX (edst2) - && !re_node_set_contains (inv_eclosure, edst2) - && re_node_set_contains (dest_nodes, edst2))) - { - err = re_node_set_add_intersect (&except_nodes, candidates, - dfa->inveclosures + cur_node); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&except_nodes); - return err; - } - } - } - } - for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) - { - Idx cur_node = inv_eclosure->elems[ecl_idx]; - if (!re_node_set_contains (&except_nodes, cur_node)) - { - Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1; - re_node_set_remove_at (dest_nodes, idx); - } - } - re_node_set_free (&except_nodes); - return REG_NOERROR; -} - -static bool -internal_function -check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits, - Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx lim_idx, src_pos, dst_pos; - - Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx); - Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx); - for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) - { - Idx subexp_idx; - struct re_backref_cache_entry *ent; - ent = mctx->bkref_ents + limits->elems[lim_idx]; - subexp_idx = dfa->nodes[ent->node].opr.idx; - - dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], - subexp_idx, dst_node, dst_idx, - dst_bkref_idx); - src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], - subexp_idx, src_node, src_idx, - src_bkref_idx); - - /* In case of: - ( ) - ( ) - ( ) */ - if (src_pos == dst_pos) - continue; /* This is unrelated limitation. */ - else - return true; - } - return false; -} - -static int -internal_function -check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, - Idx subexp_idx, Idx from_node, Idx bkref_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - const re_node_set *eclosures = dfa->eclosures + from_node; - Idx node_idx; - - /* Else, we are on the boundary: examine the nodes on the epsilon - closure. */ - for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx) - { - Idx node = eclosures->elems[node_idx]; - switch (dfa->nodes[node].type) - { - case OP_BACK_REF: - if (bkref_idx != REG_MISSING) - { - struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx; - do - { - Idx dst; - int cpos; - - if (ent->node != node) - continue; - - if (subexp_idx < BITSET_WORD_BITS - && !(ent->eps_reachable_subexps_map - & ((bitset_word_t) 1 << subexp_idx))) - continue; - - /* Recurse trying to reach the OP_OPEN_SUBEXP and - OP_CLOSE_SUBEXP cases below. But, if the - destination node is the same node as the source - node, don't recurse because it would cause an - infinite loop: a regex that exhibits this behavior - is ()\1*\1* */ - dst = dfa->edests[node].elems[0]; - if (dst == from_node) - { - if (boundaries & 1) - return -1; - else /* if (boundaries & 2) */ - return 0; - } - - cpos = - check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, - dst, bkref_idx); - if (cpos == -1 /* && (boundaries & 1) */) - return -1; - if (cpos == 0 && (boundaries & 2)) - return 0; - - if (subexp_idx < BITSET_WORD_BITS) - ent->eps_reachable_subexps_map - &= ~((bitset_word_t) 1 << subexp_idx); - } - while (ent++->more); - } - break; - - case OP_OPEN_SUBEXP: - if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx) - return -1; - break; - - case OP_CLOSE_SUBEXP: - if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx) - return 0; - break; - - default: - break; - } - } - - return (boundaries & 2) ? 1 : 0; -} - -static int -internal_function -check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit, - Idx subexp_idx, Idx from_node, Idx str_idx, - Idx bkref_idx) -{ - struct re_backref_cache_entry *lim = mctx->bkref_ents + limit; - int boundaries; - - /* If we are outside the range of the subexpression, return -1 or 1. */ - if (str_idx < lim->subexp_from) - return -1; - - if (lim->subexp_to < str_idx) - return 1; - - /* If we are within the subexpression, return 0. */ - boundaries = (str_idx == lim->subexp_from); - boundaries |= (str_idx == lim->subexp_to) << 1; - if (boundaries == 0) - return 0; - - /* Else, examine epsilon closure. */ - return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, - from_node, bkref_idx); -} - -/* Check the limitations of sub expressions LIMITS, and remove the nodes - which are against limitations from DEST_NODES. */ - -static reg_errcode_t -internal_function -check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, - const re_node_set *candidates, re_node_set *limits, - struct re_backref_cache_entry *bkref_ents, Idx str_idx) -{ - reg_errcode_t err; - Idx node_idx, lim_idx; - - for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) - { - Idx subexp_idx; - struct re_backref_cache_entry *ent; - ent = bkref_ents + limits->elems[lim_idx]; - - if (str_idx <= ent->subexp_from || ent->str_idx < str_idx) - continue; /* This is unrelated limitation. */ - - subexp_idx = dfa->nodes[ent->node].opr.idx; - if (ent->subexp_to == str_idx) - { - Idx ops_node = REG_MISSING; - Idx cls_node = REG_MISSING; - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - Idx node = dest_nodes->elems[node_idx]; - re_token_type_t type = dfa->nodes[node].type; - if (type == OP_OPEN_SUBEXP - && subexp_idx == dfa->nodes[node].opr.idx) - ops_node = node; - else if (type == OP_CLOSE_SUBEXP - && subexp_idx == dfa->nodes[node].opr.idx) - cls_node = node; - } - - /* Check the limitation of the open subexpression. */ - /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */ - if (REG_VALID_INDEX (ops_node)) - { - err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - /* Check the limitation of the close subexpression. */ - if (REG_VALID_INDEX (cls_node)) - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - Idx node = dest_nodes->elems[node_idx]; - if (!re_node_set_contains (dfa->inveclosures + node, - cls_node) - && !re_node_set_contains (dfa->eclosures + node, - cls_node)) - { - /* It is against this limitation. - Remove it form the current sifted state. */ - err = sub_epsilon_src_nodes (dfa, node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - --node_idx; - } - } - } - else /* (ent->subexp_to != str_idx) */ - { - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - Idx node = dest_nodes->elems[node_idx]; - re_token_type_t type = dfa->nodes[node].type; - if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP) - { - if (subexp_idx != dfa->nodes[node].opr.idx) - continue; - /* It is against this limitation. - Remove it form the current sifted state. */ - err = sub_epsilon_src_nodes (dfa, node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx str_idx, const re_node_set *candidates) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx node_idx, node; - re_sift_context_t local_sctx; - Idx first_idx = search_cur_bkref_entry (mctx, str_idx); - - if (first_idx == REG_MISSING) - return REG_NOERROR; - - local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */ - - for (node_idx = 0; node_idx < candidates->nelem; ++node_idx) - { - Idx enabled_idx; - re_token_type_t type; - struct re_backref_cache_entry *entry; - node = candidates->elems[node_idx]; - type = dfa->nodes[node].type; - /* Avoid infinite loop for the REs like "()\1+". */ - if (node == sctx->last_node && str_idx == sctx->last_str_idx) - continue; - if (type != OP_BACK_REF) - continue; - - entry = mctx->bkref_ents + first_idx; - enabled_idx = first_idx; - do - { - Idx subexp_len; - Idx to_idx; - Idx dst_node; - bool ok; - re_dfastate_t *cur_state; - - if (entry->node != node) - continue; - subexp_len = entry->subexp_to - entry->subexp_from; - to_idx = str_idx + subexp_len; - dst_node = (subexp_len ? dfa->nexts[node] - : dfa->edests[node].elems[0]); - - if (to_idx > sctx->last_str_idx - || sctx->sifted_states[to_idx] == NULL - || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node) - || check_dst_limits (mctx, &sctx->limits, node, - str_idx, dst_node, to_idx)) - continue; - - if (local_sctx.sifted_states == NULL) - { - local_sctx = *sctx; - err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - local_sctx.last_node = node; - local_sctx.last_str_idx = str_idx; - ok = re_node_set_insert (&local_sctx.limits, enabled_idx); - if (BE (! ok, 0)) - { - err = REG_ESPACE; - goto free_return; - } - cur_state = local_sctx.sifted_states[str_idx]; - err = sift_states_backward (mctx, &local_sctx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - if (sctx->limited_states != NULL) - { - err = merge_state_array (dfa, sctx->limited_states, - local_sctx.sifted_states, - str_idx + 1); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - local_sctx.sifted_states[str_idx] = cur_state; - re_node_set_remove (&local_sctx.limits, enabled_idx); - - /* mctx->bkref_ents may have changed, reload the pointer. */ - entry = mctx->bkref_ents + enabled_idx; - } - while (enabled_idx++, entry++->more); - } - err = REG_NOERROR; - free_return: - if (local_sctx.sifted_states != NULL) - { - re_node_set_free (&local_sctx.limits); - } - - return err; -} - - -#ifdef RE_ENABLE_I18N -static int -internal_function -sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, - Idx node_idx, Idx str_idx, Idx max_str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - int naccepted; - /* Check the node can accept "multi byte". */ - naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx); - if (naccepted > 0 && str_idx + naccepted <= max_str_idx && - !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted], - dfa->nexts[node_idx])) - /* The node can't accept the "multi byte", or the - destination was already thrown away, then the node - could't accept the current input "multi byte". */ - naccepted = 0; - /* Otherwise, it is sure that the node could accept - 'naccepted' bytes input. */ - return naccepted; -} -#endif /* RE_ENABLE_I18N */ - - -/* Functions for state transition. */ - -/* Return the next state to which the current state STATE will transit by - accepting the current input byte, and update STATE_LOG if necessary. - If STATE can accept a multibyte char/collating element/back reference - update the destination of STATE_LOG. */ - -static re_dfastate_t * -internal_function __attribute_warn_unused_result__ -transit_state (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *state) -{ - re_dfastate_t **trtable; - unsigned char ch; - -#ifdef RE_ENABLE_I18N - /* If the current state can accept multibyte. */ - if (BE (state->accept_mb, 0)) - { - *err = transit_state_mb (mctx, state); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } -#endif /* RE_ENABLE_I18N */ - - /* Then decide the next state with the single byte. */ -#if 0 - if (0) - /* don't use transition table */ - return transit_state_sb (err, mctx, state); -#endif - - /* Use transition table */ - ch = re_string_fetch_byte (&mctx->input); - for (;;) - { - trtable = state->trtable; - if (BE (trtable != NULL, 1)) - return trtable[ch]; - - trtable = state->word_trtable; - if (BE (trtable != NULL, 1)) - { - unsigned int context; - context - = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input) - 1, - mctx->eflags); - if (IS_WORD_CONTEXT (context)) - return trtable[ch + SBC_MAX]; - else - return trtable[ch]; - } - - if (!build_trtable (mctx->dfa, state)) - { - *err = REG_ESPACE; - return NULL; - } - - /* Retry, we now have a transition table. */ - } -} - -/* Update the state_log if we need */ -static re_dfastate_t * -internal_function -merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *next_state) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx cur_idx = re_string_cur_idx (&mctx->input); - - if (cur_idx > mctx->state_log_top) - { - mctx->state_log[cur_idx] = next_state; - mctx->state_log_top = cur_idx; - } - else if (mctx->state_log[cur_idx] == 0) - { - mctx->state_log[cur_idx] = next_state; - } - else - { - re_dfastate_t *pstate; - unsigned int context; - re_node_set next_nodes, *log_nodes, *table_nodes = NULL; - /* If (state_log[cur_idx] != 0), it implies that cur_idx is - the destination of a multibyte char/collating element/ - back reference. Then the next state is the union set of - these destinations and the results of the transition table. */ - pstate = mctx->state_log[cur_idx]; - log_nodes = pstate->entrance_nodes; - if (next_state != NULL) - { - table_nodes = next_state->entrance_nodes; - *err = re_node_set_init_union (&next_nodes, table_nodes, - log_nodes); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } - else - next_nodes = *log_nodes; - /* Note: We already add the nodes of the initial state, - then we don't need to add them here. */ - - context = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input) - 1, - mctx->eflags); - next_state = mctx->state_log[cur_idx] - = re_acquire_state_context (err, dfa, &next_nodes, context); - /* We don't need to check errors here, since the return value of - this function is next_state and ERR is already set. */ - - if (table_nodes != NULL) - re_node_set_free (&next_nodes); - } - - if (BE (dfa->nbackref, 0) && next_state != NULL) - { - /* Check OP_OPEN_SUBEXP in the current state in case that we use them - later. We must check them here, since the back references in the - next state might use them. */ - *err = check_subexp_matching_top (mctx, &next_state->nodes, - cur_idx); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - - /* If the next state has back references. */ - if (next_state->has_backref) - { - *err = transit_state_bkref (mctx, &next_state->nodes); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - next_state = mctx->state_log[cur_idx]; - } - } - - return next_state; -} - -/* Skip bytes in the input that correspond to part of a - multi-byte match, then look in the log for a state - from which to restart matching. */ -static re_dfastate_t * -internal_function -find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) -{ - re_dfastate_t *cur_state; - do - { - Idx max = mctx->state_log_top; - Idx cur_str_idx = re_string_cur_idx (&mctx->input); - - do - { - if (++cur_str_idx > max) - return NULL; - re_string_skip_bytes (&mctx->input, 1); - } - while (mctx->state_log[cur_str_idx] == NULL); - - cur_state = merge_state_with_log (err, mctx, NULL); - } - while (*err == REG_NOERROR && cur_state == NULL); - return cur_state; -} - -/* Helper functions for transit_state. */ - -/* From the node set CUR_NODES, pick up the nodes whose types are - OP_OPEN_SUBEXP and which have corresponding back references in the regular - expression. And register them to use them later for evaluating the - corresponding back references. */ - -static reg_errcode_t -internal_function -check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, - Idx str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx node_idx; - reg_errcode_t err; - - /* TODO: This isn't efficient. - Because there might be more than one nodes whose types are - OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all - nodes. - E.g. RE: (a){2} */ - for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx) - { - Idx node = cur_nodes->elems[node_idx]; - if (dfa->nodes[node].type == OP_OPEN_SUBEXP - && dfa->nodes[node].opr.idx < BITSET_WORD_BITS - && (dfa->used_bkref_map - & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx))) - { - err = match_ctx_add_subtop (mctx, node, str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - return REG_NOERROR; -} - -#if 0 -/* Return the next state to which the current state STATE will transit by - accepting the current input byte. */ - -static re_dfastate_t * -transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *state) -{ - const re_dfa_t *const dfa = mctx->dfa; - re_node_set next_nodes; - re_dfastate_t *next_state; - Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input); - unsigned int context; - - *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt) - { - Idx cur_node = state->nodes.elems[node_cnt]; - if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx)) - { - *err = re_node_set_merge (&next_nodes, - dfa->eclosures + dfa->nexts[cur_node]); - if (BE (*err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return NULL; - } - } - } - context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags); - next_state = re_acquire_state_context (err, dfa, &next_nodes, context); - /* We don't need to check errors here, since the return value of - this function is next_state and ERR is already set. */ - - re_node_set_free (&next_nodes); - re_string_skip_bytes (&mctx->input, 1); - return next_state; -} -#endif - -#ifdef RE_ENABLE_I18N -static reg_errcode_t -internal_function -transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx i; - - for (i = 0; i < pstate->nodes.nelem; ++i) - { - re_node_set dest_nodes, *new_nodes; - Idx cur_node_idx = pstate->nodes.elems[i]; - int naccepted; - Idx dest_idx; - unsigned int context; - re_dfastate_t *dest_state; - - if (!dfa->nodes[cur_node_idx].accept_mb) - continue; - - if (dfa->nodes[cur_node_idx].constraint) - { - context = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input), - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint, - context)) - continue; - } - - /* How many bytes the node can accept? */ - naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input, - re_string_cur_idx (&mctx->input)); - if (naccepted == 0) - continue; - - /* The node can accepts 'naccepted' bytes. */ - dest_idx = re_string_cur_idx (&mctx->input) + naccepted; - mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted - : mctx->max_mb_elem_len); - err = clean_state_log_if_needed (mctx, dest_idx); - if (BE (err != REG_NOERROR, 0)) - return err; -#ifdef DEBUG - assert (dfa->nexts[cur_node_idx] != REG_MISSING); -#endif - new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx]; - - dest_state = mctx->state_log[dest_idx]; - if (dest_state == NULL) - dest_nodes = *new_nodes; - else - { - err = re_node_set_init_union (&dest_nodes, - dest_state->entrance_nodes, new_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - context = re_string_context_at (&mctx->input, dest_idx - 1, - mctx->eflags); - mctx->state_log[dest_idx] - = re_acquire_state_context (&err, dfa, &dest_nodes, context); - if (dest_state != NULL) - re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0)) - return err; - } - return REG_NOERROR; -} -#endif /* RE_ENABLE_I18N */ - -static reg_errcode_t -internal_function -transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx i; - Idx cur_str_idx = re_string_cur_idx (&mctx->input); - - for (i = 0; i < nodes->nelem; ++i) - { - Idx dest_str_idx, prev_nelem, bkc_idx; - Idx node_idx = nodes->elems[i]; - unsigned int context; - const re_token_t *node = dfa->nodes + node_idx; - re_node_set *new_dest_nodes; - - /* Check whether 'node' is a backreference or not. */ - if (node->type != OP_BACK_REF) - continue; - - if (node->constraint) - { - context = re_string_context_at (&mctx->input, cur_str_idx, - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) - continue; - } - - /* 'node' is a backreference. - Check the substring which the substring matched. */ - bkc_idx = mctx->nbkref_ents; - err = get_subexp (mctx, node_idx, cur_str_idx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* And add the epsilon closures (which is 'new_dest_nodes') of - the backreference to appropriate state_log. */ -#ifdef DEBUG - assert (dfa->nexts[node_idx] != REG_MISSING); -#endif - for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx) - { - Idx subexp_len; - re_dfastate_t *dest_state; - struct re_backref_cache_entry *bkref_ent; - bkref_ent = mctx->bkref_ents + bkc_idx; - if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx) - continue; - subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from; - new_dest_nodes = (subexp_len == 0 - ? dfa->eclosures + dfa->edests[node_idx].elems[0] - : dfa->eclosures + dfa->nexts[node_idx]); - dest_str_idx = (cur_str_idx + bkref_ent->subexp_to - - bkref_ent->subexp_from); - context = re_string_context_at (&mctx->input, dest_str_idx - 1, - mctx->eflags); - dest_state = mctx->state_log[dest_str_idx]; - prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0 - : mctx->state_log[cur_str_idx]->nodes.nelem); - /* Add 'new_dest_node' to state_log. */ - if (dest_state == NULL) - { - mctx->state_log[dest_str_idx] - = re_acquire_state_context (&err, dfa, new_dest_nodes, - context); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) - goto free_return; - } - else - { - re_node_set dest_nodes; - err = re_node_set_init_union (&dest_nodes, - dest_state->entrance_nodes, - new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&dest_nodes); - goto free_return; - } - mctx->state_log[dest_str_idx] - = re_acquire_state_context (&err, dfa, &dest_nodes, context); - re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) - goto free_return; - } - /* We need to check recursively if the backreference can epsilon - transit. */ - if (subexp_len == 0 - && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem) - { - err = check_subexp_matching_top (mctx, new_dest_nodes, - cur_str_idx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - err = transit_state_bkref (mctx, new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - } - } - err = REG_NOERROR; - free_return: - return err; -} - -/* Enumerate all the candidates which the backreference BKREF_NODE can match - at BKREF_STR_IDX, and register them by match_ctx_add_entry(). - Note that we might collect inappropriate candidates here. - However, the cost of checking them strictly here is too high, then we - delay these checking for prune_impossible_nodes(). */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - Idx subexp_num, sub_top_idx; - const char *buf = (const char *) re_string_get_buffer (&mctx->input); - /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX. */ - Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx); - if (cache_idx != REG_MISSING) - { - const struct re_backref_cache_entry *entry - = mctx->bkref_ents + cache_idx; - do - if (entry->node == bkref_node) - return REG_NOERROR; /* We already checked it. */ - while (entry++->more); - } - - subexp_num = dfa->nodes[bkref_node].opr.idx; - - /* For each sub expression */ - for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx) - { - reg_errcode_t err; - re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx]; - re_sub_match_last_t *sub_last; - Idx sub_last_idx, sl_str, bkref_str_off; - - if (dfa->nodes[sub_top->node].opr.idx != subexp_num) - continue; /* It isn't related. */ - - sl_str = sub_top->str_idx; - bkref_str_off = bkref_str_idx; - /* At first, check the last node of sub expressions we already - evaluated. */ - for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx) - { - regoff_t sl_str_diff; - sub_last = sub_top->lasts[sub_last_idx]; - sl_str_diff = sub_last->str_idx - sl_str; - /* The matched string by the sub expression match with the substring - at the back reference? */ - if (sl_str_diff > 0) - { - if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0)) - { - /* Not enough chars for a successful match. */ - if (bkref_str_off + sl_str_diff > mctx->input.len) - break; - - err = clean_state_log_if_needed (mctx, - bkref_str_off - + sl_str_diff); - if (BE (err != REG_NOERROR, 0)) - return err; - buf = (const char *) re_string_get_buffer (&mctx->input); - } - if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0) - /* We don't need to search this sub expression any more. */ - break; - } - bkref_str_off += sl_str_diff; - sl_str += sl_str_diff; - err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, - bkref_str_idx); - - /* Reload buf, since the preceding call might have reallocated - the buffer. */ - buf = (const char *) re_string_get_buffer (&mctx->input); - - if (err == REG_NOMATCH) - continue; - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (sub_last_idx < sub_top->nlasts) - continue; - if (sub_last_idx > 0) - ++sl_str; - /* Then, search for the other last nodes of the sub expression. */ - for (; sl_str <= bkref_str_idx; ++sl_str) - { - Idx cls_node; - regoff_t sl_str_off; - const re_node_set *nodes; - sl_str_off = sl_str - sub_top->str_idx; - /* The matched string by the sub expression match with the substring - at the back reference? */ - if (sl_str_off > 0) - { - if (BE (bkref_str_off >= mctx->input.valid_len, 0)) - { - /* If we are at the end of the input, we cannot match. */ - if (bkref_str_off >= mctx->input.len) - break; - - err = extend_buffers (mctx, bkref_str_off + 1); - if (BE (err != REG_NOERROR, 0)) - return err; - - buf = (const char *) re_string_get_buffer (&mctx->input); - } - if (buf [bkref_str_off++] != buf[sl_str - 1]) - break; /* We don't need to search this sub expression - any more. */ - } - if (mctx->state_log[sl_str] == NULL) - continue; - /* Does this state have a ')' of the sub expression? */ - nodes = &mctx->state_log[sl_str]->nodes; - cls_node = find_subexp_node (dfa, nodes, subexp_num, - OP_CLOSE_SUBEXP); - if (cls_node == REG_MISSING) - continue; /* No. */ - if (sub_top->path == NULL) - { - sub_top->path = calloc (sizeof (state_array_t), - sl_str - sub_top->str_idx + 1); - if (sub_top->path == NULL) - return REG_ESPACE; - } - /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node - in the current context? */ - err = check_arrival (mctx, sub_top->path, sub_top->node, - sub_top->str_idx, cls_node, sl_str, - OP_CLOSE_SUBEXP); - if (err == REG_NOMATCH) - continue; - if (BE (err != REG_NOERROR, 0)) - return err; - sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str); - if (BE (sub_last == NULL, 0)) - return REG_ESPACE; - err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, - bkref_str_idx); - if (err == REG_NOMATCH) - continue; - } - } - return REG_NOERROR; -} - -/* Helper functions for get_subexp(). */ - -/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR. - If it can arrive, register the sub expression expressed with SUB_TOP - and SUB_LAST. */ - -static reg_errcode_t -internal_function -get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, - re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str) -{ - reg_errcode_t err; - Idx to_idx; - /* Can the subexpression arrive the back reference? */ - err = check_arrival (mctx, &sub_last->path, sub_last->node, - sub_last->str_idx, bkref_node, bkref_str, - OP_OPEN_SUBEXP); - if (err != REG_NOERROR) - return err; - err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx, - sub_last->str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx; - return clean_state_log_if_needed (mctx, to_idx); -} - -/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX. - Search '(' if FL_OPEN, or search ')' otherwise. - TODO: This function isn't efficient... - Because there might be more than one nodes whose types are - OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all - nodes. - E.g. RE: (a){2} */ - -static Idx -internal_function -find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, - Idx subexp_idx, int type) -{ - Idx cls_idx; - for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx) - { - Idx cls_node = nodes->elems[cls_idx]; - const re_token_t *node = dfa->nodes + cls_node; - if (node->type == type - && node->opr.idx == subexp_idx) - return cls_node; - } - return REG_MISSING; -} - -/* Check whether the node TOP_NODE at TOP_STR can arrive to the node - LAST_NODE at LAST_STR. We record the path onto PATH since it will be - heavily reused. - Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, - Idx top_str, Idx last_node, Idx last_str, int type) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err = REG_NOERROR; - Idx subexp_num, backup_cur_idx, str_idx, null_cnt; - re_dfastate_t *cur_state = NULL; - re_node_set *cur_nodes, next_nodes; - re_dfastate_t **backup_state_log; - unsigned int context; - - subexp_num = dfa->nodes[top_node].opr.idx; - /* Extend the buffer if we need. */ - if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0)) - { - re_dfastate_t **new_array; - Idx old_alloc = path->alloc; - Idx incr_alloc = last_str + mctx->max_mb_elem_len + 1; - Idx new_alloc; - if (BE (IDX_MAX - old_alloc < incr_alloc, 0)) - return REG_ESPACE; - new_alloc = old_alloc + incr_alloc; - if (BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0)) - return REG_ESPACE; - new_array = re_realloc (path->array, re_dfastate_t *, new_alloc); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - path->array = new_array; - path->alloc = new_alloc; - memset (new_array + old_alloc, '\0', - sizeof (re_dfastate_t *) * (path->alloc - old_alloc)); - } - - str_idx = path->next_idx ? path->next_idx : top_str; - - /* Temporary modify MCTX. */ - backup_state_log = mctx->state_log; - backup_cur_idx = mctx->input.cur_idx; - mctx->state_log = path->array; - mctx->input.cur_idx = str_idx; - - /* Setup initial node set. */ - context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); - if (str_idx == top_str) - { - err = re_node_set_init_1 (&next_nodes, top_node); - if (BE (err != REG_NOERROR, 0)) - return err; - err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - else - { - cur_state = mctx->state_log[str_idx]; - if (cur_state && cur_state->has_backref) - { - err = re_node_set_init_copy (&next_nodes, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - re_node_set_init_empty (&next_nodes); - } - if (str_idx == top_str || (cur_state && cur_state->has_backref)) - { - if (next_nodes.nelem) - { - err = expand_bkref_cache (mctx, &next_nodes, str_idx, - subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - mctx->state_log[str_idx] = cur_state; - } - - for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) - { - re_node_set_empty (&next_nodes); - if (mctx->state_log[str_idx + 1]) - { - err = re_node_set_merge (&next_nodes, - &mctx->state_log[str_idx + 1]->nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - if (cur_state) - { - err = check_arrival_add_next_nodes (mctx, str_idx, - &cur_state->non_eps_nodes, - &next_nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - ++str_idx; - if (next_nodes.nelem) - { - err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - err = expand_bkref_cache (mctx, &next_nodes, str_idx, - subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); - cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - mctx->state_log[str_idx] = cur_state; - null_cnt = cur_state == NULL ? null_cnt + 1 : 0; - } - re_node_set_free (&next_nodes); - cur_nodes = (mctx->state_log[last_str] == NULL ? NULL - : &mctx->state_log[last_str]->nodes); - path->next_idx = str_idx; - - /* Fix MCTX. */ - mctx->state_log = backup_state_log; - mctx->input.cur_idx = backup_cur_idx; - - /* Then check the current node set has the node LAST_NODE. */ - if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node)) - return REG_NOERROR; - - return REG_NOMATCH; -} - -/* Helper functions for check_arrival. */ - -/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them - to NEXT_NODES. - TODO: This function is similar to the functions transit_state*(), - however this function has many additional works. - Can't we unify them? */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, - re_node_set *cur_nodes, re_node_set *next_nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - bool ok; - Idx cur_idx; -#ifdef RE_ENABLE_I18N - reg_errcode_t err = REG_NOERROR; -#endif - re_node_set union_set; - re_node_set_init_empty (&union_set); - for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx) - { - int naccepted = 0; - Idx cur_node = cur_nodes->elems[cur_idx]; -#ifdef DEBUG - re_token_type_t type = dfa->nodes[cur_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N - /* If the node may accept "multi byte". */ - if (dfa->nodes[cur_node].accept_mb) - { - naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input, - str_idx); - if (naccepted > 1) - { - re_dfastate_t *dest_state; - Idx next_node = dfa->nexts[cur_node]; - Idx next_idx = str_idx + naccepted; - dest_state = mctx->state_log[next_idx]; - re_node_set_empty (&union_set); - if (dest_state) - { - err = re_node_set_merge (&union_set, &dest_state->nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&union_set); - return err; - } - } - ok = re_node_set_insert (&union_set, next_node); - if (BE (! ok, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } - mctx->state_log[next_idx] = re_acquire_state (&err, dfa, - &union_set); - if (BE (mctx->state_log[next_idx] == NULL - && err != REG_NOERROR, 0)) - { - re_node_set_free (&union_set); - return err; - } - } - } -#endif /* RE_ENABLE_I18N */ - if (naccepted - || check_node_accept (mctx, dfa->nodes + cur_node, str_idx)) - { - ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]); - if (BE (! ok, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } - } - } - re_node_set_free (&union_set); - return REG_NOERROR; -} - -/* For all the nodes in CUR_NODES, add the epsilon closures of them to - CUR_NODES, however exclude the nodes which are: - - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN. - - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN. -*/ - -static reg_errcode_t -internal_function -check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, - Idx ex_subexp, int type) -{ - reg_errcode_t err; - Idx idx, outside_node; - re_node_set new_nodes; -#ifdef DEBUG - assert (cur_nodes->nelem); -#endif - err = re_node_set_alloc (&new_nodes, cur_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) - return err; - /* Create a new node set NEW_NODES with the nodes which are epsilon - closures of the node in CUR_NODES. */ - - for (idx = 0; idx < cur_nodes->nelem; ++idx) - { - Idx cur_node = cur_nodes->elems[idx]; - const re_node_set *eclosure = dfa->eclosures + cur_node; - outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type); - if (outside_node == REG_MISSING) - { - /* There are no problematic nodes, just merge them. */ - err = re_node_set_merge (&new_nodes, eclosure); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&new_nodes); - return err; - } - } - else - { - /* There are problematic nodes, re-calculate incrementally. */ - err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node, - ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&new_nodes); - return err; - } - } - } - re_node_set_free (cur_nodes); - *cur_nodes = new_nodes; - return REG_NOERROR; -} - -/* Helper function for check_arrival_expand_ecl. - Check incrementally the epsilon closure of TARGET, and if it isn't - problematic append it to DST_NODES. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, - Idx target, Idx ex_subexp, int type) -{ - Idx cur_node; - for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);) - { - bool ok; - - if (dfa->nodes[cur_node].type == type - && dfa->nodes[cur_node].opr.idx == ex_subexp) - { - if (type == OP_CLOSE_SUBEXP) - { - ok = re_node_set_insert (dst_nodes, cur_node); - if (BE (! ok, 0)) - return REG_ESPACE; - } - break; - } - ok = re_node_set_insert (dst_nodes, cur_node); - if (BE (! ok, 0)) - return REG_ESPACE; - if (dfa->edests[cur_node].nelem == 0) - break; - if (dfa->edests[cur_node].nelem == 2) - { - reg_errcode_t err; - err = check_arrival_expand_ecl_sub (dfa, dst_nodes, - dfa->edests[cur_node].elems[1], - ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) - return err; - } - cur_node = dfa->edests[cur_node].elems[0]; - } - return REG_NOERROR; -} - - -/* For all the back references in the current state, calculate the - destination of the back references by the appropriate entry - in MCTX->BKREF_ENTS. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, - Idx cur_str, Idx subexp_num, int type) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str); - struct re_backref_cache_entry *ent; - - if (cache_idx_start == REG_MISSING) - return REG_NOERROR; - - restart: - ent = mctx->bkref_ents + cache_idx_start; - do - { - Idx to_idx, next_node; - - /* Is this entry ENT is appropriate? */ - if (!re_node_set_contains (cur_nodes, ent->node)) - continue; /* No. */ - - to_idx = cur_str + ent->subexp_to - ent->subexp_from; - /* Calculate the destination of the back reference, and append it - to MCTX->STATE_LOG. */ - if (to_idx == cur_str) - { - /* The backreference did epsilon transit, we must re-check all the - node in the current state. */ - re_node_set new_dests; - reg_errcode_t err2, err3; - next_node = dfa->edests[ent->node].elems[0]; - if (re_node_set_contains (cur_nodes, next_node)) - continue; - err = re_node_set_init_1 (&new_dests, next_node); - err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type); - err3 = re_node_set_merge (cur_nodes, &new_dests); - re_node_set_free (&new_dests); - if (BE (err != REG_NOERROR || err2 != REG_NOERROR - || err3 != REG_NOERROR, 0)) - { - err = (err != REG_NOERROR ? err - : (err2 != REG_NOERROR ? err2 : err3)); - return err; - } - /* TODO: It is still inefficient... */ - goto restart; - } - else - { - re_node_set union_set; - next_node = dfa->nexts[ent->node]; - if (mctx->state_log[to_idx]) - { - bool ok; - if (re_node_set_contains (&mctx->state_log[to_idx]->nodes, - next_node)) - continue; - err = re_node_set_init_copy (&union_set, - &mctx->state_log[to_idx]->nodes); - ok = re_node_set_insert (&union_set, next_node); - if (BE (err != REG_NOERROR || ! ok, 0)) - { - re_node_set_free (&union_set); - err = err != REG_NOERROR ? err : REG_ESPACE; - return err; - } - } - else - { - err = re_node_set_init_1 (&union_set, next_node); - if (BE (err != REG_NOERROR, 0)) - return err; - } - mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set); - re_node_set_free (&union_set); - if (BE (mctx->state_log[to_idx] == NULL - && err != REG_NOERROR, 0)) - return err; - } - } - while (ent++->more); - return REG_NOERROR; -} - -/* Build transition table for the state. - Return true if successful. */ - -static bool -internal_function -build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) -{ - reg_errcode_t err; - Idx i, j; - int ch; - bool need_word_trtable = false; - bitset_word_t elem, mask; - bool dests_node_malloced = false; - bool dest_states_malloced = false; - Idx ndests; /* Number of the destination states from 'state'. */ - re_dfastate_t **trtable; - re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; - re_node_set follows, *dests_node; - bitset_t *dests_ch; - bitset_t acceptable; - - struct dests_alloc - { - re_node_set dests_node[SBC_MAX]; - bitset_t dests_ch[SBC_MAX]; - } *dests_alloc; - - /* We build DFA states which corresponds to the destination nodes - from 'state'. 'dests_node[i]' represents the nodes which i-th - destination state contains, and 'dests_ch[i]' represents the - characters which i-th destination state accepts. */ - if (__libc_use_alloca (sizeof (struct dests_alloc))) - dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc)); - else - { - dests_alloc = re_malloc (struct dests_alloc, 1); - if (BE (dests_alloc == NULL, 0)) - return false; - dests_node_malloced = true; - } - dests_node = dests_alloc->dests_node; - dests_ch = dests_alloc->dests_ch; - - /* Initialize transition table. */ - state->word_trtable = state->trtable = NULL; - - /* At first, group all nodes belonging to 'state' into several - destinations. */ - ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); - if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0)) - { - if (dests_node_malloced) - free (dests_alloc); - /* Return false in case of an error, true otherwise. */ - if (ndests == 0) - { - state->trtable = (re_dfastate_t **) - calloc (sizeof (re_dfastate_t *), SBC_MAX); - if (BE (state->trtable == NULL, 0)) - return false; - return true; - } - return false; - } - - err = re_node_set_alloc (&follows, ndests + 1); - if (BE (err != REG_NOERROR, 0)) - goto out_free; - - /* Avoid arithmetic overflow in size calculation. */ - if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX) - / (3 * sizeof (re_dfastate_t *))) - < ndests), - 0)) - goto out_free; - - if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX - + ndests * 3 * sizeof (re_dfastate_t *))) - dest_states = (re_dfastate_t **) - alloca (ndests * 3 * sizeof (re_dfastate_t *)); - else - { - dest_states = (re_dfastate_t **) - malloc (ndests * 3 * sizeof (re_dfastate_t *)); - if (BE (dest_states == NULL, 0)) - { -out_free: - if (dest_states_malloced) - free (dest_states); - re_node_set_free (&follows); - for (i = 0; i < ndests; ++i) - re_node_set_free (dests_node + i); - if (dests_node_malloced) - free (dests_alloc); - return false; - } - dest_states_malloced = true; - } - dest_states_word = dest_states + ndests; - dest_states_nl = dest_states_word + ndests; - bitset_empty (acceptable); - - /* Then build the states for all destinations. */ - for (i = 0; i < ndests; ++i) - { - Idx next_node; - re_node_set_empty (&follows); - /* Merge the follows of this destination states. */ - for (j = 0; j < dests_node[i].nelem; ++j) - { - next_node = dfa->nexts[dests_node[i].elems[j]]; - if (next_node != REG_MISSING) - { - err = re_node_set_merge (&follows, dfa->eclosures + next_node); - if (BE (err != REG_NOERROR, 0)) - goto out_free; - } - } - dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0); - if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - /* If the new state has context constraint, - build appropriate states for these contexts. */ - if (dest_states[i]->has_constraint) - { - dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows, - CONTEXT_WORD); - if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - - if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1) - need_word_trtable = true; - - dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, - CONTEXT_NEWLINE); - if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - } - else - { - dest_states_word[i] = dest_states[i]; - dest_states_nl[i] = dest_states[i]; - } - bitset_merge (acceptable, dests_ch[i]); - } - - if (!BE (need_word_trtable, 0)) - { - /* We don't care about whether the following character is a word - character, or we are in a single-byte character set so we can - discern by looking at the character code: allocate a - 256-entry transition table. */ - trtable = state->trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); - if (BE (trtable == NULL, 0)) - goto out_free; - - /* For all characters ch...: */ - for (i = 0; i < BITSET_WORDS; ++i) - for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; - elem; - mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) - { - /* There must be exactly one destination which accepts - character ch. See group_nodes_into_DFAstates. */ - for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) - ; - - /* j-th destination accepts the word character ch. */ - if (dfa->word_char[i] & mask) - trtable[ch] = dest_states_word[j]; - else - trtable[ch] = dest_states[j]; - } - } - else - { - /* We care about whether the following character is a word - character, and we are in a multi-byte character set: discern - by looking at the character code: build two 256-entry - transition tables, one starting at trtable[0] and one - starting at trtable[SBC_MAX]. */ - trtable = state->word_trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); - if (BE (trtable == NULL, 0)) - goto out_free; - - /* For all characters ch...: */ - for (i = 0; i < BITSET_WORDS; ++i) - for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; - elem; - mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) - { - /* There must be exactly one destination which accepts - character ch. See group_nodes_into_DFAstates. */ - for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) - ; - - /* j-th destination accepts the word character ch. */ - trtable[ch] = dest_states[j]; - trtable[ch + SBC_MAX] = dest_states_word[j]; - } - } - - /* new line */ - if (bitset_contain (acceptable, NEWLINE_CHAR)) - { - /* The current state accepts newline character. */ - for (j = 0; j < ndests; ++j) - if (bitset_contain (dests_ch[j], NEWLINE_CHAR)) - { - /* k-th destination accepts newline character. */ - trtable[NEWLINE_CHAR] = dest_states_nl[j]; - if (need_word_trtable) - trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j]; - /* There must be only one destination which accepts - newline. See group_nodes_into_DFAstates. */ - break; - } - } - - if (dest_states_malloced) - free (dest_states); - - re_node_set_free (&follows); - for (i = 0; i < ndests; ++i) - re_node_set_free (dests_node + i); - - if (dests_node_malloced) - free (dests_alloc); - - return true; -} - -/* Group all nodes belonging to STATE into several destinations. - Then for all destinations, set the nodes belonging to the destination - to DESTS_NODE[i] and set the characters accepted by the destination - to DEST_CH[i]. This function return the number of destinations. */ - -static Idx -internal_function -group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, - re_node_set *dests_node, bitset_t *dests_ch) -{ - reg_errcode_t err; - bool ok; - Idx i, j, k; - Idx ndests; /* Number of the destinations from 'state'. */ - bitset_t accepts; /* Characters a node can accept. */ - const re_node_set *cur_nodes = &state->nodes; - bitset_empty (accepts); - ndests = 0; - - /* For all the nodes belonging to 'state', */ - for (i = 0; i < cur_nodes->nelem; ++i) - { - re_token_t *node = &dfa->nodes[cur_nodes->elems[i]]; - re_token_type_t type = node->type; - unsigned int constraint = node->constraint; - - /* Enumerate all single byte character this node can accept. */ - if (type == CHARACTER) - bitset_set (accepts, node->opr.c); - else if (type == SIMPLE_BRACKET) - { - bitset_merge (accepts, node->opr.sbcset); - } - else if (type == OP_PERIOD) - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - bitset_merge (accepts, dfa->sb_char); - else -#endif - bitset_set_all (accepts); - if (!(dfa->syntax & RE_DOT_NEWLINE)) - bitset_clear (accepts, '\n'); - if (dfa->syntax & RE_DOT_NOT_NULL) - bitset_clear (accepts, '\0'); - } -#ifdef RE_ENABLE_I18N - else if (type == OP_UTF8_PERIOD) - { - if (ASCII_CHARS % BITSET_WORD_BITS == 0) - memset (accepts, -1, ASCII_CHARS / CHAR_BIT); - else - bitset_merge (accepts, utf8_sb_map); - if (!(dfa->syntax & RE_DOT_NEWLINE)) - bitset_clear (accepts, '\n'); - if (dfa->syntax & RE_DOT_NOT_NULL) - bitset_clear (accepts, '\0'); - } -#endif - else - continue; - - /* Check the 'accepts' and sift the characters which are not - match it the context. */ - if (constraint) - { - if (constraint & NEXT_NEWLINE_CONSTRAINT) - { - bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR); - bitset_empty (accepts); - if (accepts_newline) - bitset_set (accepts, NEWLINE_CHAR); - else - continue; - } - if (constraint & NEXT_ENDBUF_CONSTRAINT) - { - bitset_empty (accepts); - continue; - } - - if (constraint & NEXT_WORD_CONSTRAINT) - { - bitset_word_t any_set = 0; - if (type == CHARACTER && !node->word_char) - { - bitset_empty (accepts); - continue; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j])); - else -#endif - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= dfa->word_char[j]); - if (!any_set) - continue; - } - if (constraint & NEXT_NOTWORD_CONSTRAINT) - { - bitset_word_t any_set = 0; - if (type == CHARACTER && node->word_char) - { - bitset_empty (accepts); - continue; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j])); - else -#endif - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= ~dfa->word_char[j]); - if (!any_set) - continue; - } - } - - /* Then divide 'accepts' into DFA states, or create a new - state. Above, we make sure that accepts is not empty. */ - for (j = 0; j < ndests; ++j) - { - bitset_t intersec; /* Intersection sets, see below. */ - bitset_t remains; - /* Flags, see below. */ - bitset_word_t has_intersec, not_subset, not_consumed; - - /* Optimization, skip if this state doesn't accept the character. */ - if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c)) - continue; - - /* Enumerate the intersection set of this state and 'accepts'. */ - has_intersec = 0; - for (k = 0; k < BITSET_WORDS; ++k) - has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k]; - /* And skip if the intersection set is empty. */ - if (!has_intersec) - continue; - - /* Then check if this state is a subset of 'accepts'. */ - not_subset = not_consumed = 0; - for (k = 0; k < BITSET_WORDS; ++k) - { - not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k]; - not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k]; - } - - /* If this state isn't a subset of 'accepts', create a - new group state, which has the 'remains'. */ - if (not_subset) - { - bitset_copy (dests_ch[ndests], remains); - bitset_copy (dests_ch[j], intersec); - err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]); - if (BE (err != REG_NOERROR, 0)) - goto error_return; - ++ndests; - } - - /* Put the position in the current group. */ - ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]); - if (BE (! ok, 0)) - goto error_return; - - /* If all characters are consumed, go to next node. */ - if (!not_consumed) - break; - } - /* Some characters remain, create a new group. */ - if (j == ndests) - { - bitset_copy (dests_ch[ndests], accepts); - err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]); - if (BE (err != REG_NOERROR, 0)) - goto error_return; - ++ndests; - bitset_empty (accepts); - } - } - return ndests; - error_return: - for (j = 0; j < ndests; ++j) - re_node_set_free (dests_node + j); - return REG_MISSING; -} - -#ifdef RE_ENABLE_I18N -/* Check how many bytes the node 'dfa->nodes[node_idx]' accepts. - Return the number of the bytes the node accepts. - STR_IDX is the current index of the input string. - - This function handles the nodes which can accept one character, or - one collating element like '.', '[a-z]', opposite to the other nodes - can only accept one byte. */ - -static int -internal_function -check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, - const re_string_t *input, Idx str_idx) -{ - const re_token_t *node = dfa->nodes + node_idx; - int char_len, elem_len; - Idx i; - - if (BE (node->type == OP_UTF8_PERIOD, 0)) - { - unsigned char c = re_string_byte_at (input, str_idx), d; - if (BE (c < 0xc2, 1)) - return 0; - - if (str_idx + 2 > input->len) - return 0; - - d = re_string_byte_at (input, str_idx + 1); - if (c < 0xe0) - return (d < 0x80 || d > 0xbf) ? 0 : 2; - else if (c < 0xf0) - { - char_len = 3; - if (c == 0xe0 && d < 0xa0) - return 0; - } - else if (c < 0xf8) - { - char_len = 4; - if (c == 0xf0 && d < 0x90) - return 0; - } - else if (c < 0xfc) - { - char_len = 5; - if (c == 0xf8 && d < 0x88) - return 0; - } - else if (c < 0xfe) - { - char_len = 6; - if (c == 0xfc && d < 0x84) - return 0; - } - else - return 0; - - if (str_idx + char_len > input->len) - return 0; - - for (i = 1; i < char_len; ++i) - { - d = re_string_byte_at (input, str_idx + i); - if (d < 0x80 || d > 0xbf) - return 0; - } - return char_len; - } - - char_len = re_string_char_size_at (input, str_idx); - if (node->type == OP_PERIOD) - { - if (char_len <= 1) - return 0; - /* FIXME: I don't think this if is needed, as both '\n' - and '\0' are char_len == 1. */ - /* '.' accepts any one character except the following two cases. */ - if ((!(dfa->syntax & RE_DOT_NEWLINE) && - re_string_byte_at (input, str_idx) == '\n') || - ((dfa->syntax & RE_DOT_NOT_NULL) && - re_string_byte_at (input, str_idx) == '\0')) - return 0; - return char_len; - } - - elem_len = re_string_elem_size_at (input, str_idx); - if ((elem_len <= 1 && char_len <= 1) || char_len == 0) - return 0; - - if (node->type == COMPLEX_BRACKET) - { - const re_charset_t *cset = node->opr.mbcset; -# ifdef _LIBC - const unsigned char *pin - = ((const unsigned char *) re_string_get_buffer (input) + str_idx); - Idx j; - uint32_t nrules; -# endif /* _LIBC */ - int match_len = 0; - wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars) - ? re_string_wchar_at (input, str_idx) : 0); - - /* match with multibyte character? */ - for (i = 0; i < cset->nmbchars; ++i) - if (wc == cset->mbchars[i]) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - /* match with character_class? */ - for (i = 0; i < cset->nchar_classes; ++i) - { - wctype_t wt = cset->char_classes[i]; - if (__iswctype (wc, wt)) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - } - -# ifdef _LIBC - nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules != 0) - { - unsigned int in_collseq = 0; - const int32_t *table, *indirect; - const unsigned char *weights, *extra; - const char *collseqwc; - /* This #include defines a local function! */ -# include - - /* match with collating_symbol? */ - if (cset->ncoll_syms) - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); - for (i = 0; i < cset->ncoll_syms; ++i) - { - const unsigned char *coll_sym = extra + cset->coll_syms[i]; - /* Compare the length of input collating element and - the length of current collating element. */ - if (*coll_sym != elem_len) - continue; - /* Compare each bytes. */ - for (j = 0; j < *coll_sym; j++) - if (pin[j] != coll_sym[1 + j]) - break; - if (j == *coll_sym) - { - /* Match if every bytes is equal. */ - match_len = j; - goto check_node_accept_bytes_match; - } - } - - if (cset->nranges) - { - if (elem_len <= char_len) - { - collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); - in_collseq = __collseq_table_lookup (collseqwc, wc); - } - else - in_collseq = find_collation_sequence_value (pin, elem_len); - } - /* match with range expression? */ - /* FIXME: Implement rational ranges here, too. */ - for (i = 0; i < cset->nranges; ++i) - if (cset->range_starts[i] <= in_collseq - && in_collseq <= cset->range_ends[i]) - { - match_len = elem_len; - goto check_node_accept_bytes_match; - } - - /* match with equivalence_class? */ - if (cset->nequiv_classes) - { - const unsigned char *cp = pin; - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - int32_t idx = findidx (&cp, elem_len); - if (idx > 0) - for (i = 0; i < cset->nequiv_classes; ++i) - { - int32_t equiv_class_idx = cset->equiv_classes[i]; - size_t weight_len = weights[idx & 0xffffff]; - if (weight_len == weights[equiv_class_idx & 0xffffff] - && (idx >> 24) == (equiv_class_idx >> 24)) - { - Idx cnt = 0; - - idx &= 0xffffff; - equiv_class_idx &= 0xffffff; - - while (cnt <= weight_len - && (weights[equiv_class_idx + 1 + cnt] - == weights[idx + 1 + cnt])) - ++cnt; - if (cnt > weight_len) - { - match_len = elem_len; - goto check_node_accept_bytes_match; - } - } - } - } - } - else -# endif /* _LIBC */ - { - /* match with range expression? */ - for (i = 0; i < cset->nranges; ++i) - { - if (cset->range_starts[i] <= wc && wc <= cset->range_ends[i]) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - } - } - check_node_accept_bytes_match: - if (!cset->non_match) - return match_len; - else - { - if (match_len > 0) - return 0; - else - return (elem_len > char_len) ? elem_len : char_len; - } - } - return 0; -} - -# ifdef _LIBC -static unsigned int -internal_function -find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) -{ - uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules == 0) - { - if (mbs_len == 1) - { - /* No valid character. Match it as a single byte character. */ - const unsigned char *collseq = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); - return collseq[mbs[0]]; - } - return UINT_MAX; - } - else - { - int32_t idx; - const unsigned char *extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); - int32_t extrasize = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra; - - for (idx = 0; idx < extrasize;) - { - int mbs_cnt; - bool found = false; - int32_t elem_mbs_len; - /* Skip the name of collating element name. */ - idx = idx + extra[idx] + 1; - elem_mbs_len = extra[idx++]; - if (mbs_len == elem_mbs_len) - { - for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt) - if (extra[idx + mbs_cnt] != mbs[mbs_cnt]) - break; - if (mbs_cnt == elem_mbs_len) - /* Found the entry. */ - found = true; - } - /* Skip the byte sequence of the collating element. */ - idx += elem_mbs_len; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - /* Skip the collation sequence value. */ - idx += sizeof (uint32_t); - /* Skip the wide char sequence of the collating element. */ - idx = idx + sizeof (uint32_t) * (*(int32_t *) (extra + idx) + 1); - /* If we found the entry, return the sequence value. */ - if (found) - return *(uint32_t *) (extra + idx); - /* Skip the collation sequence value. */ - idx += sizeof (uint32_t); - } - return UINT_MAX; - } -} -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ - -/* Check whether the node accepts the byte which is IDX-th - byte of the INPUT. */ - -static bool -internal_function -check_node_accept (const re_match_context_t *mctx, const re_token_t *node, - Idx idx) -{ - unsigned char ch; - ch = re_string_byte_at (&mctx->input, idx); - switch (node->type) - { - case CHARACTER: - if (node->opr.c != ch) - return false; - break; - - case SIMPLE_BRACKET: - if (!bitset_contain (node->opr.sbcset, ch)) - return false; - break; - -#ifdef RE_ENABLE_I18N - case OP_UTF8_PERIOD: - if (ch >= ASCII_CHARS) - return false; - /* FALLTHROUGH */ -#endif - case OP_PERIOD: - if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE)) - || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL))) - return false; - break; - - default: - return false; - } - - if (node->constraint) - { - /* The node has constraints. Check whether the current context - satisfies the constraints. */ - unsigned int context = re_string_context_at (&mctx->input, idx, - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) - return false; - } - - return true; -} - -/* Extend the buffers, if the buffers have run out. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -extend_buffers (re_match_context_t *mctx, int min_len) -{ - reg_errcode_t ret; - re_string_t *pstr = &mctx->input; - - /* Avoid overflow. */ - if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) / 2 - <= pstr->bufs_len, 0)) - return REG_ESPACE; - - /* Double the lengths of the buffers, but allocate at least MIN_LEN. */ - ret = re_string_realloc_buffers (pstr, - MAX (min_len, - MIN (pstr->len, pstr->bufs_len * 2))); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - if (mctx->state_log != NULL) - { - /* And double the length of state_log. */ - /* XXX We have no indication of the size of this buffer. If this - allocation fail we have no indication that the state_log array - does not have the right size. */ - re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *, - pstr->bufs_len + 1); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - mctx->state_log = new_array; - } - - /* Then reconstruct the buffers. */ - if (pstr->icase) - { -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - else -#endif /* RE_ENABLE_I18N */ - build_upper_buffer (pstr); - } - else - { -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - build_wcs_buffer (pstr); - else -#endif /* RE_ENABLE_I18N */ - { - if (pstr->trans != NULL) - re_string_translate_buffer (pstr); - } - } - return REG_NOERROR; -} - - -/* Functions for matching context. */ - -/* Initialize MCTX. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) -{ - mctx->eflags = eflags; - mctx->match_last = REG_MISSING; - if (n > 0) - { - /* Avoid overflow. */ - size_t max_object_size = - MAX (sizeof (struct re_backref_cache_entry), - sizeof (re_sub_match_top_t *)); - if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < n, 0)) - return REG_ESPACE; - - mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n); - mctx->sub_tops = re_malloc (re_sub_match_top_t *, n); - if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0)) - return REG_ESPACE; - } - /* Already zero-ed by the caller. - else - mctx->bkref_ents = NULL; - mctx->nbkref_ents = 0; - mctx->nsub_tops = 0; */ - mctx->abkref_ents = n; - mctx->max_mb_elem_len = 1; - mctx->asub_tops = n; - return REG_NOERROR; -} - -/* Clean the entries which depend on the current input in MCTX. - This function must be invoked when the matcher changes the start index - of the input, or changes the input string. */ - -static void -internal_function -match_ctx_clean (re_match_context_t *mctx) -{ - Idx st_idx; - for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx) - { - Idx sl_idx; - re_sub_match_top_t *top = mctx->sub_tops[st_idx]; - for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx) - { - re_sub_match_last_t *last = top->lasts[sl_idx]; - re_free (last->path.array); - re_free (last); - } - re_free (top->lasts); - if (top->path) - { - re_free (top->path->array); - re_free (top->path); - } - free (top); - } - - mctx->nsub_tops = 0; - mctx->nbkref_ents = 0; -} - -/* Free all the memory associated with MCTX. */ - -static void -internal_function -match_ctx_free (re_match_context_t *mctx) -{ - /* First, free all the memory associated with MCTX->SUB_TOPS. */ - match_ctx_clean (mctx); - re_free (mctx->sub_tops); - re_free (mctx->bkref_ents); -} - -/* Add a new backreference entry to MCTX. - Note that we assume that caller never call this function with duplicate - entry, and call with STR_IDX which isn't smaller than any existing entry. -*/ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, - Idx to) -{ - if (mctx->nbkref_ents >= mctx->abkref_ents) - { - struct re_backref_cache_entry* new_entry; - new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry, - mctx->abkref_ents * 2); - if (BE (new_entry == NULL, 0)) - { - re_free (mctx->bkref_ents); - return REG_ESPACE; - } - mctx->bkref_ents = new_entry; - memset (mctx->bkref_ents + mctx->nbkref_ents, '\0', - sizeof (struct re_backref_cache_entry) * mctx->abkref_ents); - mctx->abkref_ents *= 2; - } - if (mctx->nbkref_ents > 0 - && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx) - mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1; - - mctx->bkref_ents[mctx->nbkref_ents].node = node; - mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx; - mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from; - mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to; - - /* This is a cache that saves negative results of check_dst_limits_calc_pos. - If bit N is clear, means that this entry won't epsilon-transition to - an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression. If - it is set, check_dst_limits_calc_pos_1 will recurse and try to find one - such node. - - A backreference does not epsilon-transition unless it is empty, so set - to all zeros if FROM != TO. */ - mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map - = (from == to ? -1 : 0); - - mctx->bkref_ents[mctx->nbkref_ents++].more = 0; - if (mctx->max_mb_elem_len < to - from) - mctx->max_mb_elem_len = to - from; - return REG_NOERROR; -} - -/* Return the first entry with the same str_idx, or REG_MISSING if none is - found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */ - -static Idx -internal_function -search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) -{ - Idx left, right, mid, last; - last = right = mctx->nbkref_ents; - for (left = 0; left < right;) - { - mid = (left + right) / 2; - if (mctx->bkref_ents[mid].str_idx < str_idx) - left = mid + 1; - else - right = mid; - } - if (left < last && mctx->bkref_ents[left].str_idx == str_idx) - return left; - else - return REG_MISSING; -} - -/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches - at STR_IDX. */ - -static reg_errcode_t -internal_function __attribute_warn_unused_result__ -match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) -{ -#ifdef DEBUG - assert (mctx->sub_tops != NULL); - assert (mctx->asub_tops > 0); -#endif - if (BE (mctx->nsub_tops == mctx->asub_tops, 0)) - { - Idx new_asub_tops = mctx->asub_tops * 2; - re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops, - re_sub_match_top_t *, - new_asub_tops); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - mctx->sub_tops = new_array; - mctx->asub_tops = new_asub_tops; - } - mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t)); - if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0)) - return REG_ESPACE; - mctx->sub_tops[mctx->nsub_tops]->node = node; - mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx; - return REG_NOERROR; -} - -/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches - at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */ - -static re_sub_match_last_t * -internal_function -match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) -{ - re_sub_match_last_t *new_entry; - if (BE (subtop->nlasts == subtop->alasts, 0)) - { - Idx new_alasts = 2 * subtop->alasts + 1; - re_sub_match_last_t **new_array = re_realloc (subtop->lasts, - re_sub_match_last_t *, - new_alasts); - if (BE (new_array == NULL, 0)) - return NULL; - subtop->lasts = new_array; - subtop->alasts = new_alasts; - } - new_entry = calloc (1, sizeof (re_sub_match_last_t)); - if (BE (new_entry != NULL, 1)) - { - subtop->lasts[subtop->nlasts] = new_entry; - new_entry->node = node; - new_entry->str_idx = str_idx; - ++subtop->nlasts; - } - return new_entry; -} - -static void -internal_function -sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, - re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx) -{ - sctx->sifted_states = sifted_sts; - sctx->limited_states = limited_sts; - sctx->last_node = last_node; - sctx->last_str_idx = last_str_idx; - re_node_set_init_empty (&sctx->limits); -} diff --git a/grub-core/gnulib/size_max.h b/grub-core/gnulib/size_max.h deleted file mode 100644 index 5f3312404..000000000 --- a/grub-core/gnulib/size_max.h +++ /dev/null @@ -1,30 +0,0 @@ -/* size_max.h -- declare SIZE_MAX through system headers - Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. - Written by Simon Josefsson. - - 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, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef GNULIB_SIZE_MAX_H -#define GNULIB_SIZE_MAX_H - -/* Get SIZE_MAX declaration on systems like Solaris 7/8/9. */ -# include -/* Get SIZE_MAX declaration on systems like glibc 2. */ -# if HAVE_STDINT_H -# include -# endif -/* On systems where these include files don't define it, SIZE_MAX is defined - in config.h. */ - -#endif /* GNULIB_SIZE_MAX_H */ diff --git a/grub-core/gnulib/sleep.c b/grub-core/gnulib/sleep.c deleted file mode 100644 index 4c97d7dfa..000000000 --- a/grub-core/gnulib/sleep.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Pausing execution of the current thread. - Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2007. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#include - -#include "verify.h" - -#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - -# define WIN32_LEAN_AND_MEAN /* avoid including junk */ -# include - -unsigned int -sleep (unsigned int seconds) -{ - unsigned int remaining; - - /* Sleep for 1 second many times, because - 1. Sleep is not interruptible by Ctrl-C, - 2. we want to avoid arithmetic overflow while multiplying with 1000. */ - for (remaining = seconds; remaining > 0; remaining--) - Sleep (1000); - - return remaining; -} - -#elif HAVE_SLEEP - -# undef sleep - -/* Guarantee unlimited sleep and a reasonable return value. Cygwin - 1.5.x rejects attempts to sleep more than 49.7 days (2**32 - milliseconds), but uses uninitialized memory which results in a - garbage answer. Similarly, Linux 2.6.9 with glibc 2.3.4 has a too - small return value when asked to sleep more than 24.85 days. */ -unsigned int -rpl_sleep (unsigned int seconds) -{ - /* This requires int larger than 16 bits. */ - verify (UINT_MAX / 24 / 24 / 60 / 60); - const unsigned int limit = 24 * 24 * 60 * 60; - while (limit < seconds) - { - unsigned int result; - seconds -= limit; - result = sleep (limit); - if (result) - return seconds + result; - } - return sleep (seconds); -} - -#else /* !HAVE_SLEEP */ - - #error "Please port gnulib sleep.c to your platform, possibly using usleep() or select(), then report this to bug-gnulib." - -#endif diff --git a/grub-core/gnulib/stdalign.in.h b/grub-core/gnulib/stdalign.in.h deleted file mode 100644 index c3a67321b..000000000 --- a/grub-core/gnulib/stdalign.in.h +++ /dev/null @@ -1,90 +0,0 @@ -/* A substitute for ISO C11 . - - Copyright 2011-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 Paul Eggert and Bruno Haible. */ - -#ifndef _GL_STDALIGN_H -#define _GL_STDALIGN_H - -/* ISO C11 for platforms that lack it. - - References: - ISO C11 (latest free draft - ) - sections 6.5.3.4, 6.7.5, 7.15. - C++11 (latest free draft - ) - section 18.10. */ - -/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment - requirement of a structure member (i.e., slot or field) that is of - type TYPE, as an integer constant expression. - - This differs from GCC's __alignof__ operator, which can yield a - better-performing alignment for an object of that type. For - example, on x86 with GCC, __alignof__ (double) and __alignof__ - (long long) are 8, whereas alignof (double) and alignof (long long) - are 4 unless the option '-malign-double' is used. - - The result cannot be used as a value for an 'enum' constant, if you - want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. */ -#include -#if defined __cplusplus - template struct __alignof_helper { char __a; __t __b; }; -# define _Alignof(type) offsetof (__alignof_helper, __b) -#else -# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) -#endif -#define alignof _Alignof -#define __alignof_is_defined 1 - -/* alignas (A), also known as _Alignas (A), aligns a variable or type - to the alignment A, where A is an integer constant expression. For - example: - - int alignas (8) foo; - struct s { int a; int alignas (8) bar; }; - - aligns the address of FOO and the offset of BAR to be multiples of 8. - - A should be a power of two that is at least the type's alignment - and at most the implementation's alignment limit. This limit is - 2**28 on typical GNUish hosts, and 2**13 on MSVC. To be portable - to MSVC through at least version 10.0, A should be an integer - constant, as MSVC does not support expressions such as 1 << 3. - To be portable to Sun C 5.11, do not align auto variables to - anything stricter than their default alignment. - - The following C11 requirements are not supported here: - - - If A is zero, alignas has no effect. - - alignas can be used multiple times; the strictest one wins. - - alignas (TYPE) is equivalent to alignas (alignof (TYPE)). - - */ - -#if __GNUC__ || __IBMC__ || __IBMCPP__ || 0x5110 <= __SUNPRO_C -# define _Alignas(a) __attribute__ ((__aligned__ (a))) -#elif 1300 <= _MSC_VER -# define _Alignas(a) __declspec (align (a)) -#endif -#ifdef _Alignas -# define alignas _Alignas -# define __alignas_is_defined 1 -#endif - -#endif /* _GL_STDALIGN_H */ diff --git a/grub-core/gnulib/stdbool.in.h b/grub-core/gnulib/stdbool.in.h deleted file mode 100644 index 7c1577277..000000000 --- a/grub-core/gnulib/stdbool.in.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright (C) 2001-2003, 2006-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2001. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _GL_STDBOOL_H -#define _GL_STDBOOL_H - -/* ISO C 99 for platforms that lack it. */ - -/* Usage suggestions: - - Programs that use should be aware of some limitations - and standards compliance issues. - - Standards compliance: - - - must be #included before 'bool', 'false', 'true' - can be used. - - - You cannot assume that sizeof (bool) == 1. - - - Programs should not undefine the macros bool, true, and false, - as C99 lists that as an "obsolescent feature". - - Limitations of this substitute, when used in a C89 environment: - - - must be #included before the '_Bool' type can be used. - - - You cannot assume that _Bool is a typedef; it might be a macro. - - - Bit-fields of type 'bool' are not supported. Portable code - should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'. - - - In C99, casts and automatic conversions to '_Bool' or 'bool' are - performed in such a way that every nonzero value gets converted - to 'true', and zero gets converted to 'false'. This doesn't work - with this substitute. With this substitute, only the values 0 and 1 - give the expected result when converted to _Bool' or 'bool'. - - - C99 allows the use of (_Bool)0.0 in constant expressions, but - this substitute cannot always provide this property. - - Also, it is suggested that programs use 'bool' rather than '_Bool'; - this isn't required, but 'bool' is more common. */ - - -/* 7.16. Boolean type and values */ - -/* BeOS already #defines false 0, true 1. We use the same - definitions below, but temporarily we have to #undef them. */ -#if defined __BEOS__ && !defined __HAIKU__ -# include /* defines bool but not _Bool */ -# undef false -# undef true -#endif - -#ifdef __cplusplus -# define _Bool bool -# define bool bool -#else -# if defined __BEOS__ && !defined __HAIKU__ - /* A compiler known to have 'bool'. */ - /* If the compiler already has both 'bool' and '_Bool', we can assume they - are the same types. */ -# if !@HAVE__BOOL@ -typedef bool _Bool; -# endif -# else -# if !defined __GNUC__ - /* If @HAVE__BOOL@: - Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when - the built-in _Bool type is used. See - http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html - Similar bugs are likely with other compilers as well; this file - wouldn't be used if was working. - So we override the _Bool type. - If !@HAVE__BOOL@: - Need to define _Bool ourselves. As 'signed char' or as an enum type? - Use of a typedef, with SunPRO C, leads to a stupid - "warning: _Bool is a keyword in ISO C99". - Use of an enum type, with IRIX cc, leads to a stupid - "warning(1185): enumerated type mixed with another type". - Even the existence of an enum type, without a typedef, - "Invalid enumerator. (badenum)" with HP-UX cc on Tru64. - The only benefit of the enum, debuggability, is not important - with these compilers. So use 'signed char' and no enum. */ -# define _Bool signed char -# else - /* With this compiler, trust the _Bool type if the compiler has it. */ -# if !@HAVE__BOOL@ - /* For the sake of symbolic names in gdb, define true and false as - enum constants, not only as macros. - It is tempting to write - typedef enum { false = 0, true = 1 } _Bool; - so that gdb prints values of type 'bool' symbolically. But then - values of type '_Bool' might promote to 'int' or 'unsigned int' - (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int' - (see ISO C 99 6.3.1.1.(2)). So add a negative value to the - enum; this ensures that '_Bool' promotes to 'int'. */ -typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; -# endif -# endif -# endif -# define bool _Bool -#endif - -/* The other macros must be usable in preprocessor directives. */ -#ifdef __cplusplus -# define false false -# define true true -#else -# define false 0 -# define true 1 -#endif - -#define __bool_true_false_are_defined 1 - -#endif /* _GL_STDBOOL_H */ diff --git a/grub-core/gnulib/stddef.in.h b/grub-core/gnulib/stddef.in.h deleted file mode 100644 index 40f0536aa..000000000 --- a/grub-core/gnulib/stddef.in.h +++ /dev/null @@ -1,86 +0,0 @@ -/* A substitute for POSIX 2008 , for platforms that have issues. - - Copyright (C) 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 Eric Blake. */ - -/* - * POSIX 2008 for platforms that have issues. - * - */ - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#if defined __need_wchar_t || defined __need_size_t \ - || defined __need_ptrdiff_t || defined __need_NULL \ - || defined __need_wint_t -/* Special invocation convention inside gcc header files. In - particular, gcc provides a version of that blindly - redefines NULL even when __need_wint_t was defined, even though - wint_t is not normally provided by . Hence, we must - remember if special invocation has ever been used to obtain wint_t, - in which case we need to clean up NULL yet again. */ - -# if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T) -# ifdef __need_wint_t -# undef _@GUARD_PREFIX@_STDDEF_H -# define _GL_STDDEF_WINT_T -# endif -# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ -# endif - -#else -/* Normal invocation convention. */ - -# ifndef _@GUARD_PREFIX@_STDDEF_H - -/* The include_next requires a split double-inclusion guard. */ - -# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ - -# ifndef _@GUARD_PREFIX@_STDDEF_H -# define _@GUARD_PREFIX@_STDDEF_H - -/* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ -#if @REPLACE_NULL@ -# undef NULL -# ifdef __cplusplus - /* ISO C++ says that the macro NULL must expand to an integer constant - expression, hence '((void *) 0)' is not allowed in C++. */ -# if __GNUG__ >= 3 - /* GNU C++ has a __null macro that behaves like an integer ('int' or - 'long') but has the same size as a pointer. Use that, to avoid - warnings. */ -# define NULL __null -# else -# define NULL 0L -# endif -# else -# define NULL ((void *) 0) -# endif -#endif - -/* Some platforms lack wchar_t. */ -#if !@HAVE_WCHAR_T@ -# define wchar_t int -#endif - -# endif /* _@GUARD_PREFIX@_STDDEF_H */ -# endif /* _@GUARD_PREFIX@_STDDEF_H */ -#endif /* __need_XXX */ diff --git a/grub-core/gnulib/stdint.in.h b/grub-core/gnulib/stdint.in.h deleted file mode 100644 index 2db8b2e37..000000000 --- a/grub-core/gnulib/stdint.in.h +++ /dev/null @@ -1,636 +0,0 @@ -/* Copyright (C) 2001-2002, 2004-2013 Free Software Foundation, Inc. - Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. - This file is part of gnulib. - - 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, 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 . */ - -/* - * ISO C 99 for platforms that lack it. - * - */ - -#ifndef _@GUARD_PREFIX@_STDINT_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* When including a system file that in turn includes , - use the system , not our substitute. This avoids - problems with (for example) VMS, whose includes - . */ -#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H - -/* On Android (Bionic libc), includes this file before - having defined 'time_t'. Therefore in this case avoid including - other system header files; just include the system's . - Ideally we should test __BIONIC__ here, but it is only defined after - has been included; hence test __ANDROID__ instead. */ -#if defined __ANDROID__ \ - && defined _SYS_TYPES_H_ && !defined __need_size_t -# @INCLUDE_NEXT@ @NEXT_STDINT_H@ -#else - -/* Get those types that are already defined in other system include - files, so that we can "#define int8_t signed char" below without - worrying about a later system include file containing a "typedef - signed char int8_t;" that will get messed up by our macro. Our - macros should all be consistent with the system versions, except - for the "fast" types and macros, which we recommend against using - in public interfaces due to compiler differences. */ - -#if @HAVE_STDINT_H@ -# if defined __sgi && ! defined __c99 - /* Bypass IRIX's if in C89 mode, since it merely annoys users - with "This header file is to be used only for c99 mode compilations" - diagnostics. */ -# define __STDINT_H__ -# endif - - /* Some pre-C++11 implementations need this. */ -# ifdef __cplusplus -# ifndef __STDC_CONSTANT_MACROS -# define __STDC_CONSTANT_MACROS 1 -# endif -# ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS 1 -# endif -# endif - - /* Other systems may have an incomplete or buggy . - Include it before , since any "#include " - in would reinclude us, skipping our contents because - _@GUARD_PREFIX@_STDINT_H is defined. - The include_next requires a split double-inclusion guard. */ -# @INCLUDE_NEXT@ @NEXT_STDINT_H@ -#endif - -#if ! defined _@GUARD_PREFIX@_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H -#define _@GUARD_PREFIX@_STDINT_H - -/* defines some of the stdint.h types as well, on glibc, - IRIX 6.5, and OpenBSD 3.8 (via ). - AIX 5.2 isn't needed and causes troubles. - Mac OS X 10.4.6 includes (which is us), but - relies on the system definitions, so include - after @NEXT_STDINT_H@. */ -#if @HAVE_SYS_TYPES_H@ && ! defined _AIX -# include -#endif - -/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, - LONG_MIN, LONG_MAX, ULONG_MAX. */ -#include - -#if @HAVE_INTTYPES_H@ - /* In OpenBSD 3.8, includes , which defines - int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. - also defines intptr_t and uintptr_t. */ -# include -#elif @HAVE_SYS_INTTYPES_H@ - /* Solaris 7 has the types except the *_fast*_t types, and - the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ -# include -#endif - -#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ - /* Linux libc4 >= 4.6.7 and libc5 have a that defines - int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is - included by . */ -# include -#endif - -#undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H - -/* Minimum and maximum values for an integer type under the usual assumption. - Return an unspecified value if BITS == 0, adding a check to pacify - picky compilers. */ - -#define _STDINT_MIN(signed, bits, zero) \ - ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) - -#define _STDINT_MAX(signed, bits, zero) \ - ((signed) \ - ? ~ _STDINT_MIN (signed, bits, zero) \ - : /* The expression for the unsigned case. The subtraction of (signed) \ - is a nop in the unsigned case and avoids "signed integer overflow" \ - warnings in the signed case. */ \ - ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) - -#if !GNULIB_defined_stdint_types - -/* 7.18.1.1. Exact-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. */ - -#undef int8_t -#undef uint8_t -typedef signed char gl_int8_t; -typedef unsigned char gl_uint8_t; -#define int8_t gl_int8_t -#define uint8_t gl_uint8_t - -#undef int16_t -#undef uint16_t -typedef short int gl_int16_t; -typedef unsigned short int gl_uint16_t; -#define int16_t gl_int16_t -#define uint16_t gl_uint16_t - -#undef int32_t -#undef uint32_t -typedef int gl_int32_t; -typedef unsigned int gl_uint32_t; -#define int32_t gl_int32_t -#define uint32_t gl_uint32_t - -/* If the system defines INT64_MAX, assume int64_t works. That way, - if the underlying platform defines int64_t to be a 64-bit long long - int, the code below won't mistakenly define it to be a 64-bit long - int, which would mess up C++ name mangling. We must use #ifdef - rather than #if, to avoid an error with HP-UX 10.20 cc. */ - -#ifdef INT64_MAX -# define GL_INT64_T -#else -/* Do not undefine int64_t if gnulib is not being used with 64-bit - types, since otherwise it breaks platforms like Tandem/NSK. */ -# if LONG_MAX >> 31 >> 31 == 1 -# undef int64_t -typedef long int gl_int64_t; -# define int64_t gl_int64_t -# define GL_INT64_T -# elif defined _MSC_VER -# undef int64_t -typedef __int64 gl_int64_t; -# define int64_t gl_int64_t -# define GL_INT64_T -# elif @HAVE_LONG_LONG_INT@ -# undef int64_t -typedef long long int gl_int64_t; -# define int64_t gl_int64_t -# define GL_INT64_T -# endif -#endif - -#ifdef UINT64_MAX -# define GL_UINT64_T -#else -# if ULONG_MAX >> 31 >> 31 >> 1 == 1 -# undef uint64_t -typedef unsigned long int gl_uint64_t; -# define uint64_t gl_uint64_t -# define GL_UINT64_T -# elif defined _MSC_VER -# undef uint64_t -typedef unsigned __int64 gl_uint64_t; -# define uint64_t gl_uint64_t -# define GL_UINT64_T -# elif @HAVE_UNSIGNED_LONG_LONG_INT@ -# undef uint64_t -typedef unsigned long long int gl_uint64_t; -# define uint64_t gl_uint64_t -# define GL_UINT64_T -# endif -#endif - -/* Avoid collision with Solaris 2.5.1 etc. */ -#define _UINT8_T -#define _UINT32_T -#define _UINT64_T - - -/* 7.18.1.2. Minimum-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types - are the same as the corresponding N_t types. */ - -#undef int_least8_t -#undef uint_least8_t -#undef int_least16_t -#undef uint_least16_t -#undef int_least32_t -#undef uint_least32_t -#undef int_least64_t -#undef uint_least64_t -#define int_least8_t int8_t -#define uint_least8_t uint8_t -#define int_least16_t int16_t -#define uint_least16_t uint16_t -#define int_least32_t int32_t -#define uint_least32_t uint32_t -#ifdef GL_INT64_T -# define int_least64_t int64_t -#endif -#ifdef GL_UINT64_T -# define uint_least64_t uint64_t -#endif - -/* 7.18.1.3. Fastest minimum-width integer types */ - -/* Note: Other substitutes may define these types differently. - It is not recommended to use these types in public header files. */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types - are taken from the same list of types. The following code normally - uses types consistent with glibc, as that lessens the chance of - incompatibility with older GNU hosts. */ - -#undef int_fast8_t -#undef uint_fast8_t -#undef int_fast16_t -#undef uint_fast16_t -#undef int_fast32_t -#undef uint_fast32_t -#undef int_fast64_t -#undef uint_fast64_t -typedef signed char gl_int_fast8_t; -typedef unsigned char gl_uint_fast8_t; - -#ifdef __sun -/* Define types compatible with SunOS 5.10, so that code compiled under - earlier SunOS versions works with code compiled under SunOS 5.10. */ -typedef int gl_int_fast32_t; -typedef unsigned int gl_uint_fast32_t; -#else -typedef long int gl_int_fast32_t; -typedef unsigned long int gl_uint_fast32_t; -#endif -typedef gl_int_fast32_t gl_int_fast16_t; -typedef gl_uint_fast32_t gl_uint_fast16_t; - -#define int_fast8_t gl_int_fast8_t -#define uint_fast8_t gl_uint_fast8_t -#define int_fast16_t gl_int_fast16_t -#define uint_fast16_t gl_uint_fast16_t -#define int_fast32_t gl_int_fast32_t -#define uint_fast32_t gl_uint_fast32_t -#ifdef GL_INT64_T -# define int_fast64_t int64_t -#endif -#ifdef GL_UINT64_T -# define uint_fast64_t uint64_t -#endif - -/* 7.18.1.4. Integer types capable of holding object pointers */ - -#undef intptr_t -#undef uintptr_t -typedef long int gl_intptr_t; -typedef unsigned long int gl_uintptr_t; -#define intptr_t gl_intptr_t -#define uintptr_t gl_uintptr_t - -/* 7.18.1.5. Greatest-width integer types */ - -/* Note: These types are compiler dependent. It may be unwise to use them in - public header files. */ - -/* If the system defines INTMAX_MAX, assume that intmax_t works, and - similarly for UINTMAX_MAX and uintmax_t. This avoids problems with - assuming one type where another is used by the system. */ - -#ifndef INTMAX_MAX -# undef INTMAX_C -# undef intmax_t -# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 -typedef long long int gl_intmax_t; -# define intmax_t gl_intmax_t -# elif defined GL_INT64_T -# define intmax_t int64_t -# else -typedef long int gl_intmax_t; -# define intmax_t gl_intmax_t -# endif -#endif - -#ifndef UINTMAX_MAX -# undef UINTMAX_C -# undef uintmax_t -# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 -typedef unsigned long long int gl_uintmax_t; -# define uintmax_t gl_uintmax_t -# elif defined GL_UINT64_T -# define uintmax_t uint64_t -# else -typedef unsigned long int gl_uintmax_t; -# define uintmax_t gl_uintmax_t -# endif -#endif - -/* Verify that intmax_t and uintmax_t have the same size. Too much code - breaks if this is not the case. If this check fails, the reason is likely - to be found in the autoconf macros. */ -typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) - ? 1 : -1]; - -#define GNULIB_defined_stdint_types 1 -#endif /* !GNULIB_defined_stdint_types */ - -/* 7.18.2. Limits of specified-width integer types */ - -/* 7.18.2.1. Limits of exact-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. */ - -#undef INT8_MIN -#undef INT8_MAX -#undef UINT8_MAX -#define INT8_MIN (~ INT8_MAX) -#define INT8_MAX 127 -#define UINT8_MAX 255 - -#undef INT16_MIN -#undef INT16_MAX -#undef UINT16_MAX -#define INT16_MIN (~ INT16_MAX) -#define INT16_MAX 32767 -#define UINT16_MAX 65535 - -#undef INT32_MIN -#undef INT32_MAX -#undef UINT32_MAX -#define INT32_MIN (~ INT32_MAX) -#define INT32_MAX 2147483647 -#define UINT32_MAX 4294967295U - -#if defined GL_INT64_T && ! defined INT64_MAX -/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 - evaluates the latter incorrectly in preprocessor expressions. */ -# define INT64_MIN (- INTMAX_C (1) << 63) -# define INT64_MAX INTMAX_C (9223372036854775807) -#endif - -#if defined GL_UINT64_T && ! defined UINT64_MAX -# define UINT64_MAX UINTMAX_C (18446744073709551615) -#endif - -/* 7.18.2.2. Limits of minimum-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types - are the same as the corresponding N_t types. */ - -#undef INT_LEAST8_MIN -#undef INT_LEAST8_MAX -#undef UINT_LEAST8_MAX -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define UINT_LEAST8_MAX UINT8_MAX - -#undef INT_LEAST16_MIN -#undef INT_LEAST16_MAX -#undef UINT_LEAST16_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define UINT_LEAST16_MAX UINT16_MAX - -#undef INT_LEAST32_MIN -#undef INT_LEAST32_MAX -#undef UINT_LEAST32_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define UINT_LEAST32_MAX UINT32_MAX - -#undef INT_LEAST64_MIN -#undef INT_LEAST64_MAX -#ifdef GL_INT64_T -# define INT_LEAST64_MIN INT64_MIN -# define INT_LEAST64_MAX INT64_MAX -#endif - -#undef UINT_LEAST64_MAX -#ifdef GL_UINT64_T -# define UINT_LEAST64_MAX UINT64_MAX -#endif - -/* 7.18.2.3. Limits of fastest minimum-width integer types */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types - are taken from the same list of types. */ - -#undef INT_FAST8_MIN -#undef INT_FAST8_MAX -#undef UINT_FAST8_MAX -#define INT_FAST8_MIN SCHAR_MIN -#define INT_FAST8_MAX SCHAR_MAX -#define UINT_FAST8_MAX UCHAR_MAX - -#undef INT_FAST16_MIN -#undef INT_FAST16_MAX -#undef UINT_FAST16_MAX -#define INT_FAST16_MIN INT_FAST32_MIN -#define INT_FAST16_MAX INT_FAST32_MAX -#define UINT_FAST16_MAX UINT_FAST32_MAX - -#undef INT_FAST32_MIN -#undef INT_FAST32_MAX -#undef UINT_FAST32_MAX -#ifdef __sun -# define INT_FAST32_MIN INT_MIN -# define INT_FAST32_MAX INT_MAX -# define UINT_FAST32_MAX UINT_MAX -#else -# define INT_FAST32_MIN LONG_MIN -# define INT_FAST32_MAX LONG_MAX -# define UINT_FAST32_MAX ULONG_MAX -#endif - -#undef INT_FAST64_MIN -#undef INT_FAST64_MAX -#ifdef GL_INT64_T -# define INT_FAST64_MIN INT64_MIN -# define INT_FAST64_MAX INT64_MAX -#endif - -#undef UINT_FAST64_MAX -#ifdef GL_UINT64_T -# define UINT_FAST64_MAX UINT64_MAX -#endif - -/* 7.18.2.4. Limits of integer types capable of holding object pointers */ - -#undef INTPTR_MIN -#undef INTPTR_MAX -#undef UINTPTR_MAX -#define INTPTR_MIN LONG_MIN -#define INTPTR_MAX LONG_MAX -#define UINTPTR_MAX ULONG_MAX - -/* 7.18.2.5. Limits of greatest-width integer types */ - -#ifndef INTMAX_MAX -# undef INTMAX_MIN -# ifdef INT64_MAX -# define INTMAX_MIN INT64_MIN -# define INTMAX_MAX INT64_MAX -# else -# define INTMAX_MIN INT32_MIN -# define INTMAX_MAX INT32_MAX -# endif -#endif - -#ifndef UINTMAX_MAX -# ifdef UINT64_MAX -# define UINTMAX_MAX UINT64_MAX -# else -# define UINTMAX_MAX UINT32_MAX -# endif -#endif - -/* 7.18.3. Limits of other integer types */ - -/* ptrdiff_t limits */ -#undef PTRDIFF_MIN -#undef PTRDIFF_MAX -#if @APPLE_UNIVERSAL_BUILD@ -# ifdef _LP64 -# define PTRDIFF_MIN _STDINT_MIN (1, 64, 0l) -# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) -# else -# define PTRDIFF_MIN _STDINT_MIN (1, 32, 0) -# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) -# endif -#else -# define PTRDIFF_MIN \ - _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) -# define PTRDIFF_MAX \ - _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) -#endif - -/* sig_atomic_t limits */ -#undef SIG_ATOMIC_MIN -#undef SIG_ATOMIC_MAX -#define SIG_ATOMIC_MIN \ - _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ - 0@SIG_ATOMIC_T_SUFFIX@) -#define SIG_ATOMIC_MAX \ - _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ - 0@SIG_ATOMIC_T_SUFFIX@) - - -/* size_t limit */ -#undef SIZE_MAX -#if @APPLE_UNIVERSAL_BUILD@ -# ifdef _LP64 -# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) -# else -# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) -# endif -#else -# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) -#endif - -/* wchar_t limits */ -/* Get WCHAR_MIN, WCHAR_MAX. - This include is not on the top, above, because on OSF/1 4.0 we have a - sequence of nested includes - -> -> -> , and the latter includes - and assumes its types are already defined. */ -#if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) - /* BSD/OS 4.0.1 has a bug: , and must be - included before . */ -# include -# include -# include -# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H -# include -# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H -#endif -#undef WCHAR_MIN -#undef WCHAR_MAX -#define WCHAR_MIN \ - _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) -#define WCHAR_MAX \ - _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) - -/* wint_t limits */ -#undef WINT_MIN -#undef WINT_MAX -#define WINT_MIN \ - _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) -#define WINT_MAX \ - _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) - -/* 7.18.4. Macros for integer constants */ - -/* 7.18.4.1. Macros for minimum-width integer constants */ -/* According to ISO C 99 Technical Corrigendum 1 */ - -/* Here we assume a standard architecture where the hardware integer - types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ - -#undef INT8_C -#undef UINT8_C -#define INT8_C(x) x -#define UINT8_C(x) x - -#undef INT16_C -#undef UINT16_C -#define INT16_C(x) x -#define UINT16_C(x) x - -#undef INT32_C -#undef UINT32_C -#define INT32_C(x) x -#define UINT32_C(x) x ## U - -#undef INT64_C -#undef UINT64_C -#if LONG_MAX >> 31 >> 31 == 1 -# define INT64_C(x) x##L -#elif defined _MSC_VER -# define INT64_C(x) x##i64 -#elif @HAVE_LONG_LONG_INT@ -# define INT64_C(x) x##LL -#endif -#if ULONG_MAX >> 31 >> 31 >> 1 == 1 -# define UINT64_C(x) x##UL -#elif defined _MSC_VER -# define UINT64_C(x) x##ui64 -#elif @HAVE_UNSIGNED_LONG_LONG_INT@ -# define UINT64_C(x) x##ULL -#endif - -/* 7.18.4.2. Macros for greatest-width integer constants */ - -#ifndef INTMAX_C -# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 -# define INTMAX_C(x) x##LL -# elif defined GL_INT64_T -# define INTMAX_C(x) INT64_C(x) -# else -# define INTMAX_C(x) x##L -# endif -#endif - -#ifndef UINTMAX_C -# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 -# define UINTMAX_C(x) x##ULL -# elif defined GL_UINT64_T -# define UINTMAX_C(x) UINT64_C(x) -# else -# define UINTMAX_C(x) x##UL -# endif -#endif - -#endif /* _@GUARD_PREFIX@_STDINT_H */ -#endif /* !(defined __ANDROID__ && ...) */ -#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ diff --git a/grub-core/gnulib/stdio.in.h b/grub-core/gnulib/stdio.in.h deleted file mode 100644 index e1d28cebf..000000000 --- a/grub-core/gnulib/stdio.in.h +++ /dev/null @@ -1,1333 +0,0 @@ -/* A GNU-like . - - Copyright (C) 2004, 2007-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 . */ - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#if defined __need_FILE || defined __need___FILE || defined _GL_ALREADY_INCLUDING_STDIO_H -/* Special invocation convention: - - Inside glibc header files. - - On OSF/1 5.1 we have a sequence of nested includes - -> -> -> -> - -> -> -> . - In this situation, the functions are not yet declared, therefore we cannot - provide the C++ aliases. */ - -#@INCLUDE_NEXT@ @NEXT_STDIO_H@ - -#else -/* Normal invocation convention. */ - -#ifndef _@GUARD_PREFIX@_STDIO_H - -#define _GL_ALREADY_INCLUDING_STDIO_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_STDIO_H@ - -#undef _GL_ALREADY_INCLUDING_STDIO_H - -#ifndef _@GUARD_PREFIX@_STDIO_H -#define _@GUARD_PREFIX@_STDIO_H - -/* Get va_list. Needed on many systems, including glibc 2.8. */ -#include - -#include - -/* Get off_t and ssize_t. Needed on many systems, including glibc 2.8 - and eglibc 2.11.2. - May also define off_t to a 64-bit type on native Windows. */ -#include - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The __-protected variants of the attributes 'format' and 'printf' are - accepted by gcc versions 2.6.4 (effectively 2.7) and later. - We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because - gnulib and libintl do '#define printf __printf__' when they override - the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -#else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ -#endif - -/* _GL_ATTRIBUTE_FORMAT_PRINTF - indicates to GCC that the function takes a format string and arguments, - where the format string directives are the ones standardized by ISO C99 - and POSIX. */ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__gnu_printf__, formatstring_parameter, first_argument)) -#else -# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) -#endif - -/* _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_PRINTF, - except that it indicates to GCC that the supported format string directives - are the ones of the system printf(), rather than the ones standardized by - ISO C99 and POSIX. */ -#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) - -/* _GL_ATTRIBUTE_FORMAT_SCANF - indicates to GCC that the function takes a format string and arguments, - where the format string directives are the ones standardized by ISO C99 - and POSIX. */ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) -# define _GL_ATTRIBUTE_FORMAT_SCANF(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__gnu_scanf__, formatstring_parameter, first_argument)) -#else -# define _GL_ATTRIBUTE_FORMAT_SCANF(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument)) -#endif - -/* _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_SCANF, - except that it indicates to GCC that the supported format string directives - are the ones of the system scanf(), rather than the ones standardized by - ISO C99 and POSIX. */ -#define _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM(formatstring_parameter, first_argument) \ - _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument)) - -/* Solaris 10 declares renameat in , not in . */ -/* But in any case avoid namespace pollution on glibc systems. */ -#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __sun \ - && ! defined __GLIBC__ -# include -#endif - - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - -/* Macros for stringification. */ -#define _GL_STDIO_STRINGIZE(token) #token -#define _GL_STDIO_MACROEXPAND_AND_STRINGIZE(token) _GL_STDIO_STRINGIZE(token) - - -#if @GNULIB_DPRINTF@ -# if @REPLACE_DPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define dprintf rpl_dprintf -# endif -_GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *format, ...)); -# else -# if !@HAVE_DPRINTF@ -_GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *format, ...)); -# endif -_GL_CXXALIASWARN (dprintf); -#elif defined GNULIB_POSIXCHECK -# undef dprintf -# if HAVE_RAW_DECL_DPRINTF -_GL_WARN_ON_USE (dprintf, "dprintf is unportable - " - "use gnulib module dprintf for portability"); -# endif -#endif - -#if @GNULIB_FCLOSE@ -/* Close STREAM and its underlying file descriptor. */ -# if @REPLACE_FCLOSE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define fclose rpl_fclose -# endif -_GL_FUNCDECL_RPL (fclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (fclose, int, (FILE *stream)); -# else -_GL_CXXALIAS_SYS (fclose, int, (FILE *stream)); -# endif -_GL_CXXALIASWARN (fclose); -#elif defined GNULIB_POSIXCHECK -# undef fclose -/* Assume fclose is always declared. */ -_GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - " - "use gnulib module fclose for portable POSIX compliance"); -#endif - -#if @GNULIB_FDOPEN@ -# if @REPLACE_FDOPEN@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fdopen -# define fdopen rpl_fdopen -# endif -_GL_FUNCDECL_RPL (fdopen, FILE *, (int fd, const char *mode) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); -# else -_GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); -# endif -_GL_CXXALIASWARN (fdopen); -#elif defined GNULIB_POSIXCHECK -# undef fdopen -/* Assume fdopen is always declared. */ -_GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX compliant - " - "use gnulib module fdopen for portability"); -#endif - -#if @GNULIB_FFLUSH@ -/* Flush all pending data on STREAM according to POSIX rules. Both - output and seekable input streams are supported. - Note! LOSS OF DATA can occur if fflush is applied on an input stream - that is _not_seekable_ or on an update stream that is _not_seekable_ - and in which the most recent operation was input. Seekability can - be tested with lseek(fileno(fp),0,SEEK_CUR). */ -# if @REPLACE_FFLUSH@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define fflush rpl_fflush -# endif -_GL_FUNCDECL_RPL (fflush, int, (FILE *gl_stream)); -_GL_CXXALIAS_RPL (fflush, int, (FILE *gl_stream)); -# else -_GL_CXXALIAS_SYS (fflush, int, (FILE *gl_stream)); -# endif -_GL_CXXALIASWARN (fflush); -#elif defined GNULIB_POSIXCHECK -# undef fflush -/* Assume fflush is always declared. */ -_GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " - "use gnulib module fflush for portable POSIX compliance"); -#endif - -#if @GNULIB_FGETC@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fgetc -# define fgetc rpl_fgetc -# endif -_GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (fgetc, int, (FILE *stream)); -# else -_GL_CXXALIAS_SYS (fgetc, int, (FILE *stream)); -# endif -_GL_CXXALIASWARN (fgetc); -#endif - -#if @GNULIB_FGETS@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fgets -# define fgets rpl_fgets -# endif -_GL_FUNCDECL_RPL (fgets, char *, (char *s, int n, FILE *stream) - _GL_ARG_NONNULL ((1, 3))); -_GL_CXXALIAS_RPL (fgets, char *, (char *s, int n, FILE *stream)); -# else -_GL_CXXALIAS_SYS (fgets, char *, (char *s, int n, FILE *stream)); -# endif -_GL_CXXALIASWARN (fgets); -#endif - -#if @GNULIB_FOPEN@ -# if @REPLACE_FOPEN@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fopen -# define fopen rpl_fopen -# endif -_GL_FUNCDECL_RPL (fopen, FILE *, (const char *filename, const char *mode) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (fopen, FILE *, (const char *filename, const char *mode)); -# else -_GL_CXXALIAS_SYS (fopen, FILE *, (const char *filename, const char *mode)); -# endif -_GL_CXXALIASWARN (fopen); -#elif defined GNULIB_POSIXCHECK -# undef fopen -/* Assume fopen is always declared. */ -_GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX compliant - " - "use gnulib module fopen for portability"); -#endif - -#if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@ -# if (@GNULIB_FPRINTF_POSIX@ && @REPLACE_FPRINTF@) \ - || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define fprintf rpl_fprintf -# endif -# define GNULIB_overrides_fprintf 1 -# if @GNULIB_FPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ -_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); -# else -_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_RPL (fprintf, int, (FILE *fp, const char *format, ...)); -# else -_GL_CXXALIAS_SYS (fprintf, int, (FILE *fp, const char *format, ...)); -# endif -_GL_CXXALIASWARN (fprintf); -#endif -#if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK -# if !GNULIB_overrides_fprintf -# undef fprintf -# endif -/* Assume fprintf is always declared. */ -_GL_WARN_ON_USE (fprintf, "fprintf is not always POSIX compliant - " - "use gnulib module fprintf-posix for portable " - "POSIX compliance"); -#endif - -#if @GNULIB_FPURGE@ -/* Discard all pending buffered I/O data on STREAM. - STREAM must not be wide-character oriented. - When discarding pending output, the file position is set back to where it - was before the write calls. When discarding pending input, the file - position is advanced to match the end of the previously read input. - Return 0 if successful. Upon error, return -1 and set errno. */ -# if @REPLACE_FPURGE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define fpurge rpl_fpurge -# endif -_GL_FUNCDECL_RPL (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (fpurge, int, (FILE *gl_stream)); -# else -# if !@HAVE_DECL_FPURGE@ -_GL_FUNCDECL_SYS (fpurge, int, (FILE *gl_stream) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (fpurge, int, (FILE *gl_stream)); -# endif -_GL_CXXALIASWARN (fpurge); -#elif defined GNULIB_POSIXCHECK -# undef fpurge -# if HAVE_RAW_DECL_FPURGE -_GL_WARN_ON_USE (fpurge, "fpurge is not always present - " - "use gnulib module fpurge for portability"); -# endif -#endif - -#if @GNULIB_FPUTC@ -# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fputc -# define fputc rpl_fputc -# endif -_GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (fputc, int, (int c, FILE *stream)); -# else -_GL_CXXALIAS_SYS (fputc, int, (int c, FILE *stream)); -# endif -_GL_CXXALIASWARN (fputc); -#endif - -#if @GNULIB_FPUTS@ -# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fputs -# define fputs rpl_fputs -# endif -_GL_FUNCDECL_RPL (fputs, int, (const char *string, FILE *stream) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (fputs, int, (const char *string, FILE *stream)); -# else -_GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream)); -# endif -_GL_CXXALIASWARN (fputs); -#endif - -#if @GNULIB_FREAD@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fread -# define fread rpl_fread -# endif -_GL_FUNCDECL_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream) - _GL_ARG_NONNULL ((4))); -_GL_CXXALIAS_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); -# else -_GL_CXXALIAS_SYS (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); -# endif -_GL_CXXALIASWARN (fread); -#endif - -#if @GNULIB_FREOPEN@ -# if @REPLACE_FREOPEN@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef freopen -# define freopen rpl_freopen -# endif -_GL_FUNCDECL_RPL (freopen, FILE *, - (const char *filename, const char *mode, FILE *stream) - _GL_ARG_NONNULL ((2, 3))); -_GL_CXXALIAS_RPL (freopen, FILE *, - (const char *filename, const char *mode, FILE *stream)); -# else -_GL_CXXALIAS_SYS (freopen, FILE *, - (const char *filename, const char *mode, FILE *stream)); -# endif -_GL_CXXALIASWARN (freopen); -#elif defined GNULIB_POSIXCHECK -# undef freopen -/* Assume freopen is always declared. */ -_GL_WARN_ON_USE (freopen, - "freopen on native Windows platforms is not POSIX compliant - " - "use gnulib module freopen for portability"); -#endif - -#if @GNULIB_FSCANF@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fscanf -# define fscanf rpl_fscanf -# endif -_GL_FUNCDECL_RPL (fscanf, int, (FILE *stream, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (fscanf, int, (FILE *stream, const char *format, ...)); -# else -_GL_CXXALIAS_SYS (fscanf, int, (FILE *stream, const char *format, ...)); -# endif -_GL_CXXALIASWARN (fscanf); -#endif - - -/* Set up the following warnings, based on which modules are in use. - GNU Coding Standards discourage the use of fseek, since it imposes - an arbitrary limitation on some 32-bit hosts. Remember that the - fseek module depends on the fseeko module, so we only have three - cases to consider: - - 1. The developer is not using either module. Issue a warning under - GNULIB_POSIXCHECK for both functions, to remind them that both - functions have bugs on some systems. _GL_NO_LARGE_FILES has no - impact on this warning. - - 2. The developer is using both modules. They may be unaware of the - arbitrary limitations of fseek, so issue a warning under - GNULIB_POSIXCHECK. On the other hand, they may be using both - modules intentionally, so the developer can define - _GL_NO_LARGE_FILES in the compilation units where the use of fseek - is safe, to silence the warning. - - 3. The developer is using the fseeko module, but not fseek. Gnulib - guarantees that fseek will still work around platform bugs in that - case, but we presume that the developer is aware of the pitfalls of - fseek and was trying to avoid it, so issue a warning even when - GNULIB_POSIXCHECK is undefined. Again, _GL_NO_LARGE_FILES can be - defined to silence the warning in particular compilation units. - In C++ compilations with GNULIB_NAMESPACE, in order to avoid that - fseek gets defined as a macro, it is recommended that the developer - uses the fseek module, even if he is not calling the fseek function. - - Most gnulib clients that perform stream operations should fall into - category 3. */ - -#if @GNULIB_FSEEK@ -# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES -# define _GL_FSEEK_WARN /* Category 2, above. */ -# undef fseek -# endif -# if @REPLACE_FSEEK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fseek -# define fseek rpl_fseek -# endif -_GL_FUNCDECL_RPL (fseek, int, (FILE *fp, long offset, int whence) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (fseek, int, (FILE *fp, long offset, int whence)); -# else -_GL_CXXALIAS_SYS (fseek, int, (FILE *fp, long offset, int whence)); -# endif -_GL_CXXALIASWARN (fseek); -#endif - -#if @GNULIB_FSEEKO@ -# if !@GNULIB_FSEEK@ && !defined _GL_NO_LARGE_FILES -# define _GL_FSEEK_WARN /* Category 3, above. */ -# undef fseek -# endif -# if @REPLACE_FSEEKO@ -/* Provide an fseeko function that is aware of a preceding fflush(), and which - detects pipes. */ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fseeko -# define fseeko rpl_fseeko -# endif -_GL_FUNCDECL_RPL (fseeko, int, (FILE *fp, off_t offset, int whence) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (fseeko, int, (FILE *fp, off_t offset, int whence)); -# else -# if ! @HAVE_DECL_FSEEKO@ -_GL_FUNCDECL_SYS (fseeko, int, (FILE *fp, off_t offset, int whence) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (fseeko, int, (FILE *fp, off_t offset, int whence)); -# endif -_GL_CXXALIASWARN (fseeko); -#elif defined GNULIB_POSIXCHECK -# define _GL_FSEEK_WARN /* Category 1, above. */ -# undef fseek -# undef fseeko -# if HAVE_RAW_DECL_FSEEKO -_GL_WARN_ON_USE (fseeko, "fseeko is unportable - " - "use gnulib module fseeko for portability"); -# endif -#endif - -#ifdef _GL_FSEEK_WARN -# undef _GL_FSEEK_WARN -/* Here, either fseek is undefined (but C89 guarantees that it is - declared), or it is defined as rpl_fseek (declared above). */ -_GL_WARN_ON_USE (fseek, "fseek cannot handle files larger than 4 GB " - "on 32-bit platforms - " - "use fseeko function for handling of large files"); -#endif - - -/* ftell, ftello. See the comments on fseek/fseeko. */ - -#if @GNULIB_FTELL@ -# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES -# define _GL_FTELL_WARN /* Category 2, above. */ -# undef ftell -# endif -# if @REPLACE_FTELL@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef ftell -# define ftell rpl_ftell -# endif -_GL_FUNCDECL_RPL (ftell, long, (FILE *fp) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (ftell, long, (FILE *fp)); -# else -_GL_CXXALIAS_SYS (ftell, long, (FILE *fp)); -# endif -_GL_CXXALIASWARN (ftell); -#endif - -#if @GNULIB_FTELLO@ -# if !@GNULIB_FTELL@ && !defined _GL_NO_LARGE_FILES -# define _GL_FTELL_WARN /* Category 3, above. */ -# undef ftell -# endif -# if @REPLACE_FTELLO@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef ftello -# define ftello rpl_ftello -# endif -_GL_FUNCDECL_RPL (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (ftello, off_t, (FILE *fp)); -# else -# if ! @HAVE_DECL_FTELLO@ -_GL_FUNCDECL_SYS (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (ftello, off_t, (FILE *fp)); -# endif -_GL_CXXALIASWARN (ftello); -#elif defined GNULIB_POSIXCHECK -# define _GL_FTELL_WARN /* Category 1, above. */ -# undef ftell -# undef ftello -# if HAVE_RAW_DECL_FTELLO -_GL_WARN_ON_USE (ftello, "ftello is unportable - " - "use gnulib module ftello for portability"); -# endif -#endif - -#ifdef _GL_FTELL_WARN -# undef _GL_FTELL_WARN -/* Here, either ftell is undefined (but C89 guarantees that it is - declared), or it is defined as rpl_ftell (declared above). */ -_GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB " - "on 32-bit platforms - " - "use ftello function for handling of large files"); -#endif - - -#if @GNULIB_FWRITE@ -# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fwrite -# define fwrite rpl_fwrite -# endif -_GL_FUNCDECL_RPL (fwrite, size_t, - (const void *ptr, size_t s, size_t n, FILE *stream) - _GL_ARG_NONNULL ((1, 4))); -_GL_CXXALIAS_RPL (fwrite, size_t, - (const void *ptr, size_t s, size_t n, FILE *stream)); -# else -_GL_CXXALIAS_SYS (fwrite, size_t, - (const void *ptr, size_t s, size_t n, FILE *stream)); - -/* Work around bug 11959 when fortifying glibc 2.4 through 2.15 - , - which sometimes causes an unwanted diagnostic for fwrite calls. - This affects only function declaration attributes under certain - versions of gcc, and is not needed for C++. */ -# if (0 < __USE_FORTIFY_LEVEL \ - && __GLIBC__ == 2 && 4 <= __GLIBC_MINOR__ && __GLIBC_MINOR__ <= 15 \ - && 3 < __GNUC__ + (4 <= __GNUC_MINOR__) \ - && !defined __cplusplus) -# undef fwrite -# define fwrite(a, b, c, d) ({size_t __r = fwrite (a, b, c, d); __r; }) -# endif -# endif -_GL_CXXALIASWARN (fwrite); -#endif - -#if @GNULIB_GETC@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getc -# define getc rpl_fgetc -# endif -_GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL_1 (getc, rpl_fgetc, int, (FILE *stream)); -# else -_GL_CXXALIAS_SYS (getc, int, (FILE *stream)); -# endif -_GL_CXXALIASWARN (getc); -#endif - -#if @GNULIB_GETCHAR@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getchar -# define getchar rpl_getchar -# endif -_GL_FUNCDECL_RPL (getchar, int, (void)); -_GL_CXXALIAS_RPL (getchar, int, (void)); -# else -_GL_CXXALIAS_SYS (getchar, int, (void)); -# endif -_GL_CXXALIASWARN (getchar); -#endif - -#if @GNULIB_GETDELIM@ -/* Read input, up to (and including) the next occurrence of DELIMITER, from - STREAM, store it in *LINEPTR (and NUL-terminate it). - *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE - bytes of space. It is realloc'd as necessary. - Return the number of bytes read and stored at *LINEPTR (not including the - NUL terminator), or -1 on error or EOF. */ -# if @REPLACE_GETDELIM@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getdelim -# define getdelim rpl_getdelim -# endif -_GL_FUNCDECL_RPL (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream) - _GL_ARG_NONNULL ((1, 2, 4))); -_GL_CXXALIAS_RPL (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream)); -# else -# if !@HAVE_DECL_GETDELIM@ -_GL_FUNCDECL_SYS (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream) - _GL_ARG_NONNULL ((1, 2, 4))); -# endif -_GL_CXXALIAS_SYS (getdelim, ssize_t, - (char **lineptr, size_t *linesize, int delimiter, - FILE *stream)); -# endif -_GL_CXXALIASWARN (getdelim); -#elif defined GNULIB_POSIXCHECK -# undef getdelim -# if HAVE_RAW_DECL_GETDELIM -_GL_WARN_ON_USE (getdelim, "getdelim is unportable - " - "use gnulib module getdelim for portability"); -# endif -#endif - -#if @GNULIB_GETLINE@ -/* Read a line, up to (and including) the next newline, from STREAM, store it - in *LINEPTR (and NUL-terminate it). - *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE - bytes of space. It is realloc'd as necessary. - Return the number of bytes read and stored at *LINEPTR (not including the - NUL terminator), or -1 on error or EOF. */ -# if @REPLACE_GETLINE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getline -# define getline rpl_getline -# endif -_GL_FUNCDECL_RPL (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream) - _GL_ARG_NONNULL ((1, 2, 3))); -_GL_CXXALIAS_RPL (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream)); -# else -# if !@HAVE_DECL_GETLINE@ -_GL_FUNCDECL_SYS (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream) - _GL_ARG_NONNULL ((1, 2, 3))); -# endif -_GL_CXXALIAS_SYS (getline, ssize_t, - (char **lineptr, size_t *linesize, FILE *stream)); -# endif -# if @HAVE_DECL_GETLINE@ -_GL_CXXALIASWARN (getline); -# endif -#elif defined GNULIB_POSIXCHECK -# undef getline -# if HAVE_RAW_DECL_GETLINE -_GL_WARN_ON_USE (getline, "getline is unportable - " - "use gnulib module getline for portability"); -# endif -#endif - -/* It is very rare that the developer ever has full control of stdin, - so any use of gets warrants an unconditional warning; besides, C11 - removed it. */ -#undef gets -#if HAVE_RAW_DECL_GETS -#endif - - -#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ -struct obstack; -/* Grow an obstack with formatted output. Return the number of - bytes added to OBS. No trailing nul byte is added, and the - object should be closed with obstack_finish before use. Upon - memory allocation error, call obstack_alloc_failed_handler. Upon - other error, return -1. */ -# if @REPLACE_OBSTACK_PRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define obstack_printf rpl_obstack_printf -# endif -_GL_FUNCDECL_RPL (obstack_printf, int, - (struct obstack *obs, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (obstack_printf, int, - (struct obstack *obs, const char *format, ...)); -# else -# if !@HAVE_DECL_OBSTACK_PRINTF@ -_GL_FUNCDECL_SYS (obstack_printf, int, - (struct obstack *obs, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (obstack_printf, int, - (struct obstack *obs, const char *format, ...)); -# endif -_GL_CXXALIASWARN (obstack_printf); -# if @REPLACE_OBSTACK_PRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define obstack_vprintf rpl_obstack_vprintf -# endif -_GL_FUNCDECL_RPL (obstack_vprintf, int, - (struct obstack *obs, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (obstack_vprintf, int, - (struct obstack *obs, const char *format, va_list args)); -# else -# if !@HAVE_DECL_OBSTACK_PRINTF@ -_GL_FUNCDECL_SYS (obstack_vprintf, int, - (struct obstack *obs, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (obstack_vprintf, int, - (struct obstack *obs, const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (obstack_vprintf); -#endif - -#if @GNULIB_PCLOSE@ -# if !@HAVE_PCLOSE@ -_GL_FUNCDECL_SYS (pclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (pclose, int, (FILE *stream)); -_GL_CXXALIASWARN (pclose); -#elif defined GNULIB_POSIXCHECK -# undef pclose -# if HAVE_RAW_DECL_PCLOSE -_GL_WARN_ON_USE (pclose, "pclose is unportable - " - "use gnulib module pclose for more portability"); -# endif -#endif - -#if @GNULIB_PERROR@ -/* Print a message to standard error, describing the value of ERRNO, - (if STRING is not NULL and not empty) prefixed with STRING and ": ", - and terminated with a newline. */ -# if @REPLACE_PERROR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define perror rpl_perror -# endif -_GL_FUNCDECL_RPL (perror, void, (const char *string)); -_GL_CXXALIAS_RPL (perror, void, (const char *string)); -# else -_GL_CXXALIAS_SYS (perror, void, (const char *string)); -# endif -_GL_CXXALIASWARN (perror); -#elif defined GNULIB_POSIXCHECK -# undef perror -/* Assume perror is always declared. */ -_GL_WARN_ON_USE (perror, "perror is not always POSIX compliant - " - "use gnulib module perror for portability"); -#endif - -#if @GNULIB_POPEN@ -# if @REPLACE_POPEN@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef popen -# define popen rpl_popen -# endif -_GL_FUNCDECL_RPL (popen, FILE *, (const char *cmd, const char *mode) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode)); -# else -# if !@HAVE_POPEN@ -_GL_FUNCDECL_SYS (popen, FILE *, (const char *cmd, const char *mode) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode)); -# endif -_GL_CXXALIASWARN (popen); -#elif defined GNULIB_POSIXCHECK -# undef popen -# if HAVE_RAW_DECL_POPEN -_GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " - "use gnulib module popen or pipe for more portability"); -# endif -#endif - -#if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@ -# if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \ - || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) -# if defined __GNUC__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -/* Don't break __attribute__((format(printf,M,N))). */ -# define printf __printf__ -# endif -# if @GNULIB_PRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ -_GL_FUNCDECL_RPL_1 (__printf__, int, - (const char *format, ...) - __asm__ (@ASM_SYMBOL_PREFIX@ - _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) - _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) - _GL_ARG_NONNULL ((1))); -# else -_GL_FUNCDECL_RPL_1 (__printf__, int, - (const char *format, ...) - __asm__ (@ASM_SYMBOL_PREFIX@ - _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) - _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 2) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...)); -# else -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define printf rpl_printf -# endif -_GL_FUNCDECL_RPL (printf, int, - (const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (printf, int, (const char *format, ...)); -# endif -# define GNULIB_overrides_printf 1 -# else -_GL_CXXALIAS_SYS (printf, int, (const char *format, ...)); -# endif -_GL_CXXALIASWARN (printf); -#endif -#if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK -# if !GNULIB_overrides_printf -# undef printf -# endif -/* Assume printf is always declared. */ -_GL_WARN_ON_USE (printf, "printf is not always POSIX compliant - " - "use gnulib module printf-posix for portable " - "POSIX compliance"); -#endif - -#if @GNULIB_PUTC@ -# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef putc -# define putc rpl_fputc -# endif -_GL_FUNCDECL_RPL (fputc, int, (int c, FILE *stream) _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL_1 (putc, rpl_fputc, int, (int c, FILE *stream)); -# else -_GL_CXXALIAS_SYS (putc, int, (int c, FILE *stream)); -# endif -_GL_CXXALIASWARN (putc); -#endif - -#if @GNULIB_PUTCHAR@ -# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef putchar -# define putchar rpl_putchar -# endif -_GL_FUNCDECL_RPL (putchar, int, (int c)); -_GL_CXXALIAS_RPL (putchar, int, (int c)); -# else -_GL_CXXALIAS_SYS (putchar, int, (int c)); -# endif -_GL_CXXALIASWARN (putchar); -#endif - -#if @GNULIB_PUTS@ -# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef puts -# define puts rpl_puts -# endif -_GL_FUNCDECL_RPL (puts, int, (const char *string) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (puts, int, (const char *string)); -# else -_GL_CXXALIAS_SYS (puts, int, (const char *string)); -# endif -_GL_CXXALIASWARN (puts); -#endif - -#if @GNULIB_REMOVE@ -# if @REPLACE_REMOVE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef remove -# define remove rpl_remove -# endif -_GL_FUNCDECL_RPL (remove, int, (const char *name) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (remove, int, (const char *name)); -# else -_GL_CXXALIAS_SYS (remove, int, (const char *name)); -# endif -_GL_CXXALIASWARN (remove); -#elif defined GNULIB_POSIXCHECK -# undef remove -/* Assume remove is always declared. */ -_GL_WARN_ON_USE (remove, "remove cannot handle directories on some platforms - " - "use gnulib module remove for more portability"); -#endif - -#if @GNULIB_RENAME@ -# if @REPLACE_RENAME@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef rename -# define rename rpl_rename -# endif -_GL_FUNCDECL_RPL (rename, int, - (const char *old_filename, const char *new_filename) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (rename, int, - (const char *old_filename, const char *new_filename)); -# else -_GL_CXXALIAS_SYS (rename, int, - (const char *old_filename, const char *new_filename)); -# endif -_GL_CXXALIASWARN (rename); -#elif defined GNULIB_POSIXCHECK -# undef rename -/* Assume rename is always declared. */ -_GL_WARN_ON_USE (rename, "rename is buggy on some platforms - " - "use gnulib module rename for more portability"); -#endif - -#if @GNULIB_RENAMEAT@ -# if @REPLACE_RENAMEAT@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef renameat -# define renameat rpl_renameat -# endif -_GL_FUNCDECL_RPL (renameat, int, - (int fd1, char const *file1, int fd2, char const *file2) - _GL_ARG_NONNULL ((2, 4))); -_GL_CXXALIAS_RPL (renameat, int, - (int fd1, char const *file1, int fd2, char const *file2)); -# else -# if !@HAVE_RENAMEAT@ -_GL_FUNCDECL_SYS (renameat, int, - (int fd1, char const *file1, int fd2, char const *file2) - _GL_ARG_NONNULL ((2, 4))); -# endif -_GL_CXXALIAS_SYS (renameat, int, - (int fd1, char const *file1, int fd2, char const *file2)); -# endif -_GL_CXXALIASWARN (renameat); -#elif defined GNULIB_POSIXCHECK -# undef renameat -# if HAVE_RAW_DECL_RENAMEAT -_GL_WARN_ON_USE (renameat, "renameat is not portable - " - "use gnulib module renameat for portability"); -# endif -#endif - -#if @GNULIB_SCANF@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if defined __GNUC__ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef scanf -/* Don't break __attribute__((format(scanf,M,N))). */ -# define scanf __scanf__ -# endif -_GL_FUNCDECL_RPL_1 (__scanf__, int, - (const char *format, ...) - __asm__ (@ASM_SYMBOL_PREFIX@ - _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf)) - _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *format, ...)); -# else -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef scanf -# define scanf rpl_scanf -# endif -_GL_FUNCDECL_RPL (scanf, int, (const char *format, ...) - _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (scanf, int, (const char *format, ...)); -# endif -# else -_GL_CXXALIAS_SYS (scanf, int, (const char *format, ...)); -# endif -_GL_CXXALIASWARN (scanf); -#endif - -#if @GNULIB_SNPRINTF@ -# if @REPLACE_SNPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define snprintf rpl_snprintf -# endif -_GL_FUNCDECL_RPL (snprintf, int, - (char *str, size_t size, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) - _GL_ARG_NONNULL ((3))); -_GL_CXXALIAS_RPL (snprintf, int, - (char *str, size_t size, const char *format, ...)); -# else -# if !@HAVE_DECL_SNPRINTF@ -_GL_FUNCDECL_SYS (snprintf, int, - (char *str, size_t size, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) - _GL_ARG_NONNULL ((3))); -# endif -_GL_CXXALIAS_SYS (snprintf, int, - (char *str, size_t size, const char *format, ...)); -# endif -_GL_CXXALIASWARN (snprintf); -#elif defined GNULIB_POSIXCHECK -# undef snprintf -# if HAVE_RAW_DECL_SNPRINTF -_GL_WARN_ON_USE (snprintf, "snprintf is unportable - " - "use gnulib module snprintf for portability"); -# endif -#endif - -/* Some people would argue that all sprintf uses should be warned about - (for example, OpenBSD issues a link warning for it), - since it can cause security holes due to buffer overruns. - However, we believe that sprintf can be used safely, and is more - efficient than snprintf in those safe cases; and as proof of our - belief, we use sprintf in several gnulib modules. So this header - intentionally avoids adding a warning to sprintf except when - GNULIB_POSIXCHECK is defined. */ - -#if @GNULIB_SPRINTF_POSIX@ -# if @REPLACE_SPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define sprintf rpl_sprintf -# endif -_GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...)); -# else -_GL_CXXALIAS_SYS (sprintf, int, (char *str, const char *format, ...)); -# endif -_GL_CXXALIASWARN (sprintf); -#elif defined GNULIB_POSIXCHECK -# undef sprintf -/* Assume sprintf is always declared. */ -_GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX compliant - " - "use gnulib module sprintf-posix for portable " - "POSIX compliance"); -#endif - -#if @GNULIB_TMPFILE@ -# if @REPLACE_TMPFILE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define tmpfile rpl_tmpfile -# endif -_GL_FUNCDECL_RPL (tmpfile, FILE *, (void)); -_GL_CXXALIAS_RPL (tmpfile, FILE *, (void)); -# else -_GL_CXXALIAS_SYS (tmpfile, FILE *, (void)); -# endif -_GL_CXXALIASWARN (tmpfile); -#elif defined GNULIB_POSIXCHECK -# undef tmpfile -# if HAVE_RAW_DECL_TMPFILE -_GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " - "use gnulib module tmpfile for portability"); -# endif -#endif - -#if @GNULIB_VASPRINTF@ -/* Write formatted output to a string dynamically allocated with malloc(). - If the memory allocation succeeds, store the address of the string in - *RESULT and return the number of resulting bytes, excluding the trailing - NUL. Upon memory allocation error, or some other error, return -1. */ -# if @REPLACE_VASPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define asprintf rpl_asprintf -# endif -_GL_FUNCDECL_RPL (asprintf, int, - (char **result, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (asprintf, int, - (char **result, const char *format, ...)); -# else -# if !@HAVE_VASPRINTF@ -_GL_FUNCDECL_SYS (asprintf, int, - (char **result, const char *format, ...) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (asprintf, int, - (char **result, const char *format, ...)); -# endif -_GL_CXXALIASWARN (asprintf); -# if @REPLACE_VASPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define vasprintf rpl_vasprintf -# endif -_GL_FUNCDECL_RPL (vasprintf, int, - (char **result, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (vasprintf, int, - (char **result, const char *format, va_list args)); -# else -# if !@HAVE_VASPRINTF@ -_GL_FUNCDECL_SYS (vasprintf, int, - (char **result, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (vasprintf, int, - (char **result, const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vasprintf); -#endif - -#if @GNULIB_VDPRINTF@ -# if @REPLACE_VDPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define vdprintf rpl_vdprintf -# endif -_GL_FUNCDECL_RPL (vdprintf, int, (int fd, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (vdprintf, int, (int fd, const char *format, va_list args)); -# else -# if !@HAVE_VDPRINTF@ -_GL_FUNCDECL_SYS (vdprintf, int, (int fd, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((2))); -# endif -/* Need to cast, because on Solaris, the third parameter will likely be - __va_list args. */ -_GL_CXXALIAS_SYS_CAST (vdprintf, int, - (int fd, const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vdprintf); -#elif defined GNULIB_POSIXCHECK -# undef vdprintf -# if HAVE_RAW_DECL_VDPRINTF -_GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " - "use gnulib module vdprintf for portability"); -# endif -#endif - -#if @GNULIB_VFPRINTF_POSIX@ || @GNULIB_VFPRINTF@ -# if (@GNULIB_VFPRINTF_POSIX@ && @REPLACE_VFPRINTF@) \ - || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define vfprintf rpl_vfprintf -# endif -# define GNULIB_overrides_vfprintf 1 -# if @GNULIB_VFPRINTF_POSIX@ -_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((1, 2))); -# else -_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)); -# else -/* Need to cast, because on Solaris, the third parameter is - __va_list args - and GCC's fixincludes did not change this to __gnuc_va_list. */ -_GL_CXXALIAS_SYS_CAST (vfprintf, int, - (FILE *fp, const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vfprintf); -#endif -#if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK -# if !GNULIB_overrides_vfprintf -# undef vfprintf -# endif -/* Assume vfprintf is always declared. */ -_GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " - "use gnulib module vfprintf-posix for portable " - "POSIX compliance"); -#endif - -#if @GNULIB_VFSCANF@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef vfscanf -# define vfscanf rpl_vfscanf -# endif -_GL_FUNCDECL_RPL (vfscanf, int, - (FILE *stream, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (vfscanf, int, - (FILE *stream, const char *format, va_list args)); -# else -_GL_CXXALIAS_SYS (vfscanf, int, - (FILE *stream, const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vfscanf); -#endif - -#if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@ -# if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \ - || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define vprintf rpl_vprintf -# endif -# define GNULIB_overrides_vprintf 1 -# if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ -_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (1, 0) - _GL_ARG_NONNULL ((1))); -# else -_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_RPL (vprintf, int, (const char *format, va_list args)); -# else -/* Need to cast, because on Solaris, the second parameter is - __va_list args - and GCC's fixincludes did not change this to __gnuc_va_list. */ -_GL_CXXALIAS_SYS_CAST (vprintf, int, (const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vprintf); -#endif -#if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK -# if !GNULIB_overrides_vprintf -# undef vprintf -# endif -/* Assume vprintf is always declared. */ -_GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " - "use gnulib module vprintf-posix for portable " - "POSIX compliance"); -#endif - -#if @GNULIB_VSCANF@ -# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef vscanf -# define vscanf rpl_vscanf -# endif -_GL_FUNCDECL_RPL (vscanf, int, (const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (vscanf, int, (const char *format, va_list args)); -# else -_GL_CXXALIAS_SYS (vscanf, int, (const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vscanf); -#endif - -#if @GNULIB_VSNPRINTF@ -# if @REPLACE_VSNPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define vsnprintf rpl_vsnprintf -# endif -_GL_FUNCDECL_RPL (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) - _GL_ARG_NONNULL ((3))); -_GL_CXXALIAS_RPL (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args)); -# else -# if !@HAVE_DECL_VSNPRINTF@ -_GL_FUNCDECL_SYS (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) - _GL_ARG_NONNULL ((3))); -# endif -_GL_CXXALIAS_SYS (vsnprintf, int, - (char *str, size_t size, const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vsnprintf); -#elif defined GNULIB_POSIXCHECK -# undef vsnprintf -# if HAVE_RAW_DECL_VSNPRINTF -_GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " - "use gnulib module vsnprintf for portability"); -# endif -#endif - -#if @GNULIB_VSPRINTF_POSIX@ -# if @REPLACE_VSPRINTF@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define vsprintf rpl_vsprintf -# endif -_GL_FUNCDECL_RPL (vsprintf, int, - (char *str, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (vsprintf, int, - (char *str, const char *format, va_list args)); -# else -/* Need to cast, because on Solaris, the third parameter is - __va_list args - and GCC's fixincludes did not change this to __gnuc_va_list. */ -_GL_CXXALIAS_SYS_CAST (vsprintf, int, - (char *str, const char *format, va_list args)); -# endif -_GL_CXXALIASWARN (vsprintf); -#elif defined GNULIB_POSIXCHECK -# undef vsprintf -/* Assume vsprintf is always declared. */ -_GL_WARN_ON_USE (vsprintf, "vsprintf is not always POSIX compliant - " - "use gnulib module vsprintf-posix for portable " - "POSIX compliance"); -#endif - -#endif /* _@GUARD_PREFIX@_STDIO_H */ -#endif /* _@GUARD_PREFIX@_STDIO_H */ -#endif diff --git a/grub-core/gnulib/stdlib.in.h b/grub-core/gnulib/stdlib.in.h deleted file mode 100644 index c9552480e..000000000 --- a/grub-core/gnulib/stdlib.in.h +++ /dev/null @@ -1,954 +0,0 @@ -/* A GNU-like . - - Copyright (C) 1995, 2001-2004, 2006-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#if defined __need_system_stdlib_h || defined __need_malloc_and_calloc -/* Special invocation conventions inside some gnulib header files, - and inside some glibc header files, respectively. */ - -#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ - -#else -/* Normal invocation convention. */ - -#ifndef _@GUARD_PREFIX@_STDLIB_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_STDLIB_H@ - -#ifndef _@GUARD_PREFIX@_STDLIB_H -#define _@GUARD_PREFIX@_STDLIB_H - -/* NetBSD 5.0 mis-defines NULL. */ -#include - -/* MirBSD 10 defines WEXITSTATUS in , not in . */ -#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS -# include -#endif - -/* Solaris declares getloadavg() in . */ -#if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@ -# include -#endif - -/* Native Windows platforms declare mktemp() in . */ -#if 0 && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) -# include -#endif - -#if @GNULIB_RANDOM_R@ - -/* OSF/1 5.1 declares 'struct random_data' in , which is included - from if _REENTRANT is defined. Include it whenever we need - 'struct random_data'. */ -# if @HAVE_RANDOM_H@ -# include -# endif - -# if !@HAVE_STRUCT_RANDOM_DATA@ || @REPLACE_RANDOM_R@ || !@HAVE_RANDOM_R@ -# include -# endif - -# if !@HAVE_STRUCT_RANDOM_DATA@ -/* Define 'struct random_data'. - But allow multiple gnulib generated replacements to coexist. */ -# if !GNULIB_defined_struct_random_data -struct random_data -{ - int32_t *fptr; /* Front pointer. */ - int32_t *rptr; /* Rear pointer. */ - int32_t *state; /* Array of state values. */ - int rand_type; /* Type of random number generator. */ - int rand_deg; /* Degree of random number generator. */ - int rand_sep; /* Distance between front and rear. */ - int32_t *end_ptr; /* Pointer behind state table. */ -}; -# define GNULIB_defined_struct_random_data 1 -# endif -# endif -#endif - -#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) -/* On Mac OS X 10.3, only declares mkstemp. */ -/* On Mac OS X 10.5, only declares mkstemps. */ -/* On Cygwin 1.7.1, only declares getsubopt. */ -/* But avoid namespace pollution on glibc systems and native Windows. */ -# include -#endif - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The attribute __pure__ was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -# define _GL_ATTRIBUTE_PURE /* empty */ -#endif - -/* The definition of _Noreturn is copied here. */ - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - - -/* Some systems do not define EXIT_*, despite otherwise supporting C89. */ -#ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -#endif -/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere - with proper operation of xargs. */ -#ifndef EXIT_FAILURE -# define EXIT_FAILURE 1 -#elif EXIT_FAILURE != 1 -# undef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - - -#if @GNULIB__EXIT@ -/* Terminate the current process with the given return code, without running - the 'atexit' handlers. */ -# if !@HAVE__EXIT@ -_GL_FUNCDECL_SYS (_Exit, _Noreturn void, (int status)); -# endif -_GL_CXXALIAS_SYS (_Exit, void, (int status)); -_GL_CXXALIASWARN (_Exit); -#elif defined GNULIB_POSIXCHECK -# undef _Exit -# if HAVE_RAW_DECL__EXIT -_GL_WARN_ON_USE (_Exit, "_Exit is unportable - " - "use gnulib module _Exit for portability"); -# endif -#endif - - -#if @GNULIB_ATOLL@ -/* Parse a signed decimal integer. - Returns the value of the integer. Errors are not detected. */ -# if !@HAVE_ATOLL@ -_GL_FUNCDECL_SYS (atoll, long long, (const char *string) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (atoll, long long, (const char *string)); -_GL_CXXALIASWARN (atoll); -#elif defined GNULIB_POSIXCHECK -# undef atoll -# if HAVE_RAW_DECL_ATOLL -_GL_WARN_ON_USE (atoll, "atoll is unportable - " - "use gnulib module atoll for portability"); -# endif -#endif - -#if @GNULIB_CALLOC_POSIX@ -# if @REPLACE_CALLOC@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef calloc -# define calloc rpl_calloc -# endif -_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size)); -_GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size)); -# else -_GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size)); -# endif -_GL_CXXALIASWARN (calloc); -#elif defined GNULIB_POSIXCHECK -# undef calloc -/* Assume calloc is always declared. */ -_GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - " - "use gnulib module calloc-posix for portability"); -#endif - -#if @GNULIB_CANONICALIZE_FILE_NAME@ -# if @REPLACE_CANONICALIZE_FILE_NAME@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define canonicalize_file_name rpl_canonicalize_file_name -# endif -_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name)); -# else -# if !@HAVE_CANONICALIZE_FILE_NAME@ -_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name)); -# endif -_GL_CXXALIASWARN (canonicalize_file_name); -#elif defined GNULIB_POSIXCHECK -# undef canonicalize_file_name -# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME -_GL_WARN_ON_USE (canonicalize_file_name, - "canonicalize_file_name is unportable - " - "use gnulib module canonicalize-lgpl for portability"); -# endif -#endif - -#if @GNULIB_GETLOADAVG@ -/* Store max(NELEM,3) load average numbers in LOADAVG[]. - The three numbers are the load average of the last 1 minute, the last 5 - minutes, and the last 15 minutes, respectively. - LOADAVG is an array of NELEM numbers. */ -# if !@HAVE_DECL_GETLOADAVG@ -_GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem)); -_GL_CXXALIASWARN (getloadavg); -#elif defined GNULIB_POSIXCHECK -# undef getloadavg -# if HAVE_RAW_DECL_GETLOADAVG -_GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - " - "use gnulib module getloadavg for portability"); -# endif -#endif - -#if @GNULIB_GETSUBOPT@ -/* Assuming *OPTIONP is a comma separated list of elements of the form - "token" or "token=value", getsubopt parses the first of these elements. - If the first element refers to a "token" that is member of the given - NULL-terminated array of tokens: - - It replaces the comma with a NUL byte, updates *OPTIONP to point past - the first option and the comma, sets *VALUEP to the value of the - element (or NULL if it doesn't contain an "=" sign), - - It returns the index of the "token" in the given array of tokens. - Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined. - For more details see the POSIX:2001 specification. - http://www.opengroup.org/susv3xsh/getsubopt.html */ -# if !@HAVE_GETSUBOPT@ -_GL_FUNCDECL_SYS (getsubopt, int, - (char **optionp, char *const *tokens, char **valuep) - _GL_ARG_NONNULL ((1, 2, 3))); -# endif -_GL_CXXALIAS_SYS (getsubopt, int, - (char **optionp, char *const *tokens, char **valuep)); -_GL_CXXALIASWARN (getsubopt); -#elif defined GNULIB_POSIXCHECK -# undef getsubopt -# if HAVE_RAW_DECL_GETSUBOPT -_GL_WARN_ON_USE (getsubopt, "getsubopt is unportable - " - "use gnulib module getsubopt for portability"); -# endif -#endif - -#if @GNULIB_GRANTPT@ -/* Change the ownership and access permission of the slave side of the - pseudo-terminal whose master side is specified by FD. */ -# if !@HAVE_GRANTPT@ -_GL_FUNCDECL_SYS (grantpt, int, (int fd)); -# endif -_GL_CXXALIAS_SYS (grantpt, int, (int fd)); -_GL_CXXALIASWARN (grantpt); -#elif defined GNULIB_POSIXCHECK -# undef grantpt -# if HAVE_RAW_DECL_GRANTPT -_GL_WARN_ON_USE (grantpt, "grantpt is not portable - " - "use gnulib module grantpt for portability"); -# endif -#endif - -/* If _GL_USE_STDLIB_ALLOC is nonzero, the including module does not - rely on GNU or POSIX semantics for malloc and realloc (for example, - by never specifying a zero size), so it does not need malloc or - realloc to be redefined. */ -#if @GNULIB_MALLOC_POSIX@ -# if @REPLACE_MALLOC@ -# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ - || _GL_USE_STDLIB_ALLOC) -# undef malloc -# define malloc rpl_malloc -# endif -_GL_FUNCDECL_RPL (malloc, void *, (size_t size)); -_GL_CXXALIAS_RPL (malloc, void *, (size_t size)); -# else -_GL_CXXALIAS_SYS (malloc, void *, (size_t size)); -# endif -_GL_CXXALIASWARN (malloc); -#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC -# undef malloc -/* Assume malloc is always declared. */ -_GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " - "use gnulib module malloc-posix for portability"); -#endif - -/* Convert a multibyte character to a wide character. */ -#if @GNULIB_MBTOWC@ -# if @REPLACE_MBTOWC@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mbtowc -# define mbtowc rpl_mbtowc -# endif -_GL_FUNCDECL_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); -_GL_CXXALIAS_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); -# else -_GL_CXXALIAS_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); -# endif -_GL_CXXALIASWARN (mbtowc); -#endif - -#if @GNULIB_MKDTEMP@ -/* Create a unique temporary directory from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the directory name unique. - Returns TEMPLATE, or a null pointer if it cannot get a unique name. - The directory is created mode 700. */ -# if !@HAVE_MKDTEMP@ -_GL_FUNCDECL_SYS (mkdtemp, char *, (char * /*template*/) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/)); -_GL_CXXALIASWARN (mkdtemp); -#elif defined GNULIB_POSIXCHECK -# undef mkdtemp -# if HAVE_RAW_DECL_MKDTEMP -_GL_WARN_ON_USE (mkdtemp, "mkdtemp is unportable - " - "use gnulib module mkdtemp for portability"); -# endif -#endif - -#if @GNULIB_MKOSTEMP@ -/* Create a unique temporary file from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the file name unique. - The flags are a bitmask, possibly including O_CLOEXEC (defined in ) - and O_TEXT, O_BINARY (defined in "binary-io.h"). - The file is then created, with the specified flags, ensuring it didn't exist - before. - The file is created read-write (mask at least 0600 & ~umask), but it may be - world-readable and world-writable (mask 0666 & ~umask), depending on the - implementation. - Returns the open file descriptor if successful, otherwise -1 and errno - set. */ -# if !@HAVE_MKOSTEMP@ -_GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)); -_GL_CXXALIASWARN (mkostemp); -#elif defined GNULIB_POSIXCHECK -# undef mkostemp -# if HAVE_RAW_DECL_MKOSTEMP -_GL_WARN_ON_USE (mkostemp, "mkostemp is unportable - " - "use gnulib module mkostemp for portability"); -# endif -#endif - -#if @GNULIB_MKOSTEMPS@ -/* Create a unique temporary file from TEMPLATE. - The last six characters of TEMPLATE before a suffix of length - SUFFIXLEN must be "XXXXXX"; - they are replaced with a string that makes the file name unique. - The flags are a bitmask, possibly including O_CLOEXEC (defined in ) - and O_TEXT, O_BINARY (defined in "binary-io.h"). - The file is then created, with the specified flags, ensuring it didn't exist - before. - The file is created read-write (mask at least 0600 & ~umask), but it may be - world-readable and world-writable (mask 0666 & ~umask), depending on the - implementation. - Returns the open file descriptor if successful, otherwise -1 and errno - set. */ -# if !@HAVE_MKOSTEMPS@ -_GL_FUNCDECL_SYS (mkostemps, int, - (char * /*template*/, int /*suffixlen*/, int /*flags*/) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (mkostemps, int, - (char * /*template*/, int /*suffixlen*/, int /*flags*/)); -_GL_CXXALIASWARN (mkostemps); -#elif defined GNULIB_POSIXCHECK -# undef mkostemps -# if HAVE_RAW_DECL_MKOSTEMPS -_GL_WARN_ON_USE (mkostemps, "mkostemps is unportable - " - "use gnulib module mkostemps for portability"); -# endif -#endif - -#if @GNULIB_MKSTEMP@ -/* Create a unique temporary file from TEMPLATE. - The last six characters of TEMPLATE must be "XXXXXX"; - they are replaced with a string that makes the file name unique. - The file is then created, ensuring it didn't exist before. - The file is created read-write (mask at least 0600 & ~umask), but it may be - world-readable and world-writable (mask 0666 & ~umask), depending on the - implementation. - Returns the open file descriptor if successful, otherwise -1 and errno - set. */ -# if @REPLACE_MKSTEMP@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define mkstemp rpl_mkstemp -# endif -_GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/)); -# else -# if ! @HAVE_MKSTEMP@ -_GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/)); -# endif -_GL_CXXALIASWARN (mkstemp); -#elif defined GNULIB_POSIXCHECK -# undef mkstemp -# if HAVE_RAW_DECL_MKSTEMP -_GL_WARN_ON_USE (mkstemp, "mkstemp is unportable - " - "use gnulib module mkstemp for portability"); -# endif -#endif - -#if @GNULIB_MKSTEMPS@ -/* Create a unique temporary file from TEMPLATE. - The last six characters of TEMPLATE prior to a suffix of length - SUFFIXLEN must be "XXXXXX"; - they are replaced with a string that makes the file name unique. - The file is then created, ensuring it didn't exist before. - The file is created read-write (mask at least 0600 & ~umask), but it may be - world-readable and world-writable (mask 0666 & ~umask), depending on the - implementation. - Returns the open file descriptor if successful, otherwise -1 and errno - set. */ -# if !@HAVE_MKSTEMPS@ -_GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)); -_GL_CXXALIASWARN (mkstemps); -#elif defined GNULIB_POSIXCHECK -# undef mkstemps -# if HAVE_RAW_DECL_MKSTEMPS -_GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - " - "use gnulib module mkstemps for portability"); -# endif -#endif - -#if @GNULIB_POSIX_OPENPT@ -/* Return an FD open to the master side of a pseudo-terminal. Flags should - include O_RDWR, and may also include O_NOCTTY. */ -# if !@HAVE_POSIX_OPENPT@ -_GL_FUNCDECL_SYS (posix_openpt, int, (int flags)); -# endif -_GL_CXXALIAS_SYS (posix_openpt, int, (int flags)); -_GL_CXXALIASWARN (posix_openpt); -#elif defined GNULIB_POSIXCHECK -# undef posix_openpt -# if HAVE_RAW_DECL_POSIX_OPENPT -_GL_WARN_ON_USE (posix_openpt, "posix_openpt is not portable - " - "use gnulib module posix_openpt for portability"); -# endif -#endif - -#if @GNULIB_PTSNAME@ -/* Return the pathname of the pseudo-terminal slave associated with - the master FD is open on, or NULL on errors. */ -# if @REPLACE_PTSNAME@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef ptsname -# define ptsname rpl_ptsname -# endif -_GL_FUNCDECL_RPL (ptsname, char *, (int fd)); -_GL_CXXALIAS_RPL (ptsname, char *, (int fd)); -# else -# if !@HAVE_PTSNAME@ -_GL_FUNCDECL_SYS (ptsname, char *, (int fd)); -# endif -_GL_CXXALIAS_SYS (ptsname, char *, (int fd)); -# endif -_GL_CXXALIASWARN (ptsname); -#elif defined GNULIB_POSIXCHECK -# undef ptsname -# if HAVE_RAW_DECL_PTSNAME -_GL_WARN_ON_USE (ptsname, "ptsname is not portable - " - "use gnulib module ptsname for portability"); -# endif -#endif - -#if @GNULIB_PTSNAME_R@ -/* Set the pathname of the pseudo-terminal slave associated with - the master FD is open on and return 0, or set errno and return - non-zero on errors. */ -# if @REPLACE_PTSNAME_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef ptsname_r -# define ptsname_r rpl_ptsname_r -# endif -_GL_FUNCDECL_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); -_GL_CXXALIAS_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); -# else -# if !@HAVE_PTSNAME_R@ -_GL_FUNCDECL_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); -# endif -_GL_CXXALIAS_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); -# endif -_GL_CXXALIASWARN (ptsname_r); -#elif defined GNULIB_POSIXCHECK -# undef ptsname_r -# if HAVE_RAW_DECL_PTSNAME_R -_GL_WARN_ON_USE (ptsname_r, "ptsname_r is not portable - " - "use gnulib module ptsname_r for portability"); -# endif -#endif - -#if @GNULIB_PUTENV@ -# if @REPLACE_PUTENV@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef putenv -# define putenv rpl_putenv -# endif -_GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (putenv, int, (char *string)); -# else -_GL_CXXALIAS_SYS (putenv, int, (char *string)); -# endif -_GL_CXXALIASWARN (putenv); -#endif - - -#if @GNULIB_RANDOM_R@ -# if !@HAVE_RANDOM_R@ -# ifndef RAND_MAX -# define RAND_MAX 2147483647 -# endif -# endif -#endif - - -#if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ -_GL_FUNCDECL_SYS (random, long, (void)); -# endif -_GL_CXXALIAS_SYS (random, long, (void)); -_GL_CXXALIASWARN (random); -#elif defined GNULIB_POSIXCHECK -# undef random -# if HAVE_RAW_DECL_RANDOM -_GL_WARN_ON_USE (random, "random is unportable - " - "use gnulib module random for portability"); -# endif -#endif - -#if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ -_GL_FUNCDECL_SYS (srandom, void, (unsigned int seed)); -# endif -_GL_CXXALIAS_SYS (srandom, void, (unsigned int seed)); -_GL_CXXALIASWARN (srandom); -#elif defined GNULIB_POSIXCHECK -# undef srandom -# if HAVE_RAW_DECL_SRANDOM -_GL_WARN_ON_USE (srandom, "srandom is unportable - " - "use gnulib module random for portability"); -# endif -#endif - -#if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ -_GL_FUNCDECL_SYS (initstate, char *, - (unsigned int seed, char *buf, size_t buf_size) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (initstate, char *, - (unsigned int seed, char *buf, size_t buf_size)); -_GL_CXXALIASWARN (initstate); -#elif defined GNULIB_POSIXCHECK -# undef initstate -# if HAVE_RAW_DECL_INITSTATE_R -_GL_WARN_ON_USE (initstate, "initstate is unportable - " - "use gnulib module random for portability"); -# endif -#endif - -#if @GNULIB_RANDOM@ -# if !@HAVE_RANDOM@ -_GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (setstate, char *, (char *arg_state)); -_GL_CXXALIASWARN (setstate); -#elif defined GNULIB_POSIXCHECK -# undef setstate -# if HAVE_RAW_DECL_SETSTATE_R -_GL_WARN_ON_USE (setstate, "setstate is unportable - " - "use gnulib module random for portability"); -# endif -#endif - - -#if @GNULIB_RANDOM_R@ -# if @REPLACE_RANDOM_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef random_r -# define random_r rpl_random_r -# endif -_GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result)); -# else -# if !@HAVE_RANDOM_R@ -_GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result)); -# endif -_GL_CXXALIASWARN (random_r); -#elif defined GNULIB_POSIXCHECK -# undef random_r -# if HAVE_RAW_DECL_RANDOM_R -_GL_WARN_ON_USE (random_r, "random_r is unportable - " - "use gnulib module random_r for portability"); -# endif -#endif - -#if @GNULIB_RANDOM_R@ -# if @REPLACE_RANDOM_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef srandom_r -# define srandom_r rpl_srandom_r -# endif -_GL_FUNCDECL_RPL (srandom_r, int, - (unsigned int seed, struct random_data *rand_state) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (srandom_r, int, - (unsigned int seed, struct random_data *rand_state)); -# else -# if !@HAVE_RANDOM_R@ -_GL_FUNCDECL_SYS (srandom_r, int, - (unsigned int seed, struct random_data *rand_state) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (srandom_r, int, - (unsigned int seed, struct random_data *rand_state)); -# endif -_GL_CXXALIASWARN (srandom_r); -#elif defined GNULIB_POSIXCHECK -# undef srandom_r -# if HAVE_RAW_DECL_SRANDOM_R -_GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - " - "use gnulib module random_r for portability"); -# endif -#endif - -#if @GNULIB_RANDOM_R@ -# if @REPLACE_RANDOM_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef initstate_r -# define initstate_r rpl_initstate_r -# endif -_GL_FUNCDECL_RPL (initstate_r, int, - (unsigned int seed, char *buf, size_t buf_size, - struct random_data *rand_state) - _GL_ARG_NONNULL ((2, 4))); -_GL_CXXALIAS_RPL (initstate_r, int, - (unsigned int seed, char *buf, size_t buf_size, - struct random_data *rand_state)); -# else -# if !@HAVE_RANDOM_R@ -_GL_FUNCDECL_SYS (initstate_r, int, - (unsigned int seed, char *buf, size_t buf_size, - struct random_data *rand_state) - _GL_ARG_NONNULL ((2, 4))); -# endif -_GL_CXXALIAS_SYS (initstate_r, int, - (unsigned int seed, char *buf, size_t buf_size, - struct random_data *rand_state)); -# endif -_GL_CXXALIASWARN (initstate_r); -#elif defined GNULIB_POSIXCHECK -# undef initstate_r -# if HAVE_RAW_DECL_INITSTATE_R -_GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - " - "use gnulib module random_r for portability"); -# endif -#endif - -#if @GNULIB_RANDOM_R@ -# if @REPLACE_RANDOM_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef setstate_r -# define setstate_r rpl_setstate_r -# endif -_GL_FUNCDECL_RPL (setstate_r, int, - (char *arg_state, struct random_data *rand_state) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (setstate_r, int, - (char *arg_state, struct random_data *rand_state)); -# else -# if !@HAVE_RANDOM_R@ -_GL_FUNCDECL_SYS (setstate_r, int, - (char *arg_state, struct random_data *rand_state) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (setstate_r, int, - (char *arg_state, struct random_data *rand_state)); -# endif -_GL_CXXALIASWARN (setstate_r); -#elif defined GNULIB_POSIXCHECK -# undef setstate_r -# if HAVE_RAW_DECL_SETSTATE_R -_GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " - "use gnulib module random_r for portability"); -# endif -#endif - - -#if @GNULIB_REALLOC_POSIX@ -# if @REPLACE_REALLOC@ -# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ - || _GL_USE_STDLIB_ALLOC) -# undef realloc -# define realloc rpl_realloc -# endif -_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size)); -_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); -# else -_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); -# endif -_GL_CXXALIASWARN (realloc); -#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC -# undef realloc -/* Assume realloc is always declared. */ -_GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - " - "use gnulib module realloc-posix for portability"); -#endif - -#if @GNULIB_REALPATH@ -# if @REPLACE_REALPATH@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define realpath rpl_realpath -# endif -_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved)); -# else -# if !@HAVE_REALPATH@ -_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved)); -# endif -_GL_CXXALIASWARN (realpath); -#elif defined GNULIB_POSIXCHECK -# undef realpath -# if HAVE_RAW_DECL_REALPATH -_GL_WARN_ON_USE (realpath, "realpath is unportable - use gnulib module " - "canonicalize or canonicalize-lgpl for portability"); -# endif -#endif - -#if @GNULIB_RPMATCH@ -/* Test a user response to a question. - Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear. */ -# if !@HAVE_RPMATCH@ -_GL_FUNCDECL_SYS (rpmatch, int, (const char *response) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (rpmatch, int, (const char *response)); -_GL_CXXALIASWARN (rpmatch); -#elif defined GNULIB_POSIXCHECK -# undef rpmatch -# if HAVE_RAW_DECL_RPMATCH -_GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - " - "use gnulib module rpmatch for portability"); -# endif -#endif - -#if @GNULIB_SECURE_GETENV@ -/* Look up NAME in the environment, returning 0 in insecure situations. */ -# if !@HAVE_SECURE_GETENV@ -_GL_FUNCDECL_SYS (secure_getenv, char *, - (char const *name) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name)); -_GL_CXXALIASWARN (secure_getenv); -#elif defined GNULIB_POSIXCHECK -# undef secure_getenv -# if HAVE_RAW_DECL_SECURE_GETENV -_GL_WARN_ON_USE (secure_getenv, "secure_getenv is unportable - " - "use gnulib module secure_getenv for portability"); -# endif -#endif - -#if @GNULIB_SETENV@ -/* Set NAME to VALUE in the environment. - If REPLACE is nonzero, overwrite an existing value. */ -# if @REPLACE_SETENV@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef setenv -# define setenv rpl_setenv -# endif -_GL_FUNCDECL_RPL (setenv, int, - (const char *name, const char *value, int replace) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (setenv, int, - (const char *name, const char *value, int replace)); -# else -# if !@HAVE_DECL_SETENV@ -_GL_FUNCDECL_SYS (setenv, int, - (const char *name, const char *value, int replace) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (setenv, int, - (const char *name, const char *value, int replace)); -# endif -# if !(@REPLACE_SETENV@ && !@HAVE_DECL_SETENV@) -_GL_CXXALIASWARN (setenv); -# endif -#elif defined GNULIB_POSIXCHECK -# undef setenv -# if HAVE_RAW_DECL_SETENV -_GL_WARN_ON_USE (setenv, "setenv is unportable - " - "use gnulib module setenv for portability"); -# endif -#endif - -#if @GNULIB_STRTOD@ - /* Parse a double from STRING, updating ENDP if appropriate. */ -# if @REPLACE_STRTOD@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define strtod rpl_strtod -# endif -_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp)); -# else -# if !@HAVE_STRTOD@ -_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp)); -# endif -_GL_CXXALIASWARN (strtod); -#elif defined GNULIB_POSIXCHECK -# undef strtod -# if HAVE_RAW_DECL_STRTOD -_GL_WARN_ON_USE (strtod, "strtod is unportable - " - "use gnulib module strtod for portability"); -# endif -#endif - -#if @GNULIB_STRTOLL@ -/* Parse a signed integer whose textual representation starts at STRING. - The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, - it may be decimal or octal (with prefix "0") or hexadecimal (with prefix - "0x"). - If ENDPTR is not NULL, the address of the first byte after the integer is - stored in *ENDPTR. - Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set - to ERANGE. */ -# if !@HAVE_STRTOLL@ -_GL_FUNCDECL_SYS (strtoll, long long, - (const char *string, char **endptr, int base) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (strtoll, long long, - (const char *string, char **endptr, int base)); -_GL_CXXALIASWARN (strtoll); -#elif defined GNULIB_POSIXCHECK -# undef strtoll -# if HAVE_RAW_DECL_STRTOLL -_GL_WARN_ON_USE (strtoll, "strtoll is unportable - " - "use gnulib module strtoll for portability"); -# endif -#endif - -#if @GNULIB_STRTOULL@ -/* Parse an unsigned integer whose textual representation starts at STRING. - The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0, - it may be decimal or octal (with prefix "0") or hexadecimal (with prefix - "0x"). - If ENDPTR is not NULL, the address of the first byte after the integer is - stored in *ENDPTR. - Upon overflow, the return value is ULLONG_MAX, and errno is set to - ERANGE. */ -# if !@HAVE_STRTOULL@ -_GL_FUNCDECL_SYS (strtoull, unsigned long long, - (const char *string, char **endptr, int base) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (strtoull, unsigned long long, - (const char *string, char **endptr, int base)); -_GL_CXXALIASWARN (strtoull); -#elif defined GNULIB_POSIXCHECK -# undef strtoull -# if HAVE_RAW_DECL_STRTOULL -_GL_WARN_ON_USE (strtoull, "strtoull is unportable - " - "use gnulib module strtoull for portability"); -# endif -#endif - -#if @GNULIB_UNLOCKPT@ -/* Unlock the slave side of the pseudo-terminal whose master side is specified - by FD, so that it can be opened. */ -# if !@HAVE_UNLOCKPT@ -_GL_FUNCDECL_SYS (unlockpt, int, (int fd)); -# endif -_GL_CXXALIAS_SYS (unlockpt, int, (int fd)); -_GL_CXXALIASWARN (unlockpt); -#elif defined GNULIB_POSIXCHECK -# undef unlockpt -# if HAVE_RAW_DECL_UNLOCKPT -_GL_WARN_ON_USE (unlockpt, "unlockpt is not portable - " - "use gnulib module unlockpt for portability"); -# endif -#endif - -#if @GNULIB_UNSETENV@ -/* Remove the variable NAME from the environment. */ -# if @REPLACE_UNSETENV@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef unsetenv -# define unsetenv rpl_unsetenv -# endif -_GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (unsetenv, int, (const char *name)); -# else -# if !@HAVE_DECL_UNSETENV@ -_GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (unsetenv, int, (const char *name)); -# endif -# if !(@REPLACE_UNSETENV@ && !@HAVE_DECL_UNSETENV@) -_GL_CXXALIASWARN (unsetenv); -# endif -#elif defined GNULIB_POSIXCHECK -# undef unsetenv -# if HAVE_RAW_DECL_UNSETENV -_GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - " - "use gnulib module unsetenv for portability"); -# endif -#endif - -/* Convert a wide character to a multibyte character. */ -#if @GNULIB_WCTOMB@ -# if @REPLACE_WCTOMB@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef wctomb -# define wctomb rpl_wctomb -# endif -_GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc)); -_GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc)); -# else -_GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc)); -# endif -_GL_CXXALIASWARN (wctomb); -#endif - - -#endif /* _@GUARD_PREFIX@_STDLIB_H */ -#endif /* _@GUARD_PREFIX@_STDLIB_H */ -#endif diff --git a/grub-core/gnulib/strcasecmp.c b/grub-core/gnulib/strcasecmp.c deleted file mode 100644 index 0f0a742ff..000000000 --- a/grub-core/gnulib/strcasecmp.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Case-insensitive string comparison function. - Copyright (C) 1998-1999, 2005-2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#include - -/* Specification. */ -#include - -#include -#include - -#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) - -/* Compare strings S1 and S2, ignoring case, returning less than, equal to or - greater than zero if S1 is lexicographically less than, equal to or greater - than S2. - Note: This function does not work with multibyte strings! */ - -int -strcasecmp (const char *s1, const char *s2) -{ - const unsigned char *p1 = (const unsigned char *) s1; - const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - - if (p1 == p2) - return 0; - - do - { - c1 = TOLOWER (*p1); - c2 = TOLOWER (*p2); - - if (c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - if (UCHAR_MAX <= INT_MAX) - return c1 - c2; - else - /* On machines where 'char' and 'int' are types of the same size, the - difference of two 'unsigned char' values - including the sign bit - - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); -} diff --git a/grub-core/gnulib/strchrnul.c b/grub-core/gnulib/strchrnul.c deleted file mode 100644 index f6b072274..000000000 --- a/grub-core/gnulib/strchrnul.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Searching in a string. - Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -/* Find the first occurrence of C in S or the final NUL byte. */ -char * -strchrnul (const char *s, int c_in) -{ - /* On 32-bit hardware, choosing longword to be a 32-bit unsigned - long instead of a 64-bit uintmax_t tends to give better - performance. On 64-bit hardware, unsigned long is generally 64 - bits already. Change this typedef to experiment with - performance. */ - typedef unsigned long int longword; - - const unsigned char *char_ptr; - const longword *longword_ptr; - longword repeated_one; - longword repeated_c; - unsigned char c; - - c = (unsigned char) c_in; - if (!c) - return rawmemchr (s, 0); - - /* Handle the first few bytes by reading one byte at a time. - Do this until CHAR_PTR is aligned on a longword boundary. */ - for (char_ptr = (const unsigned char *) s; - (size_t) char_ptr % sizeof (longword) != 0; - ++char_ptr) - if (!*char_ptr || *char_ptr == c) - return (char *) char_ptr; - - longword_ptr = (const longword *) char_ptr; - - /* All these elucidatory comments refer to 4-byte longwords, - but the theory applies equally well to any size longwords. */ - - /* Compute auxiliary longword values: - repeated_one is a value which has a 1 in every byte. - repeated_c has c in every byte. */ - repeated_one = 0x01010101; - repeated_c = c | (c << 8); - repeated_c |= repeated_c << 16; - if (0xffffffffU < (longword) -1) - { - repeated_one |= repeated_one << 31 << 1; - repeated_c |= repeated_c << 31 << 1; - if (8 < sizeof (longword)) - { - size_t i; - - for (i = 64; i < sizeof (longword) * 8; i *= 2) - { - repeated_one |= repeated_one << i; - repeated_c |= repeated_c << i; - } - } - } - - /* Instead of the traditional loop which tests each byte, we will - test a longword at a time. The tricky part is testing if *any of - the four* bytes in the longword in question are equal to NUL or - c. We first use an xor with repeated_c. This reduces the task - to testing whether *any of the four* bytes in longword1 or - longword2 is zero. - - Let's consider longword1. We compute tmp = - ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). - That is, we perform the following operations: - 1. Subtract repeated_one. - 2. & ~longword1. - 3. & a mask consisting of 0x80 in every byte. - Consider what happens in each byte: - - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, - and step 3 transforms it into 0x80. A carry can also be propagated - to more significant bytes. - - If a byte of longword1 is nonzero, let its lowest 1 bit be at - position k (0 <= k <= 7); so the lowest k bits are 0. After step 1, - the byte ends in a single bit of value 0 and k bits of value 1. - After step 2, the result is just k bits of value 1: 2^k - 1. After - step 3, the result is 0. And no carry is produced. - So, if longword1 has only non-zero bytes, tmp is zero. - Whereas if longword1 has a zero byte, call j the position of the least - significant zero byte. Then the result has a zero at positions 0, ..., - j-1 and a 0x80 at position j. We cannot predict the result at the more - significant bytes (positions j+1..3), but it does not matter since we - already have a non-zero bit at position 8*j+7. - - The test whether any byte in longword1 or longword2 is zero is equivalent - to testing whether tmp1 is nonzero or tmp2 is nonzero. We can combine - this into a single test, whether (tmp1 | tmp2) is nonzero. - - This test can read more than one byte beyond the end of a string, - depending on where the terminating NUL is encountered. However, - this is considered safe since the initialization phase ensured - that the read will be aligned, therefore, the read will not cross - page boundaries and will not cause a fault. */ - - while (1) - { - longword longword1 = *longword_ptr ^ repeated_c; - longword longword2 = *longword_ptr; - - if (((((longword1 - repeated_one) & ~longword1) - | ((longword2 - repeated_one) & ~longword2)) - & (repeated_one << 7)) != 0) - break; - longword_ptr++; - } - - char_ptr = (const unsigned char *) longword_ptr; - - /* At this point, we know that one of the sizeof (longword) bytes - starting at char_ptr is == 0 or == c. On little-endian machines, - we could determine the first such byte without any further memory - accesses, just by looking at the tmp result from the last loop - iteration. But this does not work on big-endian machines. - Choose code that works in both cases. */ - - char_ptr = (unsigned char *) longword_ptr; - while (*char_ptr && (*char_ptr != c)) - char_ptr++; - return (char *) char_ptr; -} diff --git a/grub-core/gnulib/strchrnul.valgrind b/grub-core/gnulib/strchrnul.valgrind deleted file mode 100644 index b14fa1304..000000000 --- a/grub-core/gnulib/strchrnul.valgrind +++ /dev/null @@ -1,12 +0,0 @@ -# Suppress a valgrind message about use of uninitialized memory in strchrnul(). -# This use is OK because it provides only a speedup. -{ - strchrnul-value4 - Memcheck:Value4 - fun:strchrnul -} -{ - strchrnul-value8 - Memcheck:Value8 - fun:strchrnul -} diff --git a/grub-core/gnulib/streq.h b/grub-core/gnulib/streq.h deleted file mode 100644 index 12c1867c8..000000000 --- a/grub-core/gnulib/streq.h +++ /dev/null @@ -1,176 +0,0 @@ -/* Optimized string comparison. - Copyright (C) 2001-2002, 2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Bruno Haible . */ - -#ifndef _GL_STREQ_H -#define _GL_STREQ_H - -#include - -/* STREQ_OPT allows to optimize string comparison with a small literal string. - STREQ_OPT (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) - is semantically equivalent to - strcmp (s, "EUC-KR") == 0 - just faster. */ - -/* Help GCC to generate good code for string comparisons with - immediate strings. */ -#if defined (__GNUC__) && defined (__OPTIMIZE__) - -static inline int -streq9 (const char *s1, const char *s2) -{ - return strcmp (s1 + 9, s2 + 9) == 0; -} - -static inline int -streq8 (const char *s1, const char *s2, char s28) -{ - if (s1[8] == s28) - { - if (s28 == 0) - return 1; - else - return streq9 (s1, s2); - } - else - return 0; -} - -static inline int -streq7 (const char *s1, const char *s2, char s27, char s28) -{ - if (s1[7] == s27) - { - if (s27 == 0) - return 1; - else - return streq8 (s1, s2, s28); - } - else - return 0; -} - -static inline int -streq6 (const char *s1, const char *s2, char s26, char s27, char s28) -{ - if (s1[6] == s26) - { - if (s26 == 0) - return 1; - else - return streq7 (s1, s2, s27, s28); - } - else - return 0; -} - -static inline int -streq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) -{ - if (s1[5] == s25) - { - if (s25 == 0) - return 1; - else - return streq6 (s1, s2, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[4] == s24) - { - if (s24 == 0) - return 1; - else - return streq5 (s1, s2, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[3] == s23) - { - if (s23 == 0) - return 1; - else - return streq4 (s1, s2, s24, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[2] == s22) - { - if (s22 == 0) - return 1; - else - return streq3 (s1, s2, s23, s24, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[1] == s21) - { - if (s21 == 0) - return 1; - else - return streq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); - } - else - return 0; -} - -static inline int -streq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) -{ - if (s1[0] == s20) - { - if (s20 == 0) - return 1; - else - return streq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); - } - else - return 0; -} - -#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ - streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) - -#else - -#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ - (strcmp (s1, s2) == 0) - -#endif - -#endif /* _GL_STREQ_H */ diff --git a/grub-core/gnulib/strerror-override.c b/grub-core/gnulib/strerror-override.c deleted file mode 100644 index d0ed2fb86..000000000 --- a/grub-core/gnulib/strerror-override.c +++ /dev/null @@ -1,302 +0,0 @@ -/* strerror-override.c --- POSIX compatible system error routine - - Copyright (C) 2010-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Bruno Haible , 2010. */ - -#include - -#include "strerror-override.h" - -#include - -#if GNULIB_defined_EWINSOCK /* native Windows platforms */ -# if HAVE_WINSOCK2_H -# include -# endif -#endif - -/* If ERRNUM maps to an errno value defined by gnulib, return a string - describing the error. Otherwise return NULL. */ -const char * -strerror_override (int errnum) -{ - /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ - switch (errnum) - { -#if REPLACE_STRERROR_0 - case 0: - return "Success"; -#endif - -#if GNULIB_defined_ESOCK /* native Windows platforms with older */ - case EINPROGRESS: - return "Operation now in progress"; - case EALREADY: - return "Operation already in progress"; - case ENOTSOCK: - return "Socket operation on non-socket"; - case EDESTADDRREQ: - return "Destination address required"; - case EMSGSIZE: - return "Message too long"; - case EPROTOTYPE: - return "Protocol wrong type for socket"; - case ENOPROTOOPT: - return "Protocol not available"; - case EPROTONOSUPPORT: - return "Protocol not supported"; - case EOPNOTSUPP: - return "Operation not supported"; - case EAFNOSUPPORT: - return "Address family not supported by protocol"; - case EADDRINUSE: - return "Address already in use"; - case EADDRNOTAVAIL: - return "Cannot assign requested address"; - case ENETDOWN: - return "Network is down"; - case ENETUNREACH: - return "Network is unreachable"; - case ECONNRESET: - return "Connection reset by peer"; - case ENOBUFS: - return "No buffer space available"; - case EISCONN: - return "Transport endpoint is already connected"; - case ENOTCONN: - return "Transport endpoint is not connected"; - case ETIMEDOUT: - return "Connection timed out"; - case ECONNREFUSED: - return "Connection refused"; - case ELOOP: - return "Too many levels of symbolic links"; - case EHOSTUNREACH: - return "No route to host"; - case EWOULDBLOCK: - return "Operation would block"; -#endif -#if GNULIB_defined_ESTREAMS /* native Windows platforms with older */ - case ETXTBSY: - return "Text file busy"; - case ENODATA: - return "No data available"; - case ENOSR: - return "Out of streams resources"; - case ENOSTR: - return "Device not a stream"; - case ETIME: - return "Timer expired"; - case EOTHER: - return "Other error"; -#endif -#if GNULIB_defined_EWINSOCK /* native Windows platforms */ - case ESOCKTNOSUPPORT: - return "Socket type not supported"; - case EPFNOSUPPORT: - return "Protocol family not supported"; - case ESHUTDOWN: - return "Cannot send after transport endpoint shutdown"; - case ETOOMANYREFS: - return "Too many references: cannot splice"; - case EHOSTDOWN: - return "Host is down"; - case EPROCLIM: - return "Too many processes"; - case EUSERS: - return "Too many users"; - case EDQUOT: - return "Disk quota exceeded"; - case ESTALE: - return "Stale NFS file handle"; - case EREMOTE: - return "Object is remote"; -# if HAVE_WINSOCK2_H - /* WSA_INVALID_HANDLE maps to EBADF */ - /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ - /* WSA_INVALID_PARAMETER maps to EINVAL */ - case WSA_OPERATION_ABORTED: - return "Overlapped operation aborted"; - case WSA_IO_INCOMPLETE: - return "Overlapped I/O event object not in signaled state"; - case WSA_IO_PENDING: - return "Overlapped operations will complete later"; - /* WSAEINTR maps to EINTR */ - /* WSAEBADF maps to EBADF */ - /* WSAEACCES maps to EACCES */ - /* WSAEFAULT maps to EFAULT */ - /* WSAEINVAL maps to EINVAL */ - /* WSAEMFILE maps to EMFILE */ - /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ - /* WSAEINPROGRESS maps to EINPROGRESS */ - /* WSAEALREADY maps to EALREADY */ - /* WSAENOTSOCK maps to ENOTSOCK */ - /* WSAEDESTADDRREQ maps to EDESTADDRREQ */ - /* WSAEMSGSIZE maps to EMSGSIZE */ - /* WSAEPROTOTYPE maps to EPROTOTYPE */ - /* WSAENOPROTOOPT maps to ENOPROTOOPT */ - /* WSAEPROTONOSUPPORT maps to EPROTONOSUPPORT */ - /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ - /* WSAEOPNOTSUPP maps to EOPNOTSUPP */ - /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ - /* WSAEAFNOSUPPORT maps to EAFNOSUPPORT */ - /* WSAEADDRINUSE maps to EADDRINUSE */ - /* WSAEADDRNOTAVAIL maps to EADDRNOTAVAIL */ - /* WSAENETDOWN maps to ENETDOWN */ - /* WSAENETUNREACH maps to ENETUNREACH */ - /* WSAENETRESET maps to ENETRESET */ - /* WSAECONNABORTED maps to ECONNABORTED */ - /* WSAECONNRESET maps to ECONNRESET */ - /* WSAENOBUFS maps to ENOBUFS */ - /* WSAEISCONN maps to EISCONN */ - /* WSAENOTCONN maps to ENOTCONN */ - /* WSAESHUTDOWN is ESHUTDOWN */ - /* WSAETOOMANYREFS is ETOOMANYREFS */ - /* WSAETIMEDOUT maps to ETIMEDOUT */ - /* WSAECONNREFUSED maps to ECONNREFUSED */ - /* WSAELOOP maps to ELOOP */ - /* WSAENAMETOOLONG maps to ENAMETOOLONG */ - /* WSAEHOSTDOWN is EHOSTDOWN */ - /* WSAEHOSTUNREACH maps to EHOSTUNREACH */ - /* WSAENOTEMPTY maps to ENOTEMPTY */ - /* WSAEPROCLIM is EPROCLIM */ - /* WSAEUSERS is EUSERS */ - /* WSAEDQUOT is EDQUOT */ - /* WSAESTALE is ESTALE */ - /* WSAEREMOTE is EREMOTE */ - case WSASYSNOTREADY: - return "Network subsystem is unavailable"; - case WSAVERNOTSUPPORTED: - return "Winsock.dll version out of range"; - case WSANOTINITIALISED: - return "Successful WSAStartup not yet performed"; - case WSAEDISCON: - return "Graceful shutdown in progress"; - case WSAENOMORE: case WSA_E_NO_MORE: - return "No more results"; - case WSAECANCELLED: case WSA_E_CANCELLED: - return "Call was canceled"; - case WSAEINVALIDPROCTABLE: - return "Procedure call table is invalid"; - case WSAEINVALIDPROVIDER: - return "Service provider is invalid"; - case WSAEPROVIDERFAILEDINIT: - return "Service provider failed to initialize"; - case WSASYSCALLFAILURE: - return "System call failure"; - case WSASERVICE_NOT_FOUND: - return "Service not found"; - case WSATYPE_NOT_FOUND: - return "Class type not found"; - case WSAEREFUSED: - return "Database query was refused"; - case WSAHOST_NOT_FOUND: - return "Host not found"; - case WSATRY_AGAIN: - return "Nonauthoritative host not found"; - case WSANO_RECOVERY: - return "Nonrecoverable error"; - case WSANO_DATA: - return "Valid name, no data record of requested type"; - /* WSA_QOS_* omitted */ -# endif -#endif - -#if GNULIB_defined_ENOMSG - case ENOMSG: - return "No message of desired type"; -#endif - -#if GNULIB_defined_EIDRM - case EIDRM: - return "Identifier removed"; -#endif - -#if GNULIB_defined_ENOLINK - case ENOLINK: - return "Link has been severed"; -#endif - -#if GNULIB_defined_EPROTO - case EPROTO: - return "Protocol error"; -#endif - -#if GNULIB_defined_EMULTIHOP - case EMULTIHOP: - return "Multihop attempted"; -#endif - -#if GNULIB_defined_EBADMSG - case EBADMSG: - return "Bad message"; -#endif - -#if GNULIB_defined_EOVERFLOW - case EOVERFLOW: - return "Value too large for defined data type"; -#endif - -#if GNULIB_defined_ENOTSUP - case ENOTSUP: - return "Not supported"; -#endif - -#if GNULIB_defined_ENETRESET - case ENETRESET: - return "Network dropped connection on reset"; -#endif - -#if GNULIB_defined_ECONNABORTED - case ECONNABORTED: - return "Software caused connection abort"; -#endif - -#if GNULIB_defined_ESTALE - case ESTALE: - return "Stale NFS file handle"; -#endif - -#if GNULIB_defined_EDQUOT - case EDQUOT: - return "Disk quota exceeded"; -#endif - -#if GNULIB_defined_ECANCELED - case ECANCELED: - return "Operation canceled"; -#endif - -#if GNULIB_defined_EOWNERDEAD - case EOWNERDEAD: - return "Owner died"; -#endif - -#if GNULIB_defined_ENOTRECOVERABLE - case ENOTRECOVERABLE: - return "State not recoverable"; -#endif - -#if GNULIB_defined_EILSEQ - case EILSEQ: - return "Invalid or incomplete multibyte or wide character"; -#endif - - default: - return NULL; - } -} diff --git a/grub-core/gnulib/strerror-override.h b/grub-core/gnulib/strerror-override.h deleted file mode 100644 index 3b8f24b99..000000000 --- a/grub-core/gnulib/strerror-override.h +++ /dev/null @@ -1,56 +0,0 @@ -/* strerror-override.h --- POSIX compatible system error routine - - Copyright (C) 2010-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _GL_STRERROR_OVERRIDE_H -# define _GL_STRERROR_OVERRIDE_H - -# include -# include - -/* Reasonable buffer size that should never trigger ERANGE; if this - proves too small, we intentionally abort(), to remind us to fix - this value. */ -# define STACKBUF_LEN 256 - -/* If ERRNUM maps to an errno value defined by gnulib, return a string - describing the error. Otherwise return NULL. */ -# if REPLACE_STRERROR_0 \ - || GNULIB_defined_ESOCK \ - || GNULIB_defined_ESTREAMS \ - || GNULIB_defined_EWINSOCK \ - || GNULIB_defined_ENOMSG \ - || GNULIB_defined_EIDRM \ - || GNULIB_defined_ENOLINK \ - || GNULIB_defined_EPROTO \ - || GNULIB_defined_EMULTIHOP \ - || GNULIB_defined_EBADMSG \ - || GNULIB_defined_EOVERFLOW \ - || GNULIB_defined_ENOTSUP \ - || GNULIB_defined_ENETRESET \ - || GNULIB_defined_ECONNABORTED \ - || GNULIB_defined_ESTALE \ - || GNULIB_defined_EDQUOT \ - || GNULIB_defined_ECANCELED \ - || GNULIB_defined_EOWNERDEAD \ - || GNULIB_defined_ENOTRECOVERABLE \ - || GNULIB_defined_EILSEQ -extern const char *strerror_override (int errnum); -# else -# define strerror_override(ignored) NULL -# endif - -#endif /* _GL_STRERROR_OVERRIDE_H */ diff --git a/grub-core/gnulib/strerror.c b/grub-core/gnulib/strerror.c deleted file mode 100644 index 80a2f2eea..000000000 --- a/grub-core/gnulib/strerror.c +++ /dev/null @@ -1,70 +0,0 @@ -/* strerror.c --- POSIX compatible system error routine - - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#include -#include -#include -#include - -#include "intprops.h" -#include "strerror-override.h" -#include "verify.h" - -/* Use the system functions, not the gnulib overrides in this file. */ -#undef sprintf - -char * -strerror (int n) -#undef strerror -{ - static char buf[STACKBUF_LEN]; - size_t len; - - /* Cast away const, due to the historical signature of strerror; - callers should not be modifying the string. */ - const char *msg = strerror_override (n); - if (msg) - return (char *) msg; - - msg = strerror (n); - - /* Our strerror_r implementation might use the system's strerror - buffer, so all other clients of strerror have to see the error - copied into a buffer that we manage. This is not thread-safe, - even if the system strerror is, but portable programs shouldn't - be using strerror if they care about thread-safety. */ - if (!msg || !*msg) - { - static char const fmt[] = "Unknown error %d"; - verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n)); - sprintf (buf, fmt, n); - errno = EINVAL; - return buf; - } - - /* Fix STACKBUF_LEN if this ever aborts. */ - len = strlen (msg); - if (sizeof buf <= len) - abort (); - - return memcpy (buf, msg, len + 1); -} diff --git a/grub-core/gnulib/string.in.h b/grub-core/gnulib/string.in.h deleted file mode 100644 index d7a6c9c92..000000000 --- a/grub-core/gnulib/string.in.h +++ /dev/null @@ -1,1029 +0,0 @@ -/* A GNU-like . - - Copyright (C) 1995-1996, 2001-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _@GUARD_PREFIX@_STRING_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_STRING_H@ - -#ifndef _@GUARD_PREFIX@_STRING_H -#define _@GUARD_PREFIX@_STRING_H - -/* NetBSD 5.0 mis-defines NULL. */ -#include - -/* MirBSD defines mbslen as a macro. */ -#if @GNULIB_MBSLEN@ && defined __MirBSD__ -# include -#endif - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The attribute __pure__ was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -# define _GL_ATTRIBUTE_PURE /* empty */ -#endif - -/* NetBSD 5.0 declares strsignal in , not in . */ -/* But in any case avoid namespace pollution on glibc systems. */ -#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \ - && ! defined __GLIBC__ -# include -#endif - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - - -/* Find the index of the least-significant set bit. */ -#if @GNULIB_FFSL@ -# if !@HAVE_FFSL@ -_GL_FUNCDECL_SYS (ffsl, int, (long int i)); -# endif -_GL_CXXALIAS_SYS (ffsl, int, (long int i)); -_GL_CXXALIASWARN (ffsl); -#elif defined GNULIB_POSIXCHECK -# undef ffsl -# if HAVE_RAW_DECL_FFSL -_GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module"); -# endif -#endif - - -/* Find the index of the least-significant set bit. */ -#if @GNULIB_FFSLL@ -# if !@HAVE_FFSLL@ -_GL_FUNCDECL_SYS (ffsll, int, (long long int i)); -# endif -_GL_CXXALIAS_SYS (ffsll, int, (long long int i)); -_GL_CXXALIASWARN (ffsll); -#elif defined GNULIB_POSIXCHECK -# undef ffsll -# if HAVE_RAW_DECL_FFSLL -_GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module"); -# endif -#endif - - -/* Return the first instance of C within N bytes of S, or NULL. */ -#if @GNULIB_MEMCHR@ -# if @REPLACE_MEMCHR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define memchr rpl_memchr -# endif -_GL_FUNCDECL_RPL (memchr, void *, (void const *__s, int __c, size_t __n) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (memchr, void *, (void const *__s, int __c, size_t __n)); -# else -# if ! @HAVE_MEMCHR@ -_GL_FUNCDECL_SYS (memchr, void *, (void const *__s, int __c, size_t __n) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C" { const void * std::memchr (const void *, int, size_t); } - extern "C++" { void * std::memchr (void *, int, size_t); } */ -_GL_CXXALIAS_SYS_CAST2 (memchr, - void *, (void const *__s, int __c, size_t __n), - void const *, (void const *__s, int __c, size_t __n)); -# endif -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n)); -_GL_CXXALIASWARN1 (memchr, void const *, - (void const *__s, int __c, size_t __n)); -# else -_GL_CXXALIASWARN (memchr); -# endif -#elif defined GNULIB_POSIXCHECK -# undef memchr -/* Assume memchr is always declared. */ -_GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " - "use gnulib module memchr for portability" ); -#endif - -/* Return the first occurrence of NEEDLE in HAYSTACK. */ -#if @GNULIB_MEMMEM@ -# if @REPLACE_MEMMEM@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define memmem rpl_memmem -# endif -_GL_FUNCDECL_RPL (memmem, void *, - (void const *__haystack, size_t __haystack_len, - void const *__needle, size_t __needle_len) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 3))); -_GL_CXXALIAS_RPL (memmem, void *, - (void const *__haystack, size_t __haystack_len, - void const *__needle, size_t __needle_len)); -# else -# if ! @HAVE_DECL_MEMMEM@ -_GL_FUNCDECL_SYS (memmem, void *, - (void const *__haystack, size_t __haystack_len, - void const *__needle, size_t __needle_len) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 3))); -# endif -_GL_CXXALIAS_SYS (memmem, void *, - (void const *__haystack, size_t __haystack_len, - void const *__needle, size_t __needle_len)); -# endif -_GL_CXXALIASWARN (memmem); -#elif defined GNULIB_POSIXCHECK -# undef memmem -# if HAVE_RAW_DECL_MEMMEM -_GL_WARN_ON_USE (memmem, "memmem is unportable and often quadratic - " - "use gnulib module memmem-simple for portability, " - "and module memmem for speed" ); -# endif -#endif - -/* Copy N bytes of SRC to DEST, return pointer to bytes after the - last written byte. */ -#if @GNULIB_MEMPCPY@ -# if ! @HAVE_MEMPCPY@ -_GL_FUNCDECL_SYS (mempcpy, void *, - (void *restrict __dest, void const *restrict __src, - size_t __n) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (mempcpy, void *, - (void *restrict __dest, void const *restrict __src, - size_t __n)); -_GL_CXXALIASWARN (mempcpy); -#elif defined GNULIB_POSIXCHECK -# undef mempcpy -# if HAVE_RAW_DECL_MEMPCPY -_GL_WARN_ON_USE (mempcpy, "mempcpy is unportable - " - "use gnulib module mempcpy for portability"); -# endif -#endif - -/* Search backwards through a block for a byte (specified as an int). */ -#if @GNULIB_MEMRCHR@ -# if ! @HAVE_DECL_MEMRCHR@ -_GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { const void * std::memrchr (const void *, int, size_t); } - extern "C++" { void * std::memrchr (void *, int, size_t); } */ -_GL_CXXALIAS_SYS_CAST2 (memrchr, - void *, (void const *, int, size_t), - void const *, (void const *, int, size_t)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t)); -_GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t)); -# else -_GL_CXXALIASWARN (memrchr); -# endif -#elif defined GNULIB_POSIXCHECK -# undef memrchr -# if HAVE_RAW_DECL_MEMRCHR -_GL_WARN_ON_USE (memrchr, "memrchr is unportable - " - "use gnulib module memrchr for portability"); -# endif -#endif - -/* Find the first occurrence of C in S. More efficient than - memchr(S,C,N), at the expense of undefined behavior if C does not - occur within N bytes. */ -#if @GNULIB_RAWMEMCHR@ -# if ! @HAVE_RAWMEMCHR@ -_GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { const void * std::rawmemchr (const void *, int); } - extern "C++" { void * std::rawmemchr (void *, int); } */ -_GL_CXXALIAS_SYS_CAST2 (rawmemchr, - void *, (void const *__s, int __c_in), - void const *, (void const *__s, int __c_in)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in)); -_GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in)); -# else -_GL_CXXALIASWARN (rawmemchr); -# endif -#elif defined GNULIB_POSIXCHECK -# undef rawmemchr -# if HAVE_RAW_DECL_RAWMEMCHR -_GL_WARN_ON_USE (rawmemchr, "rawmemchr is unportable - " - "use gnulib module rawmemchr for portability"); -# endif -#endif - -/* Copy SRC to DST, returning the address of the terminating '\0' in DST. */ -#if @GNULIB_STPCPY@ -# if ! @HAVE_STPCPY@ -_GL_FUNCDECL_SYS (stpcpy, char *, - (char *restrict __dst, char const *restrict __src) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (stpcpy, char *, - (char *restrict __dst, char const *restrict __src)); -_GL_CXXALIASWARN (stpcpy); -#elif defined GNULIB_POSIXCHECK -# undef stpcpy -# if HAVE_RAW_DECL_STPCPY -_GL_WARN_ON_USE (stpcpy, "stpcpy is unportable - " - "use gnulib module stpcpy for portability"); -# endif -#endif - -/* Copy no more than N bytes of SRC to DST, returning a pointer past the - last non-NUL byte written into DST. */ -#if @GNULIB_STPNCPY@ -# if @REPLACE_STPNCPY@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef stpncpy -# define stpncpy rpl_stpncpy -# endif -_GL_FUNCDECL_RPL (stpncpy, char *, - (char *restrict __dst, char const *restrict __src, - size_t __n) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (stpncpy, char *, - (char *restrict __dst, char const *restrict __src, - size_t __n)); -# else -# if ! @HAVE_STPNCPY@ -_GL_FUNCDECL_SYS (stpncpy, char *, - (char *restrict __dst, char const *restrict __src, - size_t __n) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (stpncpy, char *, - (char *restrict __dst, char const *restrict __src, - size_t __n)); -# endif -_GL_CXXALIASWARN (stpncpy); -#elif defined GNULIB_POSIXCHECK -# undef stpncpy -# if HAVE_RAW_DECL_STPNCPY -_GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " - "use gnulib module stpncpy for portability"); -# endif -#endif - -#if defined GNULIB_POSIXCHECK -/* strchr() does not work with multibyte strings if the locale encoding is - GB18030 and the character to be searched is a digit. */ -# undef strchr -/* Assume strchr is always declared. */ -_GL_WARN_ON_USE (strchr, "strchr cannot work correctly on character strings " - "in some multibyte locales - " - "use mbschr if you care about internationalization"); -#endif - -/* Find the first occurrence of C in S or the final NUL byte. */ -#if @GNULIB_STRCHRNUL@ -# if @REPLACE_STRCHRNUL@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define strchrnul rpl_strchrnul -# endif -_GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strchrnul, char *, - (const char *str, int ch)); -# else -# if ! @HAVE_STRCHRNUL@ -_GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { const char * std::strchrnul (const char *, int); } - extern "C++" { char * std::strchrnul (char *, int); } */ -_GL_CXXALIAS_SYS_CAST2 (strchrnul, - char *, (char const *__s, int __c_in), - char const *, (char const *__s, int __c_in)); -# endif -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in)); -_GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in)); -# else -_GL_CXXALIASWARN (strchrnul); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strchrnul -# if HAVE_RAW_DECL_STRCHRNUL -_GL_WARN_ON_USE (strchrnul, "strchrnul is unportable - " - "use gnulib module strchrnul for portability"); -# endif -#endif - -/* Duplicate S, returning an identical malloc'd string. */ -#if @GNULIB_STRDUP@ -# if @REPLACE_STRDUP@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strdup -# define strdup rpl_strdup -# endif -_GL_FUNCDECL_RPL (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strdup, char *, (char const *__s)); -# else -# if defined __cplusplus && defined GNULIB_NAMESPACE && defined strdup - /* strdup exists as a function and as a macro. Get rid of the macro. */ -# undef strdup -# endif -# if !(@HAVE_DECL_STRDUP@ || defined strdup) -_GL_FUNCDECL_SYS (strdup, char *, (char const *__s) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (strdup, char *, (char const *__s)); -# endif -_GL_CXXALIASWARN (strdup); -#elif defined GNULIB_POSIXCHECK -# undef strdup -# if HAVE_RAW_DECL_STRDUP -_GL_WARN_ON_USE (strdup, "strdup is unportable - " - "use gnulib module strdup for portability"); -# endif -#endif - -/* Append no more than N characters from SRC onto DEST. */ -#if @GNULIB_STRNCAT@ -# if @REPLACE_STRNCAT@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strncat -# define strncat rpl_strncat -# endif -_GL_FUNCDECL_RPL (strncat, char *, (char *dest, const char *src, size_t n) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n)); -# else -_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n)); -# endif -_GL_CXXALIASWARN (strncat); -#elif defined GNULIB_POSIXCHECK -# undef strncat -# if HAVE_RAW_DECL_STRNCAT -_GL_WARN_ON_USE (strncat, "strncat is unportable - " - "use gnulib module strncat for portability"); -# endif -#endif - -/* Return a newly allocated copy of at most N bytes of STRING. */ -#if @GNULIB_STRNDUP@ -# if @REPLACE_STRNDUP@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strndup -# define strndup rpl_strndup -# endif -_GL_FUNCDECL_RPL (strndup, char *, (char const *__string, size_t __n) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strndup, char *, (char const *__string, size_t __n)); -# else -# if ! @HAVE_DECL_STRNDUP@ -_GL_FUNCDECL_SYS (strndup, char *, (char const *__string, size_t __n) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (strndup, char *, (char const *__string, size_t __n)); -# endif -_GL_CXXALIASWARN (strndup); -#elif defined GNULIB_POSIXCHECK -# undef strndup -# if HAVE_RAW_DECL_STRNDUP -_GL_WARN_ON_USE (strndup, "strndup is unportable - " - "use gnulib module strndup for portability"); -# endif -#endif - -/* Find the length (number of bytes) of STRING, but scan at most - MAXLEN bytes. If no '\0' terminator is found in that many bytes, - return MAXLEN. */ -#if @GNULIB_STRNLEN@ -# if @REPLACE_STRNLEN@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strnlen -# define strnlen rpl_strnlen -# endif -_GL_FUNCDECL_RPL (strnlen, size_t, (char const *__string, size_t __maxlen) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (strnlen, size_t, (char const *__string, size_t __maxlen)); -# else -# if ! @HAVE_DECL_STRNLEN@ -_GL_FUNCDECL_SYS (strnlen, size_t, (char const *__string, size_t __maxlen) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (strnlen, size_t, (char const *__string, size_t __maxlen)); -# endif -_GL_CXXALIASWARN (strnlen); -#elif defined GNULIB_POSIXCHECK -# undef strnlen -# if HAVE_RAW_DECL_STRNLEN -_GL_WARN_ON_USE (strnlen, "strnlen is unportable - " - "use gnulib module strnlen for portability"); -# endif -#endif - -#if defined GNULIB_POSIXCHECK -/* strcspn() assumes the second argument is a list of single-byte characters. - Even in this simple case, it does not work with multibyte strings if the - locale encoding is GB18030 and one of the characters to be searched is a - digit. */ -# undef strcspn -/* Assume strcspn is always declared. */ -_GL_WARN_ON_USE (strcspn, "strcspn cannot work correctly on character strings " - "in multibyte locales - " - "use mbscspn if you care about internationalization"); -#endif - -/* Find the first occurrence in S of any character in ACCEPT. */ -#if @GNULIB_STRPBRK@ -# if ! @HAVE_STRPBRK@ -_GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2))); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C" { const char * strpbrk (const char *, const char *); } - extern "C++" { char * strpbrk (char *, const char *); } */ -_GL_CXXALIAS_SYS_CAST2 (strpbrk, - char *, (char const *__s, char const *__accept), - const char *, (char const *__s, char const *__accept)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept)); -_GL_CXXALIASWARN1 (strpbrk, char const *, - (char const *__s, char const *__accept)); -# else -_GL_CXXALIASWARN (strpbrk); -# endif -# if defined GNULIB_POSIXCHECK -/* strpbrk() assumes the second argument is a list of single-byte characters. - Even in this simple case, it does not work with multibyte strings if the - locale encoding is GB18030 and one of the characters to be searched is a - digit. */ -# undef strpbrk -_GL_WARN_ON_USE (strpbrk, "strpbrk cannot work correctly on character strings " - "in multibyte locales - " - "use mbspbrk if you care about internationalization"); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strpbrk -# if HAVE_RAW_DECL_STRPBRK -_GL_WARN_ON_USE (strpbrk, "strpbrk is unportable - " - "use gnulib module strpbrk for portability"); -# endif -#endif - -#if defined GNULIB_POSIXCHECK -/* strspn() assumes the second argument is a list of single-byte characters. - Even in this simple case, it cannot work with multibyte strings. */ -# undef strspn -/* Assume strspn is always declared. */ -_GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " - "in multibyte locales - " - "use mbsspn if you care about internationalization"); -#endif - -#if defined GNULIB_POSIXCHECK -/* strrchr() does not work with multibyte strings if the locale encoding is - GB18030 and the character to be searched is a digit. */ -# undef strrchr -/* Assume strrchr is always declared. */ -_GL_WARN_ON_USE (strrchr, "strrchr cannot work correctly on character strings " - "in some multibyte locales - " - "use mbsrchr if you care about internationalization"); -#endif - -/* Search the next delimiter (char listed in DELIM) starting at *STRINGP. - If one is found, overwrite it with a NUL, and advance *STRINGP - to point to the next char after it. Otherwise, set *STRINGP to NULL. - If *STRINGP was already NULL, nothing happens. - Return the old value of *STRINGP. - - This is a variant of strtok() that is multithread-safe and supports - empty fields. - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - Caveat: It doesn't work with multibyte strings unless all of the delimiter - characters are ASCII characters < 0x30. - - See also strtok_r(). */ -#if @GNULIB_STRSEP@ -# if ! @HAVE_STRSEP@ -_GL_FUNCDECL_SYS (strsep, char *, - (char **restrict __stringp, char const *restrict __delim) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (strsep, char *, - (char **restrict __stringp, char const *restrict __delim)); -_GL_CXXALIASWARN (strsep); -# if defined GNULIB_POSIXCHECK -# undef strsep -_GL_WARN_ON_USE (strsep, "strsep cannot work correctly on character strings " - "in multibyte locales - " - "use mbssep if you care about internationalization"); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strsep -# if HAVE_RAW_DECL_STRSEP -_GL_WARN_ON_USE (strsep, "strsep is unportable - " - "use gnulib module strsep for portability"); -# endif -#endif - -#if @GNULIB_STRSTR@ -# if @REPLACE_STRSTR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define strstr rpl_strstr -# endif -_GL_FUNCDECL_RPL (strstr, char *, (const char *haystack, const char *needle) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (strstr, char *, (const char *haystack, const char *needle)); -# else - /* On some systems, this function is defined as an overloaded function: - extern "C++" { const char * strstr (const char *, const char *); } - extern "C++" { char * strstr (char *, const char *); } */ -_GL_CXXALIAS_SYS_CAST2 (strstr, - char *, (const char *haystack, const char *needle), - const char *, (const char *haystack, const char *needle)); -# endif -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle)); -_GL_CXXALIASWARN1 (strstr, const char *, - (const char *haystack, const char *needle)); -# else -_GL_CXXALIASWARN (strstr); -# endif -#elif defined GNULIB_POSIXCHECK -/* strstr() does not work with multibyte strings if the locale encoding is - different from UTF-8: - POSIX says that it operates on "strings", and "string" in POSIX is defined - as a sequence of bytes, not of characters. */ -# undef strstr -/* Assume strstr is always declared. */ -_GL_WARN_ON_USE (strstr, "strstr is quadratic on many systems, and cannot " - "work correctly on character strings in most " - "multibyte locales - " - "use mbsstr if you care about internationalization, " - "or use strstr if you care about speed"); -#endif - -/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive - comparison. */ -#if @GNULIB_STRCASESTR@ -# if @REPLACE_STRCASESTR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define strcasestr rpl_strcasestr -# endif -_GL_FUNCDECL_RPL (strcasestr, char *, - (const char *haystack, const char *needle) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (strcasestr, char *, - (const char *haystack, const char *needle)); -# else -# if ! @HAVE_STRCASESTR@ -_GL_FUNCDECL_SYS (strcasestr, char *, - (const char *haystack, const char *needle) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2))); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { const char * strcasestr (const char *, const char *); } - extern "C++" { char * strcasestr (char *, const char *); } */ -_GL_CXXALIAS_SYS_CAST2 (strcasestr, - char *, (const char *haystack, const char *needle), - const char *, (const char *haystack, const char *needle)); -# endif -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle)); -_GL_CXXALIASWARN1 (strcasestr, const char *, - (const char *haystack, const char *needle)); -# else -_GL_CXXALIASWARN (strcasestr); -# endif -#elif defined GNULIB_POSIXCHECK -/* strcasestr() does not work with multibyte strings: - It is a glibc extension, and glibc implements it only for unibyte - locales. */ -# undef strcasestr -# if HAVE_RAW_DECL_STRCASESTR -_GL_WARN_ON_USE (strcasestr, "strcasestr does work correctly on character " - "strings in multibyte locales - " - "use mbscasestr if you care about " - "internationalization, or use c-strcasestr if you want " - "a locale independent function"); -# endif -#endif - -/* Parse S into tokens separated by characters in DELIM. - If S is NULL, the saved pointer in SAVE_PTR is used as - the next starting point. For example: - char s[] = "-abc-=-def"; - char *sp; - x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = strtok_r(NULL, "=", &sp); // x = NULL - // s = "abc\0-def\0" - - This is a variant of strtok() that is multithread-safe. - - For the POSIX documentation for this function, see: - http://www.opengroup.org/susv3xsh/strtok.html - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - Caveat: It doesn't work with multibyte strings unless all of the delimiter - characters are ASCII characters < 0x30. - - See also strsep(). */ -#if @GNULIB_STRTOK_R@ -# if @REPLACE_STRTOK_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strtok_r -# define strtok_r rpl_strtok_r -# endif -_GL_FUNCDECL_RPL (strtok_r, char *, - (char *restrict s, char const *restrict delim, - char **restrict save_ptr) - _GL_ARG_NONNULL ((2, 3))); -_GL_CXXALIAS_RPL (strtok_r, char *, - (char *restrict s, char const *restrict delim, - char **restrict save_ptr)); -# else -# if @UNDEFINE_STRTOK_R@ || defined GNULIB_POSIXCHECK -# undef strtok_r -# endif -# if ! @HAVE_DECL_STRTOK_R@ -_GL_FUNCDECL_SYS (strtok_r, char *, - (char *restrict s, char const *restrict delim, - char **restrict save_ptr) - _GL_ARG_NONNULL ((2, 3))); -# endif -_GL_CXXALIAS_SYS (strtok_r, char *, - (char *restrict s, char const *restrict delim, - char **restrict save_ptr)); -# endif -_GL_CXXALIASWARN (strtok_r); -# if defined GNULIB_POSIXCHECK -_GL_WARN_ON_USE (strtok_r, "strtok_r cannot work correctly on character " - "strings in multibyte locales - " - "use mbstok_r if you care about internationalization"); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strtok_r -# if HAVE_RAW_DECL_STRTOK_R -_GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " - "use gnulib module strtok_r for portability"); -# endif -#endif - - -/* The following functions are not specified by POSIX. They are gnulib - extensions. */ - -#if @GNULIB_MBSLEN@ -/* Return the number of multibyte characters in the character string STRING. - This considers multibyte characters, unlike strlen, which counts bytes. */ -# ifdef __MirBSD__ /* MirBSD defines mbslen as a macro. Override it. */ -# undef mbslen -# endif -# if @HAVE_MBSLEN@ /* AIX, OSF/1, MirBSD define mbslen already in libc. */ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define mbslen rpl_mbslen -# endif -_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (mbslen, size_t, (const char *string)); -# else -_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_SYS (mbslen, size_t, (const char *string)); -# endif -_GL_CXXALIASWARN (mbslen); -#endif - -#if @GNULIB_MBSNLEN@ -/* Return the number of multibyte characters in the character string starting - at STRING and ending at STRING + LEN. */ -_GL_EXTERN_C size_t mbsnlen (const char *string, size_t len) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1)); -#endif - -#if @GNULIB_MBSCHR@ -/* Locate the first single-byte character C in the character string STRING, - and return a pointer to it. Return NULL if C is not found in STRING. - Unlike strchr(), this function works correctly in multibyte locales with - encodings such as GB18030. */ -# if defined __hpux -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define mbschr rpl_mbschr /* avoid collision with HP-UX function */ -# endif -_GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c)); -# else -_GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c)); -# endif -_GL_CXXALIASWARN (mbschr); -#endif - -#if @GNULIB_MBSRCHR@ -/* Locate the last single-byte character C in the character string STRING, - and return a pointer to it. Return NULL if C is not found in STRING. - Unlike strrchr(), this function works correctly in multibyte locales with - encodings such as GB18030. */ -# if defined __hpux || defined __INTERIX -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define mbsrchr rpl_mbsrchr /* avoid collision with system function */ -# endif -_GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c)); -# else -_GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c)); -# endif -_GL_CXXALIASWARN (mbsrchr); -#endif - -#if @GNULIB_MBSSTR@ -/* Find the first occurrence of the character string NEEDLE in the character - string HAYSTACK. Return NULL if NEEDLE is not found in HAYSTACK. - Unlike strstr(), this function works correctly in multibyte locales with - encodings different from UTF-8. */ -_GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSCASECMP@ -/* Compare the character strings S1 and S2, ignoring case, returning less than, - equal to or greater than zero if S1 is lexicographically less than, equal to - or greater than S2. - Note: This function may, in multibyte locales, return 0 for strings of - different lengths! - Unlike strcasecmp(), this function works correctly in multibyte locales. */ -_GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSNCASECMP@ -/* Compare the initial segment of the character string S1 consisting of at most - N characters with the initial segment of the character string S2 consisting - of at most N characters, ignoring case, returning less than, equal to or - greater than zero if the initial segment of S1 is lexicographically less - than, equal to or greater than the initial segment of S2. - Note: This function may, in multibyte locales, return 0 for initial segments - of different lengths! - Unlike strncasecmp(), this function works correctly in multibyte locales. - But beware that N is not a byte count but a character count! */ -_GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSPCASECMP@ -/* Compare the initial segment of the character string STRING consisting of - at most mbslen (PREFIX) characters with the character string PREFIX, - ignoring case. If the two match, return a pointer to the first byte - after this prefix in STRING. Otherwise, return NULL. - Note: This function may, in multibyte locales, return non-NULL if STRING - is of smaller length than PREFIX! - Unlike strncasecmp(), this function works correctly in multibyte - locales. */ -_GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSCASESTR@ -/* Find the first occurrence of the character string NEEDLE in the character - string HAYSTACK, using case-insensitive comparison. - Note: This function may, in multibyte locales, return success even if - strlen (haystack) < strlen (needle) ! - Unlike strcasestr(), this function works correctly in multibyte locales. */ -_GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSCSPN@ -/* Find the first occurrence in the character string STRING of any character - in the character string ACCEPT. Return the number of bytes from the - beginning of the string to this occurrence, or to the end of the string - if none exists. - Unlike strcspn(), this function works correctly in multibyte locales. */ -_GL_EXTERN_C size_t mbscspn (const char *string, const char *accept) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSPBRK@ -/* Find the first occurrence in the character string STRING of any character - in the character string ACCEPT. Return the pointer to it, or NULL if none - exists. - Unlike strpbrk(), this function works correctly in multibyte locales. */ -# if defined __hpux -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ -# endif -_GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept)); -# else -_GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept)); -# endif -_GL_CXXALIASWARN (mbspbrk); -#endif - -#if @GNULIB_MBSSPN@ -/* Find the first occurrence in the character string STRING of any character - not in the character string REJECT. Return the number of bytes from the - beginning of the string to this occurrence, or to the end of the string - if none exists. - Unlike strspn(), this function works correctly in multibyte locales. */ -_GL_EXTERN_C size_t mbsspn (const char *string, const char *reject) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSSEP@ -/* Search the next delimiter (multibyte character listed in the character - string DELIM) starting at the character string *STRINGP. - If one is found, overwrite it with a NUL, and advance *STRINGP to point - to the next multibyte character after it. Otherwise, set *STRINGP to NULL. - If *STRINGP was already NULL, nothing happens. - Return the old value of *STRINGP. - - This is a variant of mbstok_r() that supports empty fields. - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - - See also mbstok_r(). */ -_GL_EXTERN_C char * mbssep (char **stringp, const char *delim) - _GL_ARG_NONNULL ((1, 2)); -#endif - -#if @GNULIB_MBSTOK_R@ -/* Parse the character string STRING into tokens separated by characters in - the character string DELIM. - If STRING is NULL, the saved pointer in SAVE_PTR is used as - the next starting point. For example: - char s[] = "-abc-=-def"; - char *sp; - x = mbstok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = mbstok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = mbstok_r(NULL, "=", &sp); // x = NULL - // s = "abc\0-def\0" - - Caveat: It modifies the original string. - Caveat: These functions cannot be used on constant strings. - Caveat: The identity of the delimiting character is lost. - - See also mbssep(). */ -_GL_EXTERN_C char * mbstok_r (char *string, const char *delim, char **save_ptr) - _GL_ARG_NONNULL ((2, 3)); -#endif - -/* Map any int, typically from errno, into an error message. */ -#if @GNULIB_STRERROR@ -# if @REPLACE_STRERROR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strerror -# define strerror rpl_strerror -# endif -_GL_FUNCDECL_RPL (strerror, char *, (int)); -_GL_CXXALIAS_RPL (strerror, char *, (int)); -# else -_GL_CXXALIAS_SYS (strerror, char *, (int)); -# endif -_GL_CXXALIASWARN (strerror); -#elif defined GNULIB_POSIXCHECK -# undef strerror -/* Assume strerror is always declared. */ -_GL_WARN_ON_USE (strerror, "strerror is unportable - " - "use gnulib module strerror to guarantee non-NULL result"); -#endif - -/* Map any int, typically from errno, into an error message. Multithread-safe. - Uses the POSIX declaration, not the glibc declaration. */ -#if @GNULIB_STRERROR_R@ -# if @REPLACE_STRERROR_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef strerror_r -# define strerror_r rpl_strerror_r -# endif -_GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)); -# else -# if !@HAVE_DECL_STRERROR_R@ -_GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)); -# endif -# if @HAVE_DECL_STRERROR_R@ -_GL_CXXALIASWARN (strerror_r); -# endif -#elif defined GNULIB_POSIXCHECK -# undef strerror_r -# if HAVE_RAW_DECL_STRERROR_R -_GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - " - "use gnulib module strerror_r-posix for portability"); -# endif -#endif - -#if @GNULIB_STRSIGNAL@ -# if @REPLACE_STRSIGNAL@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define strsignal rpl_strsignal -# endif -_GL_FUNCDECL_RPL (strsignal, char *, (int __sig)); -_GL_CXXALIAS_RPL (strsignal, char *, (int __sig)); -# else -# if ! @HAVE_DECL_STRSIGNAL@ -_GL_FUNCDECL_SYS (strsignal, char *, (int __sig)); -# endif -/* Need to cast, because on Cygwin 1.5.x systems, the return type is - 'const char *'. */ -_GL_CXXALIAS_SYS_CAST (strsignal, char *, (int __sig)); -# endif -_GL_CXXALIASWARN (strsignal); -#elif defined GNULIB_POSIXCHECK -# undef strsignal -# if HAVE_RAW_DECL_STRSIGNAL -_GL_WARN_ON_USE (strsignal, "strsignal is unportable - " - "use gnulib module strsignal for portability"); -# endif -#endif - -#if @GNULIB_STRVERSCMP@ -# if !@HAVE_STRVERSCMP@ -_GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *) - _GL_ATTRIBUTE_PURE - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *)); -_GL_CXXALIASWARN (strverscmp); -#elif defined GNULIB_POSIXCHECK -# undef strverscmp -# if HAVE_RAW_DECL_STRVERSCMP -_GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " - "use gnulib module strverscmp for portability"); -# endif -#endif - - -#endif /* _@GUARD_PREFIX@_STRING_H */ -#endif /* _@GUARD_PREFIX@_STRING_H */ diff --git a/grub-core/gnulib/strings.in.h b/grub-core/gnulib/strings.in.h deleted file mode 100644 index 4469f86ca..000000000 --- a/grub-core/gnulib/strings.in.h +++ /dev/null @@ -1,122 +0,0 @@ -/* A substitute . - - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _@GUARD_PREFIX@_STRINGS_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* Minix 3.1.8 has a bug: must be included before . - But avoid namespace pollution on glibc systems. */ -#if defined __minix && !defined __GLIBC__ -# include -#endif - -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_STRINGS_H@ -# @INCLUDE_NEXT@ @NEXT_STRINGS_H@ -#endif - -#ifndef _@GUARD_PREFIX@_STRINGS_H -#define _@GUARD_PREFIX@_STRINGS_H - -#if ! @HAVE_DECL_STRNCASECMP@ -/* Get size_t. */ -# include -#endif - - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - -#ifdef __cplusplus -extern "C" { -#endif - - - /* Find the index of the least-significant set bit. */ -#if @GNULIB_FFS@ -# if !@HAVE_FFS@ -_GL_FUNCDECL_SYS (ffs, int, (int i)); -# endif -_GL_CXXALIAS_SYS (ffs, int, (int i)); -_GL_CXXALIASWARN (ffs); -#elif defined GNULIB_POSIXCHECK -# undef ffs -# if HAVE_RAW_DECL_FFS -_GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module"); -# endif -#endif - -/* Compare strings S1 and S2, ignoring case, returning less than, equal to or - greater than zero if S1 is lexicographically less than, equal to or greater - than S2. - Note: This function does not work in multibyte locales. */ -#if ! @HAVE_STRCASECMP@ -extern int strcasecmp (char const *s1, char const *s2) - _GL_ARG_NONNULL ((1, 2)); -#endif -#if defined GNULIB_POSIXCHECK -/* strcasecmp() does not work with multibyte strings: - POSIX says that it operates on "strings", and "string" in POSIX is defined - as a sequence of bytes, not of characters. */ -# undef strcasecmp -# if HAVE_RAW_DECL_STRCASECMP -_GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character " - "strings in multibyte locales - " - "use mbscasecmp if you care about " - "internationalization, or use c_strcasecmp , " - "gnulib module c-strcase) if you want a locale " - "independent function"); -# endif -#endif - -/* Compare no more than N bytes of strings S1 and S2, ignoring case, - returning less than, equal to or greater than zero if S1 is - lexicographically less than, equal to or greater than S2. - Note: This function cannot work correctly in multibyte locales. */ -#if ! @HAVE_DECL_STRNCASECMP@ -extern int strncasecmp (char const *s1, char const *s2, size_t n) - _GL_ARG_NONNULL ((1, 2)); -#endif -#if defined GNULIB_POSIXCHECK -/* strncasecmp() does not work with multibyte strings: - POSIX says that it operates on "strings", and "string" in POSIX is defined - as a sequence of bytes, not of characters. */ -# undef strncasecmp -# if HAVE_RAW_DECL_STRNCASECMP -_GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " - "strings in multibyte locales - " - "use mbsncasecmp or mbspcasecmp if you care about " - "internationalization, or use c_strncasecmp , " - "gnulib module c-strcase) if you want a locale " - "independent function"); -# endif -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* _@GUARD_PREFIX@_STRING_H */ -#endif /* _@GUARD_PREFIX@_STRING_H */ diff --git a/grub-core/gnulib/stripslash.c b/grub-core/gnulib/stripslash.c deleted file mode 100644 index 0e452a95e..000000000 --- a/grub-core/gnulib/stripslash.c +++ /dev/null @@ -1,45 +0,0 @@ -/* stripslash.c -- remove redundant trailing slashes from a file name - - Copyright (C) 1990, 2001, 2003-2006, 2009-2013 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -#include "dirname.h" - -/* Remove trailing slashes from FILE. Return true if a trailing slash - was removed. This is useful when using file name completion from a - shell that adds a "/" after directory names (such as tcsh and - bash), because on symlinks to directories, several system calls - have different semantics according to whether a trailing slash is - present. */ - -bool -strip_trailing_slashes (char *file) -{ - char *base = last_component (file); - char *base_lim; - bool had_slash; - - /* last_component returns "" for file system roots, but we need to turn - "///" into "/". */ - if (! *base) - base = file; - base_lim = base + base_len (base); - had_slash = (*base_lim != '\0'); - *base_lim = '\0'; - return had_slash; -} diff --git a/grub-core/gnulib/strncasecmp.c b/grub-core/gnulib/strncasecmp.c deleted file mode 100644 index 35840bc01..000000000 --- a/grub-core/gnulib/strncasecmp.c +++ /dev/null @@ -1,62 +0,0 @@ -/* strncasecmp.c -- case insensitive string comparator - Copyright (C) 1998-1999, 2005-2007, 2009-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#include - -/* Specification. */ -#include - -#include -#include - -#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) - -/* Compare no more than N bytes of strings S1 and S2, ignoring case, - returning less than, equal to or greater than zero if S1 is - lexicographically less than, equal to or greater than S2. - Note: This function cannot work correctly in multibyte locales. */ - -int -strncasecmp (const char *s1, const char *s2, size_t n) -{ - register const unsigned char *p1 = (const unsigned char *) s1; - register const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - - if (p1 == p2 || n == 0) - return 0; - - do - { - c1 = TOLOWER (*p1); - c2 = TOLOWER (*p2); - - if (--n == 0 || c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - if (UCHAR_MAX <= INT_MAX) - return c1 - c2; - else - /* On machines where 'char' and 'int' are types of the same size, the - difference of two 'unsigned char' values - including the sign bit - - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); -} diff --git a/grub-core/gnulib/strndup.c b/grub-core/gnulib/strndup.c deleted file mode 100644 index e60268b86..000000000 --- a/grub-core/gnulib/strndup.c +++ /dev/null @@ -1,36 +0,0 @@ -/* A replacement function, for systems that lack strndup. - - Copyright (C) 1996-1998, 2001-2003, 2005-2007, 2009-2013 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, 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 - -char * -strndup (char const *s, size_t n) -{ - size_t len = strnlen (s, n); - char *new = malloc (len + 1); - - if (new == NULL) - return NULL; - - new[len] = '\0'; - return memcpy (new, s, len); -} diff --git a/grub-core/gnulib/strnlen.c b/grub-core/gnulib/strnlen.c deleted file mode 100644 index 57fdfe770..000000000 --- a/grub-core/gnulib/strnlen.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Find the length of STRING, but scan at most MAXLEN characters. - Copyright (C) 2005-2007, 2009-2013 Free Software Foundation, Inc. - Written by Simon Josefsson. - - 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, 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 - -/* Find the length of STRING, but scan at most MAXLEN characters. - If no '\0' terminator is found in that many characters, return MAXLEN. */ - -size_t -strnlen (const char *string, size_t maxlen) -{ - const char *end = memchr (string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} diff --git a/grub-core/gnulib/strnlen1.c b/grub-core/gnulib/strnlen1.c deleted file mode 100644 index 0c22d21ed..000000000 --- a/grub-core/gnulib/strnlen1.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include "strnlen1.h" - -#include - -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - If no '\0' terminator is found in that many characters, return MAXLEN. */ -/* This is the same as strnlen (string, maxlen - 1) + 1. */ -size_t -strnlen1 (const char *string, size_t maxlen) -{ - const char *end = (const char *) memchr (string, '\0', maxlen); - if (end != NULL) - return end - string + 1; - else - return maxlen; -} diff --git a/grub-core/gnulib/strnlen1.h b/grub-core/gnulib/strnlen1.h deleted file mode 100644 index 7c65e3161..000000000 --- a/grub-core/gnulib/strnlen1.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - Copyright (C) 2005, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _STRNLEN1_H -#define _STRNLEN1_H - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Find the length of STRING + 1, but scan at most MAXLEN bytes. - If no '\0' terminator is found in that many characters, return MAXLEN. */ -/* This is the same as strnlen (string, maxlen - 1) + 1. */ -extern size_t strnlen1 (const char *string, size_t maxlen) - _GL_ATTRIBUTE_PURE; - - -#ifdef __cplusplus -} -#endif - - -#endif /* _STRNLEN1_H */ diff --git a/grub-core/gnulib/sys_types.in.h b/grub-core/gnulib/sys_types.in.h deleted file mode 100644 index d7da35623..000000000 --- a/grub-core/gnulib/sys_types.in.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Provide a more complete sys/types.h. - - Copyright (C) 2011-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 . */ - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#ifndef _@GUARD_PREFIX@_SYS_TYPES_H - -/* The include_next requires a split double-inclusion guard. */ -#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@ - -#ifndef _@GUARD_PREFIX@_SYS_TYPES_H -#define _@GUARD_PREFIX@_SYS_TYPES_H - -/* Override off_t if Large File Support is requested on native Windows. */ -#if @WINDOWS_64_BIT_OFF_T@ -/* Same as int64_t in . */ -# if defined _MSC_VER -# define off_t __int64 -# else -# define off_t long long int -# endif -/* Indicator, for gnulib internal purposes. */ -# define _GL_WINDOWS_64_BIT_OFF_T 1 -#endif - -/* MSVC 9 defines size_t in , not in . */ -/* But avoid namespace pollution on glibc systems. */ -#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \ - && ! defined __GLIBC__ -# include -#endif - -#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ -#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ diff --git a/grub-core/gnulib/sysexits.in.h b/grub-core/gnulib/sysexits.in.h deleted file mode 100644 index fa8db8386..000000000 --- a/grub-core/gnulib/sysexits.in.h +++ /dev/null @@ -1,72 +0,0 @@ -/* exit() exit codes for some BSD system programs. - Copyright (C) 2003, 2006-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Simon Josefsson based on sysexits(3) man page */ - -#ifndef _@GUARD_PREFIX@_SYSEXITS_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#if @HAVE_SYSEXITS_H@ - -/* IRIX 6.5 has an that defines a macro EX_OK with a nonzero - value. Override it. See - */ -# ifdef __sgi -# include -# undef EX_OK -# endif - -/* The include_next requires a split double-inclusion guard. */ -# @INCLUDE_NEXT@ @NEXT_SYSEXITS_H@ - -/* HP-UX 11 ends at EX_NOPERM. */ -# ifndef EX_CONFIG -# define EX_CONFIG 78 -# endif - -#endif - -#ifndef _@GUARD_PREFIX@_SYSEXITS_H -#define _@GUARD_PREFIX@_SYSEXITS_H - -#if !@HAVE_SYSEXITS_H@ - -# define EX_OK 0 /* same value as EXIT_SUCCESS */ - -# define EX_USAGE 64 -# define EX_DATAERR 65 -# define EX_NOINPUT 66 -# define EX_NOUSER 67 -# define EX_NOHOST 68 -# define EX_UNAVAILABLE 69 -# define EX_SOFTWARE 70 -# define EX_OSERR 71 -# define EX_OSFILE 72 -# define EX_CANTCREAT 73 -# define EX_IOERR 74 -# define EX_TEMPFAIL 75 -# define EX_PROTOCOL 76 -# define EX_NOPERM 77 -# define EX_CONFIG 78 - -#endif - -#endif /* _@GUARD_PREFIX@_SYSEXITS_H */ -#endif /* _@GUARD_PREFIX@_SYSEXITS_H */ diff --git a/grub-core/gnulib/unistd.c b/grub-core/gnulib/unistd.c deleted file mode 100644 index 6c6a8e268..000000000 --- a/grub-core/gnulib/unistd.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE -#include "unistd.h" diff --git a/grub-core/gnulib/unistd.in.h b/grub-core/gnulib/unistd.in.h deleted file mode 100644 index 2ea9af436..000000000 --- a/grub-core/gnulib/unistd.in.h +++ /dev/null @@ -1,1530 +0,0 @@ -/* Substitute for and wrapper around . - Copyright (C) 2003-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _@GUARD_PREFIX@_UNISTD_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_UNISTD_H@ -# @INCLUDE_NEXT@ @NEXT_UNISTD_H@ -#endif - -/* Get all possible declarations of gethostname(). */ -#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \ - && !defined _GL_INCLUDING_WINSOCK2_H -# define _GL_INCLUDING_WINSOCK2_H -# include -# undef _GL_INCLUDING_WINSOCK2_H -#endif - -#if !defined _@GUARD_PREFIX@_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H -#define _@GUARD_PREFIX@_UNISTD_H - -/* NetBSD 5.0 mis-defines NULL. Also get size_t. */ -#include - -/* mingw doesn't define the SEEK_* or *_FILENO macros in . */ -/* Cygwin 1.7.1 declares symlinkat in , not in . */ -/* But avoid namespace pollution on glibc systems. */ -#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \ - || ((@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK) \ - && defined __CYGWIN__)) \ - && ! defined __GLIBC__ -# include -#endif - -/* Cygwin 1.7.1 declares unlinkat in , not in . */ -/* But avoid namespace pollution on glibc systems. */ -#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) && defined __CYGWIN__ \ - && ! defined __GLIBC__ -# include -#endif - -/* mingw fails to declare _exit in . */ -/* mingw, MSVC, BeOS, Haiku declare environ in , not in - . */ -/* Solaris declares getcwd not only in but also in . */ -/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system is - included here. */ -/* But avoid namespace pollution on glibc systems. */ -#if !defined __GLIBC__ && !defined __osf__ -# define __need_system_stdlib_h -# include -# undef __need_system_stdlib_h -#endif - -/* Native Windows platforms declare chdir, getcwd, rmdir in - and/or , not in . - They also declare access(), chmod(), close(), dup(), dup2(), isatty(), - lseek(), read(), unlink(), write() in . */ -#if ((@GNULIB_CHDIR@ || @GNULIB_GETCWD@ || @GNULIB_RMDIR@ \ - || defined GNULIB_POSIXCHECK) \ - && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) -# include /* mingw32, mingw64 */ -# include /* mingw64, MSVC 9 */ -#elif (@GNULIB_CLOSE@ || @GNULIB_DUP@ || @GNULIB_DUP2@ || @GNULIB_ISATTY@ \ - || @GNULIB_LSEEK@ || @GNULIB_READ@ || @GNULIB_UNLINK@ || @GNULIB_WRITE@ \ - || defined GNULIB_POSIXCHECK) \ - && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) -# include -#endif - -/* AIX and OSF/1 5.1 declare getdomainname in , not in . - NonStop Kernel declares gethostname in , not in . */ -/* But avoid namespace pollution on glibc systems. */ -#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \ - || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \ - && !defined __GLIBC__ -# include -#endif - -/* MSVC defines off_t in . - May also define off_t to a 64-bit type on native Windows. */ -#if !@HAVE_UNISTD_H@ || @WINDOWS_64_BIT_OFF_T@ -/* Get off_t. */ -# include -#endif - -#if (@GNULIB_READ@ || @GNULIB_WRITE@ \ - || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \ - || @GNULIB_PREAD@ || @GNULIB_PWRITE@ || defined GNULIB_POSIXCHECK) -/* Get ssize_t. */ -# include -#endif - -/* Get getopt(), optarg, optind, opterr, optopt. - But avoid namespace pollution on glibc systems. */ -#if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT -# define __need_getopt -# include -#endif - -_GL_INLINE_HEADER_BEGIN -#ifndef _GL_UNISTD_INLINE -# define _GL_UNISTD_INLINE _GL_INLINE -#endif - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - - -/* Hide some function declarations from . */ - -#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ -# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef socket -# define socket socket_used_without_including_sys_socket_h -# undef connect -# define connect connect_used_without_including_sys_socket_h -# undef accept -# define accept accept_used_without_including_sys_socket_h -# undef bind -# define bind bind_used_without_including_sys_socket_h -# undef getpeername -# define getpeername getpeername_used_without_including_sys_socket_h -# undef getsockname -# define getsockname getsockname_used_without_including_sys_socket_h -# undef getsockopt -# define getsockopt getsockopt_used_without_including_sys_socket_h -# undef listen -# define listen listen_used_without_including_sys_socket_h -# undef recv -# define recv recv_used_without_including_sys_socket_h -# undef send -# define send send_used_without_including_sys_socket_h -# undef recvfrom -# define recvfrom recvfrom_used_without_including_sys_socket_h -# undef sendto -# define sendto sendto_used_without_including_sys_socket_h -# undef setsockopt -# define setsockopt setsockopt_used_without_including_sys_socket_h -# undef shutdown -# define shutdown shutdown_used_without_including_sys_socket_h -# else - _GL_WARN_ON_USE (socket, - "socket() used without including "); - _GL_WARN_ON_USE (connect, - "connect() used without including "); - _GL_WARN_ON_USE (accept, - "accept() used without including "); - _GL_WARN_ON_USE (bind, - "bind() used without including "); - _GL_WARN_ON_USE (getpeername, - "getpeername() used without including "); - _GL_WARN_ON_USE (getsockname, - "getsockname() used without including "); - _GL_WARN_ON_USE (getsockopt, - "getsockopt() used without including "); - _GL_WARN_ON_USE (listen, - "listen() used without including "); - _GL_WARN_ON_USE (recv, - "recv() used without including "); - _GL_WARN_ON_USE (send, - "send() used without including "); - _GL_WARN_ON_USE (recvfrom, - "recvfrom() used without including "); - _GL_WARN_ON_USE (sendto, - "sendto() used without including "); - _GL_WARN_ON_USE (setsockopt, - "setsockopt() used without including "); - _GL_WARN_ON_USE (shutdown, - "shutdown() used without including "); -# endif -# endif -# if !defined _@GUARD_PREFIX@_SYS_SELECT_H -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef select -# define select select_used_without_including_sys_select_h -# else - _GL_WARN_ON_USE (select, - "select() used without including "); -# endif -# endif -#endif - - -/* OS/2 EMX lacks these macros. */ -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif - -/* Ensure *_OK macros exist. */ -#ifndef F_OK -# define F_OK 0 -# define X_OK 1 -# define W_OK 2 -# define R_OK 4 -#endif - - -/* Declare overridden functions. */ - - -#if defined GNULIB_POSIXCHECK -/* The access() function is a security risk. */ -_GL_WARN_ON_USE (access, "the access function is a security risk - " - "use the gnulib module faccessat instead"); -#endif - - -#if @GNULIB_CHDIR@ -_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1))); -_GL_CXXALIASWARN (chdir); -#elif defined GNULIB_POSIXCHECK -# undef chdir -# if HAVE_RAW_DECL_CHDIR -_GL_WARN_ON_USE (chown, "chdir is not always in - " - "use gnulib module chdir for portability"); -# endif -#endif - - -#if @GNULIB_CHOWN@ -/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE - to GID (if GID is not -1). Follow symbolic links. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2008 specification - . */ -# if @REPLACE_DUP2@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define dup2 rpl_dup2 -# endif -_GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd)); -_GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd)); -# else -# if !@HAVE_DUP2@ -_GL_FUNCDECL_SYS (dup2, int, (int oldfd, int newfd)); -# endif -_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd)); -# endif -_GL_CXXALIASWARN (dup2); -#elif defined GNULIB_POSIXCHECK -# undef dup2 -# if HAVE_RAW_DECL_DUP2 -_GL_WARN_ON_USE (dup2, "dup2 is unportable - " - "use gnulib module dup2 for portability"); -# endif -#endif - - -#if @GNULIB_DUP3@ -/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the - specified flags. - The flags are a bitmask, possibly including O_CLOEXEC (defined in ) - and O_TEXT, O_BINARY (defined in "binary-io.h"). - Close NEWFD first if it is open. - Return newfd if successful, otherwise -1 and errno set. - See the Linux man page at - . */ -# if @HAVE_DUP3@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define dup3 rpl_dup3 -# endif -_GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags)); -_GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags)); -# else -_GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags)); -_GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags)); -# endif -_GL_CXXALIASWARN (dup3); -#elif defined GNULIB_POSIXCHECK -# undef dup3 -# if HAVE_RAW_DECL_DUP3 -_GL_WARN_ON_USE (dup3, "dup3 is unportable - " - "use gnulib module dup3 for portability"); -# endif -#endif - - -#if @GNULIB_ENVIRON@ -# if !@HAVE_DECL_ENVIRON@ -/* Set of environment variables and values. An array of strings of the form - "VARIABLE=VALUE", terminated with a NULL. */ -# if defined __APPLE__ && defined __MACH__ -# include -# define environ (*_NSGetEnviron ()) -# else -# ifdef __cplusplus -extern "C" { -# endif -extern char **environ; -# ifdef __cplusplus -} -# endif -# endif -# endif -#elif defined GNULIB_POSIXCHECK -# if HAVE_RAW_DECL_ENVIRON -_GL_UNISTD_INLINE char *** -rpl_environ (void) -{ - return &environ; -} -_GL_WARN_ON_USE (rpl_environ, "environ is unportable - " - "use gnulib module environ for portability"); -# undef environ -# define environ (*rpl_environ ()) -# endif -#endif - - -#if @GNULIB_EUIDACCESS@ -/* Like access(), except that it uses the effective user id and group id of - the current process. */ -# if !@HAVE_EUIDACCESS@ -_GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode)); -_GL_CXXALIASWARN (euidaccess); -# if defined GNULIB_POSIXCHECK -/* Like access(), this function is a security risk. */ -_GL_WARN_ON_USE (euidaccess, "the euidaccess function is a security risk - " - "use the gnulib module faccessat instead"); -# endif -#elif defined GNULIB_POSIXCHECK -# undef euidaccess -# if HAVE_RAW_DECL_EUIDACCESS -_GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - " - "use gnulib module euidaccess for portability"); -# endif -#endif - - -#if @GNULIB_FACCESSAT@ -# if !@HAVE_FACCESSAT@ -_GL_FUNCDECL_SYS (faccessat, int, - (int fd, char const *file, int mode, int flag) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (faccessat, int, - (int fd, char const *file, int mode, int flag)); -_GL_CXXALIASWARN (faccessat); -#elif defined GNULIB_POSIXCHECK -# undef faccessat -# if HAVE_RAW_DECL_FACCESSAT -_GL_WARN_ON_USE (faccessat, "faccessat is not portable - " - "use gnulib module faccessat for portability"); -# endif -#endif - - -#if @GNULIB_FCHDIR@ -/* Change the process' current working directory to the directory on which - the given file descriptor is open. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2008 specification - . */ -# if ! @HAVE_FCHDIR@ -_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); - -/* Gnulib internal hooks needed to maintain the fchdir metadata. */ -_GL_EXTERN_C int _gl_register_fd (int fd, const char *filename) - _GL_ARG_NONNULL ((2)); -_GL_EXTERN_C void _gl_unregister_fd (int fd); -_GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd); -_GL_EXTERN_C const char *_gl_directory_name (int fd); - -# else -# if !@HAVE_DECL_FCHDIR@ -_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); -# endif -# endif -_GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/)); -_GL_CXXALIASWARN (fchdir); -#elif defined GNULIB_POSIXCHECK -# undef fchdir -# if HAVE_RAW_DECL_FCHDIR -_GL_WARN_ON_USE (fchdir, "fchdir is unportable - " - "use gnulib module fchdir for portability"); -# endif -#endif - - -#if @GNULIB_FCHOWNAT@ -# if @REPLACE_FCHOWNAT@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef fchownat -# define fchownat rpl_fchownat -# endif -_GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file, - uid_t owner, gid_t group, int flag) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file, - uid_t owner, gid_t group, int flag)); -# else -# if !@HAVE_FCHOWNAT@ -_GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file, - uid_t owner, gid_t group, int flag) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file, - uid_t owner, gid_t group, int flag)); -# endif -_GL_CXXALIASWARN (fchownat); -#elif defined GNULIB_POSIXCHECK -# undef fchownat -# if HAVE_RAW_DECL_FCHOWNAT -_GL_WARN_ON_USE (fchownat, "fchownat is not portable - " - "use gnulib module openat for portability"); -# endif -#endif - - -#if @GNULIB_FDATASYNC@ -/* Synchronize changes to a file. - Return 0 if successful, otherwise -1 and errno set. - See POSIX:2008 specification - . */ -# if !@HAVE_FDATASYNC@ || !@HAVE_DECL_FDATASYNC@ -_GL_FUNCDECL_SYS (fdatasync, int, (int fd)); -# endif -_GL_CXXALIAS_SYS (fdatasync, int, (int fd)); -_GL_CXXALIASWARN (fdatasync); -#elif defined GNULIB_POSIXCHECK -# undef fdatasync -# if HAVE_RAW_DECL_FDATASYNC -_GL_WARN_ON_USE (fdatasync, "fdatasync is unportable - " - "use gnulib module fdatasync for portability"); -# endif -#endif - - -#if @GNULIB_FSYNC@ -/* Synchronize changes, including metadata, to a file. - Return 0 if successful, otherwise -1 and errno set. - See POSIX:2008 specification - . */ -# if !@HAVE_FSYNC@ -_GL_FUNCDECL_SYS (fsync, int, (int fd)); -# endif -_GL_CXXALIAS_SYS (fsync, int, (int fd)); -_GL_CXXALIASWARN (fsync); -#elif defined GNULIB_POSIXCHECK -# undef fsync -# if HAVE_RAW_DECL_FSYNC -_GL_WARN_ON_USE (fsync, "fsync is unportable - " - "use gnulib module fsync for portability"); -# endif -#endif - - -#if @GNULIB_FTRUNCATE@ -/* Change the size of the file to which FD is opened to become equal to LENGTH. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2008 specification - . */ -# if @REPLACE_FTRUNCATE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef ftruncate -# define ftruncate rpl_ftruncate -# endif -_GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length)); -_GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length)); -# else -# if !@HAVE_FTRUNCATE@ -_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length)); -# endif -_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length)); -# endif -_GL_CXXALIASWARN (ftruncate); -#elif defined GNULIB_POSIXCHECK -# undef ftruncate -# if HAVE_RAW_DECL_FTRUNCATE -_GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - " - "use gnulib module ftruncate for portability"); -# endif -#endif - - -#if @GNULIB_GETCWD@ -/* Get the name of the current working directory, and put it in SIZE bytes - of BUF. - Return BUF if successful, or NULL if the directory couldn't be determined - or SIZE was too small. - See the POSIX:2008 specification - . - Additionally, the gnulib module 'getcwd' guarantees the following GNU - extension: If BUF is NULL, an array is allocated with 'malloc'; the array - is SIZE bytes long, unless SIZE == 0, in which case it is as big as - necessary. */ -# if @REPLACE_GETCWD@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define getcwd rpl_getcwd -# endif -_GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size)); -_GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size)); -# else -/* Need to cast, because on mingw, the second parameter is - int size. */ -_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size)); -# endif -_GL_CXXALIASWARN (getcwd); -#elif defined GNULIB_POSIXCHECK -# undef getcwd -# if HAVE_RAW_DECL_GETCWD -_GL_WARN_ON_USE (getcwd, "getcwd is unportable - " - "use gnulib module getcwd for portability"); -# endif -#endif - - -#if @GNULIB_GETDOMAINNAME@ -/* Return the NIS domain name of the machine. - WARNING! The NIS domain name is unrelated to the fully qualified host name - of the machine. It is also unrelated to email addresses. - WARNING! The NIS domain name is usually the empty string or "(none)" when - not using NIS. - - Put up to LEN bytes of the NIS domain name into NAME. - Null terminate it if the name is shorter than LEN. - If the NIS domain name is longer than LEN, set errno = EINVAL and return -1. - Return 0 if successful, otherwise set errno and return -1. */ -# if @REPLACE_GETDOMAINNAME@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getdomainname -# define getdomainname rpl_getdomainname -# endif -_GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len)); -# else -# if !@HAVE_DECL_GETDOMAINNAME@ -_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len)); -# endif -_GL_CXXALIASWARN (getdomainname); -#elif defined GNULIB_POSIXCHECK -# undef getdomainname -# if HAVE_RAW_DECL_GETDOMAINNAME -_GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - " - "use gnulib module getdomainname for portability"); -# endif -#endif - - -#if @GNULIB_GETDTABLESIZE@ -/* Return the maximum number of file descriptors in the current process. - In POSIX, this is same as sysconf (_SC_OPEN_MAX). */ -# if !@HAVE_GETDTABLESIZE@ -_GL_FUNCDECL_SYS (getdtablesize, int, (void)); -# endif -_GL_CXXALIAS_SYS (getdtablesize, int, (void)); -_GL_CXXALIASWARN (getdtablesize); -#elif defined GNULIB_POSIXCHECK -# undef getdtablesize -# if HAVE_RAW_DECL_GETDTABLESIZE -_GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - " - "use gnulib module getdtablesize for portability"); -# endif -#endif - - -#if @GNULIB_GETGROUPS@ -/* Return the supplemental groups that the current process belongs to. - It is unspecified whether the effective group id is in the list. - If N is 0, return the group count; otherwise, N describes how many - entries are available in GROUPS. Return -1 and set errno if N is - not 0 and not large enough. Fails with ENOSYS on some systems. */ -# if @REPLACE_GETGROUPS@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef getgroups -# define getgroups rpl_getgroups -# endif -_GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups)); -_GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups)); -# else -# if !@HAVE_GETGROUPS@ -_GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups)); -# endif -_GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups)); -# endif -_GL_CXXALIASWARN (getgroups); -#elif defined GNULIB_POSIXCHECK -# undef getgroups -# if HAVE_RAW_DECL_GETGROUPS -_GL_WARN_ON_USE (getgroups, "getgroups is unportable - " - "use gnulib module getgroups for portability"); -# endif -#endif - - -#if @GNULIB_GETHOSTNAME@ -/* Return the standard host name of the machine. - WARNING! The host name may or may not be fully qualified. - - Put up to LEN bytes of the host name into NAME. - Null terminate it if the name is shorter than LEN. - If the host name is longer than LEN, set errno = EINVAL and return -1. - Return 0 if successful, otherwise set errno and return -1. */ -# if @UNISTD_H_HAVE_WINSOCK2_H@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef gethostname -# define gethostname rpl_gethostname -# endif -_GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len)); -# else -# if !@HAVE_GETHOSTNAME@ -_GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len) - _GL_ARG_NONNULL ((1))); -# endif -/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second - parameter is - int len. */ -_GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len)); -# endif -_GL_CXXALIASWARN (gethostname); -#elif @UNISTD_H_HAVE_WINSOCK2_H@ -# undef gethostname -# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname -#elif defined GNULIB_POSIXCHECK -# undef gethostname -# if HAVE_RAW_DECL_GETHOSTNAME -_GL_WARN_ON_USE (gethostname, "gethostname is unportable - " - "use gnulib module gethostname for portability"); -# endif -#endif - - -#if @GNULIB_GETLOGIN@ -/* Returns the user's login name, or NULL if it cannot be found. Upon error, - returns NULL with errno set. - - See . - - Most programs don't need to use this function, because the information is - available through environment variables: - ${LOGNAME-$USER} on Unix platforms, - $USERNAME on native Windows platforms. - */ -# if !@HAVE_GETLOGIN@ -_GL_FUNCDECL_SYS (getlogin, char *, (void)); -# endif -_GL_CXXALIAS_SYS (getlogin, char *, (void)); -_GL_CXXALIASWARN (getlogin); -#elif defined GNULIB_POSIXCHECK -# undef getlogin -# if HAVE_RAW_DECL_GETLOGIN -_GL_WARN_ON_USE (getlogin, "getlogin is unportable - " - "use gnulib module getlogin for portability"); -# endif -#endif - - -#if @GNULIB_GETLOGIN_R@ -/* Copies the user's login name to NAME. - The array pointed to by NAME has room for SIZE bytes. - - Returns 0 if successful. Upon error, an error number is returned, or -1 in - the case that the login name cannot be found but no specific error is - provided (this case is hopefully rare but is left open by the POSIX spec). - - See . - - Most programs don't need to use this function, because the information is - available through environment variables: - ${LOGNAME-$USER} on Unix platforms, - $USERNAME on native Windows platforms. - */ -# if @REPLACE_GETLOGIN_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define getlogin_r rpl_getlogin_r -# endif -_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size)); -# else -# if !@HAVE_DECL_GETLOGIN_R@ -_GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size) - _GL_ARG_NONNULL ((1))); -# endif -/* Need to cast, because on Solaris 10 systems, the second argument is - int size. */ -_GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size)); -# endif -_GL_CXXALIASWARN (getlogin_r); -#elif defined GNULIB_POSIXCHECK -# undef getlogin_r -# if HAVE_RAW_DECL_GETLOGIN_R -_GL_WARN_ON_USE (getlogin_r, "getlogin_r is unportable - " - "use gnulib module getlogin_r for portability"); -# endif -#endif - - -#if @GNULIB_GETPAGESIZE@ -# if @REPLACE_GETPAGESIZE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define getpagesize rpl_getpagesize -# endif -_GL_FUNCDECL_RPL (getpagesize, int, (void)); -_GL_CXXALIAS_RPL (getpagesize, int, (void)); -# else -# if !@HAVE_GETPAGESIZE@ -# if !defined getpagesize -/* This is for POSIX systems. */ -# if !defined _gl_getpagesize && defined _SC_PAGESIZE -# if ! (defined __VMS && __VMS_VER < 70000000) -# define _gl_getpagesize() sysconf (_SC_PAGESIZE) -# endif -# endif -/* This is for older VMS. */ -# if !defined _gl_getpagesize && defined __VMS -# ifdef __ALPHA -# define _gl_getpagesize() 8192 -# else -# define _gl_getpagesize() 512 -# endif -# endif -/* This is for BeOS. */ -# if !defined _gl_getpagesize && @HAVE_OS_H@ -# include -# if defined B_PAGE_SIZE -# define _gl_getpagesize() B_PAGE_SIZE -# endif -# endif -/* This is for AmigaOS4.0. */ -# if !defined _gl_getpagesize && defined __amigaos4__ -# define _gl_getpagesize() 2048 -# endif -/* This is for older Unix systems. */ -# if !defined _gl_getpagesize && @HAVE_SYS_PARAM_H@ -# include -# ifdef EXEC_PAGESIZE -# define _gl_getpagesize() EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define CLSIZE 1 -# endif -# define _gl_getpagesize() (NBPG * CLSIZE) -# else -# ifdef NBPC -# define _gl_getpagesize() NBPC -# endif -# endif -# endif -# endif -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define getpagesize() _gl_getpagesize () -# else -# if !GNULIB_defined_getpagesize_function -_GL_UNISTD_INLINE int -getpagesize () -{ - return _gl_getpagesize (); -} -# define GNULIB_defined_getpagesize_function 1 -# endif -# endif -# endif -# endif -/* Need to cast, because on Cygwin 1.5.x systems, the return type is size_t. */ -_GL_CXXALIAS_SYS_CAST (getpagesize, int, (void)); -# endif -# if @HAVE_DECL_GETPAGESIZE@ -_GL_CXXALIASWARN (getpagesize); -# endif -#elif defined GNULIB_POSIXCHECK -# undef getpagesize -# if HAVE_RAW_DECL_GETPAGESIZE -_GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - " - "use gnulib module getpagesize for portability"); -# endif -#endif - - -#if @GNULIB_GETUSERSHELL@ -/* Return the next valid login shell on the system, or NULL when the end of - the list has been reached. */ -# if !@HAVE_DECL_GETUSERSHELL@ -_GL_FUNCDECL_SYS (getusershell, char *, (void)); -# endif -_GL_CXXALIAS_SYS (getusershell, char *, (void)); -_GL_CXXALIASWARN (getusershell); -#elif defined GNULIB_POSIXCHECK -# undef getusershell -# if HAVE_RAW_DECL_GETUSERSHELL -_GL_WARN_ON_USE (getusershell, "getusershell is unportable - " - "use gnulib module getusershell for portability"); -# endif -#endif - -#if @GNULIB_GETUSERSHELL@ -/* Rewind to pointer that is advanced at each getusershell() call. */ -# if !@HAVE_DECL_GETUSERSHELL@ -_GL_FUNCDECL_SYS (setusershell, void, (void)); -# endif -_GL_CXXALIAS_SYS (setusershell, void, (void)); -_GL_CXXALIASWARN (setusershell); -#elif defined GNULIB_POSIXCHECK -# undef setusershell -# if HAVE_RAW_DECL_SETUSERSHELL -_GL_WARN_ON_USE (setusershell, "setusershell is unportable - " - "use gnulib module getusershell for portability"); -# endif -#endif - -#if @GNULIB_GETUSERSHELL@ -/* Free the pointer that is advanced at each getusershell() call and - associated resources. */ -# if !@HAVE_DECL_GETUSERSHELL@ -_GL_FUNCDECL_SYS (endusershell, void, (void)); -# endif -_GL_CXXALIAS_SYS (endusershell, void, (void)); -_GL_CXXALIASWARN (endusershell); -#elif defined GNULIB_POSIXCHECK -# undef endusershell -# if HAVE_RAW_DECL_ENDUSERSHELL -_GL_WARN_ON_USE (endusershell, "endusershell is unportable - " - "use gnulib module getusershell for portability"); -# endif -#endif - - -#if @GNULIB_GROUP_MEMBER@ -/* Determine whether group id is in calling user's group list. */ -# if !@HAVE_GROUP_MEMBER@ -_GL_FUNCDECL_SYS (group_member, int, (gid_t gid)); -# endif -_GL_CXXALIAS_SYS (group_member, int, (gid_t gid)); -_GL_CXXALIASWARN (group_member); -#elif defined GNULIB_POSIXCHECK -# undef group_member -# if HAVE_RAW_DECL_GROUP_MEMBER -_GL_WARN_ON_USE (group_member, "group_member is unportable - " - "use gnulib module group-member for portability"); -# endif -#endif - - -#if @GNULIB_ISATTY@ -# if @REPLACE_ISATTY@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef isatty -# define isatty rpl_isatty -# endif -_GL_FUNCDECL_RPL (isatty, int, (int fd)); -_GL_CXXALIAS_RPL (isatty, int, (int fd)); -# else -_GL_CXXALIAS_SYS (isatty, int, (int fd)); -# endif -_GL_CXXALIASWARN (isatty); -#elif defined GNULIB_POSIXCHECK -# undef isatty -# if HAVE_RAW_DECL_ISATTY -_GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - " - "use gnulib module isatty for portability"); -# endif -#endif - - -#if @GNULIB_LCHOWN@ -/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE - to GID (if GID is not -1). Do not follow symbolic links. - Return 0 if successful, otherwise -1 and errno set. - See the POSIX:2008 specification - . */ -# if @REPLACE_LCHOWN@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef lchown -# define lchown rpl_lchown -# endif -_GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group) - _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)); -# else -# if !@HAVE_LCHOWN@ -_GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group) - _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)); -# endif -_GL_CXXALIASWARN (lchown); -#elif defined GNULIB_POSIXCHECK -# undef lchown -# if HAVE_RAW_DECL_LCHOWN -_GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - " - "use gnulib module lchown for portability"); -# endif -#endif - - -#if @GNULIB_LINK@ -/* Create a new hard link for an existing file. - Return 0 if successful, otherwise -1 and errno set. - See POSIX:2008 specification - . */ -# if @REPLACE_LINK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define link rpl_link -# endif -_GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2)); -# else -# if !@HAVE_LINK@ -_GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2)); -# endif -_GL_CXXALIASWARN (link); -#elif defined GNULIB_POSIXCHECK -# undef link -# if HAVE_RAW_DECL_LINK -_GL_WARN_ON_USE (link, "link is unportable - " - "use gnulib module link for portability"); -# endif -#endif - - -#if @GNULIB_LINKAT@ -/* Create a new hard link for an existing file, relative to two - directories. FLAG controls whether symlinks are followed. - Return 0 if successful, otherwise -1 and errno set. */ -# if @REPLACE_LINKAT@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef linkat -# define linkat rpl_linkat -# endif -_GL_FUNCDECL_RPL (linkat, int, - (int fd1, const char *path1, int fd2, const char *path2, - int flag) - _GL_ARG_NONNULL ((2, 4))); -_GL_CXXALIAS_RPL (linkat, int, - (int fd1, const char *path1, int fd2, const char *path2, - int flag)); -# else -# if !@HAVE_LINKAT@ -_GL_FUNCDECL_SYS (linkat, int, - (int fd1, const char *path1, int fd2, const char *path2, - int flag) - _GL_ARG_NONNULL ((2, 4))); -# endif -_GL_CXXALIAS_SYS (linkat, int, - (int fd1, const char *path1, int fd2, const char *path2, - int flag)); -# endif -_GL_CXXALIASWARN (linkat); -#elif defined GNULIB_POSIXCHECK -# undef linkat -# if HAVE_RAW_DECL_LINKAT -_GL_WARN_ON_USE (linkat, "linkat is unportable - " - "use gnulib module linkat for portability"); -# endif -#endif - - -#if @GNULIB_LSEEK@ -/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END. - Return the new offset if successful, otherwise -1 and errno set. - See the POSIX:2008 specification - . */ -# if @REPLACE_LSEEK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define lseek rpl_lseek -# endif -_GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence)); -_GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence)); -# else -_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence)); -# endif -_GL_CXXALIASWARN (lseek); -#elif defined GNULIB_POSIXCHECK -# undef lseek -# if HAVE_RAW_DECL_LSEEK -_GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some " - "systems - use gnulib module lseek for portability"); -# endif -#endif - - -#if @GNULIB_PIPE@ -/* Create a pipe, defaulting to O_BINARY mode. - Store the read-end as fd[0] and the write-end as fd[1]. - Return 0 upon success, or -1 with errno set upon failure. */ -# if !@HAVE_PIPE@ -_GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1))); -# endif -_GL_CXXALIAS_SYS (pipe, int, (int fd[2])); -_GL_CXXALIASWARN (pipe); -#elif defined GNULIB_POSIXCHECK -# undef pipe -# if HAVE_RAW_DECL_PIPE -_GL_WARN_ON_USE (pipe, "pipe is unportable - " - "use gnulib module pipe-posix for portability"); -# endif -#endif - - -#if @GNULIB_PIPE2@ -/* Create a pipe, applying the given flags when opening the read-end of the - pipe and the write-end of the pipe. - The flags are a bitmask, possibly including O_CLOEXEC (defined in ) - and O_TEXT, O_BINARY (defined in "binary-io.h"). - Store the read-end as fd[0] and the write-end as fd[1]. - Return 0 upon success, or -1 with errno set upon failure. - See also the Linux man page at - . */ -# if @HAVE_PIPE2@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define pipe2 rpl_pipe2 -# endif -_GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags)); -# else -_GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags)); -# endif -_GL_CXXALIASWARN (pipe2); -#elif defined GNULIB_POSIXCHECK -# undef pipe2 -# if HAVE_RAW_DECL_PIPE2 -_GL_WARN_ON_USE (pipe2, "pipe2 is unportable - " - "use gnulib module pipe2 for portability"); -# endif -#endif - - -#if @GNULIB_PREAD@ -/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET. - Return the number of bytes placed into BUF if successful, otherwise - set errno and return -1. 0 indicates EOF. - See the POSIX:2008 specification - . */ -# if @REPLACE_PREAD@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef pread -# define pread rpl_pread -# endif -_GL_FUNCDECL_RPL (pread, ssize_t, - (int fd, void *buf, size_t bufsize, off_t offset) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (pread, ssize_t, - (int fd, void *buf, size_t bufsize, off_t offset)); -# else -# if !@HAVE_PREAD@ -_GL_FUNCDECL_SYS (pread, ssize_t, - (int fd, void *buf, size_t bufsize, off_t offset) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (pread, ssize_t, - (int fd, void *buf, size_t bufsize, off_t offset)); -# endif -_GL_CXXALIASWARN (pread); -#elif defined GNULIB_POSIXCHECK -# undef pread -# if HAVE_RAW_DECL_PREAD -_GL_WARN_ON_USE (pread, "pread is unportable - " - "use gnulib module pread for portability"); -# endif -#endif - - -#if @GNULIB_PWRITE@ -/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET. - Return the number of bytes written if successful, otherwise - set errno and return -1. 0 indicates nothing written. See the - POSIX:2008 specification - . */ -# if @REPLACE_PWRITE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef pwrite -# define pwrite rpl_pwrite -# endif -_GL_FUNCDECL_RPL (pwrite, ssize_t, - (int fd, const void *buf, size_t bufsize, off_t offset) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (pwrite, ssize_t, - (int fd, const void *buf, size_t bufsize, off_t offset)); -# else -# if !@HAVE_PWRITE@ -_GL_FUNCDECL_SYS (pwrite, ssize_t, - (int fd, const void *buf, size_t bufsize, off_t offset) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (pwrite, ssize_t, - (int fd, const void *buf, size_t bufsize, off_t offset)); -# endif -_GL_CXXALIASWARN (pwrite); -#elif defined GNULIB_POSIXCHECK -# undef pwrite -# if HAVE_RAW_DECL_PWRITE -_GL_WARN_ON_USE (pwrite, "pwrite is unportable - " - "use gnulib module pwrite for portability"); -# endif -#endif - - -#if @GNULIB_READ@ -/* Read up to COUNT bytes from file descriptor FD into the buffer starting - at BUF. See the POSIX:2008 specification - . */ -# if @REPLACE_READ@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef read -# define read rpl_read -# endif -_GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count)); -# else -/* Need to cast, because on mingw, the third parameter is - unsigned int count - and the return type is 'int'. */ -_GL_CXXALIAS_SYS_CAST (read, ssize_t, (int fd, void *buf, size_t count)); -# endif -_GL_CXXALIASWARN (read); -#endif - - -#if @GNULIB_READLINK@ -/* Read the contents of the symbolic link FILE and place the first BUFSIZE - bytes of it into BUF. Return the number of bytes placed into BUF if - successful, otherwise -1 and errno set. - See the POSIX:2008 specification - . */ -# if @REPLACE_READLINK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define readlink rpl_readlink -# endif -_GL_FUNCDECL_RPL (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize)); -# else -# if !@HAVE_READLINK@ -_GL_FUNCDECL_SYS (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (readlink, ssize_t, - (const char *file, char *buf, size_t bufsize)); -# endif -_GL_CXXALIASWARN (readlink); -#elif defined GNULIB_POSIXCHECK -# undef readlink -# if HAVE_RAW_DECL_READLINK -_GL_WARN_ON_USE (readlink, "readlink is unportable - " - "use gnulib module readlink for portability"); -# endif -#endif - - -#if @GNULIB_READLINKAT@ -# if !@HAVE_READLINKAT@ -_GL_FUNCDECL_SYS (readlinkat, ssize_t, - (int fd, char const *file, char *buf, size_t len) - _GL_ARG_NONNULL ((2, 3))); -# endif -_GL_CXXALIAS_SYS (readlinkat, ssize_t, - (int fd, char const *file, char *buf, size_t len)); -_GL_CXXALIASWARN (readlinkat); -#elif defined GNULIB_POSIXCHECK -# undef readlinkat -# if HAVE_RAW_DECL_READLINKAT -_GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - " - "use gnulib module readlinkat for portability"); -# endif -#endif - - -#if @GNULIB_RMDIR@ -/* Remove the directory DIR. */ -# if @REPLACE_RMDIR@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define rmdir rpl_rmdir -# endif -_GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (rmdir, int, (char const *name)); -# else -_GL_CXXALIAS_SYS (rmdir, int, (char const *name)); -# endif -_GL_CXXALIASWARN (rmdir); -#elif defined GNULIB_POSIXCHECK -# undef rmdir -# if HAVE_RAW_DECL_RMDIR -_GL_WARN_ON_USE (rmdir, "rmdir is unportable - " - "use gnulib module rmdir for portability"); -# endif -#endif - - -#if @GNULIB_SETHOSTNAME@ -/* Set the host name of the machine. - The host name may or may not be fully qualified. - - Put LEN bytes of NAME into the host name. - Return 0 if successful, otherwise, set errno and return -1. - - Platforms with no ability to set the hostname return -1 and set - errno = ENOSYS. */ -# if !@HAVE_SETHOSTNAME@ || !@HAVE_DECL_SETHOSTNAME@ -_GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len) - _GL_ARG_NONNULL ((1))); -# endif -/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5 - and FreeBSD 6.4 the second parameter is int. On Solaris 11 - 2011-10, the first parameter is not const. */ -_GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len)); -_GL_CXXALIASWARN (sethostname); -#elif defined GNULIB_POSIXCHECK -# undef sethostname -# if HAVE_RAW_DECL_SETHOSTNAME -_GL_WARN_ON_USE (sethostname, "sethostname is unportable - " - "use gnulib module sethostname for portability"); -# endif -#endif - - -#if @GNULIB_SLEEP@ -/* Pause the execution of the current thread for N seconds. - Returns the number of seconds left to sleep. - See the POSIX:2008 specification - . */ -# if @REPLACE_SLEEP@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef sleep -# define sleep rpl_sleep -# endif -_GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n)); -_GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n)); -# else -# if !@HAVE_SLEEP@ -_GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n)); -# endif -_GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n)); -# endif -_GL_CXXALIASWARN (sleep); -#elif defined GNULIB_POSIXCHECK -# undef sleep -# if HAVE_RAW_DECL_SLEEP -_GL_WARN_ON_USE (sleep, "sleep is unportable - " - "use gnulib module sleep for portability"); -# endif -#endif - - -#if @GNULIB_SYMLINK@ -# if @REPLACE_SYMLINK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef symlink -# define symlink rpl_symlink -# endif -_GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file) - _GL_ARG_NONNULL ((1, 2))); -_GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file)); -# else -# if !@HAVE_SYMLINK@ -_GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file) - _GL_ARG_NONNULL ((1, 2))); -# endif -_GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file)); -# endif -_GL_CXXALIASWARN (symlink); -#elif defined GNULIB_POSIXCHECK -# undef symlink -# if HAVE_RAW_DECL_SYMLINK -_GL_WARN_ON_USE (symlink, "symlink is not portable - " - "use gnulib module symlink for portability"); -# endif -#endif - - -#if @GNULIB_SYMLINKAT@ -# if !@HAVE_SYMLINKAT@ -_GL_FUNCDECL_SYS (symlinkat, int, - (char const *contents, int fd, char const *file) - _GL_ARG_NONNULL ((1, 3))); -# endif -_GL_CXXALIAS_SYS (symlinkat, int, - (char const *contents, int fd, char const *file)); -_GL_CXXALIASWARN (symlinkat); -#elif defined GNULIB_POSIXCHECK -# undef symlinkat -# if HAVE_RAW_DECL_SYMLINKAT -_GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - " - "use gnulib module symlinkat for portability"); -# endif -#endif - - -#if @GNULIB_TTYNAME_R@ -/* Store at most BUFLEN characters of the pathname of the terminal FD is - open on in BUF. Return 0 on success, otherwise an error number. */ -# if @REPLACE_TTYNAME_R@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef ttyname_r -# define ttyname_r rpl_ttyname_r -# endif -_GL_FUNCDECL_RPL (ttyname_r, int, - (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (ttyname_r, int, - (int fd, char *buf, size_t buflen)); -# else -# if !@HAVE_DECL_TTYNAME_R@ -_GL_FUNCDECL_SYS (ttyname_r, int, - (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (ttyname_r, int, - (int fd, char *buf, size_t buflen)); -# endif -_GL_CXXALIASWARN (ttyname_r); -#elif defined GNULIB_POSIXCHECK -# undef ttyname_r -# if HAVE_RAW_DECL_TTYNAME_R -_GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - " - "use gnulib module ttyname_r for portability"); -# endif -#endif - - -#if @GNULIB_UNLINK@ -# if @REPLACE_UNLINK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef unlink -# define unlink rpl_unlink -# endif -_GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1))); -_GL_CXXALIAS_RPL (unlink, int, (char const *file)); -# else -_GL_CXXALIAS_SYS (unlink, int, (char const *file)); -# endif -_GL_CXXALIASWARN (unlink); -#elif defined GNULIB_POSIXCHECK -# undef unlink -# if HAVE_RAW_DECL_UNLINK -_GL_WARN_ON_USE (unlink, "unlink is not portable - " - "use gnulib module unlink for portability"); -# endif -#endif - - -#if @GNULIB_UNLINKAT@ -# if @REPLACE_UNLINKAT@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef unlinkat -# define unlinkat rpl_unlinkat -# endif -_GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag)); -# else -# if !@HAVE_UNLINKAT@ -_GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag)); -# endif -_GL_CXXALIASWARN (unlinkat); -#elif defined GNULIB_POSIXCHECK -# undef unlinkat -# if HAVE_RAW_DECL_UNLINKAT -_GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " - "use gnulib module openat for portability"); -# endif -#endif - - -#if @GNULIB_USLEEP@ -/* Pause the execution of the current thread for N microseconds. - Returns 0 on completion, or -1 on range error. - See the POSIX:2001 specification - . */ -# if @REPLACE_USLEEP@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef usleep -# define usleep rpl_usleep -# endif -_GL_FUNCDECL_RPL (usleep, int, (useconds_t n)); -_GL_CXXALIAS_RPL (usleep, int, (useconds_t n)); -# else -# if !@HAVE_USLEEP@ -_GL_FUNCDECL_SYS (usleep, int, (useconds_t n)); -# endif -_GL_CXXALIAS_SYS (usleep, int, (useconds_t n)); -# endif -_GL_CXXALIASWARN (usleep); -#elif defined GNULIB_POSIXCHECK -# undef usleep -# if HAVE_RAW_DECL_USLEEP -_GL_WARN_ON_USE (usleep, "usleep is unportable - " - "use gnulib module usleep for portability"); -# endif -#endif - - -#if @GNULIB_WRITE@ -/* Write up to COUNT bytes starting at BUF to file descriptor FD. - See the POSIX:2008 specification - . */ -# if @REPLACE_WRITE@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef write -# define write rpl_write -# endif -_GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count)); -# else -/* Need to cast, because on mingw, the third parameter is - unsigned int count - and the return type is 'int'. */ -_GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count)); -# endif -_GL_CXXALIASWARN (write); -#endif - -_GL_INLINE_HEADER_END - -#endif /* _@GUARD_PREFIX@_UNISTD_H */ -#endif /* _@GUARD_PREFIX@_UNISTD_H */ diff --git a/grub-core/gnulib/unitypes.in.h b/grub-core/gnulib/unitypes.in.h deleted file mode 100644 index 06eef05ce..000000000 --- a/grub-core/gnulib/unitypes.in.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Elementary types and macros for the GNU UniString library. - Copyright (C) 2002, 2005-2006, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _UNITYPES_H -#define _UNITYPES_H - -/* Get uint8_t, uint16_t, uint32_t. */ -#include - -/* Type representing a Unicode character. */ -typedef uint32_t ucs4_t; - -/* Attribute of a function whose result depends only on the arguments - (not pointers!) and which has no side effects. */ -#ifndef _UC_ATTRIBUTE_CONST -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) -# define _UC_ATTRIBUTE_CONST __attribute__ ((__const__)) -# else -# define _UC_ATTRIBUTE_CONST -# endif -#endif - -/* Attribute of a function whose result depends only on the arguments - (possibly pointers) and global memory, and which has no side effects. */ -#ifndef _UC_ATTRIBUTE_PURE -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _UC_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define _UC_ATTRIBUTE_PURE -# endif -#endif - -#endif /* _UNITYPES_H */ diff --git a/grub-core/gnulib/uniwidth.in.h b/grub-core/gnulib/uniwidth.in.h deleted file mode 100644 index 8931cc9b0..000000000 --- a/grub-core/gnulib/uniwidth.in.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Display width functions. - Copyright (C) 2001-2002, 2005, 2007, 2009-2013 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#ifndef _UNIWIDTH_H -#define _UNIWIDTH_H - -#include "unitypes.h" - -/* Get size_t. */ -#include - -/* Get locale_charset() declaration. */ -#include "localcharset.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Display width. */ - -/* These functions are locale dependent. The encoding argument identifies - the encoding (e.g. "ISO-8859-2" for Polish). */ - -/* Determine number of column positions required for UC. */ -extern int - uc_width (ucs4_t uc, const char *encoding) - _UC_ATTRIBUTE_PURE; - -/* Determine number of column positions required for first N units - (or fewer if S ends before this) in S. */ -extern int - u8_width (const uint8_t *s, size_t n, const char *encoding) - _UC_ATTRIBUTE_PURE; -extern int - u16_width (const uint16_t *s, size_t n, const char *encoding) - _UC_ATTRIBUTE_PURE; -extern int - u32_width (const uint32_t *s, size_t n, const char *encoding) - _UC_ATTRIBUTE_PURE; - -/* Determine number of column positions required for S. */ -extern int - u8_strwidth (const uint8_t *s, const char *encoding) - _UC_ATTRIBUTE_PURE; -extern int - u16_strwidth (const uint16_t *s, const char *encoding) - _UC_ATTRIBUTE_PURE; -extern int - u32_strwidth (const uint32_t *s, const char *encoding) - _UC_ATTRIBUTE_PURE; - - -#ifdef __cplusplus -} -#endif - -#endif /* _UNIWIDTH_H */ diff --git a/grub-core/gnulib/uniwidth/cjk.h b/grub-core/gnulib/uniwidth/cjk.h deleted file mode 100644 index 11b14dfec..000000000 --- a/grub-core/gnulib/uniwidth/cjk.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Test for CJK encoding. - Copyright (C) 2001-2002, 2005-2007, 2009-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2002. - - 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 "streq.h" - -static int -is_cjk_encoding (const char *encoding) -{ - if (0 - /* Legacy Japanese encodings */ - || STREQ_OPT (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0) - /* Legacy Chinese encodings */ - || STREQ_OPT (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) - || STREQ_OPT (encoding, "GBK", 'G', 'B', 'K', 0, 0, 0, 0, 0, 0) - || STREQ_OPT (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0) - || STREQ_OPT (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0) - /* Legacy Korean encodings */ - || STREQ_OPT (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) - || STREQ_OPT (encoding, "CP949", 'C', 'P', '9', '4', '9', 0, 0, 0, 0) - || STREQ_OPT (encoding, "JOHAB", 'J', 'O', 'H', 'A', 'B', 0, 0, 0, 0)) - return 1; - return 0; -} diff --git a/grub-core/gnulib/uniwidth/width.c b/grub-core/gnulib/uniwidth/width.c deleted file mode 100644 index 173d0872c..000000000 --- a/grub-core/gnulib/uniwidth/width.c +++ /dev/null @@ -1,368 +0,0 @@ -/* Determine display width of Unicode character. - Copyright (C) 2001-2002, 2006-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2002. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include "uniwidth.h" - -#include "cjk.h" - -/* - * Non-spacing attribute table. - * Consists of: - * - Non-spacing characters; generated from PropList.txt or - * "grep '^[^;]*;[^;]*;[^;]*;[^;]*;NSM;' UnicodeData.txt" - * - Format control characters; generated from - * "grep '^[^;]*;[^;]*;Cf;' UnicodeData.txt" - * - Zero width characters; generated from - * "grep '^[^;]*;ZERO WIDTH ' UnicodeData.txt" - */ -static const unsigned char nonspacing_table_data[27*64] = { - /* 0x0000-0x01ff */ - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0000-0x003f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x0040-0x007f */ - 0xff, 0xff, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, /* 0x0080-0x00bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00c0-0x00ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0100-0x013f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0140-0x017f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180-0x01bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0-0x01ff */ - /* 0x0200-0x03ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200-0x023f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240-0x027f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280-0x02bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c0-0x02ff */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x0300-0x033f */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, /* 0x0340-0x037f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0380-0x03bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x03c0-0x03ff */ - /* 0x0400-0x05ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0400-0x043f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0440-0x047f */ - 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0480-0x04bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04c0-0x04ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0500-0x053f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0540-0x057f */ - 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, /* 0x0580-0x05bf */ - 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x05c0-0x05ff */ - /* 0x0600-0x07ff */ - 0x0f, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, /* 0x0600-0x063f */ - 0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, /* 0x0640-0x067f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0680-0x06bf */ - 0x00, 0x00, 0xc0, 0xbf, 0x9f, 0x3d, 0x00, 0x00, /* 0x06c0-0x06ff */ - 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x0700-0x073f */ - 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0740-0x077f */ - 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, /* 0x0780-0x07bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x07c0-0x07ff */ - /* 0x0800-0x09ff */ - 0x00, 0x00, 0xc0, 0xfb, 0xef, 0x3e, 0x00, 0x00, /* 0x0800-0x083f */ - 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 0x0840-0x087f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0880-0x08bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08c0-0x08ff */ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, /* 0x0900-0x093f */ - 0xfe, 0x21, 0xfe, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0940-0x097f */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0980-0x09bf */ - 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x09c0-0x09ff */ - /* 0x0a00-0x0bff */ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a00-0x0a3f */ - 0x86, 0x39, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, /* 0x0a40-0x0a7f */ - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a80-0x0abf */ - 0xbe, 0x21, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0ac0-0x0aff */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0x0b00-0x0b3f */ - 0x1e, 0x20, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0b40-0x0b7f */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b80-0x0bbf */ - 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0bc0-0x0bff */ - /* 0x0c00-0x0dff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, /* 0x0c00-0x0c3f */ - 0xc1, 0x3d, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0c40-0x0c7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0c80-0x0cbf */ - 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0cc0-0x0cff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d00-0x0d3f */ - 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0d40-0x0d7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d80-0x0dbf */ - 0x00, 0x04, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0dc0-0x0dff */ - /* 0x0e00-0x0fff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x07, /* 0x0e00-0x0e3f */ - 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e40-0x0e7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x1b, /* 0x0e80-0x0ebf */ - 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0ec0-0x0eff */ - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xa0, 0x02, /* 0x0f00-0x0f3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, /* 0x0f40-0x0f7f */ - 0xdf, 0xe0, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, /* 0x0f80-0x0fbf */ - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0fc0-0x0fff */ - /* 0x1000-0x11ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x66, /* 0x1000-0x103f */ - 0x00, 0x00, 0x00, 0xc3, 0x01, 0x00, 0x1e, 0x00, /* 0x1040-0x107f */ - 0x64, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x1080-0x10bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c0-0x10ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1100-0x113f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1140-0x117f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1180-0x11bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11c0-0x11ff */ - /* 0x1200-0x13ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1200-0x123f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1240-0x127f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1280-0x12bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x12c0-0x12ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1300-0x133f */ - 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, /* 0x1340-0x137f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1380-0x13bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13c0-0x13ff */ - /* 0x1600-0x17ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1600-0x163f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1640-0x167f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1680-0x16bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16c0-0x16ff */ - 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, /* 0x1700-0x173f */ - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1740-0x177f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x3f, /* 0x1780-0x17bf */ - 0x40, 0xfe, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x17c0-0x17ff */ - /* 0x1800-0x19ff */ - 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1800-0x183f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1840-0x187f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x1880-0x18bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18c0-0x18ff */ - 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x04, 0x0e, /* 0x1900-0x193f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1940-0x197f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1980-0x19bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x19c0-0x19ff */ - /* 0x1a00-0x1bff */ - 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, /* 0x1a00-0x1a3f */ - 0x00, 0x00, 0x40, 0x7f, 0xe5, 0x1f, 0xf8, 0x9f, /* 0x1a40-0x1a7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a80-0x1abf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ac0-0x1aff */ - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x17, /* 0x1b00-0x1b3f */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x1b40-0x1b7f */ - 0x03, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x00, /* 0x1b80-0x1bbf */ - 0x00, 0x00, 0x00, 0x00, 0x40, 0xa3, 0x03, 0x00, /* 0x1bc0-0x1bff */ - /* 0x1c00-0x1dff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, /* 0x1c00-0x1c3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c40-0x1c7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c80-0x1cbf */ - 0x00, 0x00, 0xf7, 0xff, 0xfd, 0x21, 0x00, 0x00, /* 0x1cc0-0x1cff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d00-0x1d3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d40-0x1d7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d80-0x1dbf */ - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xf0, /* 0x1dc0-0x1dff */ - /* 0x2000-0x21ff */ - 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, /* 0x2000-0x203f */ - 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, /* 0x2040-0x207f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2080-0x20bf */ - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, /* 0x20c0-0x20ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2100-0x213f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2140-0x217f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2180-0x21bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x21c0-0x21ff */ - /* 0x2c00-0x2dff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c00-0x2c3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c40-0x2c7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c80-0x2cbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, /* 0x2cc0-0x2cff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d00-0x2d3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x2d40-0x2d7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d80-0x2dbf */ - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* 0x2dc0-0x2dff */ - /* 0x3000-0x31ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, /* 0x3000-0x303f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3040-0x307f */ - 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, /* 0x3080-0x30bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30c0-0x30ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3100-0x313f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3140-0x317f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3180-0x31bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x31c0-0x31ff */ - /* 0xa600-0xa7ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa600-0xa63f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x30, /* 0xa640-0xa67f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa680-0xa6bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0xa6c0-0xa6ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa700-0xa73f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa740-0xa77f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa780-0xa7bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa7c0-0xa7ff */ - /* 0xa800-0xa9ff */ - 0x44, 0x08, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0xa800-0xa83f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa840-0xa87f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa880-0xa8bf */ - 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, /* 0xa8c0-0xa8ff */ - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, /* 0xa900-0xa93f */ - 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa940-0xa97f */ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x13, /* 0xa980-0xa9bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa9c0-0xa9ff */ - /* 0xaa00-0xabff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x66, 0x00, /* 0xaa00-0xaa3f */ - 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa40-0xaa7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xc1, /* 0xaa80-0xaabf */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaac0-0xaaff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab00-0xab3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab40-0xab7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab80-0xabbf */ - 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00, /* 0xabc0-0xabff */ - /* 0xfa00-0xfbff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa00-0xfa3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa40-0xfa7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa80-0xfabf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfac0-0xfaff */ - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0xfb00-0xfb3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb40-0xfb7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb80-0xfbbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfbc0-0xfbff */ - /* 0xfe00-0xffff */ - 0xff, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, /* 0xfe00-0xfe3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe40-0xfe7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe80-0xfebf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xfec0-0xfeff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff00-0xff3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff40-0xff7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff80-0xffbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, /* 0xffc0-0xffff */ - /* 0x10000-0x101ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10000-0x1003f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10040-0x1007f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10080-0x100bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100c0-0x100ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10100-0x1013f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10140-0x1017f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10180-0x101bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* 0x101c0-0x101ff */ - /* 0x10a00-0x10bff */ - 0x6e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0x10a00-0x10a3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a40-0x10a7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a80-0x10abf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10ac0-0x10aff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b00-0x10b3f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b40-0x10b7f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b80-0x10bbf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10bc0-0x10bff */ - /* 0x11000-0x111ff */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11000-0x1103f */ - 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11040-0x1107f */ - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x26, /* 0x11080-0x110bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110c0-0x110ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11100-0x1113f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11140-0x1117f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11180-0x111bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x111c0-0x111ff */ - /* 0x1d000-0x1d1ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d000-0x1d03f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d040-0x1d07f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d080-0x1d0bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0c0-0x1d0ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d100-0x1d13f */ - 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xf8, 0xff, /* 0x1d140-0x1d17f */ - 0xe7, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x1d180-0x1d1bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d1c0-0x1d1ff */ - /* 0x1d200-0x1d3ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d200-0x1d23f */ - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d240-0x1d27f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d280-0x1d2bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d2c0-0x1d2ff */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d300-0x1d33f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d340-0x1d37f */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d380-0x1d3bf */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x1d3c0-0x1d3ff */ -}; -static const signed char nonspacing_table_ind[240] = { - 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000-0x0fff */ - 8, 9, -1, 10, 11, 12, 13, -1, /* 0x1000-0x1fff */ - 14, -1, -1, -1, -1, -1, 15, -1, /* 0x2000-0x2fff */ - 16, -1, -1, -1, -1, -1, -1, -1, /* 0x3000-0x3fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x4000-0x4fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x5000-0x5fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x6000-0x6fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x7000-0x7fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x8000-0x8fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9000-0x9fff */ - -1, -1, -1, 17, 18, 19, -1, -1, /* 0xa000-0xafff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb000-0xbfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc000-0xcfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd000-0xdfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe000-0xefff */ - -1, -1, -1, -1, -1, 20, -1, 21, /* 0xf000-0xffff */ - 22, -1, -1, -1, -1, 23, -1, -1, /* 0x10000-0x10fff */ - 24, -1, -1, -1, -1, -1, -1, -1, /* 0x11000-0x11fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x12000-0x12fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x13000-0x13fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x14000-0x14fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x15000-0x15fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x16000-0x16fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x17000-0x17fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18000-0x18fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x19000-0x19fff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1a000-0x1afff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1b000-0x1bfff */ - -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1c000-0x1cfff */ - 25, 26, -1, -1, -1, -1, -1, -1 /* 0x1d000-0x1dfff */ -}; - -/* Determine number of column positions required for UC. */ -int -uc_width (ucs4_t uc, const char *encoding) -{ - /* Test for non-spacing or control character. */ - if ((uc >> 9) < 240) - { - int ind = nonspacing_table_ind[uc >> 9]; - if (ind >= 0) - if ((nonspacing_table_data[64*ind + ((uc >> 3) & 63)] >> (uc & 7)) & 1) - { - if (uc > 0 && uc < 0xa0) - return -1; - else - return 0; - } - } - else if ((uc >> 9) == (0xe0000 >> 9)) - { - if (uc >= 0xe0100) - { - if (uc <= 0xe01ef) - return 0; - } - else - { - if (uc >= 0xe0020 ? uc <= 0xe007f : uc == 0xe0001) - return 0; - } - } - /* Test for double-width character. - * Generated from "grep '^[^;]\{4,5\};[WF]' EastAsianWidth.txt" - * and "grep '^[^;]\{4,5\};[^WF]' EastAsianWidth.txt" - */ - if (uc >= 0x1100 - && ((uc < 0x1160) /* Hangul Jamo */ - || (uc >= 0x2329 && uc < 0x232b) /* Angle Brackets */ - || (uc >= 0x2e80 && uc < 0xa4d0 /* CJK ... Yi */ - && !(uc == 0x303f) && !(uc >= 0x4dc0 && uc < 0x4e00)) - || (uc >= 0xac00 && uc < 0xd7a4) /* Hangul Syllables */ - || (uc >= 0xf900 && uc < 0xfb00) /* CJK Compatibility Ideographs */ - || (uc >= 0xfe10 && uc < 0xfe20) /* Presentation Forms for Vertical */ - || (uc >= 0xfe30 && uc < 0xfe70) /* CJK Compatibility Forms */ - || (uc >= 0xff00 && uc < 0xff61) /* Fullwidth Forms */ - || (uc >= 0xffe0 && uc < 0xffe7) /* Fullwidth Signs */ - || (uc >= 0x20000 && uc <= 0x2ffff) /* Supplementary Ideographic Plane */ - || (uc >= 0x30000 && uc <= 0x3ffff) /* Tertiary Ideographic Plane */ - ) ) - return 2; - /* In ancient CJK encodings, Cyrillic and most other characters are - double-width as well. */ - if (uc >= 0x00A1 && uc < 0xFF61 && uc != 0x20A9 - && is_cjk_encoding (encoding)) - return 2; - return 1; -} diff --git a/grub-core/gnulib/vasnprintf.c b/grub-core/gnulib/vasnprintf.c deleted file mode 100644 index 8fdab32ea..000000000 --- a/grub-core/gnulib/vasnprintf.c +++ /dev/null @@ -1,5606 +0,0 @@ -/* vsprintf with automatic memory allocation. - Copyright (C) 1999, 2002-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 . */ - -/* This file can be parametrized with the following macros: - VASNPRINTF The name of the function being defined. - FCHAR_T The element type of the format string. - DCHAR_T The element type of the destination (result) string. - FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters - in the format string are ASCII. MUST be set if - FCHAR_T and DCHAR_T are not the same type. - DIRECTIVE Structure denoting a format directive. - Depends on FCHAR_T. - DIRECTIVES Structure denoting the set of format directives of a - format string. Depends on FCHAR_T. - PRINTF_PARSE Function that parses a format string. - Depends on FCHAR_T. - DCHAR_CPY memcpy like function for DCHAR_T[] arrays. - DCHAR_SET memset like function for DCHAR_T[] arrays. - DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays. - SNPRINTF The system's snprintf (or similar) function. - This may be either snprintf or swprintf. - TCHAR_T The element type of the argument and result string - of the said SNPRINTF function. This may be either - char or wchar_t. The code exploits that - sizeof (TCHAR_T) | sizeof (DCHAR_T) and - alignof (TCHAR_T) <= alignof (DCHAR_T). - DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type. - DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[]. - DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t. - DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t. - DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */ - -/* Tell glibc's to provide a prototype for snprintf(). - This must come before because may include - , and once has been included, it's too late. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#ifndef VASNPRINTF -# include -#endif -#ifndef IN_LIBINTL -# include -#endif - -/* Specification. */ -#ifndef VASNPRINTF -# if WIDE_CHAR_VERSION -# include "vasnwprintf.h" -# else -# include "vasnprintf.h" -# endif -#endif - -#include /* localeconv() */ -#include /* snprintf(), sprintf() */ -#include /* abort(), malloc(), realloc(), free() */ -#include /* memcpy(), strlen() */ -#include /* errno */ -#include /* CHAR_BIT */ -#include /* DBL_MAX_EXP, LDBL_MAX_EXP */ -#if HAVE_NL_LANGINFO -# include -#endif -#ifndef VASNPRINTF -# if WIDE_CHAR_VERSION -# include "wprintf-parse.h" -# else -# include "printf-parse.h" -# endif -#endif - -/* Checked size_t computations. */ -#include "xsize.h" - -#include "verify.h" - -#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL -# include -# include "float+.h" -#endif - -#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL -# include -# include "isnand-nolibm.h" -#endif - -#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL -# include -# include "isnanl-nolibm.h" -# include "fpucw.h" -#endif - -#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL -# include -# include "isnand-nolibm.h" -# include "printf-frexp.h" -#endif - -#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL -# include -# include "isnanl-nolibm.h" -# include "printf-frexpl.h" -# include "fpucw.h" -#endif - -/* Default parameters. */ -#ifndef VASNPRINTF -# if WIDE_CHAR_VERSION -# define VASNPRINTF vasnwprintf -# define FCHAR_T wchar_t -# define DCHAR_T wchar_t -# define TCHAR_T wchar_t -# define DCHAR_IS_TCHAR 1 -# define DIRECTIVE wchar_t_directive -# define DIRECTIVES wchar_t_directives -# define PRINTF_PARSE wprintf_parse -# define DCHAR_CPY wmemcpy -# define DCHAR_SET wmemset -# else -# define VASNPRINTF vasnprintf -# define FCHAR_T char -# define DCHAR_T char -# define TCHAR_T char -# define DCHAR_IS_TCHAR 1 -# define DIRECTIVE char_directive -# define DIRECTIVES char_directives -# define PRINTF_PARSE printf_parse -# define DCHAR_CPY memcpy -# define DCHAR_SET memset -# endif -#endif -#if WIDE_CHAR_VERSION - /* TCHAR_T is wchar_t. */ -# define USE_SNPRINTF 1 -# if HAVE_DECL__SNWPRINTF - /* On Windows, the function swprintf() has a different signature than - on Unix; we use the function _snwprintf() or - on mingw - snwprintf() - instead. The mingw function snwprintf() has fewer bugs than the - MSVCRT function _snwprintf(), so prefer that. */ -# if defined __MINGW32__ -# define SNPRINTF snwprintf -# else -# define SNPRINTF _snwprintf -# endif -# else - /* Unix. */ -# define SNPRINTF swprintf -# endif -#else - /* TCHAR_T is char. */ - /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'. - But don't use it on BeOS, since BeOS snprintf produces no output if the - size argument is >= 0x3000000. - Also don't use it on Linux libc5, since there snprintf with size = 1 - writes any output without bounds, like sprintf. */ -# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1) -# define USE_SNPRINTF 1 -# else -# define USE_SNPRINTF 0 -# endif -# if HAVE_DECL__SNPRINTF - /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT - function _snprintf(), so prefer that. */ -# if defined __MINGW32__ -# define SNPRINTF snprintf - /* Here we need to call the native snprintf, not rpl_snprintf. */ -# undef snprintf -# else -# define SNPRINTF _snprintf -# endif -# else - /* Unix. */ -# define SNPRINTF snprintf - /* Here we need to call the native snprintf, not rpl_snprintf. */ -# undef snprintf -# endif -#endif -/* Here we need to call the native sprintf, not rpl_sprintf. */ -#undef sprintf - -/* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized" - warnings in this file. Use -Dlint to suppress them. */ -#ifdef lint -# define IF_LINT(Code) Code -#else -# define IF_LINT(Code) /* empty */ -#endif - -/* Avoid some warnings from "gcc -Wshadow". - This file doesn't use the exp() and remainder() functions. */ -#undef exp -#define exp expo -#undef remainder -#define remainder rem - -#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION -# if (HAVE_STRNLEN && !defined _AIX) -# define local_strnlen strnlen -# else -# ifndef local_strnlen_defined -# define local_strnlen_defined 1 -static size_t -local_strnlen (const char *string, size_t maxlen) -{ - const char *end = memchr (string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} -# endif -# endif -#endif - -#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T -# if HAVE_WCSLEN -# define local_wcslen wcslen -# else - /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid - a dependency towards this library, here is a local substitute. - Define this substitute only once, even if this file is included - twice in the same compilation unit. */ -# ifndef local_wcslen_defined -# define local_wcslen_defined 1 -static size_t -local_wcslen (const wchar_t *s) -{ - const wchar_t *ptr; - - for (ptr = s; *ptr != (wchar_t) 0; ptr++) - ; - return ptr - s; -} -# endif -# endif -#endif - -#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION -# if HAVE_WCSNLEN -# define local_wcsnlen wcsnlen -# else -# ifndef local_wcsnlen_defined -# define local_wcsnlen_defined 1 -static size_t -local_wcsnlen (const wchar_t *s, size_t maxlen) -{ - const wchar_t *ptr; - - for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--) - ; - return ptr - s; -} -# endif -# endif -#endif - -#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL -/* Determine the decimal-point character according to the current locale. */ -# ifndef decimal_point_char_defined -# define decimal_point_char_defined 1 -static char -decimal_point_char (void) -{ - const char *point; - /* Determine it in a multithread-safe way. We know nl_langinfo is - multithread-safe on glibc systems and Mac OS X systems, but is not required - to be multithread-safe by POSIX. sprintf(), however, is multithread-safe. - localeconv() is rarely multithread-safe. */ -# if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__)) - point = nl_langinfo (RADIXCHAR); -# elif 1 - char pointbuf[5]; - sprintf (pointbuf, "%#.0f", 1.0); - point = &pointbuf[1]; -# else - point = localeconv () -> decimal_point; -# endif - /* The decimal point is always a single byte: either '.' or ','. */ - return (point[0] != '\0' ? point[0] : '.'); -} -# endif -#endif - -#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL - -/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ -static int -is_infinite_or_zero (double x) -{ - return isnand (x) || x + x == x; -} - -#endif - -#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL - -/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */ -static int -is_infinite_or_zerol (long double x) -{ - return isnanl (x) || x + x == x; -} - -#endif - -#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL - -/* Converting 'long double' to decimal without rare rounding bugs requires - real bignums. We use the naming conventions of GNU gmp, but vastly simpler - (and slower) algorithms. */ - -typedef unsigned int mp_limb_t; -# define GMP_LIMB_BITS 32 -verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS); - -typedef unsigned long long mp_twolimb_t; -# define GMP_TWOLIMB_BITS 64 -verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS); - -/* Representation of a bignum >= 0. */ -typedef struct -{ - size_t nlimbs; - mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */ -} mpn_t; - -/* Compute the product of two bignums >= 0. - Return the allocated memory in case of success, NULL in case of memory - allocation failure. */ -static void * -multiply (mpn_t src1, mpn_t src2, mpn_t *dest) -{ - const mp_limb_t *p1; - const mp_limb_t *p2; - size_t len1; - size_t len2; - - if (src1.nlimbs <= src2.nlimbs) - { - len1 = src1.nlimbs; - p1 = src1.limbs; - len2 = src2.nlimbs; - p2 = src2.limbs; - } - else - { - len1 = src2.nlimbs; - p1 = src2.limbs; - len2 = src1.nlimbs; - p2 = src1.limbs; - } - /* Now 0 <= len1 <= len2. */ - if (len1 == 0) - { - /* src1 or src2 is zero. */ - dest->nlimbs = 0; - dest->limbs = (mp_limb_t *) malloc (1); - } - else - { - /* Here 1 <= len1 <= len2. */ - size_t dlen; - mp_limb_t *dp; - size_t k, i, j; - - dlen = len1 + len2; - dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t)); - if (dp == NULL) - return NULL; - for (k = len2; k > 0; ) - dp[--k] = 0; - for (i = 0; i < len1; i++) - { - mp_limb_t digit1 = p1[i]; - mp_twolimb_t carry = 0; - for (j = 0; j < len2; j++) - { - mp_limb_t digit2 = p2[j]; - carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; - carry += dp[i + j]; - dp[i + j] = (mp_limb_t) carry; - carry = carry >> GMP_LIMB_BITS; - } - dp[i + len2] = (mp_limb_t) carry; - } - /* Normalise. */ - while (dlen > 0 && dp[dlen - 1] == 0) - dlen--; - dest->nlimbs = dlen; - dest->limbs = dp; - } - return dest->limbs; -} - -/* Compute the quotient of a bignum a >= 0 and a bignum b > 0. - a is written as a = q * b + r with 0 <= r < b. q is the quotient, r - the remainder. - Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd, - q is incremented. - Return the allocated memory in case of success, NULL in case of memory - allocation failure. */ -static void * -divide (mpn_t a, mpn_t b, mpn_t *q) -{ - /* Algorithm: - First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]] - with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS). - If m=n=1, perform a single-precision division: - r:=0, j:=m, - while j>0 do - {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j = - = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r=n>1, perform a multiple-precision division: - We have a/b < beta^(m-n+1). - s:=intDsize-1-(highest bit in b[n-1]), 0<=s=beta/2. - For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).} - Compute q* : - q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]). - In case of overflow (q* >= beta) set q* := beta-1. - Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2] - and c3 := b[n-2] * q*. - {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow - occurred. Furthermore 0 <= c3 < beta^2. - If there was overflow and - r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2, - the next test can be skipped.} - While c3 > c2, {Here 0 <= c2 < c3 < beta^2} - Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2]. - If q* > 0: - Put r := r - b * q* * beta^j. In detail: - [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]]. - hence: u:=0, for i:=0 to n-1 do - u := u + q* * b[i], - r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry), - u:=u div beta (+ 1, if carry in subtraction) - r[n+j]:=r[n+j]-u. - {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1 - < q* + 1 <= beta, - the carry u does not overflow.} - If a negative carry occurs, put q* := q* - 1 - and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]]. - Set q[j] := q*. - Normalise [q[m-n],..,q[0]]; this yields the quotient q. - Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the - rest r. - The room for q[j] can be allocated at the memory location of r[n+j]. - Finally, round-to-even: - Shift r left by 1 bit. - If r > b or if r = b and q[0] is odd, q := q+1. - */ - const mp_limb_t *a_ptr = a.limbs; - size_t a_len = a.nlimbs; - const mp_limb_t *b_ptr = b.limbs; - size_t b_len = b.nlimbs; - mp_limb_t *roomptr; - mp_limb_t *tmp_roomptr = NULL; - mp_limb_t *q_ptr; - size_t q_len; - mp_limb_t *r_ptr; - size_t r_len; - - /* Allocate room for a_len+2 digits. - (Need a_len+1 digits for the real division and 1 more digit for the - final rounding of q.) */ - roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t)); - if (roomptr == NULL) - return NULL; - - /* Normalise a. */ - while (a_len > 0 && a_ptr[a_len - 1] == 0) - a_len--; - - /* Normalise b. */ - for (;;) - { - if (b_len == 0) - /* Division by zero. */ - abort (); - if (b_ptr[b_len - 1] == 0) - b_len--; - else - break; - } - - /* Here m = a_len >= 0 and n = b_len > 0. */ - - if (a_len < b_len) - { - /* m beta^(m-2) <= a/b < beta^m */ - r_ptr = roomptr; - q_ptr = roomptr + 1; - { - mp_limb_t den = b_ptr[0]; - mp_limb_t remainder = 0; - const mp_limb_t *sourceptr = a_ptr + a_len; - mp_limb_t *destptr = q_ptr + a_len; - size_t count; - for (count = a_len; count > 0; count--) - { - mp_twolimb_t num = - ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr; - *--destptr = num / den; - remainder = num % den; - } - /* Normalise and store r. */ - if (remainder > 0) - { - r_ptr[0] = remainder; - r_len = 1; - } - else - r_len = 0; - /* Normalise q. */ - q_len = a_len; - if (q_ptr[q_len - 1] == 0) - q_len--; - } - } - else - { - /* n>1: multiple precision division. - beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==> - beta^(m-n-1) <= a/b < beta^(m-n+1). */ - /* Determine s. */ - size_t s; - { - mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */ - /* Determine s = GMP_LIMB_BITS - integer_length (msd). - Code copied from gnulib's integer_length.c. */ -# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) - s = __builtin_clz (msd); -# else -# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT - if (GMP_LIMB_BITS <= DBL_MANT_BIT) - { - /* Use 'double' operations. - Assumes an IEEE 754 'double' implementation. */ -# define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) -# define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1) -# define NWORDS \ - ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) - union { double value; unsigned int word[NWORDS]; } m; - - /* Use a single integer to floating-point conversion. */ - m.value = msd; - - s = GMP_LIMB_BITS - - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK) - - DBL_EXP_BIAS); - } - else -# undef NWORDS -# endif - { - s = 31; - if (msd >= 0x10000) - { - msd = msd >> 16; - s -= 16; - } - if (msd >= 0x100) - { - msd = msd >> 8; - s -= 8; - } - if (msd >= 0x10) - { - msd = msd >> 4; - s -= 4; - } - if (msd >= 0x4) - { - msd = msd >> 2; - s -= 2; - } - if (msd >= 0x2) - { - msd = msd >> 1; - s -= 1; - } - } -# endif - } - /* 0 <= s < GMP_LIMB_BITS. - Copy b, shifting it left by s bits. */ - if (s > 0) - { - tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t)); - if (tmp_roomptr == NULL) - { - free (roomptr); - return NULL; - } - { - const mp_limb_t *sourceptr = b_ptr; - mp_limb_t *destptr = tmp_roomptr; - mp_twolimb_t accu = 0; - size_t count; - for (count = b_len; count > 0; count--) - { - accu += (mp_twolimb_t) *sourceptr++ << s; - *destptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - /* accu must be zero, since that was how s was determined. */ - if (accu != 0) - abort (); - } - b_ptr = tmp_roomptr; - } - /* Copy a, shifting it left by s bits, yields r. - Memory layout: - At the beginning: r = roomptr[0..a_len], - at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */ - r_ptr = roomptr; - if (s == 0) - { - memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t)); - r_ptr[a_len] = 0; - } - else - { - const mp_limb_t *sourceptr = a_ptr; - mp_limb_t *destptr = r_ptr; - mp_twolimb_t accu = 0; - size_t count; - for (count = a_len; count > 0; count--) - { - accu += (mp_twolimb_t) *sourceptr++ << s; - *destptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - *destptr++ = (mp_limb_t) accu; - } - q_ptr = roomptr + b_len; - q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */ - { - size_t j = a_len - b_len; /* m-n */ - mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */ - mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */ - mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */ - ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd; - /* Division loop, traversed m-n+1 times. - j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */ - for (;;) - { - mp_limb_t q_star; - mp_limb_t c1; - if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */ - { - /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */ - mp_twolimb_t num = - ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS) - | r_ptr[j + b_len - 1]; - q_star = num / b_msd; - c1 = num % b_msd; - } - else - { - /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */ - q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */ - /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta - <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta - <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) - {<= beta !}. - If yes, jump directly to the subtraction loop. - (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta - <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */ - if (r_ptr[j + b_len] > b_msd - || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd) - /* r[j+n] >= b[n-1]+1 or - r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a - carry. */ - goto subtract; - } - /* q_star = q*, - c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, 0, decrease it by - b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2 - this can happen only twice. */ - if (c3 > c2) - { - q_star = q_star - 1; /* q* := q* - 1 */ - if (c3 - c2 > b_msdd) - q_star = q_star - 1; /* q* := q* - 1 */ - } - } - if (q_star > 0) - subtract: - { - /* Subtract r := r - b * q* * beta^j. */ - mp_limb_t cr; - { - const mp_limb_t *sourceptr = b_ptr; - mp_limb_t *destptr = r_ptr + j; - mp_twolimb_t carry = 0; - size_t count; - for (count = b_len; count > 0; count--) - { - /* Here 0 <= carry <= q*. */ - carry = - carry - + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++ - + (mp_limb_t) ~(*destptr); - /* Here 0 <= carry <= beta*q* + beta-1. */ - *destptr++ = ~(mp_limb_t) carry; - carry = carry >> GMP_LIMB_BITS; /* <= q* */ - } - cr = (mp_limb_t) carry; - } - /* Subtract cr from r_ptr[j + b_len], then forget about - r_ptr[j + b_len]. */ - if (cr > r_ptr[j + b_len]) - { - /* Subtraction gave a carry. */ - q_star = q_star - 1; /* q* := q* - 1 */ - /* Add b back. */ - { - const mp_limb_t *sourceptr = b_ptr; - mp_limb_t *destptr = r_ptr + j; - mp_limb_t carry = 0; - size_t count; - for (count = b_len; count > 0; count--) - { - mp_limb_t source1 = *sourceptr++; - mp_limb_t source2 = *destptr; - *destptr++ = source1 + source2 + carry; - carry = - (carry - ? source1 >= (mp_limb_t) ~source2 - : source1 > (mp_limb_t) ~source2); - } - } - /* Forget about the carry and about r[j+n]. */ - } - } - /* q* is determined. Store it as q[j]. */ - q_ptr[j] = q_star; - if (j == 0) - break; - j--; - } - } - r_len = b_len; - /* Normalise q. */ - if (q_ptr[q_len - 1] == 0) - q_len--; -# if 0 /* Not needed here, since we need r only to compare it with b/2, and - b is shifted left by s bits. */ - /* Shift r right by s bits. */ - if (s > 0) - { - mp_limb_t ptr = r_ptr + r_len; - mp_twolimb_t accu = 0; - size_t count; - for (count = r_len; count > 0; count--) - { - accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS; - accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s); - *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS); - } - } -# endif - /* Normalise r. */ - while (r_len > 0 && r_ptr[r_len - 1] == 0) - r_len--; - } - /* Compare r << 1 with b. */ - if (r_len > b_len) - goto increment_q; - { - size_t i; - for (i = b_len;;) - { - mp_limb_t r_i = - (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0) - | (i < r_len ? r_ptr[i] << 1 : 0); - mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0); - if (r_i > b_i) - goto increment_q; - if (r_i < b_i) - goto keep_q; - if (i == 0) - break; - i--; - } - } - if (q_len > 0 && ((q_ptr[0] & 1) != 0)) - /* q is odd. */ - increment_q: - { - size_t i; - for (i = 0; i < q_len; i++) - if (++(q_ptr[i]) != 0) - goto keep_q; - q_ptr[q_len++] = 1; - } - keep_q: - if (tmp_roomptr != NULL) - free (tmp_roomptr); - q->limbs = q_ptr; - q->nlimbs = q_len; - return roomptr; -} - -/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal - representation. - Destroys the contents of a. - Return the allocated memory - containing the decimal digits in low-to-high - order, terminated with a NUL character - in case of success, NULL in case - of memory allocation failure. */ -static char * -convert_to_decimal (mpn_t a, size_t extra_zeroes) -{ - mp_limb_t *a_ptr = a.limbs; - size_t a_len = a.nlimbs; - /* 0.03345 is slightly larger than log(2)/(9*log(10)). */ - size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1); - char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); - if (c_ptr != NULL) - { - char *d_ptr = c_ptr; - for (; extra_zeroes > 0; extra_zeroes--) - *d_ptr++ = '0'; - while (a_len > 0) - { - /* Divide a by 10^9, in-place. */ - mp_limb_t remainder = 0; - mp_limb_t *ptr = a_ptr + a_len; - size_t count; - for (count = a_len; count > 0; count--) - { - mp_twolimb_t num = - ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr; - *ptr = num / 1000000000; - remainder = num % 1000000000; - } - /* Store the remainder as 9 decimal digits. */ - for (count = 9; count > 0; count--) - { - *d_ptr++ = '0' + (remainder % 10); - remainder = remainder / 10; - } - /* Normalize a. */ - if (a_ptr[a_len - 1] == 0) - a_len--; - } - /* Remove leading zeroes. */ - while (d_ptr > c_ptr && d_ptr[-1] == '0') - d_ptr--; - /* But keep at least one zero. */ - if (d_ptr == c_ptr) - *d_ptr++ = '0'; - /* Terminate the string. */ - *d_ptr = '\0'; - } - return c_ptr; -} - -# if NEED_PRINTF_LONG_DOUBLE - -/* Assuming x is finite and >= 0: - write x as x = 2^e * m, where m is a bignum. - Return the allocated memory in case of success, NULL in case of memory - allocation failure. */ -static void * -decode_long_double (long double x, int *ep, mpn_t *mp) -{ - mpn_t m; - int exp; - long double y; - size_t i; - - /* Allocate memory for result. */ - m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; - m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); - if (m.limbs == NULL) - return NULL; - /* Split into exponential part and mantissa. */ - y = frexpl (x, &exp); - if (!(y >= 0.0L && y < 1.0L)) - abort (); - /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the - latter is an integer. */ - /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs. - I'm not sure whether it's safe to cast a 'long double' value between - 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only - 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int', - doesn't matter). */ -# if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0 -# if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 - { - mp_limb_t hi, lo; - y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2)); - hi = (int) y; - y -= hi; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - lo = (int) y; - y -= lo; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; - } -# else - { - mp_limb_t d; - y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS); - d = (int) y; - y -= d; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d; - } -# endif -# endif - for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) - { - mp_limb_t hi, lo; - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - hi = (int) y; - y -= hi; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - lo = (int) y; - y -= lo; - if (!(y >= 0.0L && y < 1.0L)) - abort (); - m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; - } -# if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess - precision. */ - if (!(y == 0.0L)) - abort (); -# endif - /* Normalise. */ - while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) - m.nlimbs--; - *mp = m; - *ep = exp - LDBL_MANT_BIT; - return m.limbs; -} - -# endif - -# if NEED_PRINTF_DOUBLE - -/* Assuming x is finite and >= 0: - write x as x = 2^e * m, where m is a bignum. - Return the allocated memory in case of success, NULL in case of memory - allocation failure. */ -static void * -decode_double (double x, int *ep, mpn_t *mp) -{ - mpn_t m; - int exp; - double y; - size_t i; - - /* Allocate memory for result. */ - m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS; - m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t)); - if (m.limbs == NULL) - return NULL; - /* Split into exponential part and mantissa. */ - y = frexp (x, &exp); - if (!(y >= 0.0 && y < 1.0)) - abort (); - /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the - latter is an integer. */ - /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs. - I'm not sure whether it's safe to cast a 'double' value between - 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only - 'double' values between 0 and 2^16 (to 'unsigned int' or 'int', - doesn't matter). */ -# if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0 -# if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2 - { - mp_limb_t hi, lo; - y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2)); - hi = (int) y; - y -= hi; - if (!(y >= 0.0 && y < 1.0)) - abort (); - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - lo = (int) y; - y -= lo; - if (!(y >= 0.0 && y < 1.0)) - abort (); - m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo; - } -# else - { - mp_limb_t d; - y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS); - d = (int) y; - y -= d; - if (!(y >= 0.0 && y < 1.0)) - abort (); - m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d; - } -# endif -# endif - for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; ) - { - mp_limb_t hi, lo; - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - hi = (int) y; - y -= hi; - if (!(y >= 0.0 && y < 1.0)) - abort (); - y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2); - lo = (int) y; - y -= lo; - if (!(y >= 0.0 && y < 1.0)) - abort (); - m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; - } - if (!(y == 0.0)) - abort (); - /* Normalise. */ - while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) - m.nlimbs--; - *mp = m; - *ep = exp - DBL_MANT_BIT; - return m.limbs; -} - -# endif - -/* Assuming x = 2^e * m is finite and >= 0, and n is an integer: - Returns the decimal representation of round (x * 10^n). - Return the allocated memory - containing the decimal digits in low-to-high - order, terminated with a NUL character - in case of success, NULL in case - of memory allocation failure. */ -static char * -scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n) -{ - int s; - size_t extra_zeroes; - unsigned int abs_n; - unsigned int abs_s; - mp_limb_t *pow5_ptr; - size_t pow5_len; - unsigned int s_limbs; - unsigned int s_bits; - mpn_t pow5; - mpn_t z; - void *z_memory; - char *digits; - - if (memory == NULL) - return NULL; - /* x = 2^e * m, hence - y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m) - = round (2^s * 5^n * m). */ - s = e + n; - extra_zeroes = 0; - /* Factor out a common power of 10 if possible. */ - if (s > 0 && n > 0) - { - extra_zeroes = (s < n ? s : n); - s -= extra_zeroes; - n -= extra_zeroes; - } - /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes. - Before converting to decimal, we need to compute - z = round (2^s * 5^n * m). */ - /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same - sign. 2.322 is slightly larger than log(5)/log(2). */ - abs_n = (n >= 0 ? n : -n); - abs_s = (s >= 0 ? s : -s); - pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1 - + abs_s / GMP_LIMB_BITS + 1) - * sizeof (mp_limb_t)); - if (pow5_ptr == NULL) - { - free (memory); - return NULL; - } - /* Initialize with 1. */ - pow5_ptr[0] = 1; - pow5_len = 1; - /* Multiply with 5^|n|. */ - if (abs_n > 0) - { - static mp_limb_t const small_pow5[13 + 1] = - { - 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, - 48828125, 244140625, 1220703125 - }; - unsigned int n13; - for (n13 = 0; n13 <= abs_n; n13 += 13) - { - mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13]; - size_t j; - mp_twolimb_t carry = 0; - for (j = 0; j < pow5_len; j++) - { - mp_limb_t digit2 = pow5_ptr[j]; - carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2; - pow5_ptr[j] = (mp_limb_t) carry; - carry = carry >> GMP_LIMB_BITS; - } - if (carry > 0) - pow5_ptr[pow5_len++] = (mp_limb_t) carry; - } - } - s_limbs = abs_s / GMP_LIMB_BITS; - s_bits = abs_s % GMP_LIMB_BITS; - if (n >= 0 ? s >= 0 : s <= 0) - { - /* Multiply with 2^|s|. */ - if (s_bits > 0) - { - mp_limb_t *ptr = pow5_ptr; - mp_twolimb_t accu = 0; - size_t count; - for (count = pow5_len; count > 0; count--) - { - accu += (mp_twolimb_t) *ptr << s_bits; - *ptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - if (accu > 0) - { - *ptr = (mp_limb_t) accu; - pow5_len++; - } - } - if (s_limbs > 0) - { - size_t count; - for (count = pow5_len; count > 0;) - { - count--; - pow5_ptr[s_limbs + count] = pow5_ptr[count]; - } - for (count = s_limbs; count > 0;) - { - count--; - pow5_ptr[count] = 0; - } - pow5_len += s_limbs; - } - pow5.limbs = pow5_ptr; - pow5.nlimbs = pow5_len; - if (n >= 0) - { - /* Multiply m with pow5. No division needed. */ - z_memory = multiply (m, pow5, &z); - } - else - { - /* Divide m by pow5 and round. */ - z_memory = divide (m, pow5, &z); - } - } - else - { - pow5.limbs = pow5_ptr; - pow5.nlimbs = pow5_len; - if (n >= 0) - { - /* n >= 0, s < 0. - Multiply m with pow5, then divide by 2^|s|. */ - mpn_t numerator; - mpn_t denominator; - void *tmp_memory; - tmp_memory = multiply (m, pow5, &numerator); - if (tmp_memory == NULL) - { - free (pow5_ptr); - free (memory); - return NULL; - } - /* Construct 2^|s|. */ - { - mp_limb_t *ptr = pow5_ptr + pow5_len; - size_t i; - for (i = 0; i < s_limbs; i++) - ptr[i] = 0; - ptr[s_limbs] = (mp_limb_t) 1 << s_bits; - denominator.limbs = ptr; - denominator.nlimbs = s_limbs + 1; - } - z_memory = divide (numerator, denominator, &z); - free (tmp_memory); - } - else - { - /* n < 0, s > 0. - Multiply m with 2^s, then divide by pow5. */ - mpn_t numerator; - mp_limb_t *num_ptr; - num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1) - * sizeof (mp_limb_t)); - if (num_ptr == NULL) - { - free (pow5_ptr); - free (memory); - return NULL; - } - { - mp_limb_t *destptr = num_ptr; - { - size_t i; - for (i = 0; i < s_limbs; i++) - *destptr++ = 0; - } - if (s_bits > 0) - { - const mp_limb_t *sourceptr = m.limbs; - mp_twolimb_t accu = 0; - size_t count; - for (count = m.nlimbs; count > 0; count--) - { - accu += (mp_twolimb_t) *sourceptr++ << s_bits; - *destptr++ = (mp_limb_t) accu; - accu = accu >> GMP_LIMB_BITS; - } - if (accu > 0) - *destptr++ = (mp_limb_t) accu; - } - else - { - const mp_limb_t *sourceptr = m.limbs; - size_t count; - for (count = m.nlimbs; count > 0; count--) - *destptr++ = *sourceptr++; - } - numerator.limbs = num_ptr; - numerator.nlimbs = destptr - num_ptr; - } - z_memory = divide (numerator, pow5, &z); - free (num_ptr); - } - } - free (pow5_ptr); - free (memory); - - /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */ - - if (z_memory == NULL) - return NULL; - digits = convert_to_decimal (z, extra_zeroes); - free (z_memory); - return digits; -} - -# if NEED_PRINTF_LONG_DOUBLE - -/* Assuming x is finite and >= 0, and n is an integer: - Returns the decimal representation of round (x * 10^n). - Return the allocated memory - containing the decimal digits in low-to-high - order, terminated with a NUL character - in case of success, NULL in case - of memory allocation failure. */ -static char * -scale10_round_decimal_long_double (long double x, int n) -{ - int e IF_LINT(= 0); - mpn_t m; - void *memory = decode_long_double (x, &e, &m); - return scale10_round_decimal_decoded (e, m, memory, n); -} - -# endif - -# if NEED_PRINTF_DOUBLE - -/* Assuming x is finite and >= 0, and n is an integer: - Returns the decimal representation of round (x * 10^n). - Return the allocated memory - containing the decimal digits in low-to-high - order, terminated with a NUL character - in case of success, NULL in case - of memory allocation failure. */ -static char * -scale10_round_decimal_double (double x, int n) -{ - int e IF_LINT(= 0); - mpn_t m; - void *memory = decode_double (x, &e, &m); - return scale10_round_decimal_decoded (e, m, memory, n); -} - -# endif - -# if NEED_PRINTF_LONG_DOUBLE - -/* Assuming x is finite and > 0: - Return an approximation for n with 10^n <= x < 10^(n+1). - The approximation is usually the right n, but may be off by 1 sometimes. */ -static int -floorlog10l (long double x) -{ - int exp; - long double y; - double z; - double l; - - /* Split into exponential part and mantissa. */ - y = frexpl (x, &exp); - if (!(y >= 0.0L && y < 1.0L)) - abort (); - if (y == 0.0L) - return INT_MIN; - if (y < 0.5L) - { - while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) - { - y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); - exp -= GMP_LIMB_BITS; - } - if (y < (1.0L / (1 << 16))) - { - y *= 1.0L * (1 << 16); - exp -= 16; - } - if (y < (1.0L / (1 << 8))) - { - y *= 1.0L * (1 << 8); - exp -= 8; - } - if (y < (1.0L / (1 << 4))) - { - y *= 1.0L * (1 << 4); - exp -= 4; - } - if (y < (1.0L / (1 << 2))) - { - y *= 1.0L * (1 << 2); - exp -= 2; - } - if (y < (1.0L / (1 << 1))) - { - y *= 1.0L * (1 << 1); - exp -= 1; - } - } - if (!(y >= 0.5L && y < 1.0L)) - abort (); - /* Compute an approximation for l = log2(x) = exp + log2(y). */ - l = exp; - z = y; - if (z < 0.70710678118654752444) - { - z *= 1.4142135623730950488; - l -= 0.5; - } - if (z < 0.8408964152537145431) - { - z *= 1.1892071150027210667; - l -= 0.25; - } - if (z < 0.91700404320467123175) - { - z *= 1.0905077326652576592; - l -= 0.125; - } - if (z < 0.9576032806985736469) - { - z *= 1.0442737824274138403; - l -= 0.0625; - } - /* Now 0.95 <= z <= 1.01. */ - z = 1 - z; - /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) - Four terms are enough to get an approximation with error < 10^-7. */ - l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); - /* Finally multiply with log(2)/log(10), yields an approximation for - log10(x). */ - l *= 0.30102999566398119523; - /* Round down to the next integer. */ - return (int) l + (l < 0 ? -1 : 0); -} - -# endif - -# if NEED_PRINTF_DOUBLE - -/* Assuming x is finite and > 0: - Return an approximation for n with 10^n <= x < 10^(n+1). - The approximation is usually the right n, but may be off by 1 sometimes. */ -static int -floorlog10 (double x) -{ - int exp; - double y; - double z; - double l; - - /* Split into exponential part and mantissa. */ - y = frexp (x, &exp); - if (!(y >= 0.0 && y < 1.0)) - abort (); - if (y == 0.0) - return INT_MIN; - if (y < 0.5) - { - while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2)))) - { - y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2)); - exp -= GMP_LIMB_BITS; - } - if (y < (1.0 / (1 << 16))) - { - y *= 1.0 * (1 << 16); - exp -= 16; - } - if (y < (1.0 / (1 << 8))) - { - y *= 1.0 * (1 << 8); - exp -= 8; - } - if (y < (1.0 / (1 << 4))) - { - y *= 1.0 * (1 << 4); - exp -= 4; - } - if (y < (1.0 / (1 << 2))) - { - y *= 1.0 * (1 << 2); - exp -= 2; - } - if (y < (1.0 / (1 << 1))) - { - y *= 1.0 * (1 << 1); - exp -= 1; - } - } - if (!(y >= 0.5 && y < 1.0)) - abort (); - /* Compute an approximation for l = log2(x) = exp + log2(y). */ - l = exp; - z = y; - if (z < 0.70710678118654752444) - { - z *= 1.4142135623730950488; - l -= 0.5; - } - if (z < 0.8408964152537145431) - { - z *= 1.1892071150027210667; - l -= 0.25; - } - if (z < 0.91700404320467123175) - { - z *= 1.0905077326652576592; - l -= 0.125; - } - if (z < 0.9576032806985736469) - { - z *= 1.0442737824274138403; - l -= 0.0625; - } - /* Now 0.95 <= z <= 1.01. */ - z = 1 - z; - /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...) - Four terms are enough to get an approximation with error < 10^-7. */ - l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25))); - /* Finally multiply with log(2)/log(10), yields an approximation for - log10(x). */ - l *= 0.30102999566398119523; - /* Round down to the next integer. */ - return (int) l + (l < 0 ? -1 : 0); -} - -# endif - -/* Tests whether a string of digits consists of exactly PRECISION zeroes and - a single '1' digit. */ -static int -is_borderline (const char *digits, size_t precision) -{ - for (; precision > 0; precision--, digits++) - if (*digits != '0') - return 0; - if (*digits != '1') - return 0; - digits++; - return *digits == '\0'; -} - -#endif - -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 - -/* Use a different function name, to make it possible that the 'wchar_t' - parametrization and the 'char' parametrization get compiled in the same - translation unit. */ -# if WIDE_CHAR_VERSION -# define MAX_ROOM_NEEDED wmax_room_needed -# else -# define MAX_ROOM_NEEDED max_room_needed -# endif - -/* Returns the number of TCHAR_T units needed as temporary space for the result - of sprintf or SNPRINTF of a single conversion directive. */ -static size_t -MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, - arg_type type, int flags, size_t width, int has_precision, - size_t precision, int pad_ourselves) -{ - size_t tmp_length; - - switch (conversion) - { - case 'd': case 'i': case 'u': -# if HAVE_LONG_LONG_INT - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.30103 /* binary -> decimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Multiply by 2, as an estimate for FLAG_GROUP. */ - tmp_length = xsum (tmp_length, tmp_length); - /* Add 1, to account for a leading sign. */ - tmp_length = xsum (tmp_length, 1); - break; - - case 'o': -# if HAVE_LONG_LONG_INT - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.333334 /* binary -> octal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Add 1, to account for a leading sign. */ - tmp_length = xsum (tmp_length, 1); - break; - - case 'x': case 'X': -# if HAVE_LONG_LONG_INT - if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long long) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else -# endif - if (type == TYPE_LONGINT || type == TYPE_ULONGINT) - tmp_length = - (unsigned int) (sizeof (unsigned long) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (sizeof (unsigned int) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Add 2, to account for a leading sign or alternate form. */ - tmp_length = xsum (tmp_length, 2); - break; - - case 'f': case 'F': - if (type == TYPE_LONGDOUBLE) - tmp_length = - (unsigned int) (LDBL_MAX_EXP - * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ - ) - + 1 /* turn floor into ceil */ - + 10; /* sign, decimal point etc. */ - else - tmp_length = - (unsigned int) (DBL_MAX_EXP - * 0.30103 /* binary -> decimal */ - * 2 /* estimate for FLAG_GROUP */ - ) - + 1 /* turn floor into ceil */ - + 10; /* sign, decimal point etc. */ - tmp_length = xsum (tmp_length, precision); - break; - - case 'e': case 'E': case 'g': case 'G': - tmp_length = - 12; /* sign, decimal point, exponent etc. */ - tmp_length = xsum (tmp_length, precision); - break; - - case 'a': case 'A': - if (type == TYPE_LONGDOUBLE) - tmp_length = - (unsigned int) (LDBL_DIG - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) (DBL_DIG - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Account for sign, decimal point etc. */ - tmp_length = xsum (tmp_length, 12); - break; - - case 'c': -# if HAVE_WINT_T && !WIDE_CHAR_VERSION - if (type == TYPE_WIDE_CHAR) - tmp_length = MB_CUR_MAX; - else -# endif - tmp_length = 1; - break; - - case 's': -# if HAVE_WCHAR_T - if (type == TYPE_WIDE_STRING) - { -# if WIDE_CHAR_VERSION - /* ISO C says about %ls in fwprintf: - "If the precision is not specified or is greater than the size - of the array, the array shall contain a null wide character." - So if there is a precision, we must not use wcslen. */ - const wchar_t *arg = ap->arg[arg_index].a.a_wide_string; - - if (has_precision) - tmp_length = local_wcsnlen (arg, precision); - else - tmp_length = local_wcslen (arg); -# else - /* ISO C says about %ls in fprintf: - "If a precision is specified, no more than that many bytes are - written (including shift sequences, if any), and the array - shall contain a null wide character if, to equal the multibyte - character sequence length given by the precision, the function - would need to access a wide character one past the end of the - array." - So if there is a precision, we must not use wcslen. */ - /* This case has already been handled separately in VASNPRINTF. */ - abort (); -# endif - } - else -# endif - { -# if WIDE_CHAR_VERSION - /* ISO C says about %s in fwprintf: - "If the precision is not specified or is greater than the size - of the converted array, the converted array shall contain a - null wide character." - So if there is a precision, we must not use strlen. */ - /* This case has already been handled separately in VASNPRINTF. */ - abort (); -# else - /* ISO C says about %s in fprintf: - "If the precision is not specified or greater than the size of - the array, the array shall contain a null character." - So if there is a precision, we must not use strlen. */ - const char *arg = ap->arg[arg_index].a.a_string; - - if (has_precision) - tmp_length = local_strnlen (arg, precision); - else - tmp_length = strlen (arg); -# endif - } - break; - - case 'p': - tmp_length = - (unsigned int) (sizeof (void *) * CHAR_BIT - * 0.25 /* binary -> hexadecimal */ - ) - + 1 /* turn floor into ceil */ - + 2; /* account for leading 0x */ - break; - - default: - abort (); - } - - if (!pad_ourselves) - { -# if ENABLE_UNISTDIO - /* Padding considers the number of characters, therefore the number of - elements after padding may be - > max (tmp_length, width) - but is certainly - <= tmp_length + width. */ - tmp_length = xsum (tmp_length, width); -# else - /* Padding considers the number of elements, says POSIX. */ - if (tmp_length < width) - tmp_length = width; -# endif - } - - tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ - - return tmp_length; -} - -#endif - -DCHAR_T * -VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, - const FCHAR_T *format, va_list args) -{ - DIRECTIVES d; - arguments a; - - if (PRINTF_PARSE (format, &d, &a) < 0) - /* errno is already set. */ - return NULL; - -#define CLEANUP() \ - if (d.dir != d.direct_alloc_dir) \ - free (d.dir); \ - if (a.arg != a.direct_alloc_arg) \ - free (a.arg); - - if (PRINTF_FETCHARGS (args, &a) < 0) - { - CLEANUP (); - errno = EINVAL; - return NULL; - } - - { - size_t buf_neededlength; - TCHAR_T *buf; - TCHAR_T *buf_malloced; - const FCHAR_T *cp; - size_t i; - DIRECTIVE *dp; - /* Output string accumulator. */ - DCHAR_T *result; - size_t allocated; - size_t length; - - /* Allocate a small buffer that will hold a directive passed to - sprintf or snprintf. */ - buf_neededlength = - xsum4 (7, d.max_width_length, d.max_precision_length, 6); -#if HAVE_ALLOCA - if (buf_neededlength < 4000 / sizeof (TCHAR_T)) - { - buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T)); - buf_malloced = NULL; - } - else -#endif - { - size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T)); - if (size_overflow_p (buf_memsize)) - goto out_of_memory_1; - buf = (TCHAR_T *) malloc (buf_memsize); - if (buf == NULL) - goto out_of_memory_1; - buf_malloced = buf; - } - - if (resultbuf != NULL) - { - result = resultbuf; - allocated = *lengthp; - } - else - { - result = NULL; - allocated = 0; - } - length = 0; - /* Invariants: - result is either == resultbuf or == NULL or malloc-allocated. - If length > 0, then result != NULL. */ - - /* Ensures that allocated >= needed. Aborts through a jump to - out_of_memory if needed is SIZE_MAX or otherwise too big. */ -#define ENSURE_ALLOCATION(needed) \ - if ((needed) > allocated) \ - { \ - size_t memory_size; \ - DCHAR_T *memory; \ - \ - allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \ - if ((needed) > allocated) \ - allocated = (needed); \ - memory_size = xtimes (allocated, sizeof (DCHAR_T)); \ - if (size_overflow_p (memory_size)) \ - goto out_of_memory; \ - if (result == resultbuf || result == NULL) \ - memory = (DCHAR_T *) malloc (memory_size); \ - else \ - memory = (DCHAR_T *) realloc (result, memory_size); \ - if (memory == NULL) \ - goto out_of_memory; \ - if (result == resultbuf && length > 0) \ - DCHAR_CPY (memory, result, length); \ - result = memory; \ - } - - for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++) - { - if (cp != dp->dir_start) - { - size_t n = dp->dir_start - cp; - size_t augmented_length = xsum (length, n); - - ENSURE_ALLOCATION (augmented_length); - /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we - need that the format string contains only ASCII characters - if FCHAR_T and DCHAR_T are not the same type. */ - if (sizeof (FCHAR_T) == sizeof (DCHAR_T)) - { - DCHAR_CPY (result + length, (const DCHAR_T *) cp, n); - length = augmented_length; - } - else - { - do - result[length++] = (unsigned char) *cp++; - while (--n > 0); - } - } - if (i == d.count) - break; - - /* Execute a single directive. */ - if (dp->conversion == '%') - { - size_t augmented_length; - - if (!(dp->arg_index == ARG_NONE)) - abort (); - augmented_length = xsum (length, 1); - ENSURE_ALLOCATION (augmented_length); - result[length] = '%'; - length = augmented_length; - } - else - { - if (!(dp->arg_index != ARG_NONE)) - abort (); - - if (dp->conversion == 'n') - { - switch (a.arg[dp->arg_index].type) - { - case TYPE_COUNT_SCHAR_POINTER: - *a.arg[dp->arg_index].a.a_count_schar_pointer = length; - break; - case TYPE_COUNT_SHORT_POINTER: - *a.arg[dp->arg_index].a.a_count_short_pointer = length; - break; - case TYPE_COUNT_INT_POINTER: - *a.arg[dp->arg_index].a.a_count_int_pointer = length; - break; - case TYPE_COUNT_LONGINT_POINTER: - *a.arg[dp->arg_index].a.a_count_longint_pointer = length; - break; -#if HAVE_LONG_LONG_INT - case TYPE_COUNT_LONGLONGINT_POINTER: - *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length; - break; -#endif - default: - abort (); - } - } -#if ENABLE_UNISTDIO - /* The unistdio extensions. */ - else if (dp->conversion == 'U') - { - arg_type type = a.arg[dp->arg_index].type; - int flags = dp->flags; - int has_width; - size_t width; - int has_precision; - size_t precision; - - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } - - has_precision = 0; - precision = 0; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } - - switch (type) - { - case TYPE_U8_STRING: - { - const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string; - const uint8_t *arg_end; - size_t characters; - - if (has_precision) - { - /* Use only PRECISION characters, from the left. */ - arg_end = arg; - characters = 0; - for (; precision > 0; precision--) - { - int count = u8_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else if (has_width) - { - /* Use the entire string, and count the number of - characters. */ - arg_end = arg; - characters = 0; - for (;;) - { - int count = u8_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else - { - /* Use the entire string. */ - arg_end = arg + u8_strlen (arg); - /* The number of characters doesn't matter. */ - characters = 0; - } - - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - -# if DCHAR_IS_UINT8_T - { - size_t n = arg_end - arg; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_CPY (result + length, arg, n); - length += n; - } -# else - { /* Convert. */ - DCHAR_T *converted = result + length; - size_t converted_len = allocated - length; -# if DCHAR_IS_TCHAR - /* Convert from UTF-8 to locale encoding. */ - converted = - u8_conv_to_encoding (locale_charset (), - iconveh_question_mark, - arg, arg_end - arg, NULL, - converted, &converted_len); -# else - /* Convert from UTF-8 to UTF-16/UTF-32. */ - converted = - U8_TO_DCHAR (arg, arg_end - arg, - converted, &converted_len); -# endif - if (converted == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - if (converted != result + length) - { - ENSURE_ALLOCATION (xsum (length, converted_len)); - DCHAR_CPY (result + length, converted, converted_len); - free (converted); - } - length += converted_len; - } -# endif - - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } - break; - - case TYPE_U16_STRING: - { - const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string; - const uint16_t *arg_end; - size_t characters; - - if (has_precision) - { - /* Use only PRECISION characters, from the left. */ - arg_end = arg; - characters = 0; - for (; precision > 0; precision--) - { - int count = u16_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else if (has_width) - { - /* Use the entire string, and count the number of - characters. */ - arg_end = arg; - characters = 0; - for (;;) - { - int count = u16_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else - { - /* Use the entire string. */ - arg_end = arg + u16_strlen (arg); - /* The number of characters doesn't matter. */ - characters = 0; - } - - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - -# if DCHAR_IS_UINT16_T - { - size_t n = arg_end - arg; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_CPY (result + length, arg, n); - length += n; - } -# else - { /* Convert. */ - DCHAR_T *converted = result + length; - size_t converted_len = allocated - length; -# if DCHAR_IS_TCHAR - /* Convert from UTF-16 to locale encoding. */ - converted = - u16_conv_to_encoding (locale_charset (), - iconveh_question_mark, - arg, arg_end - arg, NULL, - converted, &converted_len); -# else - /* Convert from UTF-16 to UTF-8/UTF-32. */ - converted = - U16_TO_DCHAR (arg, arg_end - arg, - converted, &converted_len); -# endif - if (converted == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - if (converted != result + length) - { - ENSURE_ALLOCATION (xsum (length, converted_len)); - DCHAR_CPY (result + length, converted, converted_len); - free (converted); - } - length += converted_len; - } -# endif - - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } - break; - - case TYPE_U32_STRING: - { - const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string; - const uint32_t *arg_end; - size_t characters; - - if (has_precision) - { - /* Use only PRECISION characters, from the left. */ - arg_end = arg; - characters = 0; - for (; precision > 0; precision--) - { - int count = u32_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else if (has_width) - { - /* Use the entire string, and count the number of - characters. */ - arg_end = arg; - characters = 0; - for (;;) - { - int count = u32_strmblen (arg_end); - if (count == 0) - break; - if (count < 0) - { - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else - { - /* Use the entire string. */ - arg_end = arg + u32_strlen (arg); - /* The number of characters doesn't matter. */ - characters = 0; - } - - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - -# if DCHAR_IS_UINT32_T - { - size_t n = arg_end - arg; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_CPY (result + length, arg, n); - length += n; - } -# else - { /* Convert. */ - DCHAR_T *converted = result + length; - size_t converted_len = allocated - length; -# if DCHAR_IS_TCHAR - /* Convert from UTF-32 to locale encoding. */ - converted = - u32_conv_to_encoding (locale_charset (), - iconveh_question_mark, - arg, arg_end - arg, NULL, - converted, &converted_len); -# else - /* Convert from UTF-32 to UTF-8/UTF-16. */ - converted = - U32_TO_DCHAR (arg, arg_end - arg, - converted, &converted_len); -# endif - if (converted == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - if (converted != result + length) - { - ENSURE_ALLOCATION (xsum (length, converted_len)); - DCHAR_CPY (result + length, converted, converted_len); - free (converted); - } - length += converted_len; - } -# endif - - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } - break; - - default: - abort (); - } - } -#endif -#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T - else if (dp->conversion == 's' -# if WIDE_CHAR_VERSION - && a.arg[dp->arg_index].type != TYPE_WIDE_STRING -# else - && a.arg[dp->arg_index].type == TYPE_WIDE_STRING -# endif - ) - { - /* The normal handling of the 's' directive below requires - allocating a temporary buffer. The determination of its - length (tmp_length), in the case when a precision is - specified, below requires a conversion between a char[] - string and a wchar_t[] wide string. It could be done, but - we have no guarantee that the implementation of sprintf will - use the exactly same algorithm. Without this guarantee, it - is possible to have buffer overrun bugs. In order to avoid - such bugs, we implement the entire processing of the 's' - directive ourselves. */ - int flags = dp->flags; - int has_width; - size_t width; - int has_precision; - size_t precision; - - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } - - has_precision = 0; - precision = 6; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } - -# if WIDE_CHAR_VERSION - /* %s in vasnwprintf. See the specification of fwprintf. */ - { - const char *arg = a.arg[dp->arg_index].a.a_string; - const char *arg_end; - size_t characters; - - if (has_precision) - { - /* Use only as many bytes as needed to produce PRECISION - wide characters, from the left. */ -# if HAVE_MBRTOWC - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - arg_end = arg; - characters = 0; - for (; precision > 0; precision--) - { - int count; -# if HAVE_MBRTOWC - count = mbrlen (arg_end, MB_CUR_MAX, &state); -# else - count = mblen (arg_end, MB_CUR_MAX); -# endif - if (count == 0) - /* Found the terminating NUL. */ - break; - if (count < 0) - { - /* Invalid or incomplete multibyte character. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else if (has_width) - { - /* Use the entire string, and count the number of wide - characters. */ -# if HAVE_MBRTOWC - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - arg_end = arg; - characters = 0; - for (;;) - { - int count; -# if HAVE_MBRTOWC - count = mbrlen (arg_end, MB_CUR_MAX, &state); -# else - count = mblen (arg_end, MB_CUR_MAX); -# endif - if (count == 0) - /* Found the terminating NUL. */ - break; - if (count < 0) - { - /* Invalid or incomplete multibyte character. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end += count; - characters++; - } - } - else - { - /* Use the entire string. */ - arg_end = arg + strlen (arg); - /* The number of characters doesn't matter. */ - characters = 0; - } - - if (has_width && width > characters - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - - if (has_precision || has_width) - { - /* We know the number of wide characters in advance. */ - size_t remaining; -# if HAVE_MBRTOWC - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - ENSURE_ALLOCATION (xsum (length, characters)); - for (remaining = characters; remaining > 0; remaining--) - { - wchar_t wc; - int count; -# if HAVE_MBRTOWC - count = mbrtowc (&wc, arg, arg_end - arg, &state); -# else - count = mbtowc (&wc, arg, arg_end - arg); -# endif - if (count <= 0) - /* mbrtowc not consistent with mbrlen, or mbtowc - not consistent with mblen. */ - abort (); - result[length++] = wc; - arg += count; - } - if (!(arg == arg_end)) - abort (); - } - else - { -# if HAVE_MBRTOWC - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - while (arg < arg_end) - { - wchar_t wc; - int count; -# if HAVE_MBRTOWC - count = mbrtowc (&wc, arg, arg_end - arg, &state); -# else - count = mbtowc (&wc, arg, arg_end - arg); -# endif - if (count <= 0) - /* mbrtowc not consistent with mbrlen, or mbtowc - not consistent with mblen. */ - abort (); - ENSURE_ALLOCATION (xsum (length, 1)); - result[length++] = wc; - arg += count; - } - } - - if (has_width && width > characters - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - characters; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } -# else - /* %ls in vasnprintf. See the specification of fprintf. */ - { - const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; - const wchar_t *arg_end; - size_t characters; -# if !DCHAR_IS_TCHAR - /* This code assumes that TCHAR_T is 'char'. */ - verify (sizeof (TCHAR_T) == 1); - TCHAR_T *tmpsrc; - DCHAR_T *tmpdst; - size_t tmpdst_len; -# endif - size_t w; - - if (has_precision) - { - /* Use only as many wide characters as needed to produce - at most PRECISION bytes, from the left. */ -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - arg_end = arg; - characters = 0; - while (precision > 0) - { - char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ - int count; - - if (*arg_end == 0) - /* Found the terminating null wide character. */ - break; -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg_end, &state); -# else - count = wctomb (cbuf, *arg_end); -# endif - if (count < 0) - { - /* Cannot convert. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - if (precision < count) - break; - arg_end++; - characters += count; - precision -= count; - } - } -# if DCHAR_IS_TCHAR - else if (has_width) -# else - else -# endif - { - /* Use the entire string, and count the number of - bytes. */ -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - arg_end = arg; - characters = 0; - for (;;) - { - char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ - int count; - - if (*arg_end == 0) - /* Found the terminating null wide character. */ - break; -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg_end, &state); -# else - count = wctomb (cbuf, *arg_end); -# endif - if (count < 0) - { - /* Cannot convert. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - arg_end++; - characters += count; - } - } -# if DCHAR_IS_TCHAR - else - { - /* Use the entire string. */ - arg_end = arg + local_wcslen (arg); - /* The number of bytes doesn't matter. */ - characters = 0; - } -# endif - -# if !DCHAR_IS_TCHAR - /* Convert the string into a piece of temporary memory. */ - tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T)); - if (tmpsrc == NULL) - goto out_of_memory; - { - TCHAR_T *tmpptr = tmpsrc; - size_t remaining; -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - for (remaining = characters; remaining > 0; ) - { - char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ - int count; - - if (*arg == 0) - abort (); -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg, &state); -# else - count = wctomb (cbuf, *arg); -# endif - if (count <= 0) - /* Inconsistency. */ - abort (); - memcpy (tmpptr, cbuf, count); - tmpptr += count; - arg++; - remaining -= count; - } - if (!(arg == arg_end)) - abort (); - } - - /* Convert from TCHAR_T[] to DCHAR_T[]. */ - tmpdst = - DCHAR_CONV_FROM_ENCODING (locale_charset (), - iconveh_question_mark, - tmpsrc, characters, - NULL, - NULL, &tmpdst_len); - if (tmpdst == NULL) - { - int saved_errno = errno; - free (tmpsrc); - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - free (tmpsrc); -# endif - - if (has_width) - { -# if ENABLE_UNISTDIO - /* Outside POSIX, it's preferable to compare the width - against the number of _characters_ of the converted - value. */ - w = DCHAR_MBSNLEN (result + length, characters); -# else - /* The width is compared against the number of _bytes_ - of the converted value, says POSIX. */ - w = characters; -# endif - } - else - /* w doesn't matter. */ - w = 0; - - if (has_width && width > w - && !(dp->flags & FLAG_LEFT)) - { - size_t n = width - w; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - -# if DCHAR_IS_TCHAR - if (has_precision || has_width) - { - /* We know the number of bytes in advance. */ - size_t remaining; -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - ENSURE_ALLOCATION (xsum (length, characters)); - for (remaining = characters; remaining > 0; ) - { - char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ - int count; - - if (*arg == 0) - abort (); -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg, &state); -# else - count = wctomb (cbuf, *arg); -# endif - if (count <= 0) - /* Inconsistency. */ - abort (); - memcpy (result + length, cbuf, count); - length += count; - arg++; - remaining -= count; - } - if (!(arg == arg_end)) - abort (); - } - else - { -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - mbstate_t state; - memset (&state, '\0', sizeof (mbstate_t)); -# endif - while (arg < arg_end) - { - char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */ - int count; - - if (*arg == 0) - abort (); -# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t - count = wcrtomb (cbuf, *arg, &state); -# else - count = wctomb (cbuf, *arg); -# endif - if (count <= 0) - { - /* Cannot convert. */ - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EILSEQ; - return NULL; - } - ENSURE_ALLOCATION (xsum (length, count)); - memcpy (result + length, cbuf, count); - length += count; - arg++; - } - } -# else - ENSURE_ALLOCATION (xsum (length, tmpdst_len)); - DCHAR_CPY (result + length, tmpdst, tmpdst_len); - free (tmpdst); - length += tmpdst_len; -# endif - - if (has_width && width > w - && (dp->flags & FLAG_LEFT)) - { - size_t n = width - w; - ENSURE_ALLOCATION (xsum (length, n)); - DCHAR_SET (result + length, ' ', n); - length += n; - } - } -# endif - } -#endif -#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL - else if ((dp->conversion == 'a' || dp->conversion == 'A') -# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE)) - && (0 -# if NEED_PRINTF_DOUBLE - || a.arg[dp->arg_index].type == TYPE_DOUBLE -# endif -# if NEED_PRINTF_LONG_DOUBLE - || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE -# endif - ) -# endif - ) - { - arg_type type = a.arg[dp->arg_index].type; - int flags = dp->flags; - int has_width; - size_t width; - int has_precision; - size_t precision; - size_t tmp_length; - DCHAR_T tmpbuf[700]; - DCHAR_T *tmp; - DCHAR_T *pad_ptr; - DCHAR_T *p; - - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } - - has_precision = 0; - precision = 0; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } - - /* Allocate a temporary buffer of sufficient size. */ - if (type == TYPE_LONGDOUBLE) - tmp_length = - (unsigned int) ((LDBL_DIG + 1) - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - else - tmp_length = - (unsigned int) ((DBL_DIG + 1) - * 0.831 /* decimal -> hexadecimal */ - ) - + 1; /* turn floor into ceil */ - if (tmp_length < precision) - tmp_length = precision; - /* Account for sign, decimal point etc. */ - tmp_length = xsum (tmp_length, 12); - - if (tmp_length < width) - tmp_length = width; - - tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ - - if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) - tmp = tmpbuf; - else - { - size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); - - if (size_overflow_p (tmp_memsize)) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - tmp = (DCHAR_T *) malloc (tmp_memsize); - if (tmp == NULL) - /* Out of memory. */ - goto out_of_memory; - } - - pad_ptr = NULL; - p = tmp; - if (type == TYPE_LONGDOUBLE) - { -# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE - long double arg = a.arg[dp->arg_index].a.a_longdouble; - - if (isnanl (arg)) - { - if (dp->conversion == 'A') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - DECL_LONG_DOUBLE_ROUNDING - - BEGIN_LONG_DOUBLE_ROUNDING (); - - if (signbit (arg)) /* arg < 0.0L or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0L && arg + arg == arg) - { - if (dp->conversion == 'A') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { - int exponent; - long double mantissa; - - if (arg > 0.0L) - mantissa = printf_frexpl (arg, &exponent); - else - { - exponent = 0; - mantissa = 0.0L; - } - - if (has_precision - && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1) - { - /* Round the mantissa. */ - long double tail = mantissa; - size_t q; - - for (q = precision; ; q--) - { - int digit = (int) tail; - tail -= digit; - if (q == 0) - { - if (digit & 1 ? tail >= 0.5L : tail > 0.5L) - tail = 1 - tail; - else - tail = - tail; - break; - } - tail *= 16.0L; - } - if (tail != 0.0L) - for (q = precision; q > 0; q--) - tail *= 0.0625L; - mantissa += tail; - } - - *p++ = '0'; - *p++ = dp->conversion - 'A' + 'X'; - pad_ptr = p; - { - int digit; - - digit = (int) mantissa; - mantissa -= digit; - *p++ = '0' + digit; - if ((flags & FLAG_ALT) - || mantissa > 0.0L || precision > 0) - { - *p++ = decimal_point_char (); - /* This loop terminates because we assume - that FLT_RADIX is a power of 2. */ - while (mantissa > 0.0L) - { - mantissa *= 16.0L; - digit = (int) mantissa; - mantissa -= digit; - *p++ = digit - + (digit < 10 - ? '0' - : dp->conversion - 10); - if (precision > 0) - precision--; - } - while (precision > 0) - { - *p++ = '0'; - precision--; - } - } - } - *p++ = dp->conversion - 'A' + 'P'; -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - - END_LONG_DOUBLE_ROUNDING (); - } -# else - abort (); -# endif - } - else - { -# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE - double arg = a.arg[dp->arg_index].a.a_double; - - if (isnand (arg)) - { - if (dp->conversion == 'A') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - - if (signbit (arg)) /* arg < 0.0 or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0 && arg + arg == arg) - { - if (dp->conversion == 'A') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { - int exponent; - double mantissa; - - if (arg > 0.0) - mantissa = printf_frexp (arg, &exponent); - else - { - exponent = 0; - mantissa = 0.0; - } - - if (has_precision - && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1) - { - /* Round the mantissa. */ - double tail = mantissa; - size_t q; - - for (q = precision; ; q--) - { - int digit = (int) tail; - tail -= digit; - if (q == 0) - { - if (digit & 1 ? tail >= 0.5 : tail > 0.5) - tail = 1 - tail; - else - tail = - tail; - break; - } - tail *= 16.0; - } - if (tail != 0.0) - for (q = precision; q > 0; q--) - tail *= 0.0625; - mantissa += tail; - } - - *p++ = '0'; - *p++ = dp->conversion - 'A' + 'X'; - pad_ptr = p; - { - int digit; - - digit = (int) mantissa; - mantissa -= digit; - *p++ = '0' + digit; - if ((flags & FLAG_ALT) - || mantissa > 0.0 || precision > 0) - { - *p++ = decimal_point_char (); - /* This loop terminates because we assume - that FLT_RADIX is a power of 2. */ - while (mantissa > 0.0) - { - mantissa *= 16.0; - digit = (int) mantissa; - mantissa -= digit; - *p++ = digit - + (digit < 10 - ? '0' - : dp->conversion - 10); - if (precision > 0) - precision--; - } - while (precision > 0) - { - *p++ = '0'; - precision--; - } - } - } - *p++ = dp->conversion - 'A' + 'P'; -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - } -# else - abort (); -# endif - } - /* The generated string now extends from tmp to p, with the - zero padding insertion point being at pad_ptr. */ - if (has_width && p - tmp < width) - { - size_t pad = width - (p - tmp); - DCHAR_T *end = p + pad; - - if (flags & FLAG_LEFT) - { - /* Pad with spaces on the right. */ - for (; pad > 0; pad--) - *p++ = ' '; - } - else if ((flags & FLAG_ZERO) && pad_ptr != NULL) - { - /* Pad with zeroes. */ - DCHAR_T *q = end; - - while (p > pad_ptr) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = '0'; - } - else - { - /* Pad with spaces on the left. */ - DCHAR_T *q = end; - - while (p > tmp) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = ' '; - } - - p = end; - } - - { - size_t count = p - tmp; - - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); - - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); - - ENSURE_ALLOCATION (n); - } - - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; - } - } -#endif -#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL - else if ((dp->conversion == 'f' || dp->conversion == 'F' - || dp->conversion == 'e' || dp->conversion == 'E' - || dp->conversion == 'g' || dp->conversion == 'G' - || dp->conversion == 'a' || dp->conversion == 'A') - && (0 -# if NEED_PRINTF_DOUBLE - || a.arg[dp->arg_index].type == TYPE_DOUBLE -# elif NEED_PRINTF_INFINITE_DOUBLE - || (a.arg[dp->arg_index].type == TYPE_DOUBLE - /* The systems (mingw) which produce wrong output - for Inf, -Inf, and NaN also do so for -0.0. - Therefore we treat this case here as well. */ - && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double)) -# endif -# if NEED_PRINTF_LONG_DOUBLE - || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE -# elif NEED_PRINTF_INFINITE_LONG_DOUBLE - || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE - /* Some systems produce wrong output for Inf, - -Inf, and NaN. Some systems in this category - (IRIX 5.3) also do so for -0.0. Therefore we - treat this case here as well. */ - && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble)) -# endif - )) - { -# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) - arg_type type = a.arg[dp->arg_index].type; -# endif - int flags = dp->flags; - int has_width; - size_t width; - int has_precision; - size_t precision; - size_t tmp_length; - DCHAR_T tmpbuf[700]; - DCHAR_T *tmp; - DCHAR_T *pad_ptr; - DCHAR_T *p; - - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } - - has_precision = 0; - precision = 0; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } - - /* POSIX specifies the default precision to be 6 for %f, %F, - %e, %E, but not for %g, %G. Implementations appear to use - the same default precision also for %g, %G. But for %a, %A, - the default precision is 0. */ - if (!has_precision) - if (!(dp->conversion == 'a' || dp->conversion == 'A')) - precision = 6; - - /* Allocate a temporary buffer of sufficient size. */ -# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE - tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1); -# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE - tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0); -# elif NEED_PRINTF_LONG_DOUBLE - tmp_length = LDBL_DIG + 1; -# elif NEED_PRINTF_DOUBLE - tmp_length = DBL_DIG + 1; -# else - tmp_length = 0; -# endif - if (tmp_length < precision) - tmp_length = precision; -# if NEED_PRINTF_LONG_DOUBLE -# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE - if (type == TYPE_LONGDOUBLE) -# endif - if (dp->conversion == 'f' || dp->conversion == 'F') - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - if (!(isnanl (arg) || arg + arg == arg)) - { - /* arg is finite and nonzero. */ - int exponent = floorlog10l (arg < 0 ? -arg : arg); - if (exponent >= 0 && tmp_length < exponent + precision) - tmp_length = exponent + precision; - } - } -# endif -# if NEED_PRINTF_DOUBLE -# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE - if (type == TYPE_DOUBLE) -# endif - if (dp->conversion == 'f' || dp->conversion == 'F') - { - double arg = a.arg[dp->arg_index].a.a_double; - if (!(isnand (arg) || arg + arg == arg)) - { - /* arg is finite and nonzero. */ - int exponent = floorlog10 (arg < 0 ? -arg : arg); - if (exponent >= 0 && tmp_length < exponent + precision) - tmp_length = exponent + precision; - } - } -# endif - /* Account for sign, decimal point etc. */ - tmp_length = xsum (tmp_length, 12); - - if (tmp_length < width) - tmp_length = width; - - tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */ - - if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T)) - tmp = tmpbuf; - else - { - size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T)); - - if (size_overflow_p (tmp_memsize)) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - tmp = (DCHAR_T *) malloc (tmp_memsize); - if (tmp == NULL) - /* Out of memory. */ - goto out_of_memory; - } - - pad_ptr = NULL; - p = tmp; - -# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE -# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE - if (type == TYPE_LONGDOUBLE) -# endif - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - - if (isnanl (arg)) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - DECL_LONG_DOUBLE_ROUNDING - - BEGIN_LONG_DOUBLE_ROUNDING (); - - if (signbit (arg)) /* arg < 0.0L or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0L && arg + arg == arg) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { -# if NEED_PRINTF_LONG_DOUBLE - pad_ptr = p; - - if (dp->conversion == 'f' || dp->conversion == 'F') - { - char *digits; - size_t ndigits; - - digits = - scale10_round_decimal_long_double (arg, precision); - if (digits == NULL) - { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - ndigits = strlen (digits); - - if (ndigits > precision) - do - { - --ndigits; - *p++ = digits[ndigits]; - } - while (ndigits > precision); - else - *p++ = '0'; - /* Here ndigits <= precision. */ - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > ndigits; precision--) - *p++ = '0'; - while (ndigits > 0) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - - free (digits); - } - else if (dp->conversion == 'e' || dp->conversion == 'E') - { - int exponent; - - if (arg == 0.0L) - { - exponent = 0; - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - } - else - { - /* arg > 0.0L. */ - int adjusted; - char *digits; - size_t ndigits; - - exponent = floorlog10l (arg); - adjusted = 0; - for (;;) - { - digits = - scale10_round_decimal_long_double (arg, - (int)precision - exponent); - if (digits == NULL) - { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - ndigits = strlen (digits); - - if (ndigits == precision + 1) - break; - if (ndigits < precision - || ndigits > precision + 2) - /* The exponent was not guessed - precisely enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is - the right one. Prevent an endless - loop. */ - abort (); - free (digits); - if (ndigits == precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; - } - /* Here ndigits = precision+1. */ - if (is_borderline (digits, precision)) - { - /* Maybe the exponent guess was too high - and a smaller exponent can be reached - by turning a 10...0 into 9...9x. */ - char *digits2 = - scale10_round_decimal_long_double (arg, - (int)precision - exponent + 1); - if (digits2 == NULL) - { - free (digits); - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - if (strlen (digits2) == precision + 1) - { - free (digits); - digits = digits2; - exponent -= 1; - } - else - free (digits2); - } - /* Here ndigits = precision+1. */ - - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - while (ndigits > 0) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - - free (digits); - } - - *p++ = dp->conversion; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', '.', '2', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+.2d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+.2d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - else if (dp->conversion == 'g' || dp->conversion == 'G') - { - if (precision == 0) - precision = 1; - /* precision >= 1. */ - - if (arg == 0.0L) - /* The exponent is 0, >= -4, < precision. - Use fixed-point notation. */ - { - size_t ndigits = precision; - /* Number of trailing zeroes that have to be - dropped. */ - size_t nzeroes = - (flags & FLAG_ALT ? 0 : precision - 1); - - --ndigits; - *p++ = '0'; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = '0'; - } - } - } - else - { - /* arg > 0.0L. */ - int exponent; - int adjusted; - char *digits; - size_t ndigits; - size_t nzeroes; - - exponent = floorlog10l (arg); - adjusted = 0; - for (;;) - { - digits = - scale10_round_decimal_long_double (arg, - (int)(precision - 1) - exponent); - if (digits == NULL) - { - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - ndigits = strlen (digits); - - if (ndigits == precision) - break; - if (ndigits < precision - 1 - || ndigits > precision + 1) - /* The exponent was not guessed - precisely enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is - the right one. Prevent an endless - loop. */ - abort (); - free (digits); - if (ndigits < precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; - } - /* Here ndigits = precision. */ - if (is_borderline (digits, precision - 1)) - { - /* Maybe the exponent guess was too high - and a smaller exponent can be reached - by turning a 10...0 into 9...9x. */ - char *digits2 = - scale10_round_decimal_long_double (arg, - (int)(precision - 1) - exponent + 1); - if (digits2 == NULL) - { - free (digits); - END_LONG_DOUBLE_ROUNDING (); - goto out_of_memory; - } - if (strlen (digits2) == precision) - { - free (digits); - digits = digits2; - exponent -= 1; - } - else - free (digits2); - } - /* Here ndigits = precision. */ - - /* Determine the number of trailing zeroes - that have to be dropped. */ - nzeroes = 0; - if ((flags & FLAG_ALT) == 0) - while (nzeroes < ndigits - && digits[nzeroes] == '0') - nzeroes++; - - /* The exponent is now determined. */ - if (exponent >= -4 - && exponent < (long)precision) - { - /* Fixed-point notation: - max(exponent,0)+1 digits, then the - decimal point, then the remaining - digits without trailing zeroes. */ - if (exponent >= 0) - { - size_t count = exponent + 1; - /* Note: count <= precision = ndigits. */ - for (; count > 0; count--) - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - } - else - { - size_t count = -exponent - 1; - *p++ = '0'; - *p++ = decimal_point_char (); - for (; count > 0; count--) - *p++ = '0'; - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - } - else - { - /* Exponential notation. */ - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - { '%', '+', '.', '2', 'd', '\0' }; - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, "%+.2d", exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, "%+.2d", exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } -# endif - } - - free (digits); - } - } - else - abort (); -# else - /* arg is finite. */ - if (!(arg == 0.0L)) - abort (); - - pad_ptr = p; - - if (dp->conversion == 'f' || dp->conversion == 'F') - { - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - } - else if (dp->conversion == 'e' || dp->conversion == 'E') - { - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - *p++ = dp->conversion; /* 'e' or 'E' */ - *p++ = '+'; - *p++ = '0'; - *p++ = '0'; - } - else if (dp->conversion == 'g' || dp->conversion == 'G') - { - *p++ = '0'; - if (flags & FLAG_ALT) - { - size_t ndigits = - (precision > 0 ? precision - 1 : 0); - *p++ = decimal_point_char (); - for (; ndigits > 0; --ndigits) - *p++ = '0'; - } - } - else if (dp->conversion == 'a' || dp->conversion == 'A') - { - *p++ = '0'; - *p++ = dp->conversion - 'A' + 'X'; - pad_ptr = p; - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - *p++ = dp->conversion - 'A' + 'P'; - *p++ = '+'; - *p++ = '0'; - } - else - abort (); -# endif - } - - END_LONG_DOUBLE_ROUNDING (); - } - } -# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE - else -# endif -# endif -# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE - { - double arg = a.arg[dp->arg_index].a.a_double; - - if (isnand (arg)) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'N'; *p++ = 'A'; *p++ = 'N'; - } - else - { - *p++ = 'n'; *p++ = 'a'; *p++ = 'n'; - } - } - else - { - int sign = 0; - - if (signbit (arg)) /* arg < 0.0 or negative zero */ - { - sign = -1; - arg = -arg; - } - - if (sign < 0) - *p++ = '-'; - else if (flags & FLAG_SHOWSIGN) - *p++ = '+'; - else if (flags & FLAG_SPACE) - *p++ = ' '; - - if (arg > 0.0 && arg + arg == arg) - { - if (dp->conversion >= 'A' && dp->conversion <= 'Z') - { - *p++ = 'I'; *p++ = 'N'; *p++ = 'F'; - } - else - { - *p++ = 'i'; *p++ = 'n'; *p++ = 'f'; - } - } - else - { -# if NEED_PRINTF_DOUBLE - pad_ptr = p; - - if (dp->conversion == 'f' || dp->conversion == 'F') - { - char *digits; - size_t ndigits; - - digits = - scale10_round_decimal_double (arg, precision); - if (digits == NULL) - goto out_of_memory; - ndigits = strlen (digits); - - if (ndigits > precision) - do - { - --ndigits; - *p++ = digits[ndigits]; - } - while (ndigits > precision); - else - *p++ = '0'; - /* Here ndigits <= precision. */ - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > ndigits; precision--) - *p++ = '0'; - while (ndigits > 0) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - - free (digits); - } - else if (dp->conversion == 'e' || dp->conversion == 'E') - { - int exponent; - - if (arg == 0.0) - { - exponent = 0; - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - } - else - { - /* arg > 0.0. */ - int adjusted; - char *digits; - size_t ndigits; - - exponent = floorlog10 (arg); - adjusted = 0; - for (;;) - { - digits = - scale10_round_decimal_double (arg, - (int)precision - exponent); - if (digits == NULL) - goto out_of_memory; - ndigits = strlen (digits); - - if (ndigits == precision + 1) - break; - if (ndigits < precision - || ndigits > precision + 2) - /* The exponent was not guessed - precisely enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is - the right one. Prevent an endless - loop. */ - abort (); - free (digits); - if (ndigits == precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; - } - /* Here ndigits = precision+1. */ - if (is_borderline (digits, precision)) - { - /* Maybe the exponent guess was too high - and a smaller exponent can be reached - by turning a 10...0 into 9...9x. */ - char *digits2 = - scale10_round_decimal_double (arg, - (int)precision - exponent + 1); - if (digits2 == NULL) - { - free (digits); - goto out_of_memory; - } - if (strlen (digits2) == precision + 1) - { - free (digits); - digits = digits2; - exponent -= 1; - } - else - free (digits2); - } - /* Here ndigits = precision+1. */ - - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - while (ndigits > 0) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - - free (digits); - } - - *p++ = dp->conversion; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - /* Produce the same number of exponent digits - as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - { '%', '+', '.', '3', 'd', '\0' }; -# else - { '%', '+', '.', '2', 'd', '\0' }; -# endif - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - { - static const char decimal_format[] = - /* Produce the same number of exponent digits - as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - "%+.3d"; -# else - "%+.2d"; -# endif - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, decimal_format, exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, decimal_format, exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } - } -# endif - } - else if (dp->conversion == 'g' || dp->conversion == 'G') - { - if (precision == 0) - precision = 1; - /* precision >= 1. */ - - if (arg == 0.0) - /* The exponent is 0, >= -4, < precision. - Use fixed-point notation. */ - { - size_t ndigits = precision; - /* Number of trailing zeroes that have to be - dropped. */ - size_t nzeroes = - (flags & FLAG_ALT ? 0 : precision - 1); - - --ndigits; - *p++ = '0'; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = '0'; - } - } - } - else - { - /* arg > 0.0. */ - int exponent; - int adjusted; - char *digits; - size_t ndigits; - size_t nzeroes; - - exponent = floorlog10 (arg); - adjusted = 0; - for (;;) - { - digits = - scale10_round_decimal_double (arg, - (int)(precision - 1) - exponent); - if (digits == NULL) - goto out_of_memory; - ndigits = strlen (digits); - - if (ndigits == precision) - break; - if (ndigits < precision - 1 - || ndigits > precision + 1) - /* The exponent was not guessed - precisely enough. */ - abort (); - if (adjusted) - /* None of two values of exponent is - the right one. Prevent an endless - loop. */ - abort (); - free (digits); - if (ndigits < precision) - exponent -= 1; - else - exponent += 1; - adjusted = 1; - } - /* Here ndigits = precision. */ - if (is_borderline (digits, precision - 1)) - { - /* Maybe the exponent guess was too high - and a smaller exponent can be reached - by turning a 10...0 into 9...9x. */ - char *digits2 = - scale10_round_decimal_double (arg, - (int)(precision - 1) - exponent + 1); - if (digits2 == NULL) - { - free (digits); - goto out_of_memory; - } - if (strlen (digits2) == precision) - { - free (digits); - digits = digits2; - exponent -= 1; - } - else - free (digits2); - } - /* Here ndigits = precision. */ - - /* Determine the number of trailing zeroes - that have to be dropped. */ - nzeroes = 0; - if ((flags & FLAG_ALT) == 0) - while (nzeroes < ndigits - && digits[nzeroes] == '0') - nzeroes++; - - /* The exponent is now determined. */ - if (exponent >= -4 - && exponent < (long)precision) - { - /* Fixed-point notation: - max(exponent,0)+1 digits, then the - decimal point, then the remaining - digits without trailing zeroes. */ - if (exponent >= 0) - { - size_t count = exponent + 1; - /* Note: count <= precision = ndigits. */ - for (; count > 0; count--) - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - } - else - { - size_t count = -exponent - 1; - *p++ = '0'; - *p++ = decimal_point_char (); - for (; count > 0; count--) - *p++ = '0'; - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - } - else - { - /* Exponential notation. */ - *p++ = digits[--ndigits]; - if ((flags & FLAG_ALT) || ndigits > nzeroes) - { - *p++ = decimal_point_char (); - while (ndigits > nzeroes) - { - --ndigits; - *p++ = digits[ndigits]; - } - } - *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */ -# if WIDE_CHAR_VERSION - { - static const wchar_t decimal_format[] = - /* Produce the same number of exponent digits - as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - { '%', '+', '.', '3', 'd', '\0' }; -# else - { '%', '+', '.', '2', 'd', '\0' }; -# endif - SNPRINTF (p, 6 + 1, decimal_format, exponent); - } - while (*p != '\0') - p++; -# else - { - static const char decimal_format[] = - /* Produce the same number of exponent digits - as the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - "%+.3d"; -# else - "%+.2d"; -# endif - if (sizeof (DCHAR_T) == 1) - { - sprintf ((char *) p, decimal_format, exponent); - while (*p != '\0') - p++; - } - else - { - char expbuf[6 + 1]; - const char *ep; - sprintf (expbuf, decimal_format, exponent); - for (ep = expbuf; (*p = *ep) != '\0'; ep++) - p++; - } - } -# endif - } - - free (digits); - } - } - else - abort (); -# else - /* arg is finite. */ - if (!(arg == 0.0)) - abort (); - - pad_ptr = p; - - if (dp->conversion == 'f' || dp->conversion == 'F') - { - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - } - else if (dp->conversion == 'e' || dp->conversion == 'E') - { - *p++ = '0'; - if ((flags & FLAG_ALT) || precision > 0) - { - *p++ = decimal_point_char (); - for (; precision > 0; precision--) - *p++ = '0'; - } - *p++ = dp->conversion; /* 'e' or 'E' */ - *p++ = '+'; - /* Produce the same number of exponent digits as - the native printf implementation. */ -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - *p++ = '0'; -# endif - *p++ = '0'; - *p++ = '0'; - } - else if (dp->conversion == 'g' || dp->conversion == 'G') - { - *p++ = '0'; - if (flags & FLAG_ALT) - { - size_t ndigits = - (precision > 0 ? precision - 1 : 0); - *p++ = decimal_point_char (); - for (; ndigits > 0; --ndigits) - *p++ = '0'; - } - } - else - abort (); -# endif - } - } - } -# endif - - /* The generated string now extends from tmp to p, with the - zero padding insertion point being at pad_ptr. */ - if (has_width && p - tmp < width) - { - size_t pad = width - (p - tmp); - DCHAR_T *end = p + pad; - - if (flags & FLAG_LEFT) - { - /* Pad with spaces on the right. */ - for (; pad > 0; pad--) - *p++ = ' '; - } - else if ((flags & FLAG_ZERO) && pad_ptr != NULL) - { - /* Pad with zeroes. */ - DCHAR_T *q = end; - - while (p > pad_ptr) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = '0'; - } - else - { - /* Pad with spaces on the left. */ - DCHAR_T *q = end; - - while (p > tmp) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = ' '; - } - - p = end; - } - - { - size_t count = p - tmp; - - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); - - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); - - ENSURE_ALLOCATION (n); - } - - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; - } - } -#endif - else - { - arg_type type = a.arg[dp->arg_index].type; - int flags = dp->flags; -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION - int has_width; - size_t width; -#endif -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION - int has_precision; - size_t precision; -#endif -#if NEED_PRINTF_UNBOUNDED_PRECISION - int prec_ourselves; -#else -# define prec_ourselves 0 -#endif -#if NEED_PRINTF_FLAG_LEFTADJUST -# define pad_ourselves 1 -#elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION - int pad_ourselves; -#else -# define pad_ourselves 0 -#endif - TCHAR_T *fbp; - unsigned int prefix_count; - int prefixes[2] IF_LINT (= { 0 }); - int orig_errno; -#if !USE_SNPRINTF - size_t tmp_length; - TCHAR_T tmpbuf[700]; - TCHAR_T *tmp; -#endif - -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION - has_width = 0; - width = 0; - if (dp->width_start != dp->width_end) - { - if (dp->width_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->width_arg_index].a.a_int; - if (arg < 0) - { - /* "A negative field width is taken as a '-' flag - followed by a positive field width." */ - flags |= FLAG_LEFT; - width = (unsigned int) (-arg); - } - else - width = arg; - } - else - { - const FCHAR_T *digitp = dp->width_start; - - do - width = xsum (xtimes (width, 10), *digitp++ - '0'); - while (digitp != dp->width_end); - } - has_width = 1; - } -#endif - -#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION - has_precision = 0; - precision = 6; - if (dp->precision_start != dp->precision_end) - { - if (dp->precision_arg_index != ARG_NONE) - { - int arg; - - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - arg = a.arg[dp->precision_arg_index].a.a_int; - /* "A negative precision is taken as if the precision - were omitted." */ - if (arg >= 0) - { - precision = arg; - has_precision = 1; - } - } - else - { - const FCHAR_T *digitp = dp->precision_start + 1; - - precision = 0; - while (digitp != dp->precision_end) - precision = xsum (xtimes (precision, 10), *digitp++ - '0'); - has_precision = 1; - } - } -#endif - - /* Decide whether to handle the precision ourselves. */ -#if NEED_PRINTF_UNBOUNDED_PRECISION - switch (dp->conversion) - { - case 'd': case 'i': case 'u': - case 'o': - case 'x': case 'X': case 'p': - prec_ourselves = has_precision && (precision > 0); - break; - default: - prec_ourselves = 0; - break; - } -#endif - - /* Decide whether to perform the padding ourselves. */ -#if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION) - switch (dp->conversion) - { -# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO - /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need - to perform the padding after this conversion. Functions - with unistdio extensions perform the padding based on - character count rather than element count. */ - case 'c': case 's': -# endif -# if NEED_PRINTF_FLAG_ZERO - case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': - case 'a': case 'A': -# endif - pad_ourselves = 1; - break; - default: - pad_ourselves = prec_ourselves; - break; - } -#endif - -#if !USE_SNPRINTF - /* Allocate a temporary buffer of sufficient size for calling - sprintf. */ - tmp_length = - MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type, - flags, width, has_precision, precision, - pad_ourselves); - - if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T)) - tmp = tmpbuf; - else - { - size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T)); - - if (size_overflow_p (tmp_memsize)) - /* Overflow, would lead to out of memory. */ - goto out_of_memory; - tmp = (TCHAR_T *) malloc (tmp_memsize); - if (tmp == NULL) - /* Out of memory. */ - goto out_of_memory; - } -#endif - - /* Construct the format string for calling snprintf or - sprintf. */ - fbp = buf; - *fbp++ = '%'; -#if NEED_PRINTF_FLAG_GROUPING - /* The underlying implementation doesn't support the ' flag. - Produce no grouping characters in this case; this is - acceptable because the grouping is locale dependent. */ -#else - if (flags & FLAG_GROUP) - *fbp++ = '\''; -#endif - if (flags & FLAG_LEFT) - *fbp++ = '-'; - if (flags & FLAG_SHOWSIGN) - *fbp++ = '+'; - if (flags & FLAG_SPACE) - *fbp++ = ' '; - if (flags & FLAG_ALT) - *fbp++ = '#'; -#if __GLIBC__ >= 2 && !defined __UCLIBC__ - if (flags & FLAG_LOCALIZED) - *fbp++ = 'I'; -#endif - if (!pad_ourselves) - { - if (flags & FLAG_ZERO) - *fbp++ = '0'; - if (dp->width_start != dp->width_end) - { - size_t n = dp->width_end - dp->width_start; - /* The width specification is known to consist only - of standard ASCII characters. */ - if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) - { - memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T)); - fbp += n; - } - else - { - const FCHAR_T *mp = dp->width_start; - do - *fbp++ = (unsigned char) *mp++; - while (--n > 0); - } - } - } - if (!prec_ourselves) - { - if (dp->precision_start != dp->precision_end) - { - size_t n = dp->precision_end - dp->precision_start; - /* The precision specification is known to consist only - of standard ASCII characters. */ - if (sizeof (FCHAR_T) == sizeof (TCHAR_T)) - { - memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T)); - fbp += n; - } - else - { - const FCHAR_T *mp = dp->precision_start; - do - *fbp++ = (unsigned char) *mp++; - while (--n > 0); - } - } - } - - switch (type) - { -#if HAVE_LONG_LONG_INT - case TYPE_LONGLONGINT: - case TYPE_ULONGLONGINT: -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - *fbp++ = 'I'; - *fbp++ = '6'; - *fbp++ = '4'; - break; -# else - *fbp++ = 'l'; - /*FALLTHROUGH*/ -# endif -#endif - case TYPE_LONGINT: - case TYPE_ULONGINT: -#if HAVE_WINT_T - case TYPE_WIDE_CHAR: -#endif -#if HAVE_WCHAR_T - case TYPE_WIDE_STRING: -#endif - *fbp++ = 'l'; - break; - case TYPE_LONGDOUBLE: - *fbp++ = 'L'; - break; - default: - break; - } -#if NEED_PRINTF_DIRECTIVE_F - if (dp->conversion == 'F') - *fbp = 'f'; - else -#endif - *fbp = dp->conversion; -#if USE_SNPRINTF -# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) - fbp[1] = '%'; - fbp[2] = 'n'; - fbp[3] = '\0'; -# else - /* On glibc2 systems from glibc >= 2.3 - probably also older - ones - we know that snprintf's return value conforms to - ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and - gl_SNPRINTF_TRUNCATION_C99 pass. - Therefore we can avoid using %n in this situation. - On glibc2 systems from 2004-10-18 or newer, the use of %n - in format strings in writable memory may crash the program - (if compiled with _FORTIFY_SOURCE=2), so we should avoid it - in this situation. */ - /* On native Windows systems (such as mingw), we can avoid using - %n because: - - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, - snprintf does not write more than the specified number - of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes - '4', '5', '6' into buf, not '4', '5', '\0'.) - - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf - allows us to recognize the case of an insufficient - buffer size: it returns -1 in this case. - On native Windows systems (such as mingw) where the OS is - Windows Vista, the use of %n in format strings by default - crashes the program. See - and - - So we should avoid %n in this situation. */ - fbp[1] = '\0'; -# endif -#else - fbp[1] = '\0'; -#endif - - /* Construct the arguments for calling snprintf or sprintf. */ - prefix_count = 0; - if (!pad_ourselves && dp->width_arg_index != ARG_NONE) - { - if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) - abort (); - prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int; - } - if (!prec_ourselves && dp->precision_arg_index != ARG_NONE) - { - if (!(a.arg[dp->precision_arg_index].type == TYPE_INT)) - abort (); - prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int; - } - -#if USE_SNPRINTF - /* The SNPRINTF result is appended after result[0..length]. - The latter is an array of DCHAR_T; SNPRINTF appends an - array of TCHAR_T to it. This is possible because - sizeof (TCHAR_T) divides sizeof (DCHAR_T) and - alignof (TCHAR_T) <= alignof (DCHAR_T). */ -# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T)) - /* Ensure that maxlen below will be >= 2. Needed on BeOS, - where an snprintf() with maxlen==1 acts like sprintf(). */ - ENSURE_ALLOCATION (xsum (length, - (2 + TCHARS_PER_DCHAR - 1) - / TCHARS_PER_DCHAR)); - /* Prepare checking whether snprintf returns the count - via %n. */ - *(TCHAR_T *) (result + length) = '\0'; -#endif - - orig_errno = errno; - - for (;;) - { - int count = -1; - -#if USE_SNPRINTF - int retcount = 0; - size_t maxlen = allocated - length; - /* SNPRINTF can fail if its second argument is - > INT_MAX. */ - if (maxlen > INT_MAX / TCHARS_PER_DCHAR) - maxlen = INT_MAX / TCHARS_PER_DCHAR; - maxlen = maxlen * TCHARS_PER_DCHAR; -# define SNPRINTF_BUF(arg) \ - switch (prefix_count) \ - { \ - case 0: \ - retcount = SNPRINTF ((TCHAR_T *) (result + length), \ - maxlen, buf, \ - arg, &count); \ - break; \ - case 1: \ - retcount = SNPRINTF ((TCHAR_T *) (result + length), \ - maxlen, buf, \ - prefixes[0], arg, &count); \ - break; \ - case 2: \ - retcount = SNPRINTF ((TCHAR_T *) (result + length), \ - maxlen, buf, \ - prefixes[0], prefixes[1], arg, \ - &count); \ - break; \ - default: \ - abort (); \ - } -#else -# define SNPRINTF_BUF(arg) \ - switch (prefix_count) \ - { \ - case 0: \ - count = sprintf (tmp, buf, arg); \ - break; \ - case 1: \ - count = sprintf (tmp, buf, prefixes[0], arg); \ - break; \ - case 2: \ - count = sprintf (tmp, buf, prefixes[0], prefixes[1],\ - arg); \ - break; \ - default: \ - abort (); \ - } -#endif - - errno = 0; - switch (type) - { - case TYPE_SCHAR: - { - int arg = a.arg[dp->arg_index].a.a_schar; - SNPRINTF_BUF (arg); - } - break; - case TYPE_UCHAR: - { - unsigned int arg = a.arg[dp->arg_index].a.a_uchar; - SNPRINTF_BUF (arg); - } - break; - case TYPE_SHORT: - { - int arg = a.arg[dp->arg_index].a.a_short; - SNPRINTF_BUF (arg); - } - break; - case TYPE_USHORT: - { - unsigned int arg = a.arg[dp->arg_index].a.a_ushort; - SNPRINTF_BUF (arg); - } - break; - case TYPE_INT: - { - int arg = a.arg[dp->arg_index].a.a_int; - SNPRINTF_BUF (arg); - } - break; - case TYPE_UINT: - { - unsigned int arg = a.arg[dp->arg_index].a.a_uint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_LONGINT: - { - long int arg = a.arg[dp->arg_index].a.a_longint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_ULONGINT: - { - unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint; - SNPRINTF_BUF (arg); - } - break; -#if HAVE_LONG_LONG_INT - case TYPE_LONGLONGINT: - { - long long int arg = a.arg[dp->arg_index].a.a_longlongint; - SNPRINTF_BUF (arg); - } - break; - case TYPE_ULONGLONGINT: - { - unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_DOUBLE: - { - double arg = a.arg[dp->arg_index].a.a_double; - SNPRINTF_BUF (arg); - } - break; - case TYPE_LONGDOUBLE: - { - long double arg = a.arg[dp->arg_index].a.a_longdouble; - SNPRINTF_BUF (arg); - } - break; - case TYPE_CHAR: - { - int arg = a.arg[dp->arg_index].a.a_char; - SNPRINTF_BUF (arg); - } - break; -#if HAVE_WINT_T - case TYPE_WIDE_CHAR: - { - wint_t arg = a.arg[dp->arg_index].a.a_wide_char; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_STRING: - { - const char *arg = a.arg[dp->arg_index].a.a_string; - SNPRINTF_BUF (arg); - } - break; -#if HAVE_WCHAR_T - case TYPE_WIDE_STRING: - { - const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string; - SNPRINTF_BUF (arg); - } - break; -#endif - case TYPE_POINTER: - { - void *arg = a.arg[dp->arg_index].a.a_pointer; - SNPRINTF_BUF (arg); - } - break; - default: - abort (); - } - -#if USE_SNPRINTF - /* Portability: Not all implementations of snprintf() - are ISO C 99 compliant. Determine the number of - bytes that snprintf() has produced or would have - produced. */ - if (count >= 0) - { - /* Verify that snprintf() has NUL-terminated its - result. */ - if (count < maxlen - && ((TCHAR_T *) (result + length)) [count] != '\0') - abort (); - /* Portability hack. */ - if (retcount > count) - count = retcount; - } - else - { - /* snprintf() doesn't understand the '%n' - directive. */ - if (fbp[1] != '\0') - { - /* Don't use the '%n' directive; instead, look - at the snprintf() return value. */ - fbp[1] = '\0'; - continue; - } - else - { - /* Look at the snprintf() return value. */ - if (retcount < 0) - { -# if !HAVE_SNPRINTF_RETVAL_C99 - /* HP-UX 10.20 snprintf() is doubly deficient: - It doesn't understand the '%n' directive, - *and* it returns -1 (rather than the length - that would have been required) when the - buffer is too small. - But a failure at this point can also come - from other reasons than a too small buffer, - such as an invalid wide string argument to - the %ls directive, or possibly an invalid - floating-point argument. */ - size_t tmp_length = - MAX_ROOM_NEEDED (&a, dp->arg_index, - dp->conversion, type, flags, - width, has_precision, - precision, pad_ourselves); - - if (maxlen < tmp_length) - { - /* Make more room. But try to do through - this reallocation only once. */ - size_t bigger_need = - xsum (length, - xsum (tmp_length, - TCHARS_PER_DCHAR - 1) - / TCHARS_PER_DCHAR); - /* And always grow proportionally. - (There may be several arguments, each - needing a little more room than the - previous one.) */ - size_t bigger_need2 = - xsum (xtimes (allocated, 2), 12); - if (bigger_need < bigger_need2) - bigger_need = bigger_need2; - ENSURE_ALLOCATION (bigger_need); - continue; - } -# endif - } - else - count = retcount; - } - } -#endif - - /* Attempt to handle failure. */ - if (count < 0) - { - /* SNPRINTF or sprintf failed. Save and use the errno - that it has set, if any. */ - int saved_errno = errno; - - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = - (saved_errno != 0 - ? saved_errno - : (dp->conversion == 'c' || dp->conversion == 's' - ? EILSEQ - : EINVAL)); - return NULL; - } - -#if USE_SNPRINTF - /* Handle overflow of the allocated buffer. - If such an overflow occurs, a C99 compliant snprintf() - returns a count >= maxlen. However, a non-compliant - snprintf() function returns only count = maxlen - 1. To - cover both cases, test whether count >= maxlen - 1. */ - if ((unsigned int) count + 1 >= maxlen) - { - /* If maxlen already has attained its allowed maximum, - allocating more memory will not increase maxlen. - Instead of looping, bail out. */ - if (maxlen == INT_MAX / TCHARS_PER_DCHAR) - goto overflow; - else - { - /* Need at least (count + 1) * sizeof (TCHAR_T) - bytes. (The +1 is for the trailing NUL.) - But ask for (count + 2) * sizeof (TCHAR_T) - bytes, so that in the next round, we likely get - maxlen > (unsigned int) count + 1 - and so we don't get here again. - And allocate proportionally, to avoid looping - eternally if snprintf() reports a too small - count. */ - size_t n = - xmax (xsum (length, - ((unsigned int) count + 2 - + TCHARS_PER_DCHAR - 1) - / TCHARS_PER_DCHAR), - xtimes (allocated, 2)); - - ENSURE_ALLOCATION (n); - continue; - } - } -#endif - -#if NEED_PRINTF_UNBOUNDED_PRECISION - if (prec_ourselves) - { - /* Handle the precision. */ - TCHAR_T *prec_ptr = -# if USE_SNPRINTF - (TCHAR_T *) (result + length); -# else - tmp; -# endif - size_t prefix_count; - size_t move; - - prefix_count = 0; - /* Put the additional zeroes after the sign. */ - if (count >= 1 - && (*prec_ptr == '-' || *prec_ptr == '+' - || *prec_ptr == ' ')) - prefix_count = 1; - /* Put the additional zeroes after the 0x prefix if - (flags & FLAG_ALT) || (dp->conversion == 'p'). */ - else if (count >= 2 - && prec_ptr[0] == '0' - && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X')) - prefix_count = 2; - - move = count - prefix_count; - if (precision > move) - { - /* Insert zeroes. */ - size_t insert = precision - move; - TCHAR_T *prec_end; - -# if USE_SNPRINTF - size_t n = - xsum (length, - (count + insert + TCHARS_PER_DCHAR - 1) - / TCHARS_PER_DCHAR); - length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; - ENSURE_ALLOCATION (n); - length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR; - prec_ptr = (TCHAR_T *) (result + length); -# endif - - prec_end = prec_ptr + count; - prec_ptr += prefix_count; - - while (prec_end > prec_ptr) - { - prec_end--; - prec_end[insert] = prec_end[0]; - } - - prec_end += insert; - do - *--prec_end = '0'; - while (prec_end > prec_ptr); - - count += insert; - } - } -#endif - -#if !USE_SNPRINTF - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); -#endif - -#if !DCHAR_IS_TCHAR - /* Convert from TCHAR_T[] to DCHAR_T[]. */ - if (dp->conversion == 'c' || dp->conversion == 's') - { - /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING - TYPE_WIDE_STRING. - The result string is not certainly ASCII. */ - const TCHAR_T *tmpsrc; - DCHAR_T *tmpdst; - size_t tmpdst_len; - /* This code assumes that TCHAR_T is 'char'. */ - verify (sizeof (TCHAR_T) == 1); -# if USE_SNPRINTF - tmpsrc = (TCHAR_T *) (result + length); -# else - tmpsrc = tmp; -# endif - tmpdst = - DCHAR_CONV_FROM_ENCODING (locale_charset (), - iconveh_question_mark, - tmpsrc, count, - NULL, - NULL, &tmpdst_len); - if (tmpdst == NULL) - { - int saved_errno = errno; - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = saved_errno; - return NULL; - } - ENSURE_ALLOCATION (xsum (length, tmpdst_len)); - DCHAR_CPY (result + length, tmpdst, tmpdst_len); - free (tmpdst); - count = tmpdst_len; - } - else - { - /* The result string is ASCII. - Simple 1:1 conversion. */ -# if USE_SNPRINTF - /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a - no-op conversion, in-place on the array starting - at (result + length). */ - if (sizeof (DCHAR_T) != sizeof (TCHAR_T)) -# endif - { - const TCHAR_T *tmpsrc; - DCHAR_T *tmpdst; - size_t n; - -# if USE_SNPRINTF - if (result == resultbuf) - { - tmpsrc = (TCHAR_T *) (result + length); - /* ENSURE_ALLOCATION will not move tmpsrc - (because it's part of resultbuf). */ - ENSURE_ALLOCATION (xsum (length, count)); - } - else - { - /* ENSURE_ALLOCATION will move the array - (because it uses realloc(). */ - ENSURE_ALLOCATION (xsum (length, count)); - tmpsrc = (TCHAR_T *) (result + length); - } -# else - tmpsrc = tmp; - ENSURE_ALLOCATION (xsum (length, count)); -# endif - tmpdst = result + length; - /* Copy backwards, because of overlapping. */ - tmpsrc += count; - tmpdst += count; - for (n = count; n > 0; n--) - *--tmpdst = (unsigned char) *--tmpsrc; - } - } -#endif - -#if DCHAR_IS_TCHAR && !USE_SNPRINTF - /* Make room for the result. */ - if (count > allocated - length) - { - /* Need at least count elements. But allocate - proportionally. */ - size_t n = - xmax (xsum (length, count), xtimes (allocated, 2)); - - ENSURE_ALLOCATION (n); - } -#endif - - /* Here count <= allocated - length. */ - - /* Perform padding. */ -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION - if (pad_ourselves && has_width) - { - size_t w; -# if ENABLE_UNISTDIO - /* Outside POSIX, it's preferable to compare the width - against the number of _characters_ of the converted - value. */ - w = DCHAR_MBSNLEN (result + length, count); -# else - /* The width is compared against the number of _bytes_ - of the converted value, says POSIX. */ - w = count; -# endif - if (w < width) - { - size_t pad = width - w; - - /* Make room for the result. */ - if (xsum (count, pad) > allocated - length) - { - /* Need at least count + pad elements. But - allocate proportionally. */ - size_t n = - xmax (xsum3 (length, count, pad), - xtimes (allocated, 2)); - -# if USE_SNPRINTF - length += count; - ENSURE_ALLOCATION (n); - length -= count; -# else - ENSURE_ALLOCATION (n); -# endif - } - /* Here count + pad <= allocated - length. */ - - { -# if !DCHAR_IS_TCHAR || USE_SNPRINTF - DCHAR_T * const rp = result + length; -# else - DCHAR_T * const rp = tmp; -# endif - DCHAR_T *p = rp + count; - DCHAR_T *end = p + pad; - DCHAR_T *pad_ptr; -# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO - if (dp->conversion == 'c' - || dp->conversion == 's') - /* No zero-padding for string directives. */ - pad_ptr = NULL; - else -# endif - { - pad_ptr = (*rp == '-' ? rp + 1 : rp); - /* No zero-padding of "inf" and "nan". */ - if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z') - || (*pad_ptr >= 'a' && *pad_ptr <= 'z')) - pad_ptr = NULL; - } - /* The generated string now extends from rp to p, - with the zero padding insertion point being at - pad_ptr. */ - - count = count + pad; /* = end - rp */ - - if (flags & FLAG_LEFT) - { - /* Pad with spaces on the right. */ - for (; pad > 0; pad--) - *p++ = ' '; - } - else if ((flags & FLAG_ZERO) && pad_ptr != NULL) - { - /* Pad with zeroes. */ - DCHAR_T *q = end; - - while (p > pad_ptr) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = '0'; - } - else - { - /* Pad with spaces on the left. */ - DCHAR_T *q = end; - - while (p > rp) - *--q = *--p; - for (; pad > 0; pad--) - *p++ = ' '; - } - } - } - } -#endif - - /* Here still count <= allocated - length. */ - -#if !DCHAR_IS_TCHAR || USE_SNPRINTF - /* The snprintf() result did fit. */ -#else - /* Append the sprintf() result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); -#endif -#if !USE_SNPRINTF - if (tmp != tmpbuf) - free (tmp); -#endif - -#if NEED_PRINTF_DIRECTIVE_F - if (dp->conversion == 'F') - { - /* Convert the %f result to upper case for %F. */ - DCHAR_T *rp = result + length; - size_t rc; - for (rc = count; rc > 0; rc--, rp++) - if (*rp >= 'a' && *rp <= 'z') - *rp = *rp - 'a' + 'A'; - } -#endif - - length += count; - break; - } - errno = orig_errno; -#undef pad_ourselves -#undef prec_ourselves - } - } - } - - /* Add the final NUL. */ - ENSURE_ALLOCATION (xsum (length, 1)); - result[length] = '\0'; - - if (result != resultbuf && length + 1 < allocated) - { - /* Shrink the allocated memory if possible. */ - DCHAR_T *memory; - - memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T)); - if (memory != NULL) - result = memory; - } - - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - *lengthp = length; - /* Note that we can produce a big string of a length > INT_MAX. POSIX - says that snprintf() fails with errno = EOVERFLOW in this case, but - that's only because snprintf() returns an 'int'. This function does - not have this limitation. */ - return result; - -#if USE_SNPRINTF - overflow: - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - CLEANUP (); - errno = EOVERFLOW; - return NULL; -#endif - - out_of_memory: - if (!(result == resultbuf || result == NULL)) - free (result); - if (buf_malloced != NULL) - free (buf_malloced); - out_of_memory_1: - CLEANUP (); - errno = ENOMEM; - return NULL; - } -} - -#undef MAX_ROOM_NEEDED -#undef TCHARS_PER_DCHAR -#undef SNPRINTF -#undef USE_SNPRINTF -#undef DCHAR_SET -#undef DCHAR_CPY -#undef PRINTF_PARSE -#undef DIRECTIVES -#undef DIRECTIVE -#undef DCHAR_IS_TCHAR -#undef TCHAR_T -#undef DCHAR_T -#undef FCHAR_T -#undef VASNPRINTF diff --git a/grub-core/gnulib/vasnprintf.h b/grub-core/gnulib/vasnprintf.h deleted file mode 100644 index 7658f505e..000000000 --- a/grub-core/gnulib/vasnprintf.h +++ /dev/null @@ -1,79 +0,0 @@ -/* vsprintf with automatic memory allocation. - Copyright (C) 2002-2004, 2007-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifndef _VASNPRINTF_H -#define _VASNPRINTF_H - -/* Get va_list. */ -#include - -/* Get size_t. */ -#include - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The __-protected variants of the attributes 'format' and 'printf' are - accepted by gcc versions 2.6.4 (effectively 2.7) and later. - We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because - gnulib and libintl do '#define printf __printf__' when they override - the 'printf' function. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -#else -# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Write formatted output to a string dynamically allocated with malloc(). - You can pass a preallocated buffer for the result in RESULTBUF and its - size in *LENGTHP; otherwise you pass RESULTBUF = NULL. - If successful, return the address of the string (this may be = RESULTBUF - if no dynamic memory allocation was necessary) and set *LENGTHP to the - number of resulting bytes, excluding the trailing NUL. Upon error, set - errno and return NULL. - - When dynamic memory allocation occurs, the preallocated buffer is left - alone (with possibly modified contents). This makes it possible to use - a statically allocated or stack-allocated buffer, like this: - - char buf[100]; - size_t len = sizeof (buf); - char *output = vasnprintf (buf, &len, format, args); - if (output == NULL) - ... error handling ...; - else - { - ... use the output string ...; - if (output != buf) - free (output); - } - */ -#if REPLACE_VASNPRINTF -# define asnprintf rpl_asnprintf -# define vasnprintf rpl_vasnprintf -#endif -extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) - _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); -extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) - _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0)); - -#ifdef __cplusplus -} -#endif - -#endif /* _VASNPRINTF_H */ diff --git a/grub-core/gnulib/verify.h b/grub-core/gnulib/verify.h deleted file mode 100644 index cb8e90b54..000000000 --- a/grub-core/gnulib/verify.h +++ /dev/null @@ -1,245 +0,0 @@ -/* Compile-time assert-like macros. - - Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ - -#ifndef _GL_VERIFY_H -# define _GL_VERIFY_H - - -/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. - This is supported by GCC 4.6.0 and later, in C mode, and its use - here generates easier-to-read diagnostics when verify (R) fails. - - Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. - This will likely be supported by future GCC versions, in C++ mode. - - Use this only with GCC. If we were willing to slow 'configure' - down we could also use it with other compilers, but since this - affects only the quality of diagnostics, why bother? */ -# if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus -# define _GL_HAVE__STATIC_ASSERT 1 -# endif -/* The condition (99 < __GNUC__) is temporary, until we know about the - first G++ release that supports static_assert. */ -# if (99 < __GNUC__) && defined __cplusplus -# define _GL_HAVE_STATIC_ASSERT 1 -# endif - -/* Each of these macros verifies that its argument R is nonzero. To - be portable, R should be an integer constant expression. Unlike - assert (R), there is no run-time overhead. - - If _Static_assert works, verify (R) uses it directly. Similarly, - _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct - that is an operand of sizeof. - - The code below uses several ideas for C++ compilers, and for C - compilers that do not support _Static_assert: - - * The first step is ((R) ? 1 : -1). Given an expression R, of - integral or boolean or floating-point type, this yields an - expression of integral type, whose value is later verified to be - constant and nonnegative. - - * Next this expression W is wrapped in a type - struct _gl_verify_type { - unsigned int _gl_verify_error_if_negative: W; - }. - If W is negative, this yields a compile-time error. No compiler can - deal with a bit-field of negative size. - - One might think that an array size check would have the same - effect, that is, that the type struct { unsigned int dummy[W]; } - would work as well. However, inside a function, some compilers - (such as C++ compilers and GNU C) allow local parameters and - variables inside array size expressions. With these compilers, - an array size check would not properly diagnose this misuse of - the verify macro: - - void function (int n) { verify (n < 0); } - - * For the verify macro, the struct _gl_verify_type will need to - somehow be embedded into a declaration. To be portable, this - declaration must declare an object, a constant, a function, or a - typedef name. If the declared entity uses the type directly, - such as in - - struct dummy {...}; - typedef struct {...} dummy; - extern struct {...} *dummy; - extern void dummy (struct {...} *); - extern struct {...} *dummy (void); - - two uses of the verify macro would yield colliding declarations - if the entity names are not disambiguated. A workaround is to - attach the current line number to the entity name: - - #define _GL_CONCAT0(x, y) x##y - #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) - extern struct {...} * _GL_CONCAT (dummy, __LINE__); - - But this has the problem that two invocations of verify from - within the same macro would collide, since the __LINE__ value - would be the same for both invocations. (The GCC __COUNTER__ - macro solves this problem, but is not portable.) - - A solution is to use the sizeof operator. It yields a number, - getting rid of the identity of the type. Declarations like - - extern int dummy [sizeof (struct {...})]; - extern void dummy (int [sizeof (struct {...})]); - extern int (*dummy (void)) [sizeof (struct {...})]; - - can be repeated. - - * Should the implementation use a named struct or an unnamed struct? - Which of the following alternatives can be used? - - extern int dummy [sizeof (struct {...})]; - extern int dummy [sizeof (struct _gl_verify_type {...})]; - extern void dummy (int [sizeof (struct {...})]); - extern void dummy (int [sizeof (struct _gl_verify_type {...})]); - extern int (*dummy (void)) [sizeof (struct {...})]; - extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})]; - - In the second and sixth case, the struct type is exported to the - outer scope; two such declarations therefore collide. GCC warns - about the first, third, and fourth cases. So the only remaining - possibility is the fifth case: - - extern int (*dummy (void)) [sizeof (struct {...})]; - - * GCC warns about duplicate declarations of the dummy function if - -Wredundant-decls is used. GCC 4.3 and later have a builtin - __COUNTER__ macro that can let us generate unique identifiers for - each dummy function, to suppress this warning. - - * This implementation exploits the fact that older versions of GCC, - which do not support _Static_assert, also do not warn about the - last declaration mentioned above. - - * GCC warns if -Wnested-externs is enabled and verify() is used - within a function body; but inside a function, you can always - arrange to use verify_expr() instead. - - * In C++, any struct definition inside sizeof is invalid. - Use a template type to work around the problem. */ - -/* Concatenate two preprocessor tokens. */ -# define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) -# define _GL_CONCAT0(x, y) x##y - -/* _GL_COUNTER is an integer, preferably one that changes each time we - use it. Use __COUNTER__ if it works, falling back on __LINE__ - otherwise. __LINE__ isn't perfect, but it's better than a - constant. */ -# if defined __COUNTER__ && __COUNTER__ != __COUNTER__ -# define _GL_COUNTER __COUNTER__ -# else -# define _GL_COUNTER __LINE__ -# endif - -/* Generate a symbol with the given prefix, making it unique if - possible. */ -# define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) - -/* Verify requirement R at compile-time, as an integer constant expression - that returns 1. If R is false, fail at compile-time, preferably - with a diagnostic that includes the string-literal DIAGNOSTIC. */ - -# define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ - (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) - -# ifdef __cplusplus -# if !GNULIB_defined_struct__gl_verify_type -template - struct _gl_verify_type { - unsigned int _gl_verify_error_if_negative: w; - }; -# define GNULIB_defined_struct__gl_verify_type 1 -# endif -# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ - _gl_verify_type<(R) ? 1 : -1> -# elif defined _GL_HAVE__STATIC_ASSERT -# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ - struct { \ - _Static_assert (R, DIAGNOSTIC); \ - int _gl_dummy; \ - } -# else -# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ - struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } -# endif - -/* Verify requirement R at compile-time, as a declaration without a - trailing ';'. If R is false, fail at compile-time, preferably - with a diagnostic that includes the string-literal DIAGNOSTIC. - - Unfortunately, unlike C11, this implementation must appear as an - ordinary declaration, and cannot appear inside struct { ... }. */ - -# ifdef _GL_HAVE__STATIC_ASSERT -# define _GL_VERIFY _Static_assert -# else -# define _GL_VERIFY(R, DIAGNOSTIC) \ - extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ - [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] -# endif - -/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ -# ifdef _GL_STATIC_ASSERT_H -# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert -# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) -# endif -# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert -# define static_assert _Static_assert /* C11 requires this #define. */ -# endif -# endif - -/* @assert.h omit start@ */ - -/* Each of these macros verifies that its argument R is nonzero. To - be portable, R should be an integer constant expression. Unlike - assert (R), there is no run-time overhead. - - There are two macros, since no single macro can be used in all - contexts in C. verify_true (R) is for scalar contexts, including - integer constant expression contexts. verify (R) is for declaration - contexts, e.g., the top level. */ - -/* Verify requirement R at compile-time, as an integer constant expression. - Return 1. This is equivalent to verify_expr (R, 1). - - verify_true is obsolescent; please use verify_expr instead. */ - -# define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") - -/* Verify requirement R at compile-time. Return the value of the - expression E. */ - -# define verify_expr(R, E) \ - (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) - -/* Verify requirement R at compile-time, as a declaration without a - trailing ';'. */ - -# define verify(R) _GL_VERIFY (R, "verify (" #R ")") - -/* @assert.h omit end@ */ - -#endif diff --git a/grub-core/gnulib/vsnprintf.c b/grub-core/gnulib/vsnprintf.c deleted file mode 100644 index 7d4dfbed9..000000000 --- a/grub-core/gnulib/vsnprintf.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Formatted output to strings. - Copyright (C) 2004, 2006-2013 Free Software Foundation, Inc. - Written by Simon Josefsson and Yoann Vandoorselaere . - - 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, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* Specification. */ -#include - -#include -#include -#include -#include -#include - -#include "vasnprintf.h" - -/* Print formatted output to string STR. Similar to vsprintf, but - additional length SIZE limit how much is written into STR. Returns - string length of formatted string (which may be larger than SIZE). - STR may be NULL, in which case nothing will be written. On error, - return a negative value. */ -int -vsnprintf (char *str, size_t size, const char *format, va_list args) -{ - char *output; - size_t len; - size_t lenbuf = size; - - output = vasnprintf (str, &lenbuf, format, args); - len = lenbuf; - - if (!output) - return -1; - - if (output != str) - { - if (size) - { - size_t pruned_len = (len < size ? len : size - 1); - memcpy (str, output, pruned_len); - str[pruned_len] = '\0'; - } - - free (output); - } - - if (len > INT_MAX) - { - errno = EOVERFLOW; - return -1; - } - - return len; -} diff --git a/grub-core/gnulib/wchar.in.h b/grub-core/gnulib/wchar.in.h deleted file mode 100644 index b6e436279..000000000 --- a/grub-core/gnulib/wchar.in.h +++ /dev/null @@ -1,1028 +0,0 @@ -/* A substitute for ISO C99 , for platforms that have issues. - - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 Eric Blake. */ - -/* - * ISO C 99 for platforms that have issues. - * - * - * For now, this just ensures proper prerequisite inclusion order and - * the declaration of wcwidth(). - */ - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H -/* Special invocation convention: - - Inside glibc and uClibc header files. - - On HP-UX 11.00 we have a sequence of nested includes - -> -> , and the latter includes , - once indirectly -> -> -> - and once directly. In both situations 'wint_t' is not yet defined, - therefore we cannot provide the function overrides; instead include only - the system's . - - On IRIX 6.5, similarly, we have an include -> , and - the latter includes . But here, we have no way to detect whether - is completely included or is still being included. */ - -#@INCLUDE_NEXT@ @NEXT_WCHAR_H@ - -#else -/* Normal invocation convention. */ - -#ifndef _@GUARD_PREFIX@_WCHAR_H - -#define _GL_ALREADY_INCLUDING_WCHAR_H - -#if @HAVE_FEATURES_H@ -# include /* for __GLIBC__ */ -#endif - -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . - In some builds of uClibc, is nonexistent and wchar_t is defined - by . - But avoid namespace pollution on glibc systems. */ -#if !(defined __GLIBC__ && !defined __UCLIBC__) -# include -#endif -#ifndef __GLIBC__ -# include -# include -#endif - -/* Include the original if it exists. - Some builds of uClibc lack it. */ -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_WCHAR_H@ -# @INCLUDE_NEXT@ @NEXT_WCHAR_H@ -#endif - -#undef _GL_ALREADY_INCLUDING_WCHAR_H - -#ifndef _@GUARD_PREFIX@_WCHAR_H -#define _@GUARD_PREFIX@_WCHAR_H - -/* The __attribute__ feature is available in gcc versions 2.5 and later. - The attribute __pure__ was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -# define _GL_ATTRIBUTE_PURE /* empty */ -#endif - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_ARG_NONNULL is copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - - -/* Define wint_t and WEOF. (Also done in wctype.in.h.) */ -#if !@HAVE_WINT_T@ && !defined wint_t -# define wint_t int -# ifndef WEOF -# define WEOF -1 -# endif -#else -/* MSVC defines wint_t as 'unsigned short' in . - This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be - "unchanged by default argument promotions". Override it. */ -# if defined _MSC_VER -# if !GNULIB_defined_wint_t -# include -typedef unsigned int rpl_wint_t; -# undef wint_t -# define wint_t rpl_wint_t -# define GNULIB_defined_wint_t 1 -# endif -# endif -# ifndef WEOF -# define WEOF ((wint_t) -1) -# endif -#endif - - -/* Override mbstate_t if it is too small. - On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for - implementing mbrtowc for encodings like UTF-8. */ -#if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ -# if !GNULIB_defined_mbstate_t -typedef int rpl_mbstate_t; -# undef mbstate_t -# define mbstate_t rpl_mbstate_t -# define GNULIB_defined_mbstate_t 1 -# endif -#endif - - -/* Convert a single-byte character to a wide character. */ -#if @GNULIB_BTOWC@ -# if @REPLACE_BTOWC@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef btowc -# define btowc rpl_btowc -# endif -_GL_FUNCDECL_RPL (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); -_GL_CXXALIAS_RPL (btowc, wint_t, (int c)); -# else -# if !@HAVE_BTOWC@ -_GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (btowc, wint_t, (int c)); -# endif -_GL_CXXALIASWARN (btowc); -#elif defined GNULIB_POSIXCHECK -# undef btowc -# if HAVE_RAW_DECL_BTOWC -_GL_WARN_ON_USE (btowc, "btowc is unportable - " - "use gnulib module btowc for portability"); -# endif -#endif - - -/* Convert a wide character to a single-byte character. */ -#if @GNULIB_WCTOB@ -# if @REPLACE_WCTOB@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef wctob -# define wctob rpl_wctob -# endif -_GL_FUNCDECL_RPL (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); -_GL_CXXALIAS_RPL (wctob, int, (wint_t wc)); -# else -# if !defined wctob && !@HAVE_DECL_WCTOB@ -/* wctob is provided by gnulib, or wctob exists but is not declared. */ -_GL_FUNCDECL_SYS (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); -# endif -_GL_CXXALIASWARN (wctob); -#elif defined GNULIB_POSIXCHECK -# undef wctob -# if HAVE_RAW_DECL_WCTOB -_GL_WARN_ON_USE (wctob, "wctob is unportable - " - "use gnulib module wctob for portability"); -# endif -#endif - - -/* Test whether *PS is in the initial state. */ -#if @GNULIB_MBSINIT@ -# if @REPLACE_MBSINIT@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mbsinit -# define mbsinit rpl_mbsinit -# endif -_GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps)); -_GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps)); -# else -# if !@HAVE_MBSINIT@ -_GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps)); -# endif -_GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (mbsinit); -#elif defined GNULIB_POSIXCHECK -# undef mbsinit -# if HAVE_RAW_DECL_MBSINIT -_GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - " - "use gnulib module mbsinit for portability"); -# endif -#endif - - -/* Convert a multibyte character to a wide character. */ -#if @GNULIB_MBRTOWC@ -# if @REPLACE_MBRTOWC@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mbrtowc -# define mbrtowc rpl_mbrtowc -# endif -_GL_FUNCDECL_RPL (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); -_GL_CXXALIAS_RPL (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); -# else -# if !@HAVE_MBRTOWC@ -_GL_FUNCDECL_SYS (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); -# endif -_GL_CXXALIAS_SYS (mbrtowc, size_t, - (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (mbrtowc); -#elif defined GNULIB_POSIXCHECK -# undef mbrtowc -# if HAVE_RAW_DECL_MBRTOWC -_GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - " - "use gnulib module mbrtowc for portability"); -# endif -#endif - - -/* Recognize a multibyte character. */ -#if @GNULIB_MBRLEN@ -# if @REPLACE_MBRLEN@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mbrlen -# define mbrlen rpl_mbrlen -# endif -_GL_FUNCDECL_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); -_GL_CXXALIAS_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); -# else -# if !@HAVE_MBRLEN@ -_GL_FUNCDECL_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); -# endif -_GL_CXXALIAS_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (mbrlen); -#elif defined GNULIB_POSIXCHECK -# undef mbrlen -# if HAVE_RAW_DECL_MBRLEN -_GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - " - "use gnulib module mbrlen for portability"); -# endif -#endif - - -/* Convert a string to a wide string. */ -#if @GNULIB_MBSRTOWCS@ -# if @REPLACE_MBSRTOWCS@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mbsrtowcs -# define mbsrtowcs rpl_mbsrtowcs -# endif -_GL_FUNCDECL_RPL (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, - mbstate_t *ps)); -# else -# if !@HAVE_MBSRTOWCS@ -_GL_FUNCDECL_SYS (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (mbsrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t len, - mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (mbsrtowcs); -#elif defined GNULIB_POSIXCHECK -# undef mbsrtowcs -# if HAVE_RAW_DECL_MBSRTOWCS -_GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - " - "use gnulib module mbsrtowcs for portability"); -# endif -#endif - - -/* Convert a string to a wide string. */ -#if @GNULIB_MBSNRTOWCS@ -# if @REPLACE_MBSNRTOWCS@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef mbsnrtowcs -# define mbsnrtowcs rpl_mbsnrtowcs -# endif -_GL_FUNCDECL_RPL (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps)); -# else -# if !@HAVE_MBSNRTOWCS@ -_GL_FUNCDECL_SYS (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (mbsnrtowcs, size_t, - (wchar_t *dest, const char **srcp, size_t srclen, size_t len, - mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (mbsnrtowcs); -#elif defined GNULIB_POSIXCHECK -# undef mbsnrtowcs -# if HAVE_RAW_DECL_MBSNRTOWCS -_GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - " - "use gnulib module mbsnrtowcs for portability"); -# endif -#endif - - -/* Convert a wide character to a multibyte character. */ -#if @GNULIB_WCRTOMB@ -# if @REPLACE_WCRTOMB@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef wcrtomb -# define wcrtomb rpl_wcrtomb -# endif -_GL_FUNCDECL_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); -_GL_CXXALIAS_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); -# else -# if !@HAVE_WCRTOMB@ -_GL_FUNCDECL_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); -# endif -_GL_CXXALIAS_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (wcrtomb); -#elif defined GNULIB_POSIXCHECK -# undef wcrtomb -# if HAVE_RAW_DECL_WCRTOMB -_GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - " - "use gnulib module wcrtomb for portability"); -# endif -#endif - - -/* Convert a wide string to a string. */ -#if @GNULIB_WCSRTOMBS@ -# if @REPLACE_WCSRTOMBS@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef wcsrtombs -# define wcsrtombs rpl_wcsrtombs -# endif -_GL_FUNCDECL_RPL (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, - mbstate_t *ps)); -# else -# if !@HAVE_WCSRTOMBS@ -_GL_FUNCDECL_SYS (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (wcsrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t len, - mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (wcsrtombs); -#elif defined GNULIB_POSIXCHECK -# undef wcsrtombs -# if HAVE_RAW_DECL_WCSRTOMBS -_GL_WARN_ON_USE (wcsrtombs, "wcsrtombs is unportable - " - "use gnulib module wcsrtombs for portability"); -# endif -#endif - - -/* Convert a wide string to a string. */ -#if @GNULIB_WCSNRTOMBS@ -# if @REPLACE_WCSNRTOMBS@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef wcsnrtombs -# define wcsnrtombs rpl_wcsnrtombs -# endif -_GL_FUNCDECL_RPL (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -_GL_CXXALIAS_RPL (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps)); -# else -# if !@HAVE_WCSNRTOMBS@ -_GL_FUNCDECL_SYS (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps) - _GL_ARG_NONNULL ((2))); -# endif -_GL_CXXALIAS_SYS (wcsnrtombs, size_t, - (char *dest, const wchar_t **srcp, size_t srclen, size_t len, - mbstate_t *ps)); -# endif -_GL_CXXALIASWARN (wcsnrtombs); -#elif defined GNULIB_POSIXCHECK -# undef wcsnrtombs -# if HAVE_RAW_DECL_WCSNRTOMBS -_GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - " - "use gnulib module wcsnrtombs for portability"); -# endif -#endif - - -/* Return the number of screen columns needed for WC. */ -#if @GNULIB_WCWIDTH@ -# if @REPLACE_WCWIDTH@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef wcwidth -# define wcwidth rpl_wcwidth -# endif -_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); -_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t)); -# else -# if !@HAVE_DECL_WCWIDTH@ -/* wcwidth exists but is not declared. */ -_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); -# endif -_GL_CXXALIASWARN (wcwidth); -#elif defined GNULIB_POSIXCHECK -# undef wcwidth -# if HAVE_RAW_DECL_WCWIDTH -_GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - " - "use gnulib module wcwidth for portability"); -# endif -#endif - - -/* Search N wide characters of S for C. */ -#if @GNULIB_WMEMCHR@ -# if !@HAVE_WMEMCHR@ -_GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n) - _GL_ATTRIBUTE_PURE); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { - const wchar_t * std::wmemchr (const wchar_t *, wchar_t, size_t); - wchar_t * std::wmemchr (wchar_t *, wchar_t, size_t); - } */ -_GL_CXXALIAS_SYS_CAST2 (wmemchr, - wchar_t *, (const wchar_t *, wchar_t, size_t), - const wchar_t *, (const wchar_t *, wchar_t, size_t)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); -_GL_CXXALIASWARN1 (wmemchr, const wchar_t *, - (const wchar_t *s, wchar_t c, size_t n)); -# else -_GL_CXXALIASWARN (wmemchr); -# endif -#elif defined GNULIB_POSIXCHECK -# undef wmemchr -# if HAVE_RAW_DECL_WMEMCHR -_GL_WARN_ON_USE (wmemchr, "wmemchr is unportable - " - "use gnulib module wmemchr for portability"); -# endif -#endif - - -/* Compare N wide characters of S1 and S2. */ -#if @GNULIB_WMEMCMP@ -# if !@HAVE_WMEMCMP@ -_GL_FUNCDECL_SYS (wmemcmp, int, - (const wchar_t *s1, const wchar_t *s2, size_t n) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wmemcmp, int, - (const wchar_t *s1, const wchar_t *s2, size_t n)); -_GL_CXXALIASWARN (wmemcmp); -#elif defined GNULIB_POSIXCHECK -# undef wmemcmp -# if HAVE_RAW_DECL_WMEMCMP -_GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - " - "use gnulib module wmemcmp for portability"); -# endif -#endif - - -/* Copy N wide characters of SRC to DEST. */ -#if @GNULIB_WMEMCPY@ -# if !@HAVE_WMEMCPY@ -_GL_FUNCDECL_SYS (wmemcpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -# endif -_GL_CXXALIAS_SYS (wmemcpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -_GL_CXXALIASWARN (wmemcpy); -#elif defined GNULIB_POSIXCHECK -# undef wmemcpy -# if HAVE_RAW_DECL_WMEMCPY -_GL_WARN_ON_USE (wmemcpy, "wmemcpy is unportable - " - "use gnulib module wmemcpy for portability"); -# endif -#endif - - -/* Copy N wide characters of SRC to DEST, guaranteeing correct behavior for - overlapping memory areas. */ -#if @GNULIB_WMEMMOVE@ -# if !@HAVE_WMEMMOVE@ -_GL_FUNCDECL_SYS (wmemmove, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -# endif -_GL_CXXALIAS_SYS (wmemmove, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -_GL_CXXALIASWARN (wmemmove); -#elif defined GNULIB_POSIXCHECK -# undef wmemmove -# if HAVE_RAW_DECL_WMEMMOVE -_GL_WARN_ON_USE (wmemmove, "wmemmove is unportable - " - "use gnulib module wmemmove for portability"); -# endif -#endif - - -/* Set N wide characters of S to C. */ -#if @GNULIB_WMEMSET@ -# if !@HAVE_WMEMSET@ -_GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); -# endif -_GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); -_GL_CXXALIASWARN (wmemset); -#elif defined GNULIB_POSIXCHECK -# undef wmemset -# if HAVE_RAW_DECL_WMEMSET -_GL_WARN_ON_USE (wmemset, "wmemset is unportable - " - "use gnulib module wmemset for portability"); -# endif -#endif - - -/* Return the number of wide characters in S. */ -#if @GNULIB_WCSLEN@ -# if !@HAVE_WCSLEN@ -_GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s) _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s)); -_GL_CXXALIASWARN (wcslen); -#elif defined GNULIB_POSIXCHECK -# undef wcslen -# if HAVE_RAW_DECL_WCSLEN -_GL_WARN_ON_USE (wcslen, "wcslen is unportable - " - "use gnulib module wcslen for portability"); -# endif -#endif - - -/* Return the number of wide characters in S, but at most MAXLEN. */ -#if @GNULIB_WCSNLEN@ -# if !@HAVE_WCSNLEN@ -_GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)); -_GL_CXXALIASWARN (wcsnlen); -#elif defined GNULIB_POSIXCHECK -# undef wcsnlen -# if HAVE_RAW_DECL_WCSNLEN -_GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - " - "use gnulib module wcsnlen for portability"); -# endif -#endif - - -/* Copy SRC to DEST. */ -#if @GNULIB_WCSCPY@ -# if !@HAVE_WCSCPY@ -_GL_FUNCDECL_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); -# endif -_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); -_GL_CXXALIASWARN (wcscpy); -#elif defined GNULIB_POSIXCHECK -# undef wcscpy -# if HAVE_RAW_DECL_WCSCPY -_GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - " - "use gnulib module wcscpy for portability"); -# endif -#endif - - -/* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST. */ -#if @GNULIB_WCPCPY@ -# if !@HAVE_WCPCPY@ -_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); -# endif -_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); -_GL_CXXALIASWARN (wcpcpy); -#elif defined GNULIB_POSIXCHECK -# undef wcpcpy -# if HAVE_RAW_DECL_WCPCPY -_GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - " - "use gnulib module wcpcpy for portability"); -# endif -#endif - - -/* Copy no more than N wide characters of SRC to DEST. */ -#if @GNULIB_WCSNCPY@ -# if !@HAVE_WCSNCPY@ -_GL_FUNCDECL_SYS (wcsncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -# endif -_GL_CXXALIAS_SYS (wcsncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -_GL_CXXALIASWARN (wcsncpy); -#elif defined GNULIB_POSIXCHECK -# undef wcsncpy -# if HAVE_RAW_DECL_WCSNCPY -_GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - " - "use gnulib module wcsncpy for portability"); -# endif -#endif - - -/* Copy no more than N characters of SRC to DEST, returning the address of - the last character written into DEST. */ -#if @GNULIB_WCPNCPY@ -# if !@HAVE_WCPNCPY@ -_GL_FUNCDECL_SYS (wcpncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -# endif -_GL_CXXALIAS_SYS (wcpncpy, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -_GL_CXXALIASWARN (wcpncpy); -#elif defined GNULIB_POSIXCHECK -# undef wcpncpy -# if HAVE_RAW_DECL_WCPNCPY -_GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - " - "use gnulib module wcpncpy for portability"); -# endif -#endif - - -/* Append SRC onto DEST. */ -#if @GNULIB_WCSCAT@ -# if !@HAVE_WCSCAT@ -_GL_FUNCDECL_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); -# endif -_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); -_GL_CXXALIASWARN (wcscat); -#elif defined GNULIB_POSIXCHECK -# undef wcscat -# if HAVE_RAW_DECL_WCSCAT -_GL_WARN_ON_USE (wcscat, "wcscat is unportable - " - "use gnulib module wcscat for portability"); -# endif -#endif - - -/* Append no more than N wide characters of SRC onto DEST. */ -#if @GNULIB_WCSNCAT@ -# if !@HAVE_WCSNCAT@ -_GL_FUNCDECL_SYS (wcsncat, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -# endif -_GL_CXXALIAS_SYS (wcsncat, wchar_t *, - (wchar_t *dest, const wchar_t *src, size_t n)); -_GL_CXXALIASWARN (wcsncat); -#elif defined GNULIB_POSIXCHECK -# undef wcsncat -# if HAVE_RAW_DECL_WCSNCAT -_GL_WARN_ON_USE (wcsncat, "wcsncat is unportable - " - "use gnulib module wcsncat for portability"); -# endif -#endif - - -/* Compare S1 and S2. */ -#if @GNULIB_WCSCMP@ -# if !@HAVE_WCSCMP@ -_GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); -_GL_CXXALIASWARN (wcscmp); -#elif defined GNULIB_POSIXCHECK -# undef wcscmp -# if HAVE_RAW_DECL_WCSCMP -_GL_WARN_ON_USE (wcscmp, "wcscmp is unportable - " - "use gnulib module wcscmp for portability"); -# endif -#endif - - -/* Compare no more than N wide characters of S1 and S2. */ -#if @GNULIB_WCSNCMP@ -# if !@HAVE_WCSNCMP@ -_GL_FUNCDECL_SYS (wcsncmp, int, - (const wchar_t *s1, const wchar_t *s2, size_t n) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcsncmp, int, - (const wchar_t *s1, const wchar_t *s2, size_t n)); -_GL_CXXALIASWARN (wcsncmp); -#elif defined GNULIB_POSIXCHECK -# undef wcsncmp -# if HAVE_RAW_DECL_WCSNCMP -_GL_WARN_ON_USE (wcsncmp, "wcsncmp is unportable - " - "use gnulib module wcsncmp for portability"); -# endif -#endif - - -/* Compare S1 and S2, ignoring case. */ -#if @GNULIB_WCSCASECMP@ -# if !@HAVE_WCSCASECMP@ -_GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)); -_GL_CXXALIASWARN (wcscasecmp); -#elif defined GNULIB_POSIXCHECK -# undef wcscasecmp -# if HAVE_RAW_DECL_WCSCASECMP -_GL_WARN_ON_USE (wcscasecmp, "wcscasecmp is unportable - " - "use gnulib module wcscasecmp for portability"); -# endif -#endif - - -/* Compare no more than N chars of S1 and S2, ignoring case. */ -#if @GNULIB_WCSNCASECMP@ -# if !@HAVE_WCSNCASECMP@ -_GL_FUNCDECL_SYS (wcsncasecmp, int, - (const wchar_t *s1, const wchar_t *s2, size_t n) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcsncasecmp, int, - (const wchar_t *s1, const wchar_t *s2, size_t n)); -_GL_CXXALIASWARN (wcsncasecmp); -#elif defined GNULIB_POSIXCHECK -# undef wcsncasecmp -# if HAVE_RAW_DECL_WCSNCASECMP -_GL_WARN_ON_USE (wcsncasecmp, "wcsncasecmp is unportable - " - "use gnulib module wcsncasecmp for portability"); -# endif -#endif - - -/* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE - category of the current locale. */ -#if @GNULIB_WCSCOLL@ -# if !@HAVE_WCSCOLL@ -_GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); -# endif -_GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); -_GL_CXXALIASWARN (wcscoll); -#elif defined GNULIB_POSIXCHECK -# undef wcscoll -# if HAVE_RAW_DECL_WCSCOLL -_GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - " - "use gnulib module wcscoll for portability"); -# endif -#endif - - -/* Transform S2 into array pointed to by S1 such that if wcscmp is applied - to two transformed strings the result is the as applying 'wcscoll' to the - original strings. */ -#if @GNULIB_WCSXFRM@ -# if !@HAVE_WCSXFRM@ -_GL_FUNCDECL_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); -# endif -_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); -_GL_CXXALIASWARN (wcsxfrm); -#elif defined GNULIB_POSIXCHECK -# undef wcsxfrm -# if HAVE_RAW_DECL_WCSXFRM -_GL_WARN_ON_USE (wcsxfrm, "wcsxfrm is unportable - " - "use gnulib module wcsxfrm for portability"); -# endif -#endif - - -/* Duplicate S, returning an identical malloc'd string. */ -#if @GNULIB_WCSDUP@ -# if !@HAVE_WCSDUP@ -_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s)); -# endif -_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); -_GL_CXXALIASWARN (wcsdup); -#elif defined GNULIB_POSIXCHECK -# undef wcsdup -# if HAVE_RAW_DECL_WCSDUP -_GL_WARN_ON_USE (wcsdup, "wcsdup is unportable - " - "use gnulib module wcsdup for portability"); -# endif -#endif - - -/* Find the first occurrence of WC in WCS. */ -#if @GNULIB_WCSCHR@ -# if !@HAVE_WCSCHR@ -_GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc) - _GL_ATTRIBUTE_PURE); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { - const wchar_t * std::wcschr (const wchar_t *, wchar_t); - wchar_t * std::wcschr (wchar_t *, wchar_t); - } */ -_GL_CXXALIAS_SYS_CAST2 (wcschr, - wchar_t *, (const wchar_t *, wchar_t), - const wchar_t *, (const wchar_t *, wchar_t)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc)); -_GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); -# else -_GL_CXXALIASWARN (wcschr); -# endif -#elif defined GNULIB_POSIXCHECK -# undef wcschr -# if HAVE_RAW_DECL_WCSCHR -_GL_WARN_ON_USE (wcschr, "wcschr is unportable - " - "use gnulib module wcschr for portability"); -# endif -#endif - - -/* Find the last occurrence of WC in WCS. */ -#if @GNULIB_WCSRCHR@ -# if !@HAVE_WCSRCHR@ -_GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc) - _GL_ATTRIBUTE_PURE); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { - const wchar_t * std::wcsrchr (const wchar_t *, wchar_t); - wchar_t * std::wcsrchr (wchar_t *, wchar_t); - } */ -_GL_CXXALIAS_SYS_CAST2 (wcsrchr, - wchar_t *, (const wchar_t *, wchar_t), - const wchar_t *, (const wchar_t *, wchar_t)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc)); -_GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); -# else -_GL_CXXALIASWARN (wcsrchr); -# endif -#elif defined GNULIB_POSIXCHECK -# undef wcsrchr -# if HAVE_RAW_DECL_WCSRCHR -_GL_WARN_ON_USE (wcsrchr, "wcsrchr is unportable - " - "use gnulib module wcsrchr for portability"); -# endif -#endif - - -/* Return the length of the initial segmet of WCS which consists entirely - of wide characters not in REJECT. */ -#if @GNULIB_WCSCSPN@ -# if !@HAVE_WCSCSPN@ -_GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)); -_GL_CXXALIASWARN (wcscspn); -#elif defined GNULIB_POSIXCHECK -# undef wcscspn -# if HAVE_RAW_DECL_WCSCSPN -_GL_WARN_ON_USE (wcscspn, "wcscspn is unportable - " - "use gnulib module wcscspn for portability"); -# endif -#endif - - -/* Return the length of the initial segmet of WCS which consists entirely - of wide characters in ACCEPT. */ -#if @GNULIB_WCSSPN@ -# if !@HAVE_WCSSPN@ -_GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)); -_GL_CXXALIASWARN (wcsspn); -#elif defined GNULIB_POSIXCHECK -# undef wcsspn -# if HAVE_RAW_DECL_WCSSPN -_GL_WARN_ON_USE (wcsspn, "wcsspn is unportable - " - "use gnulib module wcsspn for portability"); -# endif -#endif - - -/* Find the first occurrence in WCS of any character in ACCEPT. */ -#if @GNULIB_WCSPBRK@ -# if !@HAVE_WCSPBRK@ -_GL_FUNCDECL_SYS (wcspbrk, wchar_t *, - (const wchar_t *wcs, const wchar_t *accept) - _GL_ATTRIBUTE_PURE); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { - const wchar_t * std::wcspbrk (const wchar_t *, const wchar_t *); - wchar_t * std::wcspbrk (wchar_t *, const wchar_t *); - } */ -_GL_CXXALIAS_SYS_CAST2 (wcspbrk, - wchar_t *, (const wchar_t *, const wchar_t *), - const wchar_t *, (const wchar_t *, const wchar_t *)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (wcspbrk, wchar_t *, - (wchar_t *wcs, const wchar_t *accept)); -_GL_CXXALIASWARN1 (wcspbrk, const wchar_t *, - (const wchar_t *wcs, const wchar_t *accept)); -# else -_GL_CXXALIASWARN (wcspbrk); -# endif -#elif defined GNULIB_POSIXCHECK -# undef wcspbrk -# if HAVE_RAW_DECL_WCSPBRK -_GL_WARN_ON_USE (wcspbrk, "wcspbrk is unportable - " - "use gnulib module wcspbrk for portability"); -# endif -#endif - - -/* Find the first occurrence of NEEDLE in HAYSTACK. */ -#if @GNULIB_WCSSTR@ -# if !@HAVE_WCSSTR@ -_GL_FUNCDECL_SYS (wcsstr, wchar_t *, - (const wchar_t *haystack, const wchar_t *needle) - _GL_ATTRIBUTE_PURE); -# endif - /* On some systems, this function is defined as an overloaded function: - extern "C++" { - const wchar_t * std::wcsstr (const wchar_t *, const wchar_t *); - wchar_t * std::wcsstr (wchar_t *, const wchar_t *); - } */ -_GL_CXXALIAS_SYS_CAST2 (wcsstr, - wchar_t *, (const wchar_t *, const wchar_t *), - const wchar_t *, (const wchar_t *, const wchar_t *)); -# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) -_GL_CXXALIASWARN1 (wcsstr, wchar_t *, - (wchar_t *haystack, const wchar_t *needle)); -_GL_CXXALIASWARN1 (wcsstr, const wchar_t *, - (const wchar_t *haystack, const wchar_t *needle)); -# else -_GL_CXXALIASWARN (wcsstr); -# endif -#elif defined GNULIB_POSIXCHECK -# undef wcsstr -# if HAVE_RAW_DECL_WCSSTR -_GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - " - "use gnulib module wcsstr for portability"); -# endif -#endif - - -/* Divide WCS into tokens separated by characters in DELIM. */ -#if @GNULIB_WCSTOK@ -# if !@HAVE_WCSTOK@ -_GL_FUNCDECL_SYS (wcstok, wchar_t *, - (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); -# endif -_GL_CXXALIAS_SYS (wcstok, wchar_t *, - (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); -_GL_CXXALIASWARN (wcstok); -#elif defined GNULIB_POSIXCHECK -# undef wcstok -# if HAVE_RAW_DECL_WCSTOK -_GL_WARN_ON_USE (wcstok, "wcstok is unportable - " - "use gnulib module wcstok for portability"); -# endif -#endif - - -/* Determine number of column positions required for first N wide - characters (or fewer if S ends before this) in S. */ -#if @GNULIB_WCSWIDTH@ -# if @REPLACE_WCSWIDTH@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# undef wcswidth -# define wcswidth rpl_wcswidth -# endif -_GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n) - _GL_ATTRIBUTE_PURE); -_GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n)); -# else -# if !@HAVE_WCSWIDTH@ -_GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n) - _GL_ATTRIBUTE_PURE); -# endif -_GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n)); -# endif -_GL_CXXALIASWARN (wcswidth); -#elif defined GNULIB_POSIXCHECK -# undef wcswidth -# if HAVE_RAW_DECL_WCSWIDTH -_GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - " - "use gnulib module wcswidth for portability"); -# endif -#endif - - -#endif /* _@GUARD_PREFIX@_WCHAR_H */ -#endif /* _@GUARD_PREFIX@_WCHAR_H */ -#endif diff --git a/grub-core/gnulib/wcrtomb.c b/grub-core/gnulib/wcrtomb.c deleted file mode 100644 index da42809bc..000000000 --- a/grub-core/gnulib/wcrtomb.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Convert wide character to multibyte character. - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Written by Bruno Haible , 2008. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -#include -#include - - -size_t -wcrtomb (char *s, wchar_t wc, mbstate_t *ps) -{ - /* This implementation of wcrtomb on top of wctomb() supports only - stateless encodings. ps must be in the initial state. */ - if (ps != NULL && !mbsinit (ps)) - { - errno = EINVAL; - return (size_t)(-1); - } - - if (s == NULL) - /* We know the NUL wide character corresponds to the NUL character. */ - return 1; - else - { - int ret = wctomb (s, wc); - - if (ret >= 0) - return ret; - else - { - errno = EILSEQ; - return (size_t)(-1); - } - } -} diff --git a/grub-core/gnulib/wctype-h.c b/grub-core/gnulib/wctype-h.c deleted file mode 100644 index bb5f847e3..000000000 --- a/grub-core/gnulib/wctype-h.c +++ /dev/null @@ -1,4 +0,0 @@ -/* Normally this would be wctype.c, but that name's already taken. */ -#include -#define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE -#include "wctype.h" diff --git a/grub-core/gnulib/wctype.in.h b/grub-core/gnulib/wctype.in.h deleted file mode 100644 index 0cd02d5a3..000000000 --- a/grub-core/gnulib/wctype.in.h +++ /dev/null @@ -1,504 +0,0 @@ -/* A substitute for ISO C99 , for platforms that lack it. - - Copyright (C) 2006-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, 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 Bruno Haible and Paul Eggert. */ - -/* - * ISO C 99 for platforms that lack it. - * - * - * iswctype, towctrans, towlower, towupper, wctrans, wctype, - * wctrans_t, and wctype_t are not yet implemented. - */ - -#ifndef _@GUARD_PREFIX@_WCTYPE_H - -#if __GNUC__ >= 3 -@PRAGMA_SYSTEM_HEADER@ -#endif -@PRAGMA_COLUMNS@ - -#if @HAVE_WINT_T@ -/* Solaris 2.5 has a bug: must be included before . - Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -# include -# include -# include -# include -#endif - -/* Include the original if it exists. - BeOS 5 has the functions but no . */ -/* The include_next requires a split double-inclusion guard. */ -#if @HAVE_WCTYPE_H@ -# @INCLUDE_NEXT@ @NEXT_WCTYPE_H@ -#endif - -#ifndef _@GUARD_PREFIX@_WCTYPE_H -#define _@GUARD_PREFIX@_WCTYPE_H - -_GL_INLINE_HEADER_BEGIN -#ifndef _GL_WCTYPE_INLINE -# define _GL_WCTYPE_INLINE _GL_INLINE -#endif - -/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ - -/* The definition of _GL_WARN_ON_USE is copied here. */ - -/* Solaris 2.6 includes which includes which - #defines a number of identifiers in the application namespace. Revert - these #defines. */ -#ifdef __sun -# undef multibyte -# undef eucw1 -# undef eucw2 -# undef eucw3 -# undef scrw1 -# undef scrw2 -# undef scrw3 -#endif - -/* Define wint_t and WEOF. (Also done in wchar.in.h.) */ -#if !@HAVE_WINT_T@ && !defined wint_t -# define wint_t int -# ifndef WEOF -# define WEOF -1 -# endif -#else -/* MSVC defines wint_t as 'unsigned short' in . - This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be - "unchanged by default argument promotions". Override it. */ -# if defined _MSC_VER -# if !GNULIB_defined_wint_t -# include -typedef unsigned int rpl_wint_t; -# undef wint_t -# define wint_t rpl_wint_t -# define GNULIB_defined_wint_t 1 -# endif -# endif -# ifndef WEOF -# define WEOF ((wint_t) -1) -# endif -#endif - - -#if !GNULIB_defined_wctype_functions - -/* FreeBSD 4.4 to 4.11 has but lacks the functions. - Linux libc5 has and the functions but they are broken. - Assume all 11 functions (all isw* except iswblank) are implemented the - same way, or not at all. */ -# if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ - -/* IRIX 5.3 has macros but no functions, its isw* macros refer to an - undefined variable _ctmp_ and to macros like _P, and they - refer to system functions like _iswctype that are not in the - standard C library. Rather than try to get ancient buggy - implementations like this to work, just disable them. */ -# undef iswalnum -# undef iswalpha -# undef iswblank -# undef iswcntrl -# undef iswdigit -# undef iswgraph -# undef iswlower -# undef iswprint -# undef iswpunct -# undef iswspace -# undef iswupper -# undef iswxdigit -# undef towlower -# undef towupper - -/* Linux libc5 has and the functions but they are broken. */ -# if @REPLACE_ISWCNTRL@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define iswalnum rpl_iswalnum -# define iswalpha rpl_iswalpha -# define iswblank rpl_iswblank -# define iswcntrl rpl_iswcntrl -# define iswdigit rpl_iswdigit -# define iswgraph rpl_iswgraph -# define iswlower rpl_iswlower -# define iswprint rpl_iswprint -# define iswpunct rpl_iswpunct -# define iswspace rpl_iswspace -# define iswupper rpl_iswupper -# define iswxdigit rpl_iswxdigit -# endif -# endif -# if @REPLACE_TOWLOWER@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define towlower rpl_towlower -# define towupper rpl_towupper -# endif -# endif - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswalnum -# else -iswalnum -# endif - (wint_t wc) -{ - return ((wc >= '0' && wc <= '9') - || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswalpha -# else -iswalpha -# endif - (wint_t wc) -{ - return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswblank -# else -iswblank -# endif - (wint_t wc) -{ - return wc == ' ' || wc == '\t'; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswcntrl -# else -iswcntrl -# endif - (wint_t wc) -{ - return (wc & ~0x1f) == 0 || wc == 0x7f; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswdigit -# else -iswdigit -# endif - (wint_t wc) -{ - return wc >= '0' && wc <= '9'; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswgraph -# else -iswgraph -# endif - (wint_t wc) -{ - return wc >= '!' && wc <= '~'; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswlower -# else -iswlower -# endif - (wint_t wc) -{ - return wc >= 'a' && wc <= 'z'; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswprint -# else -iswprint -# endif - (wint_t wc) -{ - return wc >= ' ' && wc <= '~'; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswpunct -# else -iswpunct -# endif - (wint_t wc) -{ - return (wc >= '!' && wc <= '~' - && !((wc >= '0' && wc <= '9') - || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'))); -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswspace -# else -iswspace -# endif - (wint_t wc) -{ - return (wc == ' ' || wc == '\t' - || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r'); -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswupper -# else -iswupper -# endif - (wint_t wc) -{ - return wc >= 'A' && wc <= 'Z'; -} - -_GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ -rpl_iswxdigit -# else -iswxdigit -# endif - (wint_t wc) -{ - return ((wc >= '0' && wc <= '9') - || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); -} - -_GL_WCTYPE_INLINE wint_t -# if @REPLACE_TOWLOWER@ -rpl_towlower -# else -towlower -# endif - (wint_t wc) -{ - return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); -} - -_GL_WCTYPE_INLINE wint_t -# if @REPLACE_TOWLOWER@ -rpl_towupper -# else -towupper -# endif - (wint_t wc) -{ - return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); -} - -# elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) -/* Only the iswblank function is missing. */ - -# if @REPLACE_ISWBLANK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define iswblank rpl_iswblank -# endif -_GL_FUNCDECL_RPL (iswblank, int, (wint_t wc)); -# else -_GL_FUNCDECL_SYS (iswblank, int, (wint_t wc)); -# endif - -# endif - -# if defined __MINGW32__ - -/* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t. - The functions towlower and towupper are implemented in the MSVCRT library - to take a wchar_t argument and return a wchar_t result. mingw declares - these functions to take a wint_t argument and return a wint_t result. - This means that: - 1. When the user passes an argument outside the range 0x0000..0xFFFF, the - function will look only at the lower 16 bits. This is allowed according - to POSIX. - 2. The return value is returned in the lower 16 bits of the result register. - The upper 16 bits are random: whatever happened to be in that part of the - result register. We need to fix this by adding a zero-extend from - wchar_t to wint_t after the call. */ - -_GL_WCTYPE_INLINE wint_t -rpl_towlower (wint_t wc) -{ - return (wint_t) (wchar_t) towlower (wc); -} -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define towlower rpl_towlower -# endif - -_GL_WCTYPE_INLINE wint_t -rpl_towupper (wint_t wc) -{ - return (wint_t) (wchar_t) towupper (wc); -} -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define towupper rpl_towupper -# endif - -# endif /* __MINGW32__ */ - -# define GNULIB_defined_wctype_functions 1 -#endif - -#if @REPLACE_ISWCNTRL@ -_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); -#else -_GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswlower, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswprint, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswspace, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); -_GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); -#endif -_GL_CXXALIASWARN (iswalnum); -_GL_CXXALIASWARN (iswalpha); -_GL_CXXALIASWARN (iswcntrl); -_GL_CXXALIASWARN (iswdigit); -_GL_CXXALIASWARN (iswgraph); -_GL_CXXALIASWARN (iswlower); -_GL_CXXALIASWARN (iswprint); -_GL_CXXALIASWARN (iswpunct); -_GL_CXXALIASWARN (iswspace); -_GL_CXXALIASWARN (iswupper); -_GL_CXXALIASWARN (iswxdigit); - -#if @GNULIB_ISWBLANK@ -# if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@ -_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); -# else -_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc)); -# endif -_GL_CXXALIASWARN (iswblank); -#endif - -#if !@HAVE_WCTYPE_T@ -# if !GNULIB_defined_wctype_t -typedef void * wctype_t; -# define GNULIB_defined_wctype_t 1 -# endif -#endif - -/* Get a descriptor for a wide character property. */ -#if @GNULIB_WCTYPE@ -# if !@HAVE_WCTYPE_T@ -_GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name)); -# endif -_GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name)); -_GL_CXXALIASWARN (wctype); -#elif defined GNULIB_POSIXCHECK -# undef wctype -# if HAVE_RAW_DECL_WCTYPE -_GL_WARN_ON_USE (wctype, "wctype is unportable - " - "use gnulib module wctype for portability"); -# endif -#endif - -/* Test whether a wide character has a given property. - The argument WC must be either a wchar_t value or WEOF. - The argument DESC must have been returned by the wctype() function. */ -#if @GNULIB_ISWCTYPE@ -# if !@HAVE_WCTYPE_T@ -_GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc)); -# endif -_GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc)); -_GL_CXXALIASWARN (iswctype); -#elif defined GNULIB_POSIXCHECK -# undef iswctype -# if HAVE_RAW_DECL_ISWCTYPE -_GL_WARN_ON_USE (iswctype, "iswctype is unportable - " - "use gnulib module iswctype for portability"); -# endif -#endif - -#if @REPLACE_TOWLOWER@ || defined __MINGW32__ -_GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc)); -_GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc)); -#else -_GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc)); -_GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc)); -#endif -_GL_CXXALIASWARN (towlower); -_GL_CXXALIASWARN (towupper); - -#if !@HAVE_WCTRANS_T@ -# if !GNULIB_defined_wctrans_t -typedef void * wctrans_t; -# define GNULIB_defined_wctrans_t 1 -# endif -#endif - -/* Get a descriptor for a wide character case conversion. */ -#if @GNULIB_WCTRANS@ -# if !@HAVE_WCTRANS_T@ -_GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name)); -# endif -_GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name)); -_GL_CXXALIASWARN (wctrans); -#elif defined GNULIB_POSIXCHECK -# undef wctrans -# if HAVE_RAW_DECL_WCTRANS -_GL_WARN_ON_USE (wctrans, "wctrans is unportable - " - "use gnulib module wctrans for portability"); -# endif -#endif - -/* Perform a given case conversion on a wide character. - The argument WC must be either a wchar_t value or WEOF. - The argument DESC must have been returned by the wctrans() function. */ -#if @GNULIB_TOWCTRANS@ -# if !@HAVE_WCTRANS_T@ -_GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); -# endif -_GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); -_GL_CXXALIASWARN (towctrans); -#elif defined GNULIB_POSIXCHECK -# undef towctrans -# if HAVE_RAW_DECL_TOWCTRANS -_GL_WARN_ON_USE (towctrans, "towctrans is unportable - " - "use gnulib module towctrans for portability"); -# endif -#endif - -_GL_INLINE_HEADER_END - -#endif /* _@GUARD_PREFIX@_WCTYPE_H */ -#endif /* _@GUARD_PREFIX@_WCTYPE_H */ diff --git a/grub-core/gnulib/wcwidth.c b/grub-core/gnulib/wcwidth.c deleted file mode 100644 index 253fcaa65..000000000 --- a/grub-core/gnulib/wcwidth.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Determine the number of screen columns needed for a character. - Copyright (C) 2006-2007, 2010-2013 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include - -/* Get iswprint. */ -#include - -#include "localcharset.h" -#include "streq.h" -#include "uniwidth.h" - -int -wcwidth (wchar_t wc) -#undef wcwidth -{ - /* In UTF-8 locales, use a Unicode aware width function. */ - const char *encoding = locale_charset (); - if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0 ,0)) - { - /* We assume that in a UTF-8 locale, a wide character is the same as a - Unicode character. */ - return uc_width (wc, encoding); - } - else - { - /* Otherwise, fall back to the system's wcwidth function. */ -#if HAVE_WCWIDTH - return wcwidth (wc); -#else - return wc == 0 ? 0 : iswprint (wc) ? 1 : -1; -#endif - } -} diff --git a/grub-core/gnulib/xsize.c b/grub-core/gnulib/xsize.c deleted file mode 100644 index 4b4914c2c..000000000 --- a/grub-core/gnulib/xsize.c +++ /dev/null @@ -1,3 +0,0 @@ -#include -#define XSIZE_INLINE _GL_EXTERN_INLINE -#include "xsize.h" diff --git a/grub-core/gnulib/xsize.h b/grub-core/gnulib/xsize.h deleted file mode 100644 index 2922f3530..000000000 --- a/grub-core/gnulib/xsize.h +++ /dev/null @@ -1,114 +0,0 @@ -/* xsize.h -- Checked size_t computations. - - Copyright (C) 2003, 2008-2013 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . */ - -#ifndef _XSIZE_H -#define _XSIZE_H - -/* Get size_t. */ -#include - -/* Get SIZE_MAX. */ -#include -#if HAVE_STDINT_H -# include -#endif - -_GL_INLINE_HEADER_BEGIN -#ifndef XSIZE_INLINE -# define XSIZE_INLINE _GL_INLINE -#endif - -/* The size of memory objects is often computed through expressions of - type size_t. Example: - void* p = malloc (header_size + n * element_size). - These computations can lead to overflow. When this happens, malloc() - returns a piece of memory that is way too small, and the program then - crashes while attempting to fill the memory. - To avoid this, the functions and macros in this file check for overflow. - The convention is that SIZE_MAX represents overflow. - malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc - implementation that uses mmap --, it's recommended to use size_overflow_p() - or size_in_bounds_p() before invoking malloc(). - The example thus becomes: - size_t size = xsum (header_size, xtimes (n, element_size)); - void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); -*/ - -/* Convert an arbitrary value >= 0 to type size_t. */ -#define xcast_size_t(N) \ - ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) - -/* Sum of two sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum (size_t size1, size_t size2) -{ - size_t sum = size1 + size2; - return (sum >= size1 ? sum : SIZE_MAX); -} - -/* Sum of three sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum3 (size_t size1, size_t size2, size_t size3) -{ - return xsum (xsum (size1, size2), size3); -} - -/* Sum of four sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) -{ - return xsum (xsum (xsum (size1, size2), size3), size4); -} - -/* Maximum of two sizes, with overflow check. */ -XSIZE_INLINE size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xmax (size_t size1, size_t size2) -{ - /* No explicit check is needed here, because for any n: - max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ - return (size1 >= size2 ? size1 : size2); -} - -/* Multiplication of a count with an element size, with overflow check. - The count must be >= 0 and the element size must be > 0. - This is a macro, not a function, so that it works correctly even - when N is of a wider type and N > SIZE_MAX. */ -#define xtimes(N, ELSIZE) \ - ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) - -/* Check for overflow. */ -#define size_overflow_p(SIZE) \ - ((SIZE) == SIZE_MAX) -/* Check against overflow. */ -#define size_in_bounds_p(SIZE) \ - ((SIZE) != SIZE_MAX) - -_GL_INLINE_HEADER_END - -#endif /* _XSIZE_H */ diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c index 22438277d..a458c3aca 100644 --- a/grub-core/io/bufio.c +++ b/grub-core/io/bufio.c @@ -43,7 +43,7 @@ typedef struct grub_bufio *grub_bufio_t; static struct grub_fs grub_bufio_fs; grub_file_t -grub_bufio_open (grub_file_t io, int size) +grub_bufio_open (grub_file_t io, grub_size_t size) { grub_file_t file; grub_bufio_t bufio = 0; @@ -57,10 +57,17 @@ grub_bufio_open (grub_file_t io, int size) else if (size > GRUB_BUFIO_MAX_SIZE) size = GRUB_BUFIO_MAX_SIZE; - if ((size < 0) || ((unsigned) size > io->size)) + if (size > io->size) size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE : io->size); + /* + * Round up size to power of 2 which the binary math to + * calculate next_buf in grub_bufio_read() requires. + */ + while (size & (size - 1)) + size = (size | (size - 1)) + 1; + bufio = grub_zalloc (sizeof (struct grub_bufio) + size); if (! bufio) { @@ -81,11 +88,11 @@ grub_bufio_open (grub_file_t io, int size) } grub_file_t -grub_buffile_open (const char *name, int size) +grub_buffile_open (const char *name, enum grub_file_type type, grub_size_t size) { grub_file_t io, file; - io = grub_file_open (name); + io = grub_file_open (name, type); if (! io) return 0; @@ -198,10 +205,10 @@ grub_bufio_close (grub_file_t file) static struct grub_fs grub_bufio_fs = { .name = "bufio", - .dir = 0, - .open = 0, - .read = grub_bufio_read, - .close = grub_bufio_close, - .label = 0, + .fs_dir = 0, + .fs_open = 0, + .fs_read = grub_bufio_read, + .fs_close = grub_bufio_close, + .fs_label = 0, .next = 0 }; diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c index 0f2ea6bd8..cb7eb1fe3 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -43,6 +43,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -94,6 +95,14 @@ struct grub_gzio struct huft *tl; /* The distance code table. */ struct huft *td; + /* The checksum algorithm */ + const gcry_md_spec_t *hdesc; + /* The wanted checksum */ + grub_uint32_t orig_checksum; + /* The uncompressed length */ + grub_size_t orig_len; + /* Context for checksum calculation */ + grub_uint8_t *hcontext; /* The lookup bits for the literal/length code table. */ int bl; /* The lookup bits for the distance code table. */ @@ -140,24 +149,24 @@ eat_field (grub_file_t file, int len) #define OLD_GZIP_MAGIC grub_le_to_cpu16 (0x9E1F) /* Compression methods (see algorithm.doc) */ -#define STORED 0 -#define COMPRESSED 1 -#define PACKED 2 -#define LZHED 3 +#define GRUB_GZ_STORED 0 +#define GRUB_GZ_COMPRESSED 1 +#define GRUB_GZ_PACKED 2 +#define GRUB_GZ_LZHED 3 /* methods 4 to 7 reserved */ -#define DEFLATED 8 -#define MAX_METHODS 9 +#define GRUB_GZ_DEFLATED 8 +#define GRUB_GZ_MAX_METHODS 9 /* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ +#define GRUB_GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define GRUB_GZ_CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define GRUB_GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define GRUB_GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define GRUB_GZ_COMMENT 0x10 /* bit 4 set: file comment present */ +#define GRUB_GZ_ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define GRUB_GZ_RESERVED 0xC0 /* bit 6,7: reserved */ -#define UNSUPPORTED_FLAGS (CONTINUATION | ENCRYPTED | RESERVED) +#define GRUB_GZ_UNSUPPORTED_FLAGS (GRUB_GZ_CONTINUATION | GRUB_GZ_ENCRYPTED | GRUB_GZ_RESERVED) /* inflate block codes */ #define INFLATE_STORED 0 @@ -180,7 +189,7 @@ test_gzip_header (grub_file_t file) grub_uint8_t os_type; } hdr; grub_uint16_t extra_len; - grub_uint32_t orig_len; + grub_uint32_t crc32; grub_gzio_t gzio = file->data; if (grub_file_tell (gzio->file) != 0) @@ -201,26 +210,29 @@ test_gzip_header (grub_file_t file) * problem occurs from here on, then we have corrupt or otherwise * bad data, and the error should be reported to the user. */ - if (hdr.method != DEFLATED - || (hdr.flags & UNSUPPORTED_FLAGS) - || ((hdr.flags & EXTRA_FIELD) + if (hdr.method != GRUB_GZ_DEFLATED + || (hdr.flags & GRUB_GZ_UNSUPPORTED_FLAGS) + || ((hdr.flags & GRUB_GZ_EXTRA_FIELD) && (grub_file_read (gzio->file, &extra_len, 2) != 2 || eat_field (gzio->file, grub_le_to_cpu16 (extra_len)))) - || ((hdr.flags & ORIG_NAME) && eat_field (gzio->file, -1)) - || ((hdr.flags & COMMENT) && eat_field (gzio->file, -1))) + || ((hdr.flags & GRUB_GZ_ORIG_NAME) && eat_field (gzio->file, -1)) + || ((hdr.flags & GRUB_GZ_COMMENT) && eat_field (gzio->file, -1))) return 0; gzio->data_offset = grub_file_tell (gzio->file); /* FIXME: don't do this on not easily seekable files. */ { - grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4); - if (grub_file_read (gzio->file, &orig_len, 4) != 4) + grub_file_seek (gzio->file, grub_file_size (gzio->file) - 8); + if (grub_file_read (gzio->file, &crc32, 4) != 4) + return 0; + gzio->orig_checksum = grub_le_to_cpu32 (crc32); + if (grub_file_read (gzio->file, &gzio->orig_len, 4) != 4) return 0; /* FIXME: this does not handle files whose original size is over 4GB. But how can we know the real original size? */ - file->size = grub_le_to_cpu32 (orig_len); + file->size = grub_le_to_cpu32 (gzio->orig_len); } initialize_tables (gzio); @@ -354,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[] = @@ -365,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) @@ -381,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++]; @@ -435,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) */ @@ -495,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 @@ -542,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) @@ -576,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); @@ -657,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 { @@ -669,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); @@ -691,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 { @@ -708,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++; @@ -782,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"); @@ -867,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) @@ -885,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); } @@ -905,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; @@ -915,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; @@ -943,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; @@ -970,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; @@ -979,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; @@ -987,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; } @@ -1001,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); @@ -1095,7 +1160,23 @@ inflate_window (grub_gzio_t gzio) gzio->saved_offset += gzio->wp; - /* XXX do CRC calculation here! */ + if (gzio->hcontext) + { + gzio->hdesc->write (gzio->hcontext, gzio->slide, gzio->wp); + + if (gzio->saved_offset == gzio->orig_len) + { + grub_uint32_t csum; + + gzio->hdesc->final (gzio->hcontext); + csum = grub_get_unaligned32 (gzio->hdesc->read (gzio->hcontext)); + csum = grub_be_to_cpu32 (csum); + if (csum != gzio->orig_checksum) + grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, + "checksum mismatch %08x/%08x", + gzio->orig_checksum, csum); + } + } } @@ -1118,18 +1199,25 @@ initialize_tables (grub_gzio_t gzio) huft_free (gzio->td); gzio->tl = NULL; gzio->td = NULL; + + if (gzio->hcontext) + gzio->hdesc->init(gzio->hcontext); } -/* Open a new decompressing object on the top of IO. 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, const char *name __attribute__ ((unused))) +grub_gzio_open (grub_file_t io, enum grub_file_type type) { grub_file_t file; grub_gzio_t gzio = 0; + if (type & GRUB_FILE_TYPE_NO_DECOMPRESS) + return io; + file = (grub_file_t) grub_zalloc (sizeof (*file)); if (! file) return 0; @@ -1143,6 +1231,9 @@ grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused))) gzio->file = io; + gzio->hdesc = GRUB_MD_CRC32; + gzio->hcontext = grub_malloc(gzio->hdesc->contextsize); + file->device = io->device; file->data = gzio; file->fs = &grub_gzio_fs; @@ -1151,6 +1242,7 @@ grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused))) if (! test_gzip_header (file)) { grub_errno = GRUB_ERR_NONE; + grub_free (gzio->hcontext); grub_free (gzio); grub_free (file); grub_file_seek (io, 0); @@ -1178,12 +1270,12 @@ static int test_zlib_header (grub_gzio_t gzio) { grub_uint8_t cmf, flg; - + cmf = get_byte (gzio); flg = get_byte (gzio); /* Check that compression method is DEFLATE. */ - if ((cmf & 0xf) != DEFLATED) + if ((cmf & 0xf) != GRUB_GZ_DEFLATED) { /* TRANSLATORS: It's about given file having some strange format, not complete lack of gzip support. */ @@ -1287,6 +1379,7 @@ grub_gzio_close (grub_file_t file) grub_file_close (gzio->file); huft_free (gzio->tl); huft_free (gzio->td); + grub_free (gzio->hcontext); grub_free (gzio); /* No need to close the same device twice. */ @@ -1350,11 +1443,11 @@ grub_deflate_decompress (char *inbuf, grub_size_t insize, grub_off_t off, static struct grub_fs grub_gzio_fs = { .name = "gzio", - .dir = 0, - .open = 0, - .read = grub_gzio_read, - .close = grub_gzio_close, - .label = 0, + .fs_dir = 0, + .fs_open = 0, + .fs_read = grub_gzio_read, + .fs_close = grub_gzio_close, + .fs_label = 0, .next = 0 }; diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c index 7559c6c9c..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; } } @@ -407,12 +403,14 @@ CORRUPTED: } static grub_file_t -grub_lzopio_open (grub_file_t io, - const char *name __attribute__ ((unused))) +grub_lzopio_open (grub_file_t io, enum grub_file_type type) { grub_file_t file; grub_lzopio_t lzopio; + if (type & GRUB_FILE_TYPE_NO_DECOMPRESS) + return io; + file = (grub_file_t) grub_zalloc (sizeof (*file)); if (!file) return 0; @@ -529,11 +527,11 @@ grub_lzopio_close (grub_file_t file) static struct grub_fs grub_lzopio_fs = { .name = "lzopio", - .dir = 0, - .open = 0, - .read = grub_lzopio_read, - .close = grub_lzopio_close, - .label = 0, + .fs_dir = 0, + .fs_open = 0, + .fs_read = grub_lzopio_read, + .fs_close = grub_lzopio_close, + .fs_label = 0, .next = 0 }; diff --git a/grub-core/io/offset.c b/grub-core/io/offset.c index ebed0ebe6..7e2db4a3a 100644 --- a/grub-core/io/offset.c +++ b/grub-core/io/offset.c @@ -52,11 +52,11 @@ grub_offset_close (grub_file_t file) static struct grub_fs grub_offset_fs = { .name = "offset", - .dir = 0, - .open = 0, - .read = grub_offset_read, - .close = grub_offset_close, - .label = 0, + .fs_dir = 0, + .fs_open = 0, + .fs_read = grub_offset_read, + .fs_close = grub_offset_close, + .fs_label = 0, .next = 0 }; @@ -69,7 +69,8 @@ grub_file_offset_close (grub_file_t file) } grub_file_t -grub_file_offset_open (grub_file_t parent, grub_off_t start, grub_off_t size) +grub_file_offset_open (grub_file_t parent, enum grub_file_type type, + grub_off_t start, grub_off_t size) { struct grub_offset_file *off_data; grub_file_t off_file, last_off_file; @@ -95,10 +96,10 @@ grub_file_offset_open (grub_file_t parent, grub_off_t start, grub_off_t size) last_off_file = NULL; for (filter = GRUB_FILE_FILTER_COMPRESSION_FIRST; off_file && filter <= GRUB_FILE_FILTER_COMPRESSION_LAST; filter++) - if (grub_file_filters_enabled[filter]) + if (grub_file_filters[filter]) { last_off_file = off_file; - off_file = grub_file_filters_enabled[filter] (off_file, parent->name); + off_file = grub_file_filters[filter] (off_file, type); } if (!off_file) diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c index a3536ad73..63d8cda6a 100644 --- a/grub-core/io/xzio.c +++ b/grub-core/io/xzio.c @@ -169,12 +169,14 @@ ERROR: } static grub_file_t -grub_xzio_open (grub_file_t io, - const char *name __attribute__ ((unused))) +grub_xzio_open (grub_file_t io, enum grub_file_type type) { grub_file_t file; grub_xzio_t xzio; + if (type & GRUB_FILE_TYPE_NO_DECOMPRESS) + return io; + file = (grub_file_t) grub_zalloc (sizeof (*file)); if (!file) return 0; @@ -281,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. */ { @@ -325,11 +327,11 @@ grub_xzio_close (grub_file_t file) static struct grub_fs grub_xzio_fs = { .name = "xzio", - .dir = 0, - .open = 0, - .read = grub_xzio_read, - .close = grub_xzio_close, - .label = 0, + .fs_dir = 0, + .fs_open = 0, + .fs_read = grub_xzio_read, + .fs_close = grub_xzio_close, + .fs_label = 0, .next = 0 }; 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 34154ccdb..6c75193e4 100644 --- a/grub-core/kern/arm/cache.c +++ b/grub-core/kern/arm/cache.c @@ -29,6 +29,8 @@ void grub_arm_clean_dcache_range_armv6 (grub_addr_t start, grub_addr_t end, grub_addr_t dlinesz); void grub_arm_clean_dcache_range_armv7 (grub_addr_t start, grub_addr_t end, grub_addr_t dlinesz); +void grub_arm_clean_dcache_range_poc_armv7 (grub_addr_t start, grub_addr_t end, + grub_addr_t dlinesz); void grub_arm_invalidate_icache_range_armv6 (grub_addr_t start, grub_addr_t end, grub_addr_t dlinesz); void grub_arm_invalidate_icache_range_armv7 (grub_addr_t start, grub_addr_t end, @@ -91,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; @@ -252,6 +257,38 @@ grub_arch_sync_caches (void *address, grub_size_t len) } } +void +grub_arch_sync_dma_caches (volatile void *address, grub_size_t len) +{ + grub_addr_t start = (grub_addr_t) address; + grub_addr_t end = start + len; + + if (type == ARCH_UNKNOWN) + probe_caches (); + start = ALIGN_DOWN (start, grub_arch_cache_max_linesz); + end = ALIGN_UP (end, grub_arch_cache_max_linesz); + switch (type) + { + case ARCH_ARMV6: + grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz); + grub_arm_invalidate_icache_range_armv6 (start, end, + grub_arch_cache_ilinesz); + break; + case ARCH_ARMV5_WRITE_THROUGH: + case ARCH_ARMV6_UNIFIED: + grub_arm_clean_dcache_range_armv6 (start, end, grub_arch_cache_dlinesz); + break; + case ARCH_ARMV7: + grub_arm_clean_dcache_range_poc_armv7 (start, end, grub_arch_cache_dlinesz); + grub_arm_invalidate_icache_range_armv7 (start, end, + grub_arch_cache_ilinesz); + break; + /* Pacify GCC. */ + case ARCH_UNKNOWN: + break; + } +} + void grub_arm_disable_caches_mmu (void) { diff --git a/grub-core/kern/arm/cache_armv7.S b/grub-core/kern/arm/cache_armv7.S index 1ef2754af..5ae76a3d8 100644 --- a/grub-core/kern/arm/cache_armv7.S +++ b/grub-core/kern/arm/cache_armv7.S @@ -33,6 +33,18 @@ # define ISB isb #define ARMV7 1 +FUNCTION(grub_arm_clean_dcache_range_poc_armv7) + DSB + @ Clean data cache for range to point-of-coherence +1: cmp r0, r1 + bge 2f + mcr p15, 0, r0, c7, c14, 1 @ DCCMVAC + add r0, r0, r2 @ Next line + b 1b +2: DSB + bx lr + + @ r0 - CLIDR @ r1 - LoC @ r2 - current level diff --git a/grub-core/kern/arm/coreboot/cbtable.c b/grub-core/kern/arm/coreboot/cbtable.c new file mode 100644 index 000000000..8a655bb5c --- /dev/null +++ b/grub-core/kern/arm/coreboot/cbtable.c @@ -0,0 +1,40 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#pragma GCC diagnostic ignored "-Wcast-align" + +grub_linuxbios_table_header_t +grub_linuxbios_get_tables (void) +{ + grub_linuxbios_table_header_t table_header + = (grub_linuxbios_table_header_t) grub_arm_saved_registers.r[0]; + + if (!grub_linuxbios_check_signature (table_header)) + return 0; + + return table_header; +} diff --git a/grub-core/kern/arm/coreboot/coreboot.S b/grub-core/kern/arm/coreboot/coreboot.S new file mode 100644 index 000000000..a1104526c --- /dev/null +++ b/grub-core/kern/arm/coreboot/coreboot.S @@ -0,0 +1,44 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .file "coreboot.S" + .text + .syntax unified +#if !defined (__thumb2__) + .arch armv7a + .arm +#else + .arch armv7 + .thumb +#endif + +FUNCTION(grub_arm_pfr1) + mrc p15, 0, r0, c0, c1, 1 + bx lr + +FUNCTION(grub_armv7_get_timer_value) + isb + mrrc p15, 1, r0, r1, c14 + bx lr + +FUNCTION(grub_armv7_get_timer_frequency) + mrc p15, 0, r0, c14, c0, 0 + bx lr + diff --git a/grub-core/kern/arm/coreboot/dma.c b/grub-core/kern/arm/coreboot/dma.c new file mode 100644 index 000000000..2c2a62789 --- /dev/null +++ b/grub-core/kern/arm/coreboot/dma.c @@ -0,0 +1,59 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_pci_dma_chunk * +grub_memalign_dma32 (grub_size_t align, grub_size_t size) +{ + void *ret; + if (align < 64) + align = 64; + size = ALIGN_UP (size, align); + ret = grub_memalign (align, size); + if (!ret) + return 0; + grub_arch_sync_dma_caches (ret, size); + return ret; +} + +void +grub_dma_free (struct grub_pci_dma_chunk *ch) +{ + grub_size_t size = (((struct grub_mm_header *) ch) - 1)->size * GRUB_MM_ALIGN; + grub_arch_sync_dma_caches (ch, size); + grub_free (ch); +} + +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ch; +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (grub_uint32_t) (grub_addr_t) ch; +} + diff --git a/grub-core/kern/arm/coreboot/init.c b/grub-core/kern/arm/coreboot/init.c new file mode 100644 index 000000000..8d8c5b829 --- /dev/null +++ b/grub-core/kern/arm/coreboot/init.c @@ -0,0 +1,151 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern grub_uint8_t _start[]; +extern grub_uint8_t _end[]; +extern grub_uint8_t _edata[]; +grub_addr_t start_of_ram = ~(grub_addr_t)0; + +void __attribute__ ((noreturn)) +grub_exit (void) +{ + /* We can't use grub_fatal() in this function. This would create an infinite + loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */ + while (1) + grub_cpu_idle (); +} + +static grub_uint64_t modend; +static int have_memory = 0; + +/* Helper for grub_machine_init. */ +static int +heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, + void *data __attribute__ ((unused))) +{ + grub_uint64_t begin = addr, end = addr + size; + +#if GRUB_CPU_SIZEOF_VOID_P == 4 + /* Restrict ourselves to 32-bit memory space. */ + if (begin > GRUB_ULONG_MAX) + return 0; + if (end > GRUB_ULONG_MAX) + end = GRUB_ULONG_MAX; +#endif + + if (start_of_ram > begin) + start_of_ram = begin; + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + + if (modend && begin < modend) + { + if (begin < (grub_addr_t)_start) + { + grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) ((grub_addr_t)_start - begin)); + have_memory = 1; + } + begin = modend; + } + + /* Avoid DMA problems. */ + if (end >= 0xfe000000) + end = 0xfe000000; + + if (end <= begin) + return 0; + + grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin)); + + have_memory = 1; + + return 0; +} + +void +grub_machine_init (void) +{ + struct grub_module_header *header; + void *dtb = 0; + grub_size_t dtb_size = 0; + + modend = grub_modules_get_end (); + + grub_video_coreboot_fb_early_init (); + + grub_machine_mmap_iterate (heap_init, NULL); + if (!have_memory) + grub_fatal ("No memory found"); + + grub_video_coreboot_fb_late_init (); + + grub_font_init (); + grub_gfxterm_init (); + + FOR_MODULES (header) + if (header->type == OBJ_TYPE_DTB) + { + char *dtb_orig_addr, *dtb_copy; + dtb_orig_addr = (char *) header + sizeof (struct grub_module_header); + + dtb_size = header->size - sizeof (struct grub_module_header); + dtb = dtb_copy = grub_malloc (dtb_size); + grub_memmove (dtb_copy, dtb_orig_addr, dtb_size); + break; + } + if (!dtb) + grub_fatal ("No DTB found"); + grub_fdtbus_init (dtb, dtb_size); + + grub_rk3288_spi_init (); + + grub_machine_timer_init (); + grub_cros_init (); + grub_pl050_init (); +} + +void +grub_machine_get_bootlocation (char **device __attribute__ ((unused)), + char **path __attribute__ ((unused))) +{ +} + +void +grub_machine_fini (int flags __attribute__ ((unused))) +{ +} diff --git a/grub-core/kern/arm/coreboot/timer.c b/grub-core/kern/arm/coreboot/timer.c new file mode 100644 index 000000000..d97b844f8 --- /dev/null +++ b/grub-core/kern/arm/coreboot/timer.c @@ -0,0 +1,101 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +grub_uint64_t +grub_armv7_get_timer_value(void); + +grub_uint32_t +grub_armv7_get_timer_frequency(void); + +grub_uint32_t +grub_arm_pfr1(void); + +static int have_timer = 0; +static volatile grub_uint32_t *sp804_regs; + +static grub_uint64_t +sp804_get_time_ms (void) +{ + static grub_uint32_t high, last_low; + grub_uint32_t low = ~sp804_regs[1]; + if (last_low > low) + high++; + last_low = low; + return grub_divmod64 ((((grub_uint64_t) high) << 32) | low, + 1000, 0); +} + +static grub_err_t +sp804_attach(const struct grub_fdtbus_dev *dev) +{ + if (have_timer) + return GRUB_ERR_NONE; + sp804_regs = grub_fdtbus_map_reg (dev, 0, 0); + if (!grub_fdtbus_is_mapping_valid (sp804_regs)) + return grub_error (GRUB_ERR_IO, "could not map sp804: %p", sp804_regs); + grub_install_get_time_ms (sp804_get_time_ms); + have_timer = 1; + return GRUB_ERR_NONE; +} + +struct grub_fdtbus_driver sp804 = +{ + .compatible = "arm,sp804", + .attach = sp804_attach +}; + +static grub_uint32_t timer_frequency_in_khz; + +static grub_uint64_t +generic_get_time_ms (void) +{ + return grub_divmod64 (grub_armv7_get_timer_value(), timer_frequency_in_khz, 0); +} + +static int +try_generic_timer (void) +{ + if (((grub_arm_pfr1 () >> 16) & 0xf) != 1) + return 0; + grub_printf ("freq = %x\n", grub_armv7_get_timer_frequency()); + timer_frequency_in_khz = 0x016e3600 / 1000; //grub_armv7_get_timer_frequency() / 1000; + if (timer_frequency_in_khz == 0) + return 0; + grub_install_get_time_ms (generic_get_time_ms); + have_timer = 1; + return 1; +} + +void +grub_machine_timer_init (void) +{ + grub_fdtbus_register (&sp804); + + if (!have_timer) + try_generic_timer (); + if (!have_timer) + grub_fatal ("No timer found"); +} diff --git a/grub-core/kern/arm/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/arm/efi/misc.c b/grub-core/kern/arm/efi/misc.c deleted file mode 100644 index 7cd41842a..000000000 --- a/grub-core/kern/arm/efi/misc.c +++ /dev/null @@ -1,202 +0,0 @@ -/* misc.c - various system functions for an arm-based EFI system */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -static inline grub_size_t -page_align (grub_size_t size) -{ - return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); -} - -/* Find the optimal number of pages for the memory map. Is it better to - move this code to efi/mm.c? */ -static grub_efi_uintn_t -find_mmap_size (void) -{ - static grub_efi_uintn_t mmap_size = 0; - - if (mmap_size != 0) - return mmap_size; - - mmap_size = (1 << 12); - while (1) - { - int ret; - grub_efi_memory_descriptor_t *mmap; - grub_efi_uintn_t desc_size; - - mmap = grub_malloc (mmap_size); - if (! mmap) - return 0; - - ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); - grub_free (mmap); - - if (ret < 0) - { - grub_error (GRUB_ERR_IO, "cannot get memory map"); - return 0; - } - else if (ret > 0) - break; - - mmap_size += (1 << 12); - } - - /* Increase the size a bit for safety, because GRUB allocates more on - later, and EFI itself may allocate more. */ - mmap_size += (1 << 12); - - return page_align (mmap_size); -} - -#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ - ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) -#define PAGE_SHIFT 12 - -void * -grub_efi_allocate_loader_memory (grub_uint32_t min_offset, grub_uint32_t size) -{ - grub_efi_uintn_t desc_size; - grub_efi_memory_descriptor_t *mmap, *mmap_end; - grub_efi_uintn_t mmap_size, tmp_mmap_size; - grub_efi_memory_descriptor_t *desc; - void *mem = NULL; - grub_addr_t min_start = 0; - - mmap_size = find_mmap_size(); - if (!mmap_size) - return NULL; - - mmap = grub_malloc(mmap_size); - if (!mmap) - return NULL; - - tmp_mmap_size = mmap_size; - if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0) - { - grub_error (GRUB_ERR_IO, "cannot get memory map"); - goto fail; - } - - mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size); - /* Find lowest accessible RAM location */ - { - int found = 0; - for (desc = mmap ; !found && (desc < mmap_end) ; - desc = NEXT_MEMORY_DESCRIPTOR(desc, desc_size)) - { - switch (desc->type) - { - case GRUB_EFI_CONVENTIONAL_MEMORY: - case GRUB_EFI_LOADER_CODE: - case GRUB_EFI_LOADER_DATA: - min_start = desc->physical_start + min_offset; - found = 1; - break; - default: - break; - } - } - } - - /* First, find free pages for the real mode code - and the memory map buffer. */ - for (desc = mmap ; desc < mmap_end ; - desc = NEXT_MEMORY_DESCRIPTOR(desc, desc_size)) - { - grub_uint64_t start, end; - - grub_dprintf("mm", "%s: 0x%08x bytes @ 0x%08x\n", - __FUNCTION__, - (grub_uint32_t) (desc->num_pages << PAGE_SHIFT), - (grub_uint32_t) (desc->physical_start)); - - if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) - continue; - - start = desc->physical_start; - end = start + (desc->num_pages << PAGE_SHIFT); - grub_dprintf("mm", "%s: start=0x%016llx, end=0x%016llx\n", - __FUNCTION__, start, end); - start = start < min_start ? min_start : start; - if (start + size > end) - continue; - grub_dprintf("mm", "%s: let's allocate some (0x%x) pages @ 0x%08x...\n", - __FUNCTION__, (size >> PAGE_SHIFT), (grub_addr_t) start); - mem = grub_efi_allocate_pages (start, (size >> PAGE_SHIFT) + 1); - grub_dprintf("mm", "%s: retval=0x%08x\n", - __FUNCTION__, (grub_addr_t) mem); - if (! mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory"); - goto fail; - } - break; - } - - if (! mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory"); - goto fail; - } - - grub_free (mmap); - return mem; - - fail: - grub_free (mmap); - return NULL; -} - -grub_err_t -grub_efi_prepare_platform (void) -{ - grub_efi_uintn_t mmap_size; - grub_efi_uintn_t map_key; - grub_efi_uintn_t desc_size; - grub_efi_uint32_t desc_version; - grub_efi_memory_descriptor_t *mmap_buf; - grub_err_t err; - - /* - * Cloned from IA64 - * Must be done after grub_machine_fini because map_key is used by - *exit_boot_services. - */ - mmap_size = find_mmap_size (); - if (! mmap_size) - return GRUB_ERR_OUT_OF_MEMORY; - mmap_buf = grub_efi_allocate_pages (0, page_align (mmap_size) >> 12); - if (! mmap_buf) - return GRUB_ERR_OUT_OF_MEMORY; - - err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key, - &desc_size, &desc_version); - if (err != GRUB_ERR_NONE) - return err; - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/arm/uboot/startup.S b/grub-core/kern/arm/startup.S similarity index 77% rename from grub-core/kern/arm/uboot/startup.S rename to grub-core/kern/arm/startup.S index 5efaae16e..3946fe8e1 100644 --- a/grub-core/kern/arm/uboot/startup.S +++ b/grub-core/kern/arm/startup.S @@ -24,6 +24,7 @@ * GRUB is called from U-Boot as a Linux Kernel type image, which * means among other things that it always enters in ARM state. * + * coreboot starts in ARM mode as well. * * Overview of GRUB image layout: * @@ -86,7 +87,7 @@ FUNCTION(codestart) @ Stack pointer used as start address for signature probing mov r12, sp adr sp, entry_state - push {r1-r12,lr} @ store U-Boot context (sp in r12) + push {r0-r12,lr} @ store U-Boot context (sp in r12) adr r1, _start ldr r0, bss_start_ptr @ src @@ -127,6 +128,8 @@ reloc_done: str r1, EXT_C(grub_modbase) + /* Coreboot already places modules at right place. */ +#ifndef GRUB_MACHINE_COREBOOT add r1, r1, r2 add r0, r0, r2 sub r1, r1, #4 @@ -136,6 +139,7 @@ reloc_done: str r3, [r1], #-4 @ *dst-- = r3 subs r2, #4 @ remaining -= 4 bne 1b @ while remaining != 0 +#endif @ Since we _are_ the C run-time, we need to manually zero the BSS @ region before continuing @@ -153,69 +157,21 @@ reloc_done: b EXT_C(grub_main) - /* - * uboot_syscall(): - * This function is effectively a veneer, so it cannot - * modify the stack or corrupt any registers other than - * r12 (ip). Furthermore it needs to restore r8 for - * U-Boot (Global Data Pointer) and preserve it for Grub. - */ -FUNCTION(grub_uboot_syscall) - str r8, transition_space - str lr, transition_space + 4 - str r9, transition_space + 8 - - ldr r8, gd_backup - ldr r9, gd_backup + 4 - - bl do_syscall - - ldr r8, transition_space - ldr lr, transition_space + 4 - ldr r9, transition_space + 8 - - bx lr -do_syscall: - - ldr ip, grub_uboot_syscall_ptr - bx ip - -FUNCTION(grub_uboot_return) - adr sp, entry_state_end - pop {r4-r12, lr} - mov sp, r12 - bx lr - - .align 3 -@ U-boot context stack space -entry_state_end: -VARIABLE(grub_uboot_machine_type) +@ U-boot/coreboot context stack space +VARIABLE(grub_arm_saved_registers) + .long 0 @ r0 .long 0 @ r1 -VARIABLE(grub_uboot_boot_data) .long 0 @ r2 .long 0 @ r3 .long 0 @ r4 .long 0 @ r5 .long 0 @ r6 .long 0 @ r7 -gd_backup: - .long 0 @ r8 - U-Boot global data pointer up to 2013-09-21 - .long 0 @ r9 - U-Boot global data pointer 2013-09-21 onwards + .long 0 @ r8 + .long 0 @ r9 .long 0 @ r10 .long 0 @ r11 -VARIABLE(grub_uboot_search_hint)@ U-Boot stack pointer - - .long 0 @ also API signature address hint. + .long 0 @ sp .long 0 @ lr -entry_state: @ backup for U-Boot context - -@ GRUB context stack space -transition_space: - .long 0 @ r8 - .long 0 @ lr - .long 0 @ r9 - -VARIABLE(grub_uboot_syscall_ptr) - .long 0 @ - - END +entry_state: diff --git a/grub-core/kern/arm/uboot/init.c b/grub-core/kern/arm/uboot/init.c new file mode 100644 index 000000000..2a6aa3fdd --- /dev/null +++ b/grub-core/kern/arm/uboot/init.c @@ -0,0 +1,70 @@ +/* init.c - generic U-Boot initialization and finalization */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +extern int (*grub_uboot_syscall_ptr) (int, int *, ...); + +grub_uint32_t +grub_uboot_get_machine_type (void) +{ + return grub_arm_saved_registers.r[1]; +} + +grub_addr_t +grub_uboot_get_boot_data (void) +{ + return grub_arm_saved_registers.r[2]; +} + +int +grub_uboot_api_init (void) +{ + struct api_signature *start, *end; + struct api_signature *p; + grub_addr_t grub_uboot_search_hint = grub_arm_saved_registers.sp; + if (grub_uboot_search_hint) + { + /* Extended search range to work around Trim Slice U-Boot issue */ + start = (struct api_signature *) ((grub_uboot_search_hint & ~0x000fffff) + - 0x00500000); + end = + (struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN - + API_SIG_MAGLEN + 0x00500000); + } + else + { + start = 0; + end = (struct api_signature *) (256 * 1024 * 1024); + } + + /* Structure alignment is (at least) 8 bytes */ + for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8)) + { + if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0) + { + grub_uboot_syscall_ptr = p->syscall; + return p->version; + } + } + + return 0; +} diff --git a/grub-core/kern/arm/uboot/uboot.S b/grub-core/kern/arm/uboot/uboot.S new file mode 100644 index 000000000..d128775f1 --- /dev/null +++ b/grub-core/kern/arm/uboot/uboot.S @@ -0,0 +1,73 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + + /* + * uboot_syscall(): + * This function is effectively a veneer, so it cannot + * modify the stack or corrupt any registers other than + * r12 (ip). Furthermore it needs to restore r8 for + * U-Boot (Global Data Pointer) and preserve it for Grub. + */ +FUNCTION(grub_uboot_syscall) + str r8, transition_space + str lr, transition_space + 4 + str r9, transition_space + 8 + + ldr ip, saved_registers_ptr + ldr r8, [ip, #4 * 8] + ldr r9, [ip, #4 * 9] + + bl do_syscall + + ldr r8, transition_space + ldr lr, transition_space + 4 + ldr r9, transition_space + 8 + + bx lr +do_syscall: + + ldr ip, grub_uboot_syscall_ptr + bx ip + +FUNCTION(grub_uboot_return) + ldr ip, saved_registers_ptr + ldr sp, [ip, #4 * 4] + pop {r4-r12, lr} + mov sp, r12 + bx lr + + + .align 3 + +@ GRUB context stack space +transition_space: + .long 0 @ r8 + .long 0 @ lr + .long 0 @ r9 + +saved_registers_ptr: + .long EXT_C(grub_arm_saved_registers) + +VARIABLE(grub_uboot_syscall_ptr) + .long 0 @ + + END diff --git a/grub-core/kern/arm64/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 5cfcb3907..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) { @@ -237,7 +227,8 @@ union component64 }; }; -#if defined (__powerpc__) || defined (__arm__) || defined(__mips__) +#if defined (__powerpc__) || defined (__arm__) || defined(__mips__) || \ + (defined(__riscv) && (__riscv_xlen == 32)) /* Based on libgcc2.c from gcc suite. */ grub_uint64_t @@ -343,7 +334,8 @@ __ucmpdi2 (grub_uint64_t a, grub_uint64_t b) #endif -#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || defined(__arm__) +#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \ + defined(__arm__) || defined(__riscv) /* Based on libgcc2.c from gcc suite. */ grub_uint32_t @@ -417,3 +409,46 @@ __aeabi_llsl (grub_uint64_t u, int b) __attribute__ ((alias ("__ashldi3"))); #endif + +#if defined(__mips__) || defined(__riscv) || defined(__sparc__) +/* Based on libgcc from gcc suite. */ +int +__clzsi2 (grub_uint32_t val) +{ + int i = 32; + int j = 16; + int temp; + + for (; j; j >>= 1) + { + if ((temp = val >> j)) + { + if (j == 1) + { + return (i - 2); + } + else + { + i -= j; + val = temp; + } + } + } + return (i - val); +} +#endif + +#if defined(__mips__) || defined(__riscv) || defined(__sparc__) +int +__clzdi2 (grub_uint64_t val) +{ + if (val >> 32) + { + return __clzsi2 (val >> 32); + } + else + { + return __clzsi2 (val) + 32; + } +} +#endif diff --git a/grub-core/kern/coreboot/cbtable.c b/grub-core/kern/coreboot/cbtable.c new file mode 100644 index 000000000..b6d0801c1 --- /dev/null +++ b/grub-core/kern/coreboot/cbtable.c @@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wcast-align" + +/* Helper for grub_linuxbios_table_iterate. */ +int +grub_linuxbios_check_signature (grub_linuxbios_table_header_t tbl_header) +{ + if (! grub_memcmp (tbl_header->signature, "LBIO", 4)) + return 1; + + return 0; +} + +grub_err_t +grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t, + void *), + void *hook_data) +{ + grub_linuxbios_table_header_t table_header = grub_linuxbios_get_tables (); + grub_linuxbios_table_item_t table_item; + + if (!table_header) + return 0; + +signature_found: + + table_item = + (grub_linuxbios_table_item_t) ((char *) table_header + + table_header->header_size); + for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header + + table_header->header_size + + table_header->table_size); + table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size)) + { + if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK + && grub_linuxbios_check_signature ((grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1))) + { + table_header = (grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1); + goto signature_found; + } + if (hook (table_item, hook_data)) + return 1; + } + + return 0; +} diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/coreboot/mmap.c similarity index 97% rename from grub-core/kern/i386/coreboot/mmap.c rename to grub-core/kern/coreboot/mmap.c index 4d29f6b7d..caf8f7cef 100644 --- a/grub-core/kern/i386/coreboot/mmap.c +++ b/grub-core/kern/coreboot/mmap.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include -#include +#include +#include #include #include #include @@ -49,6 +49,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) { grub_uint64_t start = mem_region->addr; grub_uint64_t end = mem_region->addr + mem_region->size; +#ifdef __i386__ /* Mark region 0xa0000 - 0x100000 as reserved. */ if (start < 0x100000 && end >= 0xa0000 && mem_region->type == GRUB_MACHINE_MEMORY_AVAILABLE) @@ -75,6 +76,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) if (end <= start) continue; } +#endif if (ctx->hook (start, end - start, /* Multiboot mmaps match with the coreboot mmap definition. Therefore, we can just pass type diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c index d9412a316..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; } @@ -155,7 +158,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), } else if (fs) { - (fs->dir) (dev, path, grub_mini_print_files, NULL); + (fs->fs_dir) (dev, path, grub_mini_print_files, NULL); grub_xputs ("\n"); grub_refresh (); } 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 789f8c052..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; @@ -223,7 +227,7 @@ grub_disk_open (const char *name) for (dev = grub_disk_dev_list; dev; dev = dev->next) { - if ((dev->open) (raw, disk) == GRUB_ERR_NONE) + if ((dev->disk_open) (raw, disk) == GRUB_ERR_NONE) break; else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) grub_errno = GRUB_ERR_NONE; @@ -292,10 +296,14 @@ 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->close) - (disk->dev->close) (disk); + if (disk->dev && disk->dev->disk_close) + (disk->dev->disk_close) (disk); /* Reset the timer. */ grub_last_time = grub_get_time_ms (); @@ -341,10 +349,10 @@ 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->read) (disk, transform_sector (disk, sector), - 1U << (GRUB_DISK_CACHE_BITS - + GRUB_DISK_SECTOR_BITS - - disk->log_sector_size), tmp_buf); + err = (disk->dev->disk_read) (disk, grub_disk_to_native_sector (disk, sector), + 1U << (GRUB_DISK_CACHE_BITS + + GRUB_DISK_SECTOR_BITS + - disk->log_sector_size), tmp_buf); if (!err) { /* Copy it and store it in the disk cache. */ @@ -376,9 +384,9 @@ 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->read) (disk, transform_sector (disk, aligned_sector), - num, tmp_buf)) + + if ((disk->dev->disk_read) (disk, grub_disk_to_native_sector (disk, aligned_sector), + num, tmp_buf)) { grub_error_push (); grub_dprintf ("disk", "%s read failed\n", disk->name); @@ -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->read) (disk, transform_sector (disk, sector), - agglomerate << (GRUB_DISK_CACHE_BITS - + GRUB_DISK_SECTOR_BITS - - disk->log_sector_size), - buf); + 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 e394cd96f..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__) + 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__) +#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__) - 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); @@ -688,7 +831,7 @@ grub_dl_load_file (const char *filename) grub_boot_time ("Loading module %s", filename); - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); if (! file) return 0; @@ -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 d467785fc..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 * @@ -154,12 +163,23 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle) GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); } +void +grub_reboot (void) +{ + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); + grub_efi_system_table->runtime_services->reset_system (GRUB_EFI_RESET_COLD, + GRUB_EFI_SUCCESS, 0, + NULL); + for (;;) ; +} + void grub_exit (void) { grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - 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 (;;) ; } @@ -173,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; @@ -183,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; @@ -213,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" @@ -269,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; @@ -284,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) @@ -294,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; } @@ -318,9 +383,12 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) grub_size_t filesize = 0; grub_efi_device_path_t *dp; + if (!dp0) + return NULL; + 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); @@ -330,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; } @@ -348,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); @@ -360,17 +434,35 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) { grub_efi_file_path_device_path_t *fp; grub_efi_uint16_t len; + grub_efi_char16_t *dup_name; *p++ = '/'; - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 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--; - p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len); + dup_name = grub_calloc (len, sizeof (*dup_name)); + if (!dup_name) + { + grub_free (name); + return NULL; + } + p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, + grub_memcpy (dup_name, fp->path_name, len * sizeof (*dup_name)), + len); + grub_free (dup_name); } dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); @@ -430,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; } @@ -447,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; @@ -475,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); @@ -746,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", @@ -800,9 +905,20 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) fp = (grub_efi_file_path_device_path_t *) dp; buf = grub_malloc ((len - 4) * 2 + 1); if (buf) - *grub_utf16_to_utf8 (buf, fp->path_name, + { + grub_efi_char16_t *dup_name = grub_malloc (len - 4); + if (!dup_name) + { + grub_errno = GRUB_ERR_NONE; + grub_printf ("/File((null))"); + grub_free (buf); + break; + } + *grub_utf16_to_utf8 (buf, grub_memcpy (dup_name, fp->path_name, len - 4), (len - 4) / sizeof (grub_efi_char16_t)) - = '\0'; + = '\0'; + grub_free (dup_name); + } else grub_errno = GRUB_ERR_NONE; grub_printf ("/File(%s)", buf); @@ -813,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: @@ -876,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; @@ -912,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 2c31847bf..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); diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index 20a47aaf5..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; @@ -49,55 +48,140 @@ static grub_efi_uintn_t finish_desc_size; static grub_efi_uint32_t finish_desc_version; int grub_efi_is_finished = 0; +/* + * We need to roll back EFI allocations on exit. Remember allocations that + * we'll free on exit. + */ +struct efi_allocation; +struct efi_allocation { + grub_efi_physical_address_t address; + grub_efi_uint64_t pages; + struct efi_allocation *next; +}; +static struct efi_allocation *efi_allocated_memory; + +static void +grub_efi_store_alloc (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + grub_efi_boot_services_t *b; + struct efi_allocation *alloc; + grub_efi_status_t status; + + b = grub_efi_system_table->boot_services; + status = b->allocate_pool (GRUB_EFI_LOADER_DATA, + sizeof(*alloc), (void**)&alloc); + + if (status == GRUB_EFI_SUCCESS) + { + alloc->next = efi_allocated_memory; + alloc->address = address; + alloc->pages = pages; + efi_allocated_memory = alloc; + } + else + grub_printf ("Could not malloc memory to remember EFI allocation. " + "Exiting GRUB won't free all memory.\n"); +} + +static void +grub_efi_drop_alloc (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + struct efi_allocation *ea, *eap; + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + + for (eap = NULL, ea = efi_allocated_memory; ea; eap = ea, ea = ea->next) + { + if (ea->address != address) + continue; + if (ea->pages != pages) + grub_fatal ("grub_efi_drop_alloc() called with wrong page count"); + + /* Remove the current entry from the list. */ + if (eap) + eap->next = ea->next; + else + efi_allocated_memory = ea->next; + + /* Then free the memory backing it. */ + b->free_pool (ea); + + /* And leave, we're done. */ + break; + } +} + /* Allocate pages. Return the pointer to the first of allocated pages. */ void * -grub_efi_allocate_pages (grub_efi_physical_address_t address, - grub_efi_uintn_t pages) +grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + grub_efi_uintn_t pages, + grub_efi_allocate_type_t alloctype, + grub_efi_memory_type_t memtype) { - grub_efi_allocate_type_t type; grub_efi_status_t status; grub_efi_boot_services_t *b; -#if 1 /* Limit the memory access to less than 4GB for 32-bit platforms. */ if (address > GRUB_EFI_MAX_USABLE_ADDRESS) - return 0; -#endif - -#if 1 - if (address == 0) { - type = GRUB_EFI_ALLOCATE_MAX_ADDRESS; - address = GRUB_EFI_MAX_USABLE_ADDRESS; + char inv_addr[17], max_addr[17]; /* log16(2^64) = 16, plus NUL. */ + + grub_snprintf (inv_addr, sizeof (inv_addr) - 1, "%" PRIxGRUB_UINT64_T, + address); + grub_snprintf (max_addr, sizeof (max_addr) - 1, "%" PRIxGRUB_UINT64_T, + (grub_efi_uint64_t) GRUB_EFI_MAX_USABLE_ADDRESS); + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("invalid memory address (0x%s > 0x%s)"), inv_addr, max_addr); + return NULL; } - else - type = GRUB_EFI_ALLOCATE_ADDRESS; -#else - if (address == 0) - type = GRUB_EFI_ALLOCATE_ANY_PAGES; - else - type = GRUB_EFI_ALLOCATE_ADDRESS; -#endif b = grub_efi_system_table->boot_services; - status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address); + 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, type, GRUB_EFI_LOADER_DATA, 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); + return (void *) ((grub_addr_t) address); } +void * +grub_efi_allocate_any_pages (grub_efi_uintn_t pages) +{ + return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, + pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + +void * +grub_efi_allocate_fixed (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + return grub_efi_allocate_pages_real (address, pages, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + /* Free pages starting from ADDRESS. */ void grub_efi_free_pages (grub_efi_physical_address_t address, @@ -106,7 +190,9 @@ 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); } #if defined (__i386__) || defined (__x86_64__) @@ -179,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; @@ -209,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 (); @@ -217,6 +311,30 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, return GRUB_ERR_NONE; } +/* + * To obtain the UEFI memory map, we must pass a buffer of sufficient size + * to hold the entire map. This function returns a sane start value for + * buffer size. + */ +grub_efi_uintn_t +grub_efi_find_mmap_size (void) +{ + grub_efi_uintn_t mmap_size = 0; + grub_efi_uintn_t desc_size; + + if (grub_efi_get_memory_map (&mmap_size, NULL, NULL, &desc_size, 0) < 0) + { + grub_error (GRUB_ERR_IO, "cannot get EFI memory map size"); + return 0; + } + + /* + * Add an extra page, since UEFI can alter the memory map itself on + * callbacks or explicit calls, including console output. + */ + return ALIGN_UP (mmap_size + GRUB_EFI_PAGE_SIZE, GRUB_EFI_PAGE_SIZE); +} + /* Get the memory map as defined in the EFI spec. Return 1 if successful, return 0 if partial, or return -1 if an error occurs. */ int @@ -235,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) @@ -264,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); @@ -360,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; @@ -396,17 +507,23 @@ 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); pages = required_pages; } - addr = grub_efi_allocate_pages (start, pages); + addr = grub_efi_allocate_pages_real (start, pages, + GRUB_EFI_ALLOCATE_ADDRESS, + 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)); @@ -416,7 +533,25 @@ 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 +grub_efi_memory_fini (void) +{ + /* + * Free all stale allocations. grub_efi_free_pages() will remove + * the found entry from the list and it will always find the first + * list entry (efi_allocated_memory is the list start). Hence we + * remove all entries from the list until none is left altogether. + */ + while (efi_allocated_memory) + grub_efi_free_pages (efi_allocated_memory->address, + efi_allocated_memory->pages); } #if 0 @@ -440,24 +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_pages (0, - 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; @@ -466,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_pages (0, 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); @@ -491,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. */ @@ -522,6 +651,156 @@ 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; +} + +void +grub_efi_mm_init (void) +{ + if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE, GRUB_MM_ADD_REGION_NONE) != GRUB_ERR_NONE) + grub_fatal ("%s", grub_errmsg); + grub_mm_add_region_fn = grub_efi_mm_add_regions; +} + +#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) || \ + defined (__loongarch__) +grub_err_t +grub_efi_get_ram_base(grub_addr_t *base_addr) +{ + grub_efi_memory_descriptor_t *memory_map, *desc; + grub_efi_uintn_t memory_map_size, desc_size; + int ret; + + memory_map_size = grub_efi_find_mmap_size(); + + memory_map = grub_malloc (memory_map_size); + if (! memory_map) + return GRUB_ERR_OUT_OF_MEMORY; + ret = grub_efi_get_memory_map (&memory_map_size, memory_map, NULL, + &desc_size, NULL); + + if (ret < 1) + return GRUB_ERR_BUG; + + for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; + (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + if (desc->attribute & GRUB_EFI_MEMORY_WB) + *base_addr = grub_min (*base_addr, desc->physical_start); + + grub_free(memory_map); + + return GRUB_ERR_NONE; +} +#endif + +static grub_uint64_t +grub_mem_attrs_to_uefi_mem_attrs (grub_mem_attr_t attrs) +{ + grub_efi_uint64_t ret = GRUB_EFI_MEMORY_RP | GRUB_EFI_MEMORY_RO | GRUB_EFI_MEMORY_XP; + + if (attrs & GRUB_MEM_ATTR_R) + ret &= ~GRUB_EFI_MEMORY_RP; + + if (attrs & GRUB_MEM_ATTR_W) + ret &= ~GRUB_EFI_MEMORY_RO; + + if (attrs & GRUB_MEM_ATTR_X) + ret &= ~GRUB_EFI_MEMORY_XP; + + return ret; +} + +static grub_mem_attr_t +uefi_mem_attrs_to_grub_mem_attrs (grub_efi_uint64_t attrs) +{ + grub_mem_attr_t ret = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X; + + if (attrs & GRUB_EFI_MEMORY_RP) + ret &= ~GRUB_MEM_ATTR_R; + + if (attrs & GRUB_EFI_MEMORY_RO) + ret &= ~GRUB_MEM_ATTR_W; + + if (attrs & GRUB_EFI_MEMORY_XP) + ret &= ~GRUB_MEM_ATTR_X; + + return ret; +} + +grub_err_t +grub_get_mem_attrs (grub_addr_t addr, grub_size_t size, grub_mem_attr_t *attrs) +{ + grub_efi_memory_attribute_protocol_t *proto; + grub_efi_physical_address_t physaddr = addr; + static grub_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; + grub_efi_status_t efi_status; + grub_efi_uint64_t efi_attrs; + + if (physaddr & (GRUB_EFI_PAGE_SIZE - 1) || size & (GRUB_EFI_PAGE_SIZE - 1) || size == 0 || attrs == NULL) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); + + proto = grub_efi_locate_protocol (&protocol_guid, 0); + if (proto == NULL) + { + /* No protocol -> do nothing, all memory is RWX in boot services */ + *attrs = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X; + return GRUB_ERR_NONE; + } + + efi_status = proto->get_memory_attributes (proto, physaddr, size, &efi_attrs); + if (efi_status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); + + *attrs = uefi_mem_attrs_to_grub_mem_attrs (efi_attrs); + + grub_dprintf ("nx", "get 0x%" PRIxGRUB_ADDR "-0x%" PRIxGRUB_ADDR ":%c%c%c\n", + addr, addr + size - 1, + (*attrs & GRUB_MEM_ATTR_R) ? 'r' : '-', + (*attrs & GRUB_MEM_ATTR_W) ? 'w' : '-', + (*attrs & GRUB_MEM_ATTR_X) ? 'x' : '-'); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_update_mem_attrs (grub_addr_t addr, grub_size_t size, + grub_mem_attr_t set_attrs, grub_mem_attr_t clear_attrs) +{ + grub_efi_memory_attribute_protocol_t *proto; + grub_efi_physical_address_t physaddr = addr; + static grub_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; + grub_efi_status_t efi_status = GRUB_EFI_SUCCESS; + grub_efi_uint64_t uefi_set_attrs, uefi_clear_attrs; + + if (physaddr & (GRUB_EFI_PAGE_SIZE - 1) || size & (GRUB_EFI_PAGE_SIZE - 1) || size == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); + + proto = grub_efi_locate_protocol (&protocol_guid, 0); + if (proto == NULL) + /* No protocol -> do nothing, all memory is RWX in boot services */ + return GRUB_ERR_NONE; + + uefi_set_attrs = grub_mem_attrs_to_uefi_mem_attrs (set_attrs); + uefi_clear_attrs = grub_mem_attrs_to_uefi_mem_attrs (clear_attrs); + if (uefi_set_attrs) + efi_status = proto->set_memory_attributes (proto, physaddr, size, uefi_set_attrs); + if (efi_status == GRUB_EFI_SUCCESS && uefi_clear_attrs) + efi_status = proto->clear_memory_attributes (proto, physaddr, size, uefi_clear_attrs); + + if (efi_status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "%s() called with invalid arguments", __FUNCTION__); + + grub_dprintf ("nx", "set +%s%s%s -%s%s%s on 0x%" PRIxGRUB_ADDR "-0x%" PRIxGRUB_ADDR "\n", + (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "", + (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "", + (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "", + (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "", + (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "", + (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "", + addr, addr + size - 1); + + return GRUB_ERR_NONE; } diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c 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 4f282c9cf..077a8500c 100644 --- a/grub-core/kern/elf.c +++ b/grub-core/kern/elf.c @@ -136,12 +136,12 @@ fail: } grub_elf_t -grub_elf_open (const char *name) +grub_elf_open (const char *name, enum grub_file_type type) { grub_file_t file; grub_elf_t elf; - file = grub_file_open (name); + file = grub_file_open (name, type); if (! file) return 0; @@ -167,11 +167,17 @@ grub_elf_open (const char *name) #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) #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) #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.c b/grub-core/kern/emu/cache.c index 6f89e871a..113682cc4 100644 --- a/grub-core/kern/emu/cache.c +++ b/grub-core/kern/emu/cache.c @@ -25,5 +25,11 @@ grub_arch_sync_caches (void *address, grub_size_t len) return _flush_cache (address, len, 0); } +#elif defined(__riscv) +void +grub_arch_sync_caches (void *address, grub_size_t len) +{ +} + #endif diff --git a/grub-core/kern/emu/cache_s.S b/grub-core/kern/emu/cache_s.S index 76cf7560d..6885ffd69 100644 --- a/grub-core/kern/emu/cache_s.S +++ b/grub-core/kern/emu/cache_s.S @@ -2,13 +2,19 @@ #error "This source is only meant for grub-emu platform" #endif +/* An executable stack is not required for these functions. */ +#if defined (__linux__) && defined (__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + #if defined(__i386__) || defined(__x86_64__) /* Nothing is necessary. */ #elif defined(__sparc__) #include "../sparc64/cache.S" #elif defined(__powerpc__) #include "../powerpc/cache.S" -#elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) +#elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \ + defined(__mips__) || defined(__riscv) #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 87e3e2512..0e6eebdc8 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -388,11 +388,11 @@ static struct grub_disk_dev grub_util_biosdisk_dev = { .name = "hostdisk", .id = GRUB_DISK_DEVICE_HOSTDISK_ID, - .iterate = grub_util_biosdisk_iterate, - .open = grub_util_biosdisk_open, - .close = grub_util_biosdisk_close, - .read = grub_util_biosdisk_read, - .write = grub_util_biosdisk_write, + .disk_iterate = grub_util_biosdisk_iterate, + .disk_open = grub_util_biosdisk_open, + .disk_close = grub_util_biosdisk_close, + .disk_read = grub_util_biosdisk_read, + .disk_write = grub_util_biosdisk_write, .next = 0 }; @@ -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 7b28c001f..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; @@ -173,14 +173,17 @@ grub_hostfs_label (grub_device_t device __attribute ((unused)), return GRUB_ERR_NONE; } +#undef open +#undef close + static struct grub_fs grub_hostfs_fs = { .name = "hostfs", - .dir = grub_hostfs_dir, - .open = grub_hostfs_open, - .read = grub_hostfs_read, - .close = grub_hostfs_close, - .label = grub_hostfs_label, + .fs_dir = grub_hostfs_dir, + .fs_open = grub_hostfs_open, + .fs_read = grub_hostfs_read, + .fs_close = grub_hostfs_close, + .fs_label = grub_hostfs_label, .next = 0 }; diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c index b2fc93d7f..b327d4e41 100644 --- a/grub-core/kern/emu/lite.c +++ b/grub-core/kern/emu/lite.c @@ -24,6 +24,8 @@ #elif defined(__aarch64__) #include "../arm64/dl_helper.c" #include "../arm64/dl.c" +#elif defined(__riscv) +#include "../riscv/dl.c" #else #error "No target cpu type is defined" #endif 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 76661337f..1db24fde7 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -16,7 +16,9 @@ * along with GRUB. If not, see . */ +#ifndef GRUB_BUILD #include +#endif #include #include @@ -26,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -37,6 +41,9 @@ #include int verbosity; +int kexecute; + +static int grub_util_tpm_fd = -1; void grub_util_warn (const char *fmt, ...) @@ -80,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 * @@ -121,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 @@ -139,6 +158,9 @@ xasprintf (const char *fmt, ...) void grub_exit (void) { +#if defined (GRUB_KERNEL) + grub_reboot (); +#endif exit (1); } #endif @@ -166,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)); @@ -200,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 668f8930b..6e7efe89a 100644 --- a/grub-core/kern/file.c +++ b/grub-core/kern/file.c @@ -25,11 +25,11 @@ #include #include #include +#include void (*EXPORT_VAR (grub_grubnet_fini)) (void); -grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX]; -grub_file_filter_t grub_file_filters_enabled[GRUB_FILE_FILTER_MAX]; +grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX]; /* Get the device part of the filename NAME. It is enclosed by parentheses. */ char * @@ -59,7 +59,7 @@ grub_file_get_device_name (const char *name) } grub_file_t -grub_file_open (const char *name) +grub_file_open (const char *name, enum grub_file_type type) { grub_device_t device = 0; grub_file_t file = 0, last_file = 0; @@ -67,6 +67,9 @@ grub_file_open (const char *name) 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; @@ -80,6 +83,7 @@ grub_file_open (const char *name) device = grub_device_open (device_name); grub_free (device_name); + device_name = NULL; if (! device) goto fail; @@ -108,28 +112,37 @@ grub_file_open (const char *name) goto fail; } - if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE) + 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; - for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters_enabled); + for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters); filter++) - if (grub_file_filters_enabled[filter]) + if (grub_file_filters[filter]) { last_file = file; - file = grub_file_filters_enabled[filter] (file, name); + file = grub_file_filters[filter] (file, type); + if (file && file != last_file) + { + file->name = grub_strdup (name); + grub_errno = GRUB_ERR_NONE; + } } if (!file) grub_file_close (last_file); - - grub_memcpy (grub_file_filters_enabled, grub_file_filters_all, - sizeof (grub_file_filters_enabled)); return file; fail: + grub_free (device_name); if (device) grub_device_close (device); @@ -137,9 +150,6 @@ grub_file_open (const char *name) grub_free (file); - grub_memcpy (grub_file_filters_enabled, grub_file_filters_all, - sizeof (grub_file_filters_enabled)); - return 0; } @@ -179,7 +189,7 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) file->read_hook_data = file; file->progress_offset = file->offset; } - res = (file->fs->read) (file, buf, len); + res = (file->fs->fs_read) (file, buf, len); file->read_hook = read_hook; file->read_hook_data = read_hook_data; if (res > 0) @@ -191,8 +201,11 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) grub_err_t grub_file_close (grub_file_t file) { - if (file->fs->close) - (file->fs->close) (file); + if (file->fs->mod) + grub_dl_unref (file->fs->mod); + + if (file->fs->fs_close) + (file->fs->fs_close) (file); if (file->device) grub_device_close (file->device); @@ -212,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 9085895b6..80d325868 100644 --- a/grub-core/kern/fs.c +++ b/grub-core/kern/fs.c @@ -64,17 +64,19 @@ grub_fs_probe (grub_device_t device) if (grub_strcmp (p->name, "btrfs") == 0) { char *label = 0; - p->uuid (device, &label); + p->fs_uuid (device, &label); if (label) grub_free (label); } else #endif - (p->dir) (device, "/", probe_dummy_iter, NULL); + (p->fs_dir) (device, "/", probe_dummy_iter, NULL); if (grub_errno == GRUB_ERR_NONE) return p; grub_error_push (); + /* The grub_error_push() does not touch grub_errmsg. */ + grub_dprintf ("fs", _("error: %s.\n"), grub_errmsg); grub_dprintf ("fs", "%s detection failed.\n", p->name); grub_error_pop (); @@ -94,7 +96,7 @@ grub_fs_probe (grub_device_t device) { p = grub_fs_list; - (p->dir) (device, "/", probe_dummy_iter, NULL); + (p->fs_dir) (device, "/", probe_dummy_iter, NULL); if (grub_errno == GRUB_ERR_NONE) { count--; @@ -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; } @@ -243,9 +259,9 @@ grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len) struct grub_fs grub_fs_blocklist = { .name = "blocklist", - .dir = 0, - .open = grub_fs_blocklist_open, - .read = grub_fs_blocklist_read, - .close = 0, + .fs_dir = 0, + .fs_open = grub_fs_blocklist_open, + .fs_read = grub_fs_blocklist_read, + .fs_close = 0, .next = 0 }; diff --git a/grub-core/kern/i386/coreboot/cbtable.c b/grub-core/kern/i386/coreboot/cbtable.c index 1669bc0ca..34a2b59be 100644 --- a/grub-core/kern/i386/coreboot/cbtable.c +++ b/grub-core/kern/i386/coreboot/cbtable.c @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include @@ -25,59 +25,20 @@ GRUB_MOD_LICENSE ("GPLv3+"); -/* Helper for grub_linuxbios_table_iterate. */ -static int -check_signature (grub_linuxbios_table_header_t tbl_header) -{ - if (! grub_memcmp (tbl_header->signature, "LBIO", 4)) - return 1; - - return 0; -} - -grub_err_t -grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t, - void *), - void *hook_data) +grub_linuxbios_table_header_t +grub_linuxbios_get_tables (void) { grub_linuxbios_table_header_t table_header; - grub_linuxbios_table_item_t table_item; - /* Assuming table_header is aligned to its size (8 bytes). */ - for (table_header = (grub_linuxbios_table_header_t) 0x500; table_header < (grub_linuxbios_table_header_t) 0x1000; table_header++) - if (check_signature (table_header)) - goto signature_found; + if (grub_linuxbios_check_signature (table_header)) + return table_header; for (table_header = (grub_linuxbios_table_header_t) 0xf0000; table_header < (grub_linuxbios_table_header_t) 0x100000; table_header++) - if (check_signature (table_header)) - goto signature_found; - - return 0; - -signature_found: - - table_item = - (grub_linuxbios_table_item_t) ((char *) table_header + - table_header->header_size); - for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header - + table_header->header_size - + table_header->table_size); - table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size)) - { - if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK - && check_signature ((grub_linuxbios_table_header_t) (grub_addr_t) - *(grub_uint64_t *) (table_item + 1))) - { - table_header = (grub_linuxbios_table_header_t) (grub_addr_t) - *(grub_uint64_t *) (table_item + 1); - goto signature_found; - } - if (hook (table_item, hook_data)) - return 1; - } + if (grub_linuxbios_check_signature (table_header)) + return table_header; return 0; } diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c 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 a28316cc6..46476e27e 100644 --- a/grub-core/kern/i386/efi/init.c +++ b/grub-core/kern/i386/efi/init.c @@ -38,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.c b/grub-core/kern/i386/tsc.c index 2e85289d8..9293b161d 100644 --- a/grub-core/kern/i386/tsc.c +++ b/grub-core/kern/i386/tsc.c @@ -65,10 +65,10 @@ grub_tsc_init (void) tsc_boot_time = grub_get_tsc (); -#ifdef GRUB_MACHINE_XEN +#if defined (GRUB_MACHINE_XEN) || defined (GRUB_MACHINE_XEN_PVH) (void) (grub_tsc_calibrate_from_xen () || calibrate_tsc_hardcode()); #elif defined (GRUB_MACHINE_EFI) - (void) (grub_tsc_calibrate_from_pit () || grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_efi() || calibrate_tsc_hardcode()); + (void) (grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_pit () || grub_tsc_calibrate_from_efi() || calibrate_tsc_hardcode()); #elif defined (GRUB_MACHINE_COREBOOT) (void) (grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_pit () || calibrate_tsc_hardcode()); #else 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/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c new file mode 100644 index 000000000..91fbca859 --- /dev/null +++ b/grub-core/kern/i386/xen/pvh.c @@ -0,0 +1,369 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define XEN_MEMORY_MAP_SIZE 128 + +grub_uint64_t grub_rsdp_addr; + +static char hypercall_page[GRUB_XEN_PAGE_SIZE] + __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE))); + +static grub_uint32_t xen_cpuid_base; +static struct start_info grub_xen_start_page; +static struct grub_e820_mmap_entry map[XEN_MEMORY_MAP_SIZE]; +static unsigned int nr_map_entries; + +static void +grub_xen_cons_msg (const char *msg) +{ + const char *c; + + for (c = msg; *c; c++) + grub_outb (*c, XEN_HVM_DEBUGCONS_IOPORT); +} + +static void +grub_xen_panic (const char *msg) +{ + grub_xen_cons_msg (msg); + grub_xen_cons_msg ("System halted!\n"); + + asm volatile ("cli"); + + while (1) + { + asm volatile ("hlt"); + } +} + +static void +grub_xen_cpuid_base (void) +{ + grub_uint32_t base, eax, signature[3]; + + for (base = 0x40000000; base < 0x40010000; base += 0x100) + { + grub_cpuid (base, eax, signature[0], signature[1], signature[2]); + if (!grub_memcmp ("XenVMMXenVMM", signature, 12) && (eax - base) >= 2) + { + xen_cpuid_base = base; + return; + } + } + + grub_xen_panic ("Found no Xen signature!\n"); +} + +static void +grub_xen_setup_hypercall_page (void) +{ + grub_uint32_t msr, addr, eax, ebx, ecx, edx; + + /* Get base address of Xen-specific MSRs. */ + grub_cpuid (xen_cpuid_base + 2, eax, ebx, ecx, edx); + msr = ebx; + addr = (grub_uint32_t) (&hypercall_page); + + /* Specify hypercall page address for Xen. */ + asm volatile ("wrmsr" : : "c" (msr), "a" (addr), "d" (0) : "memory"); +} + +int +grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0, + grub_uint32_t a1, grub_uint32_t a2, + grub_uint32_t a3, grub_uint32_t a4, + grub_uint32_t a5 __attribute__ ((unused))) +{ + grub_uint32_t res; + + asm volatile ("call *%[callno]" + : "=a" (res), "+b" (a0), "+c" (a1), "+d" (a2), + "+S" (a3), "+D" (a4) + : [callno] "a" (&hypercall_page[callno * 32]) + : "memory"); + return res; +} + +static grub_uint32_t +grub_xen_get_param (int idx) +{ + struct xen_hvm_param xhv; + int r; + + xhv.domid = DOMID_SELF; + xhv.index = idx; + r = grub_xen_hypercall (__HYPERVISOR_hvm_op, HVMOP_get_param, + (grub_uint32_t) (&xhv), 0, 0, 0, 0); + if (r < 0) + grub_xen_panic ("Could not get parameter from Xen!\n"); + return xhv.value; +} + +static void * +grub_xen_add_physmap (unsigned int space, void *addr) +{ + struct xen_add_to_physmap xatp; + + xatp.domid = DOMID_SELF; + xatp.idx = 0; + xatp.space = space; + xatp.gpfn = (grub_addr_t) addr >> GRUB_XEN_LOG_PAGE_SIZE; + if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_add_to_physmap, + (grub_uint32_t) (&xatp), 0, 0, 0, 0)) + grub_xen_panic ("Memory_op hypercall failed!\n"); + return addr; +} + +static void +grub_xen_sort_mmap (void) +{ + grub_uint64_t from, to; + unsigned int i; + struct grub_e820_mmap_entry tmp; + + /* Align map entries to page boundaries. */ + for (i = 0; i < nr_map_entries; i++) + { + from = map[i].addr; + to = from + map[i].len; + if (map[i].type == GRUB_MEMORY_AVAILABLE) + { + from = ALIGN_UP (from, GRUB_XEN_PAGE_SIZE); + to = ALIGN_DOWN (to, GRUB_XEN_PAGE_SIZE); + } + else + { + from = ALIGN_DOWN (from, GRUB_XEN_PAGE_SIZE); + to = ALIGN_UP (to, GRUB_XEN_PAGE_SIZE); + } + map[i].addr = from; + map[i].len = to - from; + } + + again: + /* Sort entries by start address. */ + for (i = 1; i < nr_map_entries; i++) + { + if (map[i].addr >= map[i - 1].addr) + continue; + tmp = map[i]; + map[i] = map[i - 1]; + map[i - 1] = tmp; + i = 0; + } + + /* Detect overlapping areas. */ + for (i = 1; i < nr_map_entries; i++) + { + if (map[i].addr >= map[i - 1].addr + map[i - 1].len) + continue; + tmp = map[i - 1]; + map[i - 1].len = map[i].addr - map[i - 1].addr; + if (map[i].addr + map[i].len >= tmp.addr + tmp.len) + continue; + if (nr_map_entries < ARRAY_SIZE (map)) + { + map[nr_map_entries].addr = map[i].addr + map[i].len; + map[nr_map_entries].len = tmp.addr + tmp.len - map[nr_map_entries].addr; + map[nr_map_entries].type = tmp.type; + nr_map_entries++; + goto again; + } + } + + /* Merge adjacent entries. */ + for (i = 1; i < nr_map_entries; i++) + { + if (map[i].type == map[i - 1].type && + map[i].addr == map[i - 1].addr + map[i - 1].len) + { + map[i - 1].len += map[i].len; + map[i] = map[nr_map_entries - 1]; + nr_map_entries--; + goto again; + } + } +} + +static void +grub_xen_get_mmap (void) +{ + struct xen_memory_map memmap; + + memmap.nr_entries = ARRAY_SIZE (map); + set_xen_guest_handle (memmap.buffer, map); + if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_memory_map, + (grub_uint32_t) (&memmap), 0, 0, 0, 0)) + grub_xen_panic ("Could not get memory map from Xen!\n"); + nr_map_entries = memmap.nr_entries; + + grub_xen_sort_mmap (); +} + +static void +grub_xen_set_mmap (void) +{ + struct xen_foreign_memory_map memmap; + + memmap.domid = DOMID_SELF; + memmap.map.nr_entries = nr_map_entries; + set_xen_guest_handle (memmap.map.buffer, map); + grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_set_memory_map, + (grub_uint32_t) (&memmap), 0, 0, 0, 0); +} + +static void +grub_xen_mm_init_regions (void) +{ + grub_uint64_t modend, from, to; + unsigned int i; + + modend = grub_modules_get_end (); + + for (i = 0; i < nr_map_entries; i++) + { + if (map[i].type != GRUB_MEMORY_AVAILABLE) + continue; + from = map[i].addr; + to = from + map[i].len; + if (from < modend) + from = modend; + if (from >= to || from >= (1ULL << 32)) + continue; + if (to > (1ULL << 32)) + to = 1ULL << 32; + grub_mm_init_region ((void *) (grub_addr_t) from, to - from); + } +} + +static grub_uint64_t +grub_xen_find_page (grub_uint64_t start) +{ + unsigned int i, j; + grub_uint64_t last = start; + + /* + * Try to find a e820 map hole below 4G. + * Relies on page-aligned entries (addr and len) and input (start). + */ + + for (i = 0; i < nr_map_entries; i++) + { + if (last > map[i].addr + map[i].len) + continue; + if (last < map[i].addr) + return last; + if ((map[i].addr >> 32) || ((map[i].addr + map[i].len) >> 32)) + break; + last = map[i].addr + map[i].len; + } + if (i == nr_map_entries) + return last; + + /* No hole found, use the highest RAM page below 4G and reserve it. */ + if (nr_map_entries == ARRAY_SIZE (map)) + grub_xen_panic ("Memory map size limit reached!\n"); + for (i = 0, j = 0; i < nr_map_entries; i++) + { + if (map[i].type != GRUB_MEMORY_AVAILABLE) + continue; + if (map[i].addr >> 32) + break; + j = i; + if ((map[i].addr + map[i].len) >> 32) + break; + } + if (map[j].type != GRUB_MEMORY_AVAILABLE) + grub_xen_panic ("No free memory page found!\n"); + if ((map[j].addr + map[j].len) >> 32) + last = (1ULL << 32) - GRUB_XEN_PAGE_SIZE; + else + last = map[j].addr + map[j].len - GRUB_XEN_PAGE_SIZE; + map[nr_map_entries].addr = last; + map[nr_map_entries].len = GRUB_XEN_PAGE_SIZE; + map[nr_map_entries].type = GRUB_MEMORY_RESERVED; + nr_map_entries++; + grub_xen_sort_mmap (); + + return last; +} + +void +grub_xen_setup_pvh (void) +{ + grub_addr_t par; + + grub_xen_cpuid_base (); + grub_xen_setup_hypercall_page (); + grub_xen_get_mmap (); + + /* Setup Xen data. */ + grub_xen_start_page_addr = &grub_xen_start_page; + + par = grub_xen_get_param (HVM_PARAM_CONSOLE_PFN); + grub_xen_start_page_addr->console.domU.mfn = par; + grub_xen_xcons = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE); + par = grub_xen_get_param (HVM_PARAM_CONSOLE_EVTCHN); + grub_xen_start_page_addr->console.domU.evtchn = par; + + par = grub_xen_get_param (HVM_PARAM_STORE_PFN); + grub_xen_start_page_addr->store_mfn = par; + grub_xen_xenstore = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE); + par = grub_xen_get_param (HVM_PARAM_STORE_EVTCHN); + grub_xen_start_page_addr->store_evtchn = par; + + par = grub_xen_find_page (0); + grub_xen_grant_table = grub_xen_add_physmap (XENMAPSPACE_grant_table, + (void *) par); + par = grub_xen_find_page (par + GRUB_XEN_PAGE_SIZE); + grub_xen_shared_info = grub_xen_add_physmap (XENMAPSPACE_shared_info, + (void *) par); + grub_xen_set_mmap (); + + grub_xen_mm_init_regions (); + + grub_rsdp_addr = pvh_start_info->rsdp_paddr; +} + +grub_err_t +grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) +{ + unsigned int i; + + for (i = 0; i < nr_map_entries; i++) + { + if (map[i].len && hook (map[i].addr, map[i].len, map[i].type, hook_data)) + break; + } + + return GRUB_ERR_NONE; +} diff --git a/grub-core/kern/i386/xen/startup_pvh.S b/grub-core/kern/i386/xen/startup_pvh.S new file mode 100644 index 000000000..363c31858 --- /dev/null +++ b/grub-core/kern/i386/xen/startup_pvh.S @@ -0,0 +1,81 @@ +/* startup.S - bootstrap GRUB itself */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + + .file "startup_pvh.S" + .text + .globl start, _start + .code32 + +start: +_start: + cld + lgdt gdtdesc + ljmp $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f +1: + movl $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %eax + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + mov %eax, %ss + leal LOCAL(stack_end), %esp + + /* Save address of start info structure. */ + mov %ebx, pvh_start_info + call EXT_C(grub_main) + /* Doesn't return. */ + + .p2align 3 +gdt: + .word 0, 0 + .byte 0, 0, 0, 0 + + /* -- code segment -- + * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present + * type = 32bit code execute/read, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x9A, 0xCF, 0 + + /* -- data segment -- + * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present + * type = 32 bit data read/write, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x92, 0xCF, 0 + + .p2align 3 +/* this is the GDT descriptor */ +gdtdesc: + .word 0x17 /* limit */ + .long gdt /* addr */ + + .p2align 2 +/* Saved pointer to start info structure. */ + .globl pvh_start_info +pvh_start_info: + .long 0 + + .bss + .space GRUB_MEMORY_MACHINE_PROT_STACK_SIZE +LOCAL(stack_end): diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 082aebc3a..db59300fe 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -119,6 +119,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, case R_IA64_LTOFF22: if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) value = *(grub_uint64_t *) sym->st_value + rel->r_addend; + /* Fallthrough. */ case R_IA64_LTOFF_FPTR22: { grub_uint64_t *gpptr = mod->gotptr; @@ -135,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 3e12e6b24..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]; @@ -108,6 +107,9 @@ grub_ieee1275_find_options (void) if (rc >= 0) { char *ptr; + + if (grub_strncmp (tmp, "sun4v", 5) == 0) + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_RAW_DEVNAMES); for (ptr = tmp; ptr - tmp < actual; ptr += grub_strlen (ptr) + 1) { if (grub_memcmp (ptr, "MacRISC", sizeof ("MacRISC") - 1) == 0 @@ -121,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) @@ -186,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 98217029f..36ca2dbfc 100644 --- a/grub-core/kern/ieee1275/ieee1275.c +++ b/grub-core/kern/ieee1275/ieee1275.c @@ -19,6 +19,7 @@ #include #include +#include #define IEEE1275_PHANDLE_INVALID ((grub_ieee1275_cell_t) -1) #define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0) @@ -305,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 @@ -397,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; @@ -482,6 +480,91 @@ grub_ieee1275_close (grub_ieee1275_ihandle_t ihandle) return 0; } +int +grub_ieee1275_decode_unit4 (grub_ieee1275_ihandle_t ihandle, + void *addr, grub_size_t size, + grub_uint32_t *phy_lo, grub_uint32_t *phy_hi, + grub_uint32_t *lun_lo, grub_uint32_t *lun_hi) +{ + struct decode_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t size; + grub_ieee1275_cell_t addr; + grub_ieee1275_cell_t catch_result; + grub_ieee1275_cell_t tgt_h; + grub_ieee1275_cell_t tgt_l; + grub_ieee1275_cell_t lun_h; + grub_ieee1275_cell_t lun_l; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 5); + args.method = (grub_ieee1275_cell_t) "decode-unit"; + args.ihandle = ihandle; + args.size = size; + args.addr = (grub_ieee1275_cell_t) addr; + args.catch_result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "decode-unit failed\n"); + return -1; + } + + *phy_lo = args.tgt_l; + *phy_hi = args.tgt_h; + *lun_lo = args.lun_l; + *lun_hi = args.lun_h; + return 0; +} + +char * +grub_ieee1275_encode_uint4 (grub_ieee1275_ihandle_t ihandle, + grub_uint32_t phy_lo, grub_uint32_t phy_hi, + grub_uint32_t lun_lo, grub_uint32_t lun_hi, + grub_size_t *size) +{ + char *addr; + struct encode_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t tgt_h; + grub_ieee1275_cell_t tgt_l; + grub_ieee1275_cell_t lun_h; + grub_ieee1275_cell_t lun_l; + grub_ieee1275_cell_t catch_result; + grub_ieee1275_cell_t size; + grub_ieee1275_cell_t addr; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 3); + args.method = (grub_ieee1275_cell_t) "encode-unit"; + args.ihandle = ihandle; + + args.tgt_l = phy_lo; + args.tgt_h = phy_hi; + args.lun_l = lun_lo; + args.lun_h = lun_hi; + args.catch_result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "encode-unit failed\n"); + return 0; + } + + addr = (void *)args.addr; + *size = args.size; + addr = grub_strdup ((char *)args.addr); + return addr; +} + int grub_ieee1275_claim (grub_addr_t addr, grub_size_t size, unsigned int align, grub_addr_t *result) @@ -507,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; } @@ -607,3 +693,117 @@ grub_ieee1275_milliseconds (grub_uint32_t *msecs) *msecs = args.msecs; return 0; } + +int +grub_ieee1275_set_address (grub_ieee1275_ihandle_t ihandle, + grub_uint32_t target, grub_uint32_t lun) +{ + struct set_address + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t tgt; + grub_ieee1275_cell_t lun; + grub_ieee1275_cell_t catch_result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 4, 1); + + /* + * IEEE 1275-1994 Standard for Boot (Initialization Configuration) + * Firmware: Core Requirements and Practices + * E.3.2.2 Bus-specific methods for bus nodes + * + * A package implementing the scsi-2 device type shall implement the + * following bus-specific method: + * + * set-address ( unit# target# -- ) + * Sets the SCSI target number (0x0..0xf) and unit number (0..7) to which + * subsequent commands apply. + */ + args.method = (grub_ieee1275_cell_t) "set-address"; + args.ihandle = ihandle; + args.tgt = target; + args.lun = lun; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + + return args.catch_result; +} + +int +grub_ieee1275_no_data_command (grub_ieee1275_ihandle_t ihandle, + const void *cmd_addr, grub_ssize_t *result) +{ + struct set_address + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t cmd_addr; + grub_ieee1275_cell_t error; + grub_ieee1275_cell_t catch_result; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); + + /* + * IEEE 1275-1994 Standard for Boot (Initialization Configuration) + * Firmware: Core Requirements and Practices + * + * E.3.2.2 Bus-specific methods for bus nodes + * + * A package implementing the scsi-2 device type shall implement the + * following bus-specific method: + * + * no-data-command ( cmd-addr -- error? ) + * Executes a simple SCSI command, automatically retrying under + * certain conditions. cmd-addr is the address of a 6-byte command buffer + * containing an SCSI command that does not have a data transfer phase. + * Executes the command, retrying indefinitely with the same retry criteria + * as retry-command. + * + * error? is nonzero if an error occurred, zero otherwise. + * NOTE no-data-command is a convenience function. It provides + * no capabilities that are not present in retry-command, but for + * those commands that meet its restrictions, it is easier to use. + */ + args.method = (grub_ieee1275_cell_t) "no-data-command"; + args.ihandle = ihandle; + args.cmd_addr = (grub_ieee1275_cell_t) cmd_addr; + + if (IEEE1275_CALL_ENTRY_FN (&args) == -1) + return -1; + + if (result) + *result = args.error; + + return args.catch_result; +} + +int +grub_ieee1275_get_block_size (grub_ieee1275_ihandle_t ihandle) +{ + struct size_args_ieee1275 + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t result; + grub_ieee1275_cell_t size; + } args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2); + args.method = (grub_ieee1275_cell_t) "block-size"; + args.ihandle = ihandle; + args.result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) + return 0; + + return args.size; +} diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c index 12590225e..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 @@ -30,6 +32,9 @@ #include #include #include +#ifdef __sparc__ +#include +#endif #include #include #include @@ -41,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[]; @@ -67,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) { @@ -94,28 +150,12 @@ void grub_machine_get_bootlocation (char **device, char **path) { char *bootpath; - grub_ssize_t bootpath_size; char *filename; char *type; - if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", - &bootpath_size) - || bootpath_size <= 0) - { - /* Should never happen. */ - grub_printf ("/chosen/bootpath property missing!\n"); - return; - } - - bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); + bootpath = grub_ieee1275_get_boot_dev (); if (! bootpath) - { - grub_print_error (); - return; - } - grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, - (grub_size_t) bootpath_size + 1, 0); - bootpath[bootpath_size] = '\0'; + return; /* Transform an OF device path to a GRUB path. */ @@ -126,6 +166,8 @@ grub_machine_get_bootlocation (char **device, char **path) char *ptr; dev = grub_ieee1275_get_aliasdevname (bootpath); canon = grub_ieee1275_canonicalise_devname (dev); + if (! canon) + return; ptr = canon + grub_strlen (canon) - 1; while (ptr > canon && (*ptr == ',' || *ptr == ':')) ptr--; @@ -160,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) @@ -188,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 @@ -211,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; @@ -218,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 @@ -286,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 (); @@ -294,8 +1008,11 @@ grub_machine_init (void) grub_console_init_early (); grub_claim_heap (); grub_console_init_lately (); +#ifdef __sparc__ + grub_obdisk_init (); +#else grub_ofdisk_init (); - +#endif grub_parse_cmdline (); #ifdef __i386__ @@ -310,7 +1027,11 @@ grub_machine_fini (int flags) { if (flags & GRUB_LOADER_FLAG_NORETURN) { +#ifdef __sparc__ + grub_obdisk_fini (); +#else grub_ofdisk_fini (); +#endif grub_console_fini (); } } diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c index ddb778340..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); @@ -479,6 +479,9 @@ grub_ieee1275_encode_devname (const char *path) char *optr; const char *iptr; + if (! device) + return 0; + encoding = grub_malloc (sizeof ("ieee1275/") + 2 * grub_strlen (device) + sizeof (",XXXXXXXXXXXX")); if (!encoding) @@ -561,3 +564,30 @@ grub_ieee1275_canonicalise_devname (const char *path) return NULL; } +char * +grub_ieee1275_get_boot_dev (void) +{ + char *bootpath; + grub_ssize_t bootpath_size; + + if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", + &bootpath_size) + || bootpath_size <= 0) + { + /* Should never happen. */ + grub_printf ("/chosen/bootpath property missing!\n"); + return NULL; + } + + bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); + if (! bootpath) + { + grub_print_error (); + return NULL; + } + grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, + (grub_size_t) bootpath_size + 1, 0); + bootpath[bootpath_size] = '\0'; + + return bootpath; +} diff --git a/grub-core/kern/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/arm/efi/loader.h b/grub-core/kern/loongarch64/cache_flush.S similarity index 66% rename from include/grub/arm/efi/loader.h rename to grub-core/kern/loongarch64/cache_flush.S index 4bab18e83..a587ed58f 100644 --- a/include/grub/arm/efi/loader.h +++ b/grub-core/kern/loongarch64/cache_flush.S @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 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,11 +16,18 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_LOADER_MACHINE_HEADER -#define GRUB_LOADER_MACHINE_HEADER 1 +#include -grub_err_t EXPORT_FUNC (grub_efi_prepare_platform) (void); -void * EXPORT_FUNC (grub_efi_allocate_loader_memory) (grub_uint32_t min_offset, - grub_uint32_t size); + .file "cache_flush.S" + .text +/* + * No further work to do because cache consistency is maintained by hardware on + * LoongArch. + */ +FUNCTION(grub_arch_clean_dcache_range) + dbar 0 + jr $ra -#endif /* ! GRUB_LOADER_MACHINE_HEADER */ +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 e320a4ee7..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; @@ -236,6 +236,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, sym_value &= 0xffff0000; *(grub_uint16_t *) addr = 0; } + /* Fallthrough. */ case R_MIPS_CALL16: { grub_uint32_t *gpptr = mod->gotptr; @@ -264,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 d1a54df6c..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; @@ -391,12 +461,13 @@ grub_strtoull (const char *str, char **end, int base) unsigned long digit; digit = grub_tolower (*str) - '0'; - if (digit > 9) - { - digit += '0' - 'a' + 10; - if (digit >= (unsigned long) base) - break; - } + if (digit >= 'a' - '0') + digit += '0' - 'a' + 10; + else if (digit > 9) + break; + + if (digit >= (unsigned long) base) + break; found = 1; @@ -405,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; } @@ -416,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; } @@ -587,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') @@ -602,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 @@ -622,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; @@ -651,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++; @@ -674,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); @@ -705,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 != '%') @@ -723,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++; } @@ -761,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; @@ -768,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': @@ -781,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) { @@ -800,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; } } @@ -812,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) @@ -833,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; } @@ -852,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; @@ -881,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; } @@ -894,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': @@ -957,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; @@ -981,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--) @@ -991,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; } } @@ -1020,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 @@ -1080,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 @@ -1111,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 @@ -1140,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 3a7fa3ed3..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,14 +74,15 @@ 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; rel++) - if (ELF_R_TYPE (rel->r_info) == GRUB_ELF_R_PPC_REL24) + 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); @@ -122,6 +123,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, *(Elf_Half *) addr = value; break; + case GRUB_ELF_R_PPC_PLTREL24: case GRUB_ELF_R_PPC_REL24: { Elf_Sword delta = value - (Elf_Word) addr; @@ -136,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/cache.c b/grub-core/kern/riscv/cache.c new file mode 100644 index 000000000..47777a033 --- /dev/null +++ b/grub-core/kern/riscv/cache.c @@ -0,0 +1,63 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +static grub_int64_t dlinesz; +static grub_int64_t ilinesz; + +/* Prototypes for asm functions. */ +void grub_arch_clean_dcache_range (grub_addr_t beg, grub_addr_t end, + grub_size_t line_size); +void grub_arch_invalidate_icache_range (grub_addr_t beg, grub_addr_t end, + grub_size_t line_size); + +static void +probe_caches (void) +{ + /* TODO */ + dlinesz = 32; + ilinesz = 32; +} + +void +grub_arch_sync_caches (void *address, grub_size_t len) +{ + grub_size_t start, end, max_align; + + if (dlinesz == 0) + probe_caches(); + if (dlinesz == 0) + grub_fatal ("Unknown cache line size!"); + + max_align = dlinesz > ilinesz ? dlinesz : ilinesz; + + start = ALIGN_DOWN ((grub_size_t) address, max_align); + end = ALIGN_UP ((grub_size_t) address + len, max_align); + + grub_arch_clean_dcache_range (start, end, dlinesz); + grub_arch_invalidate_icache_range (start, end, ilinesz); +} + +void +grub_arch_sync_dma_caches (volatile void *address __attribute__((unused)), + grub_size_t len __attribute__((unused))) +{ + /* DMA incoherent devices not supported yet */ +} diff --git a/grub-core/kern/riscv/cache_flush.S b/grub-core/kern/riscv/cache_flush.S new file mode 100644 index 000000000..41de6e411 --- /dev/null +++ b/grub-core/kern/riscv/cache_flush.S @@ -0,0 +1,44 @@ +/* + * 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 + + .file "cache_flush.S" + .text + +/* + * Simple cache maintenance functions + */ + +/* + * a0 - *beg (inclusive) + * a1 - *end (exclusive) + * a2 - line size +*/ +FUNCTION(grub_arch_clean_dcache_range) + /* TODO */ + ret + +/* + * a0 - *beg (inclusive) + * a1 - *end (exclusive) + * a2 - line size + */ +FUNCTION(grub_arch_invalidate_icache_range) + fence.i + ret diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c new file mode 100644 index 000000000..896653bb4 --- /dev/null +++ b/grub-core/kern/riscv/dl.c @@ -0,0 +1,346 @@ +/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* + * Instructions and instruction encoding are documented in the RISC-V + * specification. This file is based on version 2.2: + * + * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf + */ +#define LDR 0x58000050 +#define BR 0xd61f0200 + +/* + * Check if EHDR is a valid ELF header. + */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_RISCV) + return grub_error (GRUB_ERR_BAD_OS, + N_("invalid arch-dependent ELF magic")); + + return GRUB_ERR_NONE; +} + +#pragma GCC diagnostic ignored "-Wcast-align" + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) +{ + Elf_Rel *rel, *max; + + for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), + max = (Elf_Rel *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) + { + Elf_Sym *sym; + void *place; + grub_size_t sym_addr; + + if (rel->r_offset >= seg->size) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); + + sym_addr = sym->st_value; + if (s->sh_type == SHT_RELA) + sym_addr += ((Elf_Rela *) rel)->r_addend; + + place = (void *) ((grub_addr_t) seg->addr + rel->r_offset); + + switch (ELF_R_TYPE (rel->r_info)) + { + case R_RISCV_32: + { + grub_uint32_t *abs_place = place; + + grub_dprintf ("dl", " reloc_abs32 %p => 0x%016llx\n", + place, (unsigned long long) sym_addr); + + *abs_place = (grub_uint32_t) sym_addr; + } + break; + case R_RISCV_64: + { + grub_size_t *abs_place = place; + + grub_dprintf ("dl", " reloc_abs64 %p => 0x%016llx\n", + place, (unsigned long long) sym_addr); + + *abs_place = (grub_size_t) sym_addr; + } + break; + + case R_RISCV_ADD8: + { + grub_uint8_t *abs_place = place; + + *abs_place += (grub_uint8_t) sym_addr; + } + break; + case R_RISCV_ADD16: + { + grub_uint16_t *abs_place = place; + + *abs_place += (grub_uint16_t) sym_addr; + } + break; + case R_RISCV_ADD32: + { + grub_uint32_t *abs_place = place; + + *abs_place += (grub_uint32_t) sym_addr; + } + break; + case R_RISCV_ADD64: + { + grub_size_t *abs_place = place; + + *abs_place += (grub_size_t) sym_addr; + } + break; + + case R_RISCV_SUB8: + { + grub_uint8_t *abs_place = place; + + *abs_place -= (grub_uint8_t) sym_addr; + } + break; + case R_RISCV_SUB16: + { + grub_uint16_t *abs_place = place; + + *abs_place -= (grub_uint16_t) sym_addr; + } + break; + case R_RISCV_SUB32: + { + grub_uint32_t *abs_place = place; + + *abs_place -= (grub_uint32_t) sym_addr; + } + break; + case R_RISCV_SUB64: + { + grub_size_t *abs_place = place; + + *abs_place -= (grub_size_t) sym_addr; + } + break; + + case R_RISCV_BRANCH: + { + grub_uint32_t *abs_place = place; + grub_ssize_t off = sym_addr - (grub_addr_t) place; + grub_uint32_t imm12 = (off & 0x1000) << (31 - 12); + grub_uint32_t imm11 = (off & 0x800) >> (11 - 7); + grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10); + grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4); + *abs_place = (*abs_place & 0x1fff07f) + | imm12 | imm11 | imm10_5 | imm4_1; + } + break; + + case R_RISCV_JAL: + { + grub_uint32_t *abs_place = place; + grub_ssize_t off = sym_addr - (grub_addr_t) place; + grub_uint32_t imm20 = (off & 0x100000) << (31 - 20); + grub_uint32_t imm19_12 = (off & 0xff000); + grub_uint32_t imm11 = (off & 0x800) << (20 - 11); + grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10); + *abs_place = (*abs_place & 0xfff) + | imm20 | imm19_12 | imm11 | imm10_1; + } + break; + + case R_RISCV_CALL: + case R_RISCV_CALL_PLT: + { + grub_uint32_t *abs_place = place; + grub_ssize_t off = sym_addr - (grub_addr_t) place; + grub_uint32_t hi20, lo12; + + if (off != (grub_int32_t) off) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); + + hi20 = (off + 0x800) & 0xfffff000; + lo12 = (off - hi20) & 0xfff; + abs_place[0] = (abs_place[0] & 0xfff) | hi20; + abs_place[1] = (abs_place[1] & 0xfffff) | (lo12 << 20); + } + break; + + case R_RISCV_RVC_BRANCH: + { + grub_uint16_t *abs_place = place; + grub_ssize_t off = sym_addr - (grub_addr_t) place; + grub_uint16_t imm8 = (off & 0x100) << (12 - 8); + grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5); + grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10); + *abs_place = (*abs_place & 0xe383) + | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1; + } + break; + + case R_RISCV_RVC_JUMP: + { + grub_uint16_t *abs_place = place; + grub_ssize_t off = sym_addr - (grub_addr_t) place; + grub_uint16_t imm11 = (off & 0x800) << (12 - 11); + grub_uint16_t imm10 = (off & 0x400) >> (10 - 8); + grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11); + grub_uint16_t imm7 = (off & 0x80) >> (7 - 6); + grub_uint16_t imm6 = (off & 0x40) << (12 - 11); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4 = (off & 0x10) << (12 - 5); + grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10); + *abs_place = ((*abs_place & 0xe003) + | imm11 | imm10 | imm9_8 | imm7 | imm6 + | imm5 | imm4 | imm3_1); + } + break; + + case R_RISCV_PCREL_HI20: + { + grub_uint32_t *abs_place = place; + grub_ssize_t off = sym_addr - (grub_addr_t) place; + grub_int32_t hi20; + + if (off != (grub_int32_t)off) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); + + hi20 = (off + 0x800) & 0xfffff000; + *abs_place = (*abs_place & 0xfff) | hi20; + } + break; + + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: + { + grub_uint32_t *t32 = place; + Elf_Rela *rel2; + /* Search backwards for matching HI20 reloc. */ + for (rel2 = (Elf_Rela *) ((char *) rel - s->sh_entsize); + (unsigned long)rel2 >= ((unsigned long)ehdr + s->sh_offset); + rel2 = (Elf_Rela *) ((char *) rel2 - s->sh_entsize)) + { + Elf_Addr rel2_info; + Elf_Addr rel2_offset; + Elf_Addr rel2_sym_addr; + Elf_Addr rel2_loc; + grub_ssize_t rel2_off; + grub_ssize_t off; + Elf_Sym *sym2; + + rel2_offset = rel2->r_offset; + rel2_info = rel2->r_info; + rel2_loc = (grub_addr_t) seg->addr + rel2_offset; + + if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20 + && rel2_loc == sym_addr) + { + sym2 = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel2->r_info)); + rel2_sym_addr = sym2->st_value; + if (s->sh_type == SHT_RELA) + rel2_sym_addr += ((Elf_Rela *) rel2)->r_addend; + + rel2_off = rel2_sym_addr - rel2_loc; + off = rel2_off - ((rel2_off + 0x800) & 0xfffff000); + + if (ELF_R_TYPE (rel->r_info) == R_RISCV_PCREL_LO12_I) + *t32 = (*t32 & 0xfffff) | (off & 0xfff) << 20; + else + { + grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4); + *t32 = (*t32 & 0x1fff07f) | imm11_5 | imm4_0; + } + break; + } + } + if ((unsigned long)rel2 < ((unsigned long)ehdr + s->sh_offset)) + return grub_error (GRUB_ERR_BAD_MODULE, "cannot find matching HI20 relocation"); + } + break; + + case R_RISCV_HI20: + { + grub_uint32_t *abs_place = place; + *abs_place = (*abs_place & 0xfff) | + (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + } + break; + + case R_RISCV_LO12_I: + { + grub_uint32_t *abs_place = place; + grub_int32_t lo12 = (grub_int32_t) sym_addr - + (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + *abs_place = (*abs_place & 0xfffff) | ((lo12 & 0xfff) << 20); + } + break; + + case R_RISCV_LO12_S: + { + grub_uint32_t *abs_place = place; + grub_int32_t lo12 = (grub_int32_t) sym_addr - + (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4); + *abs_place = (*abs_place & 0x1fff07f) | imm11_5 | imm4_0; + } + break; + + case R_RISCV_RELAX: + break; + default: + { + char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ + + grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, + (grub_uint64_t) ELF_R_TYPE (rel->r_info)); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%s is not implemented yet"), rel_info); + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c new file mode 100644 index 000000000..0d7de4f54 --- /dev/null +++ b/grub-core/kern/riscv/efi/init.c @@ -0,0 +1,78 @@ +/* init.c - initialize a riscv-based EFI system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static grub_uint64_t timer_frequency_in_khz; + +static grub_uint64_t +grub_efi_get_time_ms (void) +{ + grub_uint64_t tmr; + +#if __riscv_xlen == 64 + asm volatile ("rdtime %0" : "=r"(tmr)); +#else + grub_uint32_t lo, hi, tmp; + asm volatile ("1:\n" + "rdtimeh %0\n" + "rdtime %1\n" + "rdtimeh %2\n" + "bne %0, %2, 1b" + : "=&r" (hi), "=&r" (lo), "=&r" (tmp)); + tmr = ((grub_uint64_t)hi << 32) | lo; +#endif + + return tmr / timer_frequency_in_khz; +} + +void +grub_machine_init (void) +{ + grub_uint64_t time_before, time_after; + + grub_efi_init (); + + /* Calculate timer frequency */ + timer_frequency_in_khz = 1; + time_before = grub_efi_get_time_ms(); + grub_efi_stall(1000); + time_after = grub_efi_get_time_ms(); + timer_frequency_in_khz = time_after - time_before; + + grub_install_get_time_ms (grub_efi_get_time_ms); +} + +void +grub_machine_fini (int flags) +{ + if (!(flags & GRUB_LOADER_FLAG_NORETURN)) + return; + + grub_efi_fini (); + + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) + grub_efi_memory_fini (); +} diff --git a/grub-core/kern/riscv/efi/startup.S b/grub-core/kern/riscv/efi/startup.S new file mode 100644 index 000000000..f2a7b2b1e --- /dev/null +++ b/grub-core/kern/riscv/efi/startup.S @@ -0,0 +1,48 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#if __riscv_xlen == 64 +#define sl sd +#define ll ld +#else +#define sl sw +#define ll lw +#endif + + + .file "startup.S" + .text +FUNCTION(_start) + /* + * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. + */ + + ll a2, efi_image_handle_val + sl a0, 0(a2) + ll a2, efi_system_table_val + sl a1, 0(a2) + ll a2, grub_main_val + jr a2 +grub_main_val: + .quad EXT_C(grub_main) +efi_system_table_val: + .quad EXT_C(grub_efi_system_table) +efi_image_handle_val: + .quad EXT_C(grub_efi_image_handle) diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c index d25c15e10..f3d960186 100644 --- a/grub-core/kern/sparc64/dl.c +++ b/grub-core/kern/sparc64/dl.c @@ -159,6 +159,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, if (value >> 32) return grub_error (GRUB_ERR_BAD_MODULE, "address out of 32 bits range"); + /* Fallthrough. */ case R_SPARC_LM22: *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF); break; @@ -175,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/sparc64/ieee1275/ieee1275.c b/grub-core/kern/sparc64/ieee1275/ieee1275.c index 53be692c3..5a59aaf06 100644 --- a/grub-core/kern/sparc64/ieee1275/ieee1275.c +++ b/grub-core/kern/sparc64/ieee1275/ieee1275.c @@ -89,3 +89,59 @@ grub_ieee1275_alloc_physmem (grub_addr_t *paddr, grub_size_t size, return args.catch_result; } + +grub_uint64_t +grub_ieee1275_num_blocks (grub_ieee1275_ihandle_t ihandle) +{ + struct nblocks_args_ieee1275 + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t catch_result; + grub_ieee1275_cell_t blocks; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 2); + args.method = (grub_ieee1275_cell_t) "#blocks"; + args.ihandle = ihandle; + args.catch_result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0)) + return -1; + + /* + * If the number of blocks exceeds the range of an unsigned number, + * return 0 to alert the caller to try the #blocks64 command. + */ + if (args.blocks >= 0xffffffffULL) + return 0; + + return args.blocks; +} + +grub_uint64_t +grub_ieee1275_num_blocks64 (grub_ieee1275_ihandle_t ihandle) +{ + struct nblocks_args_ieee1275 + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t ihandle; + grub_ieee1275_cell_t catch_result; + grub_ieee1275_cell_t hi_blocks; + grub_ieee1275_cell_t lo_blocks; + } + args; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); + args.method = (grub_ieee1275_cell_t) "#blocks64"; + args.ihandle = ihandle; + args.catch_result = 1; + + if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.catch_result != 0)) + return -1; + + return ((args.hi_blocks << 32) | (args.lo_blocks)); +} diff --git a/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/init.c b/grub-core/kern/uboot/init.c index 5dcc106ed..3e338645c 100644 --- a/grub-core/kern/uboot/init.c +++ b/grub-core/kern/uboot/init.c @@ -36,30 +36,14 @@ extern char __bss_start[]; extern char _end[]; extern grub_size_t grub_total_module_size; -extern int (*grub_uboot_syscall_ptr) (int, int *, ...); static unsigned long timer_start; -extern grub_uint32_t grub_uboot_machine_type; -extern grub_addr_t grub_uboot_boot_data; - void grub_exit (void) { grub_uboot_return (0); } -grub_uint32_t -grub_uboot_get_machine_type (void) -{ - return grub_uboot_machine_type; -} - -grub_addr_t -grub_uboot_get_boot_data (void) -{ - return grub_uboot_boot_data; -} - static grub_uint64_t uboot_timer_ms (void) { diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c index 6800a4beb..aac8f9ae1 100644 --- a/grub-core/kern/uboot/uboot.c +++ b/grub-core/kern/uboot/uboot.c @@ -39,48 +39,13 @@ * returns: 0 if the call not found, 1 if serviced */ -extern int (*grub_uboot_syscall_ptr) (int, int *, ...); extern int grub_uboot_syscall (int, int *, ...); -extern grub_addr_t grub_uboot_search_hint; static struct sys_info uboot_sys_info; static struct mem_region uboot_mem_info[5]; static struct device_info * devices; static int num_devices; -int -grub_uboot_api_init (void) -{ - struct api_signature *start, *end; - struct api_signature *p; - - if (grub_uboot_search_hint) - { - /* Extended search range to work around Trim Slice U-Boot issue */ - start = (struct api_signature *) ((grub_uboot_search_hint & ~0x000fffff) - - 0x00500000); - end = - (struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN - - API_SIG_MAGLEN + 0x00500000); - } - else - { - start = 0; - end = (struct api_signature *) (256 * 1024 * 1024); - } - - /* Structure alignment is (at least) 8 bytes */ - for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8)) - { - if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0) - { - grub_uboot_syscall_ptr = p->syscall; - return p->version; - } - } - - return 0; -} /* * All functions below are wrappers around the grub_uboot_syscall() function @@ -168,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; @@ -278,6 +243,22 @@ grub_uboot_dev_read (struct device_info *dev, void *buf, grub_size_t blocks, return retval; } +int +grub_uboot_dev_write (struct device_info *dev, const void *buf, + grub_size_t blocks, grub_uint32_t start) +{ + int retval; + + if (!OPEN_DEV (dev)) + return -1; + + if (!grub_uboot_syscall (API_DEV_WRITE, &retval, dev, buf, + &blocks, &start)) + return -1; + + return retval; +} + int grub_uboot_dev_recv (struct device_info *dev, void *buf, int size, int *real_size) diff --git a/grub-core/kern/verifiers.c b/grub-core/kern/verifiers.c new file mode 100644 index 000000000..75d7994cf --- /dev/null +++ b/grub-core/kern/verifiers.c @@ -0,0 +1,228 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + * + * Verifiers helper. + */ + +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +struct grub_file_verifier *grub_file_verifiers; + +struct grub_verified +{ + grub_file_t file; + void *buf; +}; +typedef struct grub_verified *grub_verified_t; + +static void +verified_free (grub_verified_t verified) +{ + if (verified) + { + grub_free (verified->buf); + grub_free (verified); + } +} + +static grub_ssize_t +verified_read (struct grub_file *file, char *buf, grub_size_t len) +{ + grub_verified_t verified = file->data; + + grub_memcpy (buf, (char *) verified->buf + file->offset, len); + return len; +} + +static grub_err_t +verified_close (struct grub_file *file) +{ + grub_verified_t verified = file->data; + + grub_file_close (verified->file); + verified_free (verified); + file->data = 0; + + /* Device and name are freed by parent. */ + file->device = 0; + file->name = 0; + + return grub_errno; +} + +struct grub_fs verified_fs = +{ + .name = "verified_read", + .fs_read = verified_read, + .fs_close = verified_close +}; + +static grub_file_t +grub_verifiers_open (grub_file_t io, enum grub_file_type type) +{ + grub_verified_t verified = NULL; + struct grub_file_verifier *ver; + void *context; + grub_file_t ret = 0; + grub_err_t err; + int defer = 0; + + grub_dprintf ("verify", "file: %s type: %d\n", io->name, type); + + if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE + || (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE + || (type & GRUB_FILE_TYPE_SKIP_SIGNATURE)) + return io; + + if (io->device->disk && + (io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID + || io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID)) + return io; + + FOR_LIST_ELEMENTS(ver, grub_file_verifiers) + { + enum grub_verify_flags flags = 0; + err = ver->init (io, type, &context, &flags); + if (err) + goto fail_noclose; + if (flags & GRUB_VERIFY_FLAGS_DEFER_AUTH) + { + defer = 1; + continue; + } + if (!(flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION)) + break; + } + + if (!ver) + { + if (defer) + { + grub_error (GRUB_ERR_ACCESS_DENIED, + N_("verification requested but nobody cares: %s"), io->name); + goto fail_noclose; + } + + /* No verifiers wanted to verify. Just return underlying file. */ + return io; + } + + ret = grub_malloc (sizeof (*ret)); + if (!ret) + { + goto fail; + } + *ret = *io; + + ret->fs = &verified_fs; + ret->not_easily_seekable = 0; + if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1)) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("big file signature isn't implemented yet")); + goto fail; + } + verified = grub_malloc (sizeof (*verified)); + if (!verified) + { + goto fail; + } + verified->buf = grub_malloc (ret->size); + if (!verified->buf) + { + goto fail; + } + if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size) + { + if (!grub_errno) + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), + io->name); + goto fail; + } + + err = ver->write (context, verified->buf, ret->size); + if (err) + goto fail; + + err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; + if (err) + goto fail; + + if (ver->close) + ver->close (context); + + FOR_LIST_ELEMENTS_NEXT(ver, grub_file_verifiers) + { + enum grub_verify_flags flags = 0; + err = ver->init (io, type, &context, &flags); + if (err) + goto fail_noclose; + if (flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION || + /* Verification done earlier. So, we are happy here. */ + flags & GRUB_VERIFY_FLAGS_DEFER_AUTH) + continue; + err = ver->write (context, verified->buf, ret->size); + if (err) + goto fail; + + err = ver->fini ? ver->fini (context) : GRUB_ERR_NONE; + if (err) + goto fail; + + if (ver->close) + ver->close (context); + } + + verified->file = io; + ret->data = verified; + return ret; + + fail: + if (ver->close) + ver->close (context); + fail_noclose: + verified_free (verified); + grub_free (ret); + return NULL; +} + +grub_err_t +grub_verify_string (char *str, enum grub_verify_string_type type) +{ + struct grub_file_verifier *ver; + + grub_dprintf ("verify", "string: %s, type: %d\n", str, type); + + FOR_LIST_ELEMENTS(ver, grub_file_verifiers) + { + grub_err_t err; + err = ver->verify_string ? ver->verify_string (str, type) : GRUB_ERR_NONE; + if (err) + return err; + } + return GRUB_ERR_NONE; +} + +void +grub_verifiers_init (void) +{ + grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open); +} diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c index 440690673..e5a8bdcf4 100644 --- a/grub-core/kern/x86_64/dl.c +++ b/grub-core/kern/x86_64/dl.c @@ -70,6 +70,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, break; case R_X86_64_PC32: + case R_X86_64_PLT32: { grub_int64_t value; value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value - @@ -105,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/kern/xen/init.c b/grub-core/kern/xen/init.c index 0559c033c..782ca7295 100644 --- a/grub-core/kern/xen/init.c +++ b/grub-core/kern/xen/init.c @@ -41,9 +41,13 @@ grub_size_t grub_xen_n_allocated_shared_pages; static grub_xen_mfn_t grub_xen_ptr2mfn (void *ptr) { +#ifdef GRUB_MACHINE_XEN grub_xen_mfn_t *mfn_list = (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list; return mfn_list[(grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE]; +#else + return (grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE; +#endif } void * @@ -104,18 +108,6 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)), { } -static grub_uint8_t window[GRUB_XEN_PAGE_SIZE] - __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE))); - -#ifdef __x86_64__ -#define NUMBER_OF_LEVELS 4 -#else -#define NUMBER_OF_LEVELS 3 -#endif - -#define LOG_POINTERS_PER_PAGE 9 -#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE) - void grub_xen_store_send (const void *buf_, grub_size_t len) { @@ -318,6 +310,38 @@ grub_xenstore_dir (const char *dir, unsigned long gntframe = 0; +static void +grub_xen_setup_gnttab (void) +{ + struct gnttab_set_version gnttab_setver; + struct gnttab_setup_table gnttab_setup; + + grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver)); + + gnttab_setver.version = 1; + grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1); + + grub_memset (&gnttab_setup, 0, sizeof (gnttab_setup)); + gnttab_setup.dom = DOMID_SELF; + gnttab_setup.nr_frames = 1; + gnttab_setup.frame_list.p = &gntframe; + + grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1); +} + +#ifdef GRUB_MACHINE_XEN +static grub_uint8_t window[GRUB_XEN_PAGE_SIZE] + __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE))); + +#ifdef __x86_64__ +#define NUMBER_OF_LEVELS 4 +#else +#define NUMBER_OF_LEVELS 3 +#endif + +#define LOG_POINTERS_PER_PAGE 9 +#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE) + #define MAX_N_UNUSABLE_PAGES 4 static int @@ -357,26 +381,12 @@ map_all_pages (void) (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list; grub_uint64_t *pg = (grub_uint64_t *) window; grub_uint64_t oldpgstart, oldpgend; - struct gnttab_setup_table gnttab_setup; - struct gnttab_set_version gnttab_setver; grub_size_t n_unusable_pages = 0; struct mmu_update m2p_updates[2 * MAX_N_UNUSABLE_PAGES]; if (total_pages > MAX_TOTAL_PAGES - 4) total_pages = MAX_TOTAL_PAGES - 4; - grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver)); - - gnttab_setver.version = 1; - grub_xen_grant_table_op (GNTTABOP_set_version, &gnttab_setver, 1); - - grub_memset (&gnttab_setup, 0, sizeof (gnttab_setup)); - gnttab_setup.dom = DOMID_SELF; - gnttab_setup.nr_frames = 1; - gnttab_setup.frame_list.p = &gntframe; - - grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1); - for (j = 0; j < total_pages - n_unusable_pages; j++) while (!grub_xen_is_page_usable (mfn_list[j])) { @@ -524,20 +534,45 @@ map_all_pages (void) grub_mm_init_region ((void *) heap_start, heap_end - heap_start); } +grub_err_t +grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) +{ + grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages; + grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12; + if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data)) + return GRUB_ERR_NONE; + + hook (page2offset (usable_pages), page2offset (total_pages - usable_pages), + GRUB_MEMORY_RESERVED, hook_data); + + return GRUB_ERR_NONE; +} +#endif + extern char _end[]; void grub_machine_init (void) { +#ifdef GRUB_MACHINE_XEN #ifdef __i386__ grub_xen_vm_assist (VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3); +#endif #endif grub_modbase = ALIGN_UP ((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); +#ifdef GRUB_MACHINE_XEN_PVH + grub_xen_setup_pvh (); +#endif + + grub_xen_setup_gnttab (); + +#ifdef GRUB_MACHINE_XEN map_all_pages (); +#endif grub_console_init (); @@ -564,17 +599,3 @@ grub_machine_fini (int flags __attribute__ ((unused))) grub_xendisk_fini (); grub_boot_fini (); } - -grub_err_t -grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) -{ - grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages; - grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12; - if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data)) - return GRUB_ERR_NONE; - - hook (page2offset (usable_pages), page2offset (total_pages - usable_pages), - GRUB_MEMORY_RESERVED, hook_data); - - return GRUB_ERR_NONE; -} 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/cmdline.c b/grub-core/lib/cmdline.c index d5e10ee87..ed0b149dc 100644 --- a/grub-core/lib/cmdline.c +++ b/grub-core/lib/cmdline.c @@ -62,12 +62,13 @@ unsigned int grub_loader_cmdline_size (int argc, char *argv[]) return size; } -int grub_create_loader_cmdline (int argc, char *argv[], char *buf, - grub_size_t size) +grub_err_t +grub_create_loader_cmdline (int argc, char *argv[], char *buf, + grub_size_t size, enum grub_verify_string_type type) { int i, space; unsigned int arg_size; - char *c; + char *c, *orig_buf = buf; for (i = 0; i < argc; i++) { @@ -104,5 +105,5 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf, *buf = 0; - return i; + return grub_verify_string (orig_buf, type); } diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index 683a8aaa7..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,11 +458,11 @@ grub_password_get (char buf[], unsigned buf_size) while (1) { - key = grub_getkey (); + key = grub_getkey (); if (key == '\n' || key == '\r') break; - if (key == '\e') + if (key == GRUB_TERM_ESC) { cur_len = 0; break; @@ -487,7 +487,7 @@ grub_password_get (char buf[], unsigned buf_size) grub_xputs ("\n"); grub_refresh (); - return (key != '\e'); + return (key != GRUB_TERM_ESC); } #endif 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 0f186883a..123993dd4 100644 --- a/grub-core/lib/disk.c +++ b/grub-core/lib/disk.c @@ -101,8 +101,8 @@ 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->write) (disk, transform_sector (disk, sector), - 1, tmp_buf) != GRUB_ERR_NONE) + if ((disk->dev->disk_write) (disk, grub_disk_to_native_sector (disk, sector), + 1, tmp_buf) != GRUB_ERR_NONE) { grub_free (tmp_buf); goto finish; @@ -130,8 +130,8 @@ 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->write) (disk, transform_sector (disk, sector), - n, buf) != GRUB_ERR_NONE) + if ((disk->dev->disk_write) (disk, grub_disk_to_native_sector (disk, sector), + n, buf) != GRUB_ERR_NONE) goto finish; while (n--) diff --git a/grub-core/lib/uboot/datetime.c b/grub-core/lib/dummy/datetime.c similarity index 91% rename from grub-core/lib/uboot/datetime.c rename to grub-core/lib/dummy/datetime.c index 4be716928..cf693fc6b 100644 --- a/grub-core/lib/uboot/datetime.c +++ b/grub-core/lib/dummy/datetime.c @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -30,12 +29,12 @@ grub_err_t grub_get_datetime (struct grub_datetime *datetime __attribute__ ((unused))) { return grub_error (GRUB_ERR_INVALID_COMMAND, - "can\'t get datetime using U-Boot"); + "can\'t get datetime on this machine"); } grub_err_t grub_set_datetime (struct grub_datetime * datetime __attribute__ ((unused))) { return grub_error (GRUB_ERR_INVALID_COMMAND, - "can\'t set datetime using U-Boot"); + "can\'t set datetime on this machine"); } diff --git a/grub-core/lib/uboot/halt.c b/grub-core/lib/dummy/halt.c similarity index 100% rename from grub-core/lib/uboot/halt.c rename to grub-core/lib/dummy/halt.c diff --git a/grub-core/lib/efi/reboot.c b/grub-core/lib/dummy/reboot.c similarity index 77% rename from grub-core/lib/efi/reboot.c rename to grub-core/lib/dummy/reboot.c index 7de8bcb5d..b8cbed8f8 100644 --- a/grub-core/lib/efi/reboot.c +++ b/grub-core/lib/dummy/reboot.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2011 Free Software Foundation, Inc. + * 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 @@ -16,10 +16,8 @@ * along with GRUB. If not, see . */ -#include -#include -#include #include +#include #include #include @@ -27,7 +25,8 @@ 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); - for (;;) ; + + /* Just stop here */ + + while (1); } 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 e9441c844..a58a747e5 100644 --- a/grub-core/lib/efi/halt.c +++ b/grub-core/lib/efi/halt.c @@ -28,12 +28,14 @@ void grub_halt (void) { - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); -#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); +#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \ + !defined(__loongarch__) && !defined(__riscv) grub_acpi_halt (); #endif - 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 b5d520f20..73cfa94a2 100644 --- a/grub-core/lib/fdt.c +++ b/grub-core/lib/fdt.c @@ -41,11 +41,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); (2 * sizeof(grub_uint32_t) \ + ALIGN_UP (grub_strlen (name) + 1, sizeof(grub_uint32_t))) -/* Size needed by a property entry: 1 token (FDT_PROPERTY), plus len and nameoff - fields, plus the property value, plus padding if needed. */ -#define prop_entry_size(prop_len) \ - (3 * sizeof(grub_uint32_t) + ALIGN_UP(prop_len, sizeof(grub_uint32_t))) - #define SKIP_NODE_NAME(name, token, end) \ name = (char *) ((token) + 1); \ while (name < (char *) end) \ @@ -86,7 +81,7 @@ static grub_uint32_t *get_next_node (const void *fdt, char *node_name) case FDT_PROP: /* Skip property token and following data (len, nameoff and property value). */ - token += prop_entry_size(grub_be_to_cpu32(*(token + 1))) + token += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(token + 1))) / sizeof(*token); break; case FDT_NOP: @@ -102,13 +97,13 @@ static grub_uint32_t *get_next_node (const void *fdt, char *node_name) static int get_mem_rsvmap_size (const void *fdt) { int size = 0; - grub_uint64_t *ptr = (void *) ((grub_addr_t) fdt - + grub_fdt_get_off_mem_rsvmap (fdt)); + grub_unaligned_uint64_t *ptr = (void *) ((grub_addr_t) fdt + + grub_fdt_get_off_mem_rsvmap (fdt)); do { size += 2 * sizeof(*ptr); - if (!*ptr && !*(ptr + 1)) + if (!ptr[0].val && !ptr[1].val) return size; ptr += 2; } while ((grub_addr_t) ptr <= (grub_addr_t) fdt + grub_fdt_get_totalsize (fdt) @@ -150,7 +145,7 @@ static int add_subnode (void *fdt, int parentoffset, const char *name) { case FDT_PROP: /* Skip len, nameoff and property value. */ - token += prop_entry_size(grub_be_to_cpu32(*(token + 1))) + token += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(token + 1))) / sizeof(*token); break; case FDT_BEGIN_NODE: @@ -229,7 +224,7 @@ static int rearrange_blocks (void *fdt, unsigned int clearance) return 0; } -static grub_uint32_t *find_prop (void *fdt, unsigned int nodeoffset, +static grub_uint32_t *find_prop (const void *fdt, unsigned int nodeoffset, const char *name) { grub_uint32_t *prop = (void *) ((grub_addr_t) fdt @@ -249,12 +244,12 @@ static grub_uint32_t *find_prop (void *fdt, unsigned int nodeoffset, && !grub_strcmp (name, (char *) fdt + grub_fdt_get_off_dt_strings (fdt) + nameoff)) { - if (prop + prop_entry_size(grub_be_to_cpu32(*(prop + 1))) + if (prop + grub_fdt_prop_entry_size(grub_be_to_cpu32(*(prop + 1))) / sizeof (*prop) >= end) return NULL; return prop; } - prop += prop_entry_size(grub_be_to_cpu32(*(prop + 1))) / sizeof (*prop); + prop += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(prop + 1))) / sizeof (*prop); } else if (grub_be_to_cpu32(*prop) == FDT_NOP) prop++; @@ -268,9 +263,9 @@ static grub_uint32_t *find_prop (void *fdt, unsigned int nodeoffset, the size allocated for the FDT; if this function is called before the other functions in this file and returns success, the other functions are guaranteed not to access memory locations outside the allocated memory. */ -int grub_fdt_check_header_nosize (void *fdt) +int grub_fdt_check_header_nosize (const void *fdt) { - if (((grub_addr_t) fdt & 0x7) || (grub_fdt_get_magic (fdt) != FDT_MAGIC) + if (((grub_addr_t) fdt & 0x3) || (grub_fdt_get_magic (fdt) != FDT_MAGIC) || (grub_fdt_get_version (fdt) < FDT_SUPPORTED_VERSION) || (grub_fdt_get_last_comp_version (fdt) > FDT_SUPPORTED_VERSION) || (grub_fdt_get_off_dt_struct (fdt) & 0x00000003) @@ -286,7 +281,7 @@ int grub_fdt_check_header_nosize (void *fdt) return 0; } -int grub_fdt_check_header (void *fdt, unsigned int size) +int grub_fdt_check_header (const void *fdt, unsigned int size) { if (size < sizeof (grub_fdt_header_t) || (grub_fdt_get_totalsize (fdt) > size) @@ -295,52 +290,105 @@ int grub_fdt_check_header (void *fdt, unsigned int size) return 0; } -/* Find a direct sub-node of a given parent node. */ -int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset, - const char *name) +static const grub_uint32_t * +advance_token (const void *fdt, const grub_uint32_t *token, const grub_uint32_t *end, int skip_current) { - grub_uint32_t *token, *end; - char *node_name; - - if (parentoffset & 0x3) - return -1; - token = (void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt) - + parentoffset); - end = (void *) struct_end (fdt); - if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE)) - return -1; - SKIP_NODE_NAME(node_name, token, end); - while (token < end) + for (; token < end; skip_current = 0) { - switch (grub_be_to_cpu32(*token)) + switch (grub_be_to_cpu32 (*token)) { case FDT_BEGIN_NODE: - node_name = (char *) (token + 1); - if (node_name + grub_strlen (name) >= (char *) end) - return -1; - if (!grub_strcmp (node_name, name)) - return (int) ((grub_addr_t) token - (grub_addr_t) fdt - - grub_fdt_get_off_dt_struct (fdt)); - token = get_next_node (fdt, node_name); - if (!token) - return -1; - break; + if (skip_current) + { + token = get_next_node (fdt, (char *) (token + 1)); + continue; + } + char *ptr; + for (ptr = (char *) (token + 1); *ptr && ptr < (char *) end; ptr++) + ; + if (ptr >= (char *) end) + return 0; + return token; case FDT_PROP: /* Skip property token and following data (len, nameoff and property value). */ if (token >= end - 1) - return -1; - token += prop_entry_size(grub_be_to_cpu32(*(token + 1))) + return 0; + token += grub_fdt_prop_entry_size(grub_be_to_cpu32(*(token + 1))) / sizeof(*token); break; case FDT_NOP: token++; break; default: - return -1; + return 0; } } - return -1; + return 0; +} + +int grub_fdt_next_node (const void *fdt, unsigned int currentoffset) +{ + const grub_uint32_t *token = (const grub_uint32_t *) fdt + (currentoffset + grub_fdt_get_off_dt_struct (fdt)) / 4; + token = advance_token (fdt, token, (const void *) struct_end (fdt), 1); + if (!token) + return -1; + return (int) ((grub_addr_t) token - (grub_addr_t) fdt + - grub_fdt_get_off_dt_struct (fdt)); +} + +int grub_fdt_first_node (const void *fdt, unsigned int parentoffset) +{ + const grub_uint32_t *token, *end; + char *node_name; + + if (parentoffset & 0x3) + return -1; + token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt) + + parentoffset); + end = (const void *) struct_end (fdt); + if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE)) + return -1; + SKIP_NODE_NAME(node_name, token, end); + token = advance_token (fdt, token, end, 0); + if (!token) + return -1; + return (int) ((grub_addr_t) token - (grub_addr_t) fdt + - grub_fdt_get_off_dt_struct (fdt)); +} + +/* Find a direct sub-node of a given parent node. */ +int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset, + const char *name) +{ + const grub_uint32_t *token, *end; + const char *node_name; + int skip_current = 0; + + if (parentoffset & 0x3) + return -1; + token = (const void *) ((grub_addr_t) fdt + grub_fdt_get_off_dt_struct(fdt) + + parentoffset); + end = (const void *) struct_end (fdt); + if ((token >= end) || (grub_be_to_cpu32(*token) != FDT_BEGIN_NODE)) + return -1; + SKIP_NODE_NAME(node_name, token, end); + while (1) { + token = advance_token (fdt, token, end, skip_current); + if (!token) + return -1; + skip_current = 1; + node_name = (const char *) token + 4; + if (grub_strcmp (node_name, name) == 0) + return (int) ((grub_addr_t) token - (grub_addr_t) fdt + - grub_fdt_get_off_dt_struct (fdt)); + } +} + +const char * +grub_fdt_get_nodename (const void *fdt, unsigned int nodeoffset) +{ + return (const char *) fdt + grub_fdt_get_off_dt_struct(fdt) + nodeoffset + 4; } int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset, @@ -359,6 +407,24 @@ int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset, return add_subnode (fdt, parentoffset, name); } +const void * +grub_fdt_get_prop (const void *fdt, unsigned int nodeoffset, const char *name, + grub_uint32_t *len) +{ + grub_uint32_t *prop; + if ((nodeoffset >= grub_fdt_get_size_dt_struct (fdt)) || (nodeoffset & 0x3) + || (grub_be_to_cpu32(*(grub_uint32_t *) ((grub_addr_t) fdt + + grub_fdt_get_off_dt_struct (fdt) + nodeoffset)) + != FDT_BEGIN_NODE)) + return 0; + prop = find_prop (fdt, nodeoffset, name); + if (!prop) + return 0; + if (len) + *len = grub_be_to_cpu32 (*(prop + 1)); + return prop + 3; +} + int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, const void *val, grub_uint32_t len) { @@ -396,12 +462,12 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, unsigned int needed_space = 0; if (!prop) - needed_space = prop_entry_size(len); + needed_space = grub_fdt_prop_entry_size(len); if (!prop_name_present) needed_space += grub_strlen (name) + 1; if (needed_space > get_free_space (fdt)) return -1; - if (rearrange_blocks (fdt, !prop ? prop_entry_size(len) : 0) < 0) + if (rearrange_blocks (fdt, !prop ? grub_fdt_prop_entry_size(len) : 0) < 0) return -1; } if (!prop_name_present) { @@ -418,10 +484,10 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, + sizeof(grub_uint32_t)); prop = (void *) (node_name + ALIGN_UP(grub_strlen(node_name) + 1, 4)); - grub_memmove (prop + prop_entry_size(len) / sizeof(*prop), prop, + grub_memmove (prop + grub_fdt_prop_entry_size(len) / sizeof(*prop), prop, struct_end(fdt) - (grub_addr_t) prop); grub_fdt_set_size_dt_struct (fdt, grub_fdt_get_size_dt_struct (fdt) - + prop_entry_size(len)); + + grub_fdt_prop_entry_size(len)); *prop = grub_cpu_to_be32_compile_time (FDT_PROP); *(prop + 2) = grub_cpu_to_be32 (nameoff); } @@ -429,7 +495,7 @@ int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, /* Insert padding bytes at the end of the value; if they are not needed, they will be overwritten by the following memcpy. */ - *(prop + prop_entry_size(len) / sizeof(grub_uint32_t) - 1) = 0; + *(prop + grub_fdt_prop_entry_size(len) / sizeof(grub_uint32_t) - 1) = 0; grub_memcpy (prop + 3, val, len); return 0; diff --git a/grub-core/gnulib-fix-width.diff b/grub-core/lib/gnulib-patches/fix-width.patch similarity index 75% rename from grub-core/gnulib-fix-width.diff rename to grub-core/lib/gnulib-patches/fix-width.patch index ae77af6c9..15f091c0d 100644 --- a/grub-core/gnulib-fix-width.diff +++ b/grub-core/lib/gnulib-patches/fix-width.patch @@ -1,8 +1,8 @@ diff --git a/lib/argp-fmtstream.c b/lib/argp-fmtstream.c -index 7aa317c..02406ff 100644 +index ba6a407f7..d0685b3d4 100644 --- a/lib/argp-fmtstream.c +++ b/lib/argp-fmtstream.c -@@ -29,9 +29,11 @@ +@@ -28,9 +28,11 @@ #include #include #include @@ -14,7 +14,7 @@ index 7aa317c..02406ff 100644 #ifndef ARGP_FMTSTREAM_USE_LINEWRAP -@@ -116,6 +118,51 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free) +@@ -115,6 +117,51 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free) #endif #endif @@ -66,12 +66,12 @@ index 7aa317c..02406ff 100644 /* Process FS's buffer so that line wrapping is done from POINT_OFFS to the end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ void -@@ -168,14 +215,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs) - +@@ -168,13 +215,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs) if (!nl) { -+ size_t display_width = mbsnwidth (buf, fs->p - buf, MBSW_STOP_AT_NUL); /* The buffer ends in a partial line. */ ++ size_t display_width = mbsnwidth (buf, fs->p - buf, ++ MBSW_STOP_AT_NUL); - if (fs->point_col + len < fs->rmargin) + if (fs->point_col + display_width < fs->rmargin) @@ -84,7 +84,7 @@ index 7aa317c..02406ff 100644 break; } else -@@ -183,14 +231,18 @@ __argp_fmtstream_update (argp_fmtstream_t fs) +@@ -182,14 +231,18 @@ __argp_fmtstream_update (argp_fmtstream_t fs) the end of the buffer. */ nl = fs->p; } @@ -111,16 +111,16 @@ index 7aa317c..02406ff 100644 /* This line is too long. */ r = fs->rmargin - 1; -@@ -226,7 +278,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) +@@ -225,7 +278,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) char *p, *nextline; int i; - p = buf + (r + 1 - fs->point_col); -+ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); ++ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); while (p >= buf && !isblank ((unsigned char) *p)) --p; nextline = p + 1; /* This will begin the next line. */ -@@ -244,7 +296,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) +@@ -243,7 +296,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) { /* A single word that is greater than the maximum line width. Oh well. Put it on an overlong line by itself. */ @@ -129,21 +129,21 @@ index 7aa317c..02406ff 100644 /* Find the end of the long word. */ if (p < nl) do -@@ -278,7 +330,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs) +@@ -277,7 +330,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs) && fs->p > nextline) { /* The margin needs more blanks than we removed. */ - if (fs->end - fs->p > fs->wmargin + 1) + if (mbsnwidth (fs->p, fs->end - fs->p, MBSW_STOP_AT_NUL) -+ > fs->wmargin + 1) ++ > fs->wmargin + 1) /* Make some space for them. */ { size_t mv = fs->p - nextline; diff --git a/lib/argp-help.c b/lib/argp-help.c -index 354f1e2..2914f47 100644 +index e5375a0f0..5d8f451ec 100644 --- a/lib/argp-help.c +++ b/lib/argp-help.c -@@ -50,6 +50,7 @@ +@@ -52,6 +52,7 @@ #include "argp.h" #include "argp-fmtstream.h" #include "argp-namefrob.h" @@ -151,7 +151,7 @@ index 354f1e2..2914f47 100644 #ifndef SIZE_MAX # define SIZE_MAX ((size_t) -1) -@@ -1452,7 +1453,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. */ @@ -161,71 +161,57 @@ index 354f1e2..2914f47 100644 __argp_fmtstream_write (stream, cp, nl - cp); } diff --git a/lib/mbswidth.c b/lib/mbswidth.c -index 7c2dfce..baa4f27 100644 +index 408a15e34..b3fb7f83a 100644 --- a/lib/mbswidth.c +++ b/lib/mbswidth.c -@@ -90,6 +90,9 @@ mbsnwidth (const char *string, size_t nbytes, int flags) +@@ -38,6 +38,14 @@ + /* Get INT_MAX. */ + #include + ++#ifndef FALLTHROUGH ++# if __GNUC__ < 7 ++# define FALLTHROUGH ((void) 0) ++# else ++# define FALLTHROUGH __attribute__ ((__fallthrough__)) ++# endif ++#endif ++ + /* Returns the number of columns needed to represent the multibyte + character string pointed to by STRING. If a non-printable character + occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. +@@ -90,6 +98,10 @@ mbsnwidth (const char *string, size_t nbytes, int flags) p++; width++; break; -+ case '\0': -+ if (flags & MBSW_STOP_AT_NUL) -+ return width; ++ case '\0': ++ if (flags & MBSW_STOP_AT_NUL) ++ return width; ++ FALLTHROUGH; default: /* If we have a multibyte sequence, scan it up to its end. */ { -@@ -168,6 +171,9 @@ mbsnwidth (const char *string, size_t nbytes, int flags) +@@ -168,6 +180,9 @@ mbsnwidth (const char *string, size_t nbytes, int flags) { unsigned char c = (unsigned char) *p++; + if (c == 0 && (flags & MBSW_STOP_AT_NUL)) -+ return width; ++ return width; + if (isprint (c)) { if (width == INT_MAX) diff --git a/lib/mbswidth.h b/lib/mbswidth.h -index e9c0b03..d7207c5 100644 +index 2b5c53c37..45a123e63 100644 --- a/lib/mbswidth.h +++ b/lib/mbswidth.h -@@ -45,6 +45,9 @@ extern "C" { +@@ -40,6 +40,10 @@ extern "C" { control characters and 1 otherwise. */ #define MBSW_REJECT_UNPRINTABLE 2 +/* If this bit is set \0 is treated as the end of string. + Otherwise it's treated as a normal one column width character. */ +#define MBSW_STOP_AT_NUL 4 ++ /* Returns the number of screen columns needed for STRING. */ #define mbswidth gnu_mbswidth /* avoid clash with UnixWare 7.1.1 function */ -diff --git a/modules/argp b/modules/argp -index 125046a..6f14d10 100644 ---- a/modules/argp -+++ b/modules/argp -@@ -40,6 +40,7 @@ stdalign - strerror - memchr - memmove -+mbswidth - - configure.ac: - gl_ARGP -diff --git a/modules/argp-tests b/modules/argp-tests -index 8f92a4d..0463927 100644 ---- a/modules/argp-tests -+++ b/modules/argp-tests -@@ -1,11 +1,13 @@ - Files: - tests/test-argp.c - tests/test-argp-2.sh -+tests/test-argp-2-utf.sh - - Depends-on: - progname - - Makefile.am: - TESTS += test-argp test-argp-2.sh --check_PROGRAMS += test-argp -+TESTS += test-argp test-argp-2.sh test-argp-2-utf.sh -+check_PROGRAMS += test-argp test-argp-utf8 - test_argp_LDADD = $(LDADD) @LIBINTL@ diff --git a/grub-core/lib/i386/halt.c b/grub-core/lib/i386/halt.c index 9f8405494..2364fe4d7 100644 --- a/grub-core/lib/i386/halt.c +++ b/grub-core/lib/i386/halt.c @@ -66,7 +66,7 @@ grub_halt (void) #endif /* Disable interrupts. */ - __asm__ __volatile__ ("cli"); + asm volatile ("cli"); /* Bochs, QEMU, etc. Removed in newer QEMU releases. */ for (i = 0; i < sizeof (bochs_shutdown) - 1; i++) diff --git a/grub-core/lib/i386/reboot.c b/grub-core/lib/i386/reboot.c index a234244dc..d0fd6a50e 100644 --- a/grub-core/lib/i386/reboot.c +++ b/grub-core/lib/i386/reboot.c @@ -16,6 +16,8 @@ * along with GRUB. If not, see . */ +#ifndef GRUB_MACHINE_EFI + #include #include #include @@ -53,8 +55,10 @@ grub_reboot (void) state.a20 = 0; grub_stop_floppy (); - + err = grub_relocator16_boot (relocator, state); while (1); } + +#endif /* GRUB_MACHINE_EFI */ diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c 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 c8d6f86d8..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)) @@ -204,8 +210,9 @@ LOCAL(gate_a20_check_state): ret LOCAL(gate_a20_done): - /* we are in real mode now - * set up the real mode segment registers : DS, SS, ES + /* + * We are in real mode now. Set up the real mode segment registers and + * all the other general purpose registers. cs is updated with ljmp. */ /* movw imm16, %ax. */ .byte 0xb8 @@ -298,7 +305,7 @@ LOCAL(gdt): .byte 0, 0x92, 0xCF, 0 /* -- 16 bit real mode CS -- - * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present + * base = filled by code, limit 0x0FFFF (1 B Granularity), present * type = 16 bit code execute/read only/conforming, DPL = 0 */ .word 0xFFFF @@ -310,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/bufhelp.h b/grub-core/lib/libgcrypt/cipher/bufhelp.h new file mode 100644 index 000000000..df3559472 --- /dev/null +++ b/grub-core/lib/libgcrypt/cipher/bufhelp.h @@ -0,0 +1,432 @@ +/* bufhelp.h - Some buffer manipulation helpers + * Copyright (C) 2012 Jussi Kivilinna + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ +#ifndef GCRYPT_BUFHELP_H +#define GCRYPT_BUFHELP_H + + +#include "bithelp.h" + + +#undef BUFHELP_FAST_UNALIGNED_ACCESS +#if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \ + defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \ + (defined(__i386__) || defined(__x86_64__) || \ + (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \ + defined(__aarch64__)) +/* These architectures are able of unaligned memory accesses and can + handle those fast. + */ +# define BUFHELP_FAST_UNALIGNED_ACCESS 1 +#endif + + +#ifdef BUFHELP_FAST_UNALIGNED_ACCESS +/* Define type with one-byte alignment on architectures with fast unaligned + memory accesses. + */ +typedef struct bufhelp_int_s +{ + uintptr_t a; +} __attribute__((packed, aligned(1))) bufhelp_int_t; +#else +/* Define type with default alignment for other architectures (unaligned + accessed handled in per byte loops). + */ +typedef struct bufhelp_int_s +{ + uintptr_t a; +} bufhelp_int_t; +#endif + + +/* Optimized function for small buffer copying */ +static inline void +buf_cpy(void *_dst, const void *_src, size_t len) +{ +#if __GNUC__ >= 4 && (defined(__x86_64__) || defined(__i386__)) + /* For AMD64 and i386, memcpy is faster. */ + memcpy(_dst, _src, len); +#else + byte *dst = _dst; + const byte *src = _src; + bufhelp_int_t *ldst; + const bufhelp_int_t *lsrc; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; + + /* Skip fast processing if buffers are unaligned. */ + if (((uintptr_t)dst | (uintptr_t)src) & longmask) + goto do_bytes; +#endif + + ldst = (bufhelp_int_t *)(void *)dst; + lsrc = (const bufhelp_int_t *)(const void *)src; + + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst++)->a = (lsrc++)->a; + + dst = (byte *)ldst; + src = (const byte *)lsrc; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + *dst++ = *src++; +#endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/ +} + + +/* Optimized function for buffer xoring */ +static inline void +buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len) +{ + byte *dst = _dst; + const byte *src1 = _src1; + const byte *src2 = _src2; + bufhelp_int_t *ldst; + const bufhelp_int_t *lsrc1, *lsrc2; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; + + /* Skip fast processing if buffers are unaligned. */ + if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask) + goto do_bytes; +#endif + + ldst = (bufhelp_int_t *)(void *)dst; + lsrc1 = (const bufhelp_int_t *)(const void *)src1; + lsrc2 = (const bufhelp_int_t *)(const void *)src2; + + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst++)->a = (lsrc1++)->a ^ (lsrc2++)->a; + + dst = (byte *)ldst; + src1 = (const byte *)lsrc1; + src2 = (const byte *)lsrc2; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + *dst++ = *src1++ ^ *src2++; +} + + +/* Optimized function for in-place buffer xoring. */ +static inline void +buf_xor_1(void *_dst, const void *_src, size_t len) +{ + byte *dst = _dst; + const byte *src = _src; + bufhelp_int_t *ldst; + const bufhelp_int_t *lsrc; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; + + /* Skip fast processing if buffers are unaligned. */ + if (((uintptr_t)dst | (uintptr_t)src) & longmask) + goto do_bytes; +#endif + + ldst = (bufhelp_int_t *)(void *)dst; + lsrc = (const bufhelp_int_t *)(const void *)src; + + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst++)->a ^= (lsrc++)->a; + + dst = (byte *)ldst; + src = (const byte *)lsrc; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + *dst++ ^= *src++; +} + + +/* Optimized function for buffer xoring with two destination buffers. Used + mainly by CFB mode encryption. */ +static inline void +buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len) +{ + byte *dst1 = _dst1; + byte *dst2 = _dst2; + const byte *src = _src; + bufhelp_int_t *ldst1, *ldst2; + const bufhelp_int_t *lsrc; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; + + /* Skip fast processing if buffers are unaligned. */ + if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask) + goto do_bytes; +#endif + + ldst1 = (bufhelp_int_t *)(void *)dst1; + ldst2 = (bufhelp_int_t *)(void *)dst2; + lsrc = (const bufhelp_int_t *)(const void *)src; + + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + (ldst1++)->a = ((ldst2++)->a ^= (lsrc++)->a); + + dst1 = (byte *)ldst1; + dst2 = (byte *)ldst2; + src = (const byte *)lsrc; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + *dst1++ = (*dst2++ ^= *src++); +} + + +/* Optimized function for combined buffer xoring and copying. Used by mainly + CBC mode decryption. */ +static inline void +buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy, + const void *_src_cpy, size_t len) +{ + byte *dst_xor = _dst_xor; + byte *srcdst_cpy = _srcdst_cpy; + const byte *src_xor = _src_xor; + const byte *src_cpy = _src_cpy; + byte temp; + bufhelp_int_t *ldst_xor, *lsrcdst_cpy; + const bufhelp_int_t *lsrc_cpy, *lsrc_xor; + uintptr_t ltemp; +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + const unsigned int longmask = sizeof(bufhelp_int_t) - 1; + + /* Skip fast processing if buffers are unaligned. */ + if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor | + (uintptr_t)srcdst_cpy) & longmask) + goto do_bytes; +#endif + + ldst_xor = (bufhelp_int_t *)(void *)dst_xor; + lsrc_xor = (const bufhelp_int_t *)(void *)src_xor; + lsrcdst_cpy = (bufhelp_int_t *)(void *)srcdst_cpy; + lsrc_cpy = (const bufhelp_int_t *)(const void *)src_cpy; + + for (; len >= sizeof(bufhelp_int_t); len -= sizeof(bufhelp_int_t)) + { + ltemp = (lsrc_cpy++)->a; + (ldst_xor++)->a = (lsrcdst_cpy)->a ^ (lsrc_xor++)->a; + (lsrcdst_cpy++)->a = ltemp; + } + + dst_xor = (byte *)ldst_xor; + src_xor = (const byte *)lsrc_xor; + srcdst_cpy = (byte *)lsrcdst_cpy; + src_cpy = (const byte *)lsrc_cpy; + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS +do_bytes: +#endif + /* Handle tail. */ + for (; len; len--) + { + temp = *src_cpy++; + *dst_xor++ = *srcdst_cpy ^ *src_xor++; + *srcdst_cpy++ = temp; + } +} + + +/* Optimized function for combined buffer xoring and copying. Used by mainly + CFB mode decryption. */ +static inline void +buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len) +{ + buf_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, len); +} + + +/* Constant-time compare of two buffers. Returns 1 if buffers are equal, + and 0 if buffers differ. */ +static inline int +buf_eq_const(const void *_a, const void *_b, size_t len) +{ + const byte *a = _a; + const byte *b = _b; + size_t diff, i; + + /* Constant-time compare. */ + for (i = 0, diff = 0; i < len; i++) + diff -= !!(a[i] - b[i]); + + return !diff; +} + + +#ifndef BUFHELP_FAST_UNALIGNED_ACCESS + +/* Functions for loading and storing unaligned u32 values of different + endianness. */ +static inline u32 buf_get_be32(const void *_buf) +{ + const byte *in = _buf; + return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \ + ((u32)in[2] << 8) | (u32)in[3]; +} + +static inline u32 buf_get_le32(const void *_buf) +{ + const byte *in = _buf; + return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \ + ((u32)in[1] << 8) | (u32)in[0]; +} + +static inline void buf_put_be32(void *_buf, u32 val) +{ + byte *out = _buf; + out[0] = val >> 24; + out[1] = val >> 16; + out[2] = val >> 8; + out[3] = val; +} + +static inline void buf_put_le32(void *_buf, u32 val) +{ + byte *out = _buf; + out[3] = val >> 24; + out[2] = val >> 16; + out[1] = val >> 8; + out[0] = val; +} + + +/* Functions for loading and storing unaligned u64 values of different + endianness. */ +static inline u64 buf_get_be64(const void *_buf) +{ + const byte *in = _buf; + return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \ + ((u64)in[2] << 40) | ((u64)in[3] << 32) | \ + ((u64)in[4] << 24) | ((u64)in[5] << 16) | \ + ((u64)in[6] << 8) | (u64)in[7]; +} + +static inline u64 buf_get_le64(const void *_buf) +{ + const byte *in = _buf; + return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \ + ((u64)in[5] << 40) | ((u64)in[4] << 32) | \ + ((u64)in[3] << 24) | ((u64)in[2] << 16) | \ + ((u64)in[1] << 8) | (u64)in[0]; +} + +static inline void buf_put_be64(void *_buf, u64 val) +{ + byte *out = _buf; + out[0] = val >> 56; + out[1] = val >> 48; + out[2] = val >> 40; + out[3] = val >> 32; + out[4] = val >> 24; + out[5] = val >> 16; + out[6] = val >> 8; + out[7] = val; +} + +static inline void buf_put_le64(void *_buf, u64 val) +{ + byte *out = _buf; + out[7] = val >> 56; + out[6] = val >> 48; + out[5] = val >> 40; + out[4] = val >> 32; + out[3] = val >> 24; + out[2] = val >> 16; + out[1] = val >> 8; + out[0] = val; +} + +#else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ + +typedef struct bufhelp_u32_s +{ + u32 a; +} __attribute__((packed, aligned(1))) bufhelp_u32_t; + +/* Functions for loading and storing unaligned u32 values of different + endianness. */ +static inline u32 buf_get_be32(const void *_buf) +{ + return be_bswap32(((const bufhelp_u32_t *)_buf)->a); +} + +static inline u32 buf_get_le32(const void *_buf) +{ + return le_bswap32(((const bufhelp_u32_t *)_buf)->a); +} + +static inline void buf_put_be32(void *_buf, u32 val) +{ + bufhelp_u32_t *out = _buf; + out->a = be_bswap32(val); +} + +static inline void buf_put_le32(void *_buf, u32 val) +{ + bufhelp_u32_t *out = _buf; + out->a = le_bswap32(val); +} + + +typedef struct bufhelp_u64_s +{ + u64 a; +} __attribute__((packed, aligned(1))) bufhelp_u64_t; + +/* Functions for loading and storing unaligned u64 values of different + endianness. */ +static inline u64 buf_get_be64(const void *_buf) +{ + return be_bswap64(((const bufhelp_u64_t *)_buf)->a); +} + +static inline u64 buf_get_le64(const void *_buf) +{ + return le_bswap64(((const bufhelp_u64_t *)_buf)->a); +} + +static inline void buf_put_be64(void *_buf, u64 val) +{ + bufhelp_u64_t *out = _buf; + out->a = be_bswap64(val); +} + +static inline void buf_put_le64(void *_buf, u64 val) +{ + bufhelp_u64_t *out = _buf; + out->a = le_bswap64(val); +} + + +#endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ + +#endif /*GCRYPT_BUFHELP_H*/ diff --git a/grub-core/lib/libgcrypt/cipher/crc.c b/grub-core/lib/libgcrypt/cipher/crc.c index 9e406f1b1..28454f8ab 100644 --- a/grub-core/lib/libgcrypt/cipher/crc.c +++ b/grub-core/lib/libgcrypt/cipher/crc.c @@ -28,116 +28,8 @@ #include "cipher.h" #include "bithelp.h" +#include "bufhelp.h" -/* Table of CRCs of all 8-bit messages. Generated by running code - from RFC 1952 modified to print out the table. */ -static u32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -/* - * The following function was extracted from RFC 1952 by Simon - * Josefsson, for the Shishi project, and modified to be compatible - * with the modified CRC-32 used by RFC 1510, and subsequently - * modified for GNU Libgcrypt to allow it to be used for calculating - * both unmodified CRC-32 and modified CRC-32 values. Original - * copyright and notice from the document follows: - * - * Copyright (c) 1996 L. Peter Deutsch - * - * Permission is granted to copy and distribute this document for - * any purpose and without charge, including translations into - * other languages and incorporation into compilations, provided - * that the copyright notice and this notice are preserved, and - * that any substantive changes or deletions from the original are - * clearly marked. - * - * The copyright on RFCs, and consequently the function below, are - * supposedly also retroactively claimed by the Internet Society - * (according to rfc-editor@rfc-editor.org), with the following - * copyright notice: - * - * Copyright (C) The Internet Society. All Rights Reserved. - * - * This document and translations of it may be copied and furnished - * to others, and derivative works that comment on or otherwise - * explain it or assist in its implementation may be prepared, - * copied, published and distributed, in whole or in part, without - * restriction of any kind, provided that the above copyright - * notice and this paragraph are included on all such copies and - * derivative works. However, this document itself may not be - * modified in any way, such as by removing the copyright notice or - * references to the Internet Society or other Internet - * organizations, except as needed for the purpose of developing - * Internet standards in which case the procedures for copyrights - * defined in the Internet Standards process must be followed, or - * as required to translate it into languages other than English. - * - * The limited permissions granted above are perpetual and will not be - * revoked by the Internet Society or its successors or assigns. - * - * This document and the information contained herein is provided - * on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET - * ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE - * OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A - * PARTICULAR PURPOSE. - * - */ -static u32 -update_crc32 (u32 crc, const void *buf_arg, size_t len) -{ - const char *buf = buf_arg; - size_t n; - - for (n = 0; n < len; n++) - crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8); - - return crc; -} typedef struct { @@ -146,8 +38,302 @@ typedef struct } CRC_CONTEXT; + +/* + * Code generated by universal_crc by Danjel McGougan + * + * CRC parameters used: + * bits: 32 + * poly: 0x04c11db7 + * init: 0xffffffff + * xor: 0xffffffff + * reverse: true + * non-direct: false + * + * CRC of the string "123456789" is 0xcbf43926 + */ + +static const u32 crc32_table[1024] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + 0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, + 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7, + 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, + 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf, + 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, + 0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, + 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e, + 0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, + 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, + 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d, + 0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, + 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034, + 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, + 0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, + 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, + 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, + 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, + 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93, + 0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, + 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b, + 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, + 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, + 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768, + 0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, + 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, + 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539, + 0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, + 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, + 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, + 0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, + 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd, + 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, + 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, + 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, + 0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, + 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026, + 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, + 0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, + 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277, + 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, + 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, + 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81, + 0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, + 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, + 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, + 0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, + 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b, + 0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, + 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, + 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a, + 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, + 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72, + 0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, + 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685, + 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, + 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d, + 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, + 0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, + 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d, + 0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, + 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, + 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd, + 0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, + 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315, + 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, + 0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, + 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, + 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, + 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, + 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835, + 0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, + 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d, + 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, + 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, + 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d, + 0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, + 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, + 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, + 0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, + 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05, + 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, + 0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, + 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75, + 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, + 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, + 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, + 0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, + 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d, + 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, + 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, + 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d, + 0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, + 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, + 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d, + 0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, + 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, + 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, + 0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, + 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625, + 0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, + 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, + 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555, + 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, + 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed, + 0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, + 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9, + 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, + 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056, + 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, + 0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, + 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9, + 0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, + 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, + 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68, + 0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, + 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018, + 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, + 0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, + 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, + 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, + 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, + 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b, + 0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, + 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4, + 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, + 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, + 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755, + 0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, + 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, + 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca, + 0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, + 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82, + 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, + 0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, + 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d, + 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, + 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, + 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, + 0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, + 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953, + 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, + 0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, + 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc, + 0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, + 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, + 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50, + 0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, + 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, + 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, + 0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, + 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, + 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, + 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, + 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, + 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, + 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1 +}; + /* CRC32 */ +static inline u32 +crc32_next (u32 crc, byte data) +{ + return (crc >> 8) ^ crc32_table[(crc & 0xff) ^ data]; +} + +/* + * Process 4 bytes in one go + */ +static inline u32 +crc32_next4 (u32 crc, u32 data) +{ + crc ^= data; + crc = crc32_table[(crc & 0xff) + 0x300] ^ + crc32_table[((crc >> 8) & 0xff) + 0x200] ^ + crc32_table[((crc >> 16) & 0xff) + 0x100] ^ + crc32_table[(crc >> 24) & 0xff]; + return crc; +} + static void crc32_init (void *context) { @@ -156,12 +342,40 @@ crc32_init (void *context) } static void -crc32_write (void *context, const void *inbuf, size_t inlen) +crc32_write (void *context, const void *inbuf_arg, size_t inlen) { CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; - if (!inbuf) + const byte *inbuf = inbuf_arg; + u32 crc; + + if (!inbuf || !inlen) return; - ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen); + + crc = ctx->CRC; + + while (inlen >= 16) + { + inlen -= 16; + crc = crc32_next4(crc, buf_get_le32(&inbuf[0])); + crc = crc32_next4(crc, buf_get_le32(&inbuf[4])); + crc = crc32_next4(crc, buf_get_le32(&inbuf[8])); + crc = crc32_next4(crc, buf_get_le32(&inbuf[12])); + inbuf += 16; + } + + while (inlen >= 4) + { + inlen -= 4; + crc = crc32_next4(crc, buf_get_le32(inbuf)); + inbuf += 4; + } + + while (inlen--) + { + crc = crc32_next(crc, *inbuf++); + } + + ctx->CRC = crc; } static byte * @@ -176,13 +390,12 @@ crc32_final (void *context) { CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; ctx->CRC ^= 0xffffffffL; - ctx->buf[0] = (ctx->CRC >> 24) & 0xFF; - ctx->buf[1] = (ctx->CRC >> 16) & 0xFF; - ctx->buf[2] = (ctx->CRC >> 8) & 0xFF; - ctx->buf[3] = (ctx->CRC ) & 0xFF; + buf_put_be32 (ctx->buf, ctx->CRC); } /* CRC32 a'la RFC 1510 */ +/* CRC of the string "123456789" is 0x2dfd2d88 */ + static void crc32rfc1510_init (void *context) { @@ -194,82 +407,366 @@ static void crc32rfc1510_final (void *context) { CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; - ctx->buf[0] = (ctx->CRC >> 24) & 0xFF; - ctx->buf[1] = (ctx->CRC >> 16) & 0xFF; - ctx->buf[2] = (ctx->CRC >> 8) & 0xFF; - ctx->buf[3] = (ctx->CRC ) & 0xFF; + buf_put_be32(ctx->buf, ctx->CRC); } /* CRC24 a'la RFC 2440 */ /* - * The following CRC 24 routines are adapted from RFC 2440, which has - * the following copyright notice: + * Code generated by universal_crc by Danjel McGougan * - * Copyright (C) The Internet Society (1998). All Rights Reserved. + * CRC parameters used: + * bits: 24 + * poly: 0x864cfb + * init: 0xb704ce + * xor: 0x000000 + * reverse: false + * non-direct: false * - * This document and translations of it may be copied and furnished - * to others, and derivative works that comment on or otherwise - * explain it or assist in its implementation may be prepared, - * copied, published and distributed, in whole or in part, without - * restriction of any kind, provided that the above copyright notice - * and this paragraph are included on all such copies and derivative - * works. However, this document itself may not be modified in any - * way, such as by removing the copyright notice or references to - * the Internet Society or other Internet organizations, except as - * needed for the purpose of developing Internet standards in which - * case the procedures for copyrights defined in the Internet - * Standards process must be followed, or as required to translate - * it into languages other than English. - * - * The limited permissions granted above are perpetual and will not be - * revoked by the Internet Society or its successors or assigns. - * - * This document and the information contained herein is provided on - * an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET - * ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE - * OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY - * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR - * PURPOSE. + * CRC of the string "123456789" is 0x21cf02 */ -#define CRC24_INIT 0xb704ceL -#define CRC24_POLY 0x1864cfbL +static const u32 crc24_table[1024] = +{ + 0x00000000, 0x00fb4c86, 0x000dd58a, 0x00f6990c, + 0x00e1e693, 0x001aaa15, 0x00ec3319, 0x00177f9f, + 0x003981a1, 0x00c2cd27, 0x0034542b, 0x00cf18ad, + 0x00d86732, 0x00232bb4, 0x00d5b2b8, 0x002efe3e, + 0x00894ec5, 0x00720243, 0x00849b4f, 0x007fd7c9, + 0x0068a856, 0x0093e4d0, 0x00657ddc, 0x009e315a, + 0x00b0cf64, 0x004b83e2, 0x00bd1aee, 0x00465668, + 0x005129f7, 0x00aa6571, 0x005cfc7d, 0x00a7b0fb, + 0x00e9d10c, 0x00129d8a, 0x00e40486, 0x001f4800, + 0x0008379f, 0x00f37b19, 0x0005e215, 0x00feae93, + 0x00d050ad, 0x002b1c2b, 0x00dd8527, 0x0026c9a1, + 0x0031b63e, 0x00cafab8, 0x003c63b4, 0x00c72f32, + 0x00609fc9, 0x009bd34f, 0x006d4a43, 0x009606c5, + 0x0081795a, 0x007a35dc, 0x008cacd0, 0x0077e056, + 0x00591e68, 0x00a252ee, 0x0054cbe2, 0x00af8764, + 0x00b8f8fb, 0x0043b47d, 0x00b52d71, 0x004e61f7, + 0x00d2a319, 0x0029ef9f, 0x00df7693, 0x00243a15, + 0x0033458a, 0x00c8090c, 0x003e9000, 0x00c5dc86, + 0x00eb22b8, 0x00106e3e, 0x00e6f732, 0x001dbbb4, + 0x000ac42b, 0x00f188ad, 0x000711a1, 0x00fc5d27, + 0x005beddc, 0x00a0a15a, 0x00563856, 0x00ad74d0, + 0x00ba0b4f, 0x004147c9, 0x00b7dec5, 0x004c9243, + 0x00626c7d, 0x009920fb, 0x006fb9f7, 0x0094f571, + 0x00838aee, 0x0078c668, 0x008e5f64, 0x007513e2, + 0x003b7215, 0x00c03e93, 0x0036a79f, 0x00cdeb19, + 0x00da9486, 0x0021d800, 0x00d7410c, 0x002c0d8a, + 0x0002f3b4, 0x00f9bf32, 0x000f263e, 0x00f46ab8, + 0x00e31527, 0x001859a1, 0x00eec0ad, 0x00158c2b, + 0x00b23cd0, 0x00497056, 0x00bfe95a, 0x0044a5dc, + 0x0053da43, 0x00a896c5, 0x005e0fc9, 0x00a5434f, + 0x008bbd71, 0x0070f1f7, 0x008668fb, 0x007d247d, + 0x006a5be2, 0x00911764, 0x00678e68, 0x009cc2ee, + 0x00a44733, 0x005f0bb5, 0x00a992b9, 0x0052de3f, + 0x0045a1a0, 0x00beed26, 0x0048742a, 0x00b338ac, + 0x009dc692, 0x00668a14, 0x00901318, 0x006b5f9e, + 0x007c2001, 0x00876c87, 0x0071f58b, 0x008ab90d, + 0x002d09f6, 0x00d64570, 0x0020dc7c, 0x00db90fa, + 0x00ccef65, 0x0037a3e3, 0x00c13aef, 0x003a7669, + 0x00148857, 0x00efc4d1, 0x00195ddd, 0x00e2115b, + 0x00f56ec4, 0x000e2242, 0x00f8bb4e, 0x0003f7c8, + 0x004d963f, 0x00b6dab9, 0x004043b5, 0x00bb0f33, + 0x00ac70ac, 0x00573c2a, 0x00a1a526, 0x005ae9a0, + 0x0074179e, 0x008f5b18, 0x0079c214, 0x00828e92, + 0x0095f10d, 0x006ebd8b, 0x00982487, 0x00636801, + 0x00c4d8fa, 0x003f947c, 0x00c90d70, 0x003241f6, + 0x00253e69, 0x00de72ef, 0x0028ebe3, 0x00d3a765, + 0x00fd595b, 0x000615dd, 0x00f08cd1, 0x000bc057, + 0x001cbfc8, 0x00e7f34e, 0x00116a42, 0x00ea26c4, + 0x0076e42a, 0x008da8ac, 0x007b31a0, 0x00807d26, + 0x009702b9, 0x006c4e3f, 0x009ad733, 0x00619bb5, + 0x004f658b, 0x00b4290d, 0x0042b001, 0x00b9fc87, + 0x00ae8318, 0x0055cf9e, 0x00a35692, 0x00581a14, + 0x00ffaaef, 0x0004e669, 0x00f27f65, 0x000933e3, + 0x001e4c7c, 0x00e500fa, 0x001399f6, 0x00e8d570, + 0x00c62b4e, 0x003d67c8, 0x00cbfec4, 0x0030b242, + 0x0027cddd, 0x00dc815b, 0x002a1857, 0x00d154d1, + 0x009f3526, 0x006479a0, 0x0092e0ac, 0x0069ac2a, + 0x007ed3b5, 0x00859f33, 0x0073063f, 0x00884ab9, + 0x00a6b487, 0x005df801, 0x00ab610d, 0x00502d8b, + 0x00475214, 0x00bc1e92, 0x004a879e, 0x00b1cb18, + 0x00167be3, 0x00ed3765, 0x001bae69, 0x00e0e2ef, + 0x00f79d70, 0x000cd1f6, 0x00fa48fa, 0x0001047c, + 0x002ffa42, 0x00d4b6c4, 0x00222fc8, 0x00d9634e, + 0x00ce1cd1, 0x00355057, 0x00c3c95b, 0x003885dd, + 0x00000000, 0x00488f66, 0x00901ecd, 0x00d891ab, + 0x00db711c, 0x0093fe7a, 0x004b6fd1, 0x0003e0b7, + 0x00b6e338, 0x00fe6c5e, 0x0026fdf5, 0x006e7293, + 0x006d9224, 0x00251d42, 0x00fd8ce9, 0x00b5038f, + 0x006cc771, 0x00244817, 0x00fcd9bc, 0x00b456da, + 0x00b7b66d, 0x00ff390b, 0x0027a8a0, 0x006f27c6, + 0x00da2449, 0x0092ab2f, 0x004a3a84, 0x0002b5e2, + 0x00015555, 0x0049da33, 0x00914b98, 0x00d9c4fe, + 0x00d88ee3, 0x00900185, 0x0048902e, 0x00001f48, + 0x0003ffff, 0x004b7099, 0x0093e132, 0x00db6e54, + 0x006e6ddb, 0x0026e2bd, 0x00fe7316, 0x00b6fc70, + 0x00b51cc7, 0x00fd93a1, 0x0025020a, 0x006d8d6c, + 0x00b44992, 0x00fcc6f4, 0x0024575f, 0x006cd839, + 0x006f388e, 0x0027b7e8, 0x00ff2643, 0x00b7a925, + 0x0002aaaa, 0x004a25cc, 0x0092b467, 0x00da3b01, + 0x00d9dbb6, 0x009154d0, 0x0049c57b, 0x00014a1d, + 0x004b5141, 0x0003de27, 0x00db4f8c, 0x0093c0ea, + 0x0090205d, 0x00d8af3b, 0x00003e90, 0x0048b1f6, + 0x00fdb279, 0x00b53d1f, 0x006dacb4, 0x002523d2, + 0x0026c365, 0x006e4c03, 0x00b6dda8, 0x00fe52ce, + 0x00279630, 0x006f1956, 0x00b788fd, 0x00ff079b, + 0x00fce72c, 0x00b4684a, 0x006cf9e1, 0x00247687, + 0x00917508, 0x00d9fa6e, 0x00016bc5, 0x0049e4a3, + 0x004a0414, 0x00028b72, 0x00da1ad9, 0x009295bf, + 0x0093dfa2, 0x00db50c4, 0x0003c16f, 0x004b4e09, + 0x0048aebe, 0x000021d8, 0x00d8b073, 0x00903f15, + 0x00253c9a, 0x006db3fc, 0x00b52257, 0x00fdad31, + 0x00fe4d86, 0x00b6c2e0, 0x006e534b, 0x0026dc2d, + 0x00ff18d3, 0x00b797b5, 0x006f061e, 0x00278978, + 0x002469cf, 0x006ce6a9, 0x00b47702, 0x00fcf864, + 0x0049fbeb, 0x0001748d, 0x00d9e526, 0x00916a40, + 0x00928af7, 0x00da0591, 0x0002943a, 0x004a1b5c, + 0x0096a282, 0x00de2de4, 0x0006bc4f, 0x004e3329, + 0x004dd39e, 0x00055cf8, 0x00ddcd53, 0x00954235, + 0x002041ba, 0x0068cedc, 0x00b05f77, 0x00f8d011, + 0x00fb30a6, 0x00b3bfc0, 0x006b2e6b, 0x0023a10d, + 0x00fa65f3, 0x00b2ea95, 0x006a7b3e, 0x0022f458, + 0x002114ef, 0x00699b89, 0x00b10a22, 0x00f98544, + 0x004c86cb, 0x000409ad, 0x00dc9806, 0x00941760, + 0x0097f7d7, 0x00df78b1, 0x0007e91a, 0x004f667c, + 0x004e2c61, 0x0006a307, 0x00de32ac, 0x0096bdca, + 0x00955d7d, 0x00ddd21b, 0x000543b0, 0x004dccd6, + 0x00f8cf59, 0x00b0403f, 0x0068d194, 0x00205ef2, + 0x0023be45, 0x006b3123, 0x00b3a088, 0x00fb2fee, + 0x0022eb10, 0x006a6476, 0x00b2f5dd, 0x00fa7abb, + 0x00f99a0c, 0x00b1156a, 0x006984c1, 0x00210ba7, + 0x00940828, 0x00dc874e, 0x000416e5, 0x004c9983, + 0x004f7934, 0x0007f652, 0x00df67f9, 0x0097e89f, + 0x00ddf3c3, 0x00957ca5, 0x004ded0e, 0x00056268, + 0x000682df, 0x004e0db9, 0x00969c12, 0x00de1374, + 0x006b10fb, 0x00239f9d, 0x00fb0e36, 0x00b38150, + 0x00b061e7, 0x00f8ee81, 0x00207f2a, 0x0068f04c, + 0x00b134b2, 0x00f9bbd4, 0x00212a7f, 0x0069a519, + 0x006a45ae, 0x0022cac8, 0x00fa5b63, 0x00b2d405, + 0x0007d78a, 0x004f58ec, 0x0097c947, 0x00df4621, + 0x00dca696, 0x009429f0, 0x004cb85b, 0x0004373d, + 0x00057d20, 0x004df246, 0x009563ed, 0x00ddec8b, + 0x00de0c3c, 0x0096835a, 0x004e12f1, 0x00069d97, + 0x00b39e18, 0x00fb117e, 0x002380d5, 0x006b0fb3, + 0x0068ef04, 0x00206062, 0x00f8f1c9, 0x00b07eaf, + 0x0069ba51, 0x00213537, 0x00f9a49c, 0x00b12bfa, + 0x00b2cb4d, 0x00fa442b, 0x0022d580, 0x006a5ae6, + 0x00df5969, 0x0097d60f, 0x004f47a4, 0x0007c8c2, + 0x00042875, 0x004ca713, 0x009436b8, 0x00dcb9de, + 0x00000000, 0x00d70983, 0x00555f80, 0x00825603, + 0x0051f286, 0x0086fb05, 0x0004ad06, 0x00d3a485, + 0x0059a88b, 0x008ea108, 0x000cf70b, 0x00dbfe88, + 0x00085a0d, 0x00df538e, 0x005d058d, 0x008a0c0e, + 0x00491c91, 0x009e1512, 0x001c4311, 0x00cb4a92, + 0x0018ee17, 0x00cfe794, 0x004db197, 0x009ab814, + 0x0010b41a, 0x00c7bd99, 0x0045eb9a, 0x0092e219, + 0x0041469c, 0x00964f1f, 0x0014191c, 0x00c3109f, + 0x006974a4, 0x00be7d27, 0x003c2b24, 0x00eb22a7, + 0x00388622, 0x00ef8fa1, 0x006dd9a2, 0x00bad021, + 0x0030dc2f, 0x00e7d5ac, 0x006583af, 0x00b28a2c, + 0x00612ea9, 0x00b6272a, 0x00347129, 0x00e378aa, + 0x00206835, 0x00f761b6, 0x007537b5, 0x00a23e36, + 0x00719ab3, 0x00a69330, 0x0024c533, 0x00f3ccb0, + 0x0079c0be, 0x00aec93d, 0x002c9f3e, 0x00fb96bd, + 0x00283238, 0x00ff3bbb, 0x007d6db8, 0x00aa643b, + 0x0029a4ce, 0x00fead4d, 0x007cfb4e, 0x00abf2cd, + 0x00785648, 0x00af5fcb, 0x002d09c8, 0x00fa004b, + 0x00700c45, 0x00a705c6, 0x002553c5, 0x00f25a46, + 0x0021fec3, 0x00f6f740, 0x0074a143, 0x00a3a8c0, + 0x0060b85f, 0x00b7b1dc, 0x0035e7df, 0x00e2ee5c, + 0x00314ad9, 0x00e6435a, 0x00641559, 0x00b31cda, + 0x003910d4, 0x00ee1957, 0x006c4f54, 0x00bb46d7, + 0x0068e252, 0x00bfebd1, 0x003dbdd2, 0x00eab451, + 0x0040d06a, 0x0097d9e9, 0x00158fea, 0x00c28669, + 0x001122ec, 0x00c62b6f, 0x00447d6c, 0x009374ef, + 0x001978e1, 0x00ce7162, 0x004c2761, 0x009b2ee2, + 0x00488a67, 0x009f83e4, 0x001dd5e7, 0x00cadc64, + 0x0009ccfb, 0x00dec578, 0x005c937b, 0x008b9af8, + 0x00583e7d, 0x008f37fe, 0x000d61fd, 0x00da687e, + 0x00506470, 0x00876df3, 0x00053bf0, 0x00d23273, + 0x000196f6, 0x00d69f75, 0x0054c976, 0x0083c0f5, + 0x00a9041b, 0x007e0d98, 0x00fc5b9b, 0x002b5218, + 0x00f8f69d, 0x002fff1e, 0x00ada91d, 0x007aa09e, + 0x00f0ac90, 0x0027a513, 0x00a5f310, 0x0072fa93, + 0x00a15e16, 0x00765795, 0x00f40196, 0x00230815, + 0x00e0188a, 0x00371109, 0x00b5470a, 0x00624e89, + 0x00b1ea0c, 0x0066e38f, 0x00e4b58c, 0x0033bc0f, + 0x00b9b001, 0x006eb982, 0x00ecef81, 0x003be602, + 0x00e84287, 0x003f4b04, 0x00bd1d07, 0x006a1484, + 0x00c070bf, 0x0017793c, 0x00952f3f, 0x004226bc, + 0x00918239, 0x00468bba, 0x00c4ddb9, 0x0013d43a, + 0x0099d834, 0x004ed1b7, 0x00cc87b4, 0x001b8e37, + 0x00c82ab2, 0x001f2331, 0x009d7532, 0x004a7cb1, + 0x00896c2e, 0x005e65ad, 0x00dc33ae, 0x000b3a2d, + 0x00d89ea8, 0x000f972b, 0x008dc128, 0x005ac8ab, + 0x00d0c4a5, 0x0007cd26, 0x00859b25, 0x005292a6, + 0x00813623, 0x00563fa0, 0x00d469a3, 0x00036020, + 0x0080a0d5, 0x0057a956, 0x00d5ff55, 0x0002f6d6, + 0x00d15253, 0x00065bd0, 0x00840dd3, 0x00530450, + 0x00d9085e, 0x000e01dd, 0x008c57de, 0x005b5e5d, + 0x0088fad8, 0x005ff35b, 0x00dda558, 0x000aacdb, + 0x00c9bc44, 0x001eb5c7, 0x009ce3c4, 0x004bea47, + 0x00984ec2, 0x004f4741, 0x00cd1142, 0x001a18c1, + 0x009014cf, 0x00471d4c, 0x00c54b4f, 0x001242cc, + 0x00c1e649, 0x0016efca, 0x0094b9c9, 0x0043b04a, + 0x00e9d471, 0x003eddf2, 0x00bc8bf1, 0x006b8272, + 0x00b826f7, 0x006f2f74, 0x00ed7977, 0x003a70f4, + 0x00b07cfa, 0x00677579, 0x00e5237a, 0x00322af9, + 0x00e18e7c, 0x003687ff, 0x00b4d1fc, 0x0063d87f, + 0x00a0c8e0, 0x0077c163, 0x00f59760, 0x00229ee3, + 0x00f13a66, 0x002633e5, 0x00a465e6, 0x00736c65, + 0x00f9606b, 0x002e69e8, 0x00ac3feb, 0x007b3668, + 0x00a892ed, 0x007f9b6e, 0x00fdcd6d, 0x002ac4ee, + 0x00000000, 0x00520936, 0x00a4126c, 0x00f61b5a, + 0x004825d8, 0x001a2cee, 0x00ec37b4, 0x00be3e82, + 0x006b0636, 0x00390f00, 0x00cf145a, 0x009d1d6c, + 0x002323ee, 0x00712ad8, 0x00873182, 0x00d538b4, + 0x00d60c6c, 0x0084055a, 0x00721e00, 0x00201736, + 0x009e29b4, 0x00cc2082, 0x003a3bd8, 0x006832ee, + 0x00bd0a5a, 0x00ef036c, 0x00191836, 0x004b1100, + 0x00f52f82, 0x00a726b4, 0x00513dee, 0x000334d8, + 0x00ac19d8, 0x00fe10ee, 0x00080bb4, 0x005a0282, + 0x00e43c00, 0x00b63536, 0x00402e6c, 0x0012275a, + 0x00c71fee, 0x009516d8, 0x00630d82, 0x003104b4, + 0x008f3a36, 0x00dd3300, 0x002b285a, 0x0079216c, + 0x007a15b4, 0x00281c82, 0x00de07d8, 0x008c0eee, + 0x0032306c, 0x0060395a, 0x00962200, 0x00c42b36, + 0x00111382, 0x00431ab4, 0x00b501ee, 0x00e708d8, + 0x0059365a, 0x000b3f6c, 0x00fd2436, 0x00af2d00, + 0x00a37f36, 0x00f17600, 0x00076d5a, 0x0055646c, + 0x00eb5aee, 0x00b953d8, 0x004f4882, 0x001d41b4, + 0x00c87900, 0x009a7036, 0x006c6b6c, 0x003e625a, + 0x00805cd8, 0x00d255ee, 0x00244eb4, 0x00764782, + 0x0075735a, 0x00277a6c, 0x00d16136, 0x00836800, + 0x003d5682, 0x006f5fb4, 0x009944ee, 0x00cb4dd8, + 0x001e756c, 0x004c7c5a, 0x00ba6700, 0x00e86e36, + 0x005650b4, 0x00045982, 0x00f242d8, 0x00a04bee, + 0x000f66ee, 0x005d6fd8, 0x00ab7482, 0x00f97db4, + 0x00474336, 0x00154a00, 0x00e3515a, 0x00b1586c, + 0x006460d8, 0x003669ee, 0x00c072b4, 0x00927b82, + 0x002c4500, 0x007e4c36, 0x0088576c, 0x00da5e5a, + 0x00d96a82, 0x008b63b4, 0x007d78ee, 0x002f71d8, + 0x00914f5a, 0x00c3466c, 0x00355d36, 0x00675400, + 0x00b26cb4, 0x00e06582, 0x00167ed8, 0x004477ee, + 0x00fa496c, 0x00a8405a, 0x005e5b00, 0x000c5236, + 0x0046ff6c, 0x0014f65a, 0x00e2ed00, 0x00b0e436, + 0x000edab4, 0x005cd382, 0x00aac8d8, 0x00f8c1ee, + 0x002df95a, 0x007ff06c, 0x0089eb36, 0x00dbe200, + 0x0065dc82, 0x0037d5b4, 0x00c1ceee, 0x0093c7d8, + 0x0090f300, 0x00c2fa36, 0x0034e16c, 0x0066e85a, + 0x00d8d6d8, 0x008adfee, 0x007cc4b4, 0x002ecd82, + 0x00fbf536, 0x00a9fc00, 0x005fe75a, 0x000dee6c, + 0x00b3d0ee, 0x00e1d9d8, 0x0017c282, 0x0045cbb4, + 0x00eae6b4, 0x00b8ef82, 0x004ef4d8, 0x001cfdee, + 0x00a2c36c, 0x00f0ca5a, 0x0006d100, 0x0054d836, + 0x0081e082, 0x00d3e9b4, 0x0025f2ee, 0x0077fbd8, + 0x00c9c55a, 0x009bcc6c, 0x006dd736, 0x003fde00, + 0x003cead8, 0x006ee3ee, 0x0098f8b4, 0x00caf182, + 0x0074cf00, 0x0026c636, 0x00d0dd6c, 0x0082d45a, + 0x0057ecee, 0x0005e5d8, 0x00f3fe82, 0x00a1f7b4, + 0x001fc936, 0x004dc000, 0x00bbdb5a, 0x00e9d26c, + 0x00e5805a, 0x00b7896c, 0x00419236, 0x00139b00, + 0x00ada582, 0x00ffacb4, 0x0009b7ee, 0x005bbed8, + 0x008e866c, 0x00dc8f5a, 0x002a9400, 0x00789d36, + 0x00c6a3b4, 0x0094aa82, 0x0062b1d8, 0x0030b8ee, + 0x00338c36, 0x00618500, 0x00979e5a, 0x00c5976c, + 0x007ba9ee, 0x0029a0d8, 0x00dfbb82, 0x008db2b4, + 0x00588a00, 0x000a8336, 0x00fc986c, 0x00ae915a, + 0x0010afd8, 0x0042a6ee, 0x00b4bdb4, 0x00e6b482, + 0x00499982, 0x001b90b4, 0x00ed8bee, 0x00bf82d8, + 0x0001bc5a, 0x0053b56c, 0x00a5ae36, 0x00f7a700, + 0x00229fb4, 0x00709682, 0x00868dd8, 0x00d484ee, + 0x006aba6c, 0x0038b35a, 0x00cea800, 0x009ca136, + 0x009f95ee, 0x00cd9cd8, 0x003b8782, 0x00698eb4, + 0x00d7b036, 0x0085b900, 0x0073a25a, 0x0021ab6c, + 0x00f493d8, 0x00a69aee, 0x005081b4, 0x00028882, + 0x00bcb600, 0x00eebf36, 0x0018a46c, 0x004aad5a +}; + +static inline +u32 crc24_init (void) +{ + return 0xce04b7; +} + +static inline +u32 crc24_next (u32 crc, byte data) +{ + return (crc >> 8) ^ crc24_table[(crc & 0xff) ^ data]; +} + +/* + * Process 4 bytes in one go + */ +static inline +u32 crc24_next4 (u32 crc, u32 data) +{ + crc ^= data; + crc = crc24_table[(crc & 0xff) + 0x300] ^ + crc24_table[((crc >> 8) & 0xff) + 0x200] ^ + crc24_table[((crc >> 16) & 0xff) + 0x100] ^ + crc24_table[(crc >> 24) & 0xff]; + return crc; +} + +static inline +u32 crc24_final (u32 crc) +{ + return crc & 0xffffff; +} static void crc24rfc2440_init (void *context) { CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; - ctx->CRC = CRC24_INIT; + ctx->CRC = crc24_init(); } static void crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen) { const unsigned char *inbuf = inbuf_arg; - int i; CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; + u32 crc; - if (!inbuf) + if (!inbuf || !inlen) return; - while (inlen--) { - ctx->CRC ^= (*inbuf++) << 16; - for (i = 0; i < 8; i++) { - ctx->CRC <<= 1; - if (ctx->CRC & 0x1000000) - ctx->CRC ^= CRC24_POLY; + crc = ctx->CRC; + + while (inlen >= 16) + { + inlen -= 16; + crc = crc24_next4(crc, buf_get_le32(&inbuf[0])); + crc = crc24_next4(crc, buf_get_le32(&inbuf[4])); + crc = crc24_next4(crc, buf_get_le32(&inbuf[8])); + crc = crc24_next4(crc, buf_get_le32(&inbuf[12])); + inbuf += 16; } - } + + while (inlen >= 4) + { + inlen -= 4; + crc = crc24_next4(crc, buf_get_le32(inbuf)); + inbuf += 4; + } + + while (inlen--) + { + crc = crc24_next(crc, *inbuf++); + } + + ctx->CRC = crc; } static void crc24rfc2440_final (void *context) { CRC_CONTEXT *ctx = (CRC_CONTEXT *) context; - ctx->buf[0] = (ctx->CRC >> 16) & 0xFF; - ctx->buf[1] = (ctx->CRC >> 8) & 0xFF; - ctx->buf[2] = (ctx->CRC ) & 0xFF; + ctx->CRC = crc24_final(ctx->CRC); + buf_put_le32 (ctx->buf, ctx->CRC); } gcry_md_spec_t _gcry_digest_spec_crc32 = 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 955295403..4be7b4080 100644 --- a/grub-core/lib/posix_wrap/limits.h +++ b/grub-core/lib/posix_wrap/limits.h @@ -25,11 +25,22 @@ #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 +#define SHRT_MIN GRUB_SHRT_MIN #define SHRT_MAX GRUB_SHRT_MAX +#define INT_MIN GRUB_INT_MIN #define INT_MAX GRUB_INT_MAX +#define LONG_MIN GRUB_LONG_MIN +#define LONG_MAX GRUB_LONG_MAX #define CHAR_BIT 8 +#define WORD_BIT 32 #endif diff --git a/grub-core/lib/posix_wrap/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/riscv/setjmp.S b/grub-core/lib/riscv/setjmp.S new file mode 100644 index 000000000..b48ef29ea --- /dev/null +++ b/grub-core/lib/riscv/setjmp.S @@ -0,0 +1,84 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + + .file "setjmp.S" + +GRUB_MOD_LICENSE "GPLv3+" + + .text + +#if __riscv_xlen == 64 +#define STORE_IDX(reg, idx) sd reg, (idx*8)(a0) +#define LOAD_IDX(reg, idx) ld reg, (idx*8)(a0) +#else +#define STORE_IDX(reg, idx) sw reg, (idx*4)(a0) +#define LOAD_IDX(reg, idx) lw reg, (idx*4)(a0) +#endif + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + /* Preserve all callee-saved registers and the SP */ + STORE_IDX(s0, 0) + STORE_IDX(s1, 1) + STORE_IDX(s2, 2) + STORE_IDX(s3, 3) + STORE_IDX(s4, 4) + STORE_IDX(s5, 5) + STORE_IDX(s6, 6) + STORE_IDX(s7, 7) + STORE_IDX(s8, 8) + STORE_IDX(s9, 9) + STORE_IDX(s10, 10) + STORE_IDX(s11, 11) + STORE_IDX(ra, 12) + STORE_IDX(sp, 13) + li a0, 0 + ret + +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + LOAD_IDX(s0, 0) + LOAD_IDX(s1, 1) + LOAD_IDX(s2, 2) + LOAD_IDX(s3, 3) + LOAD_IDX(s4, 4) + LOAD_IDX(s5, 5) + LOAD_IDX(s6, 6) + LOAD_IDX(s7, 7) + LOAD_IDX(s8, 8) + LOAD_IDX(s9, 9) + LOAD_IDX(s10, 10) + LOAD_IDX(s11, 11) + LOAD_IDX(ra, 12) + LOAD_IDX(sp, 13) + + /* Move the return value in place, but return 1 if passed 0. */ + beq a1, zero, longjmp_1 + mv a0, a1 + ret + + longjmp_1: + li a0, 1 + ret diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S index f6e4905e2..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,10 @@ #include "./arm/setjmp.S" #elif defined(__aarch64__) #include "./arm64/setjmp.S" +#elif defined(__loongarch_lp64) +#include "./loongarch64/setjmp.S" +#elif defined(__riscv) +#include "./riscv/setjmp.S" #else #error "Unknown target cpu type" #endif diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c index 28ba3aef0..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); @@ -696,7 +696,7 @@ syslinux_parse_real (struct syslinux_menu *menu) char *buf = NULL; grub_err_t err = GRUB_ERR_NONE; - file = grub_file_open (menu->filename); + file = grub_file_open (menu->filename, GRUB_FILE_TYPE_CONFIG); if (!file) return grub_errno; while ((grub_free (buf), buf = grub_file_getline (file))) @@ -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; @@ -807,6 +811,10 @@ print_file (struct output_buffer *outbuf, return print_escaped (outbuf, from, to); } +/* + * Makefile.am mimics this when generating tests/syslinux/ubuntu10.04_grub.cfg, + * so changes here may need to be reflected there too. + */ static void simplify_filename (char *str) { @@ -1032,7 +1040,7 @@ write_entry (struct output_buffer *outbuf, case KERNEL_COM: { char *basename = NULL; - + { char *ptr; for (ptr = curentry->kernel_file; *ptr; ptr++) @@ -1058,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) @@ -1082,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 @@ -1239,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" @@ -1411,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); @@ -1499,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 fe7158bb2..d1417039a 100644 --- a/grub-core/lib/xzembed/xz.h +++ b/grub-core/lib/xzembed/xz.h @@ -24,14 +24,12 @@ #ifndef XZ_H #define XZ_H +#include #include #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_lzma2.c b/grub-core/lib/xzembed/xz_dec_lzma2.c index 8a2a1183d..af7b77079 100644 --- a/grub-core/lib/xzembed/xz_dec_lzma2.c +++ b/grub-core/lib/xzembed/xz_dec_lzma2.c @@ -1044,6 +1044,8 @@ enum xz_ret xz_dec_lzma2_run( s->lzma2.sequence = SEQ_LZMA_PREPARE; + /* Fall through */ + case SEQ_LZMA_PREPARE: if (s->lzma2.compressed < RC_INIT_BYTES) return XZ_DATA_ERROR; @@ -1054,6 +1056,8 @@ enum xz_ret xz_dec_lzma2_run( s->lzma2.compressed -= RC_INIT_BYTES; s->lzma2.sequence = SEQ_LZMA_RUN; + /* Fall through */ + case SEQ_LZMA_RUN: /* * Set dictionary limit to indicate how much we want diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c index c16b13060..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) { @@ -750,6 +750,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_START; + /* FALLTHROUGH */ case SEQ_BLOCK_START: /* We need one byte of input to continue. */ if (b->in_pos == b->in_size) @@ -773,6 +774,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->temp.pos = 0; s->sequence = SEQ_BLOCK_HEADER; + /* FALLTHROUGH */ case SEQ_BLOCK_HEADER: if (!fill_temp(s, b)) return XZ_OK; @@ -783,6 +785,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_UNCOMPRESS; + /* FALLTHROUGH */ case SEQ_BLOCK_UNCOMPRESS: ret = dec_block(s, b); if (ret != XZ_STREAM_END) @@ -810,6 +813,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_CHECK; + /* FALLTHROUGH */ case SEQ_BLOCK_CHECK: ret = hash_validate(s, b, 0); if (ret != XZ_STREAM_END) @@ -858,6 +862,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_INDEX_CRC32; + /* FALLTHROUGH */ case SEQ_INDEX_CRC32: ret = hash_validate(s, b, 1); if (ret != XZ_STREAM_END) @@ -866,6 +871,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->temp.size = STREAM_HEADER_SIZE; s->sequence = SEQ_STREAM_FOOTER; + /* FALLTHROUGH */ case SEQ_STREAM_FOOTER: if (!fill_temp(s, b)) return XZ_OK; diff --git a/grub-core/lib/zstd/bitstream.h b/grub-core/lib/zstd/bitstream.h new file mode 100644 index 000000000..2f91460c5 --- /dev/null +++ b/grub-core/lib/zstd/bitstream.h @@ -0,0 +1,458 @@ +/* ****************************************************************** + bitstream + Part of FSE library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ +#ifndef BITSTREAM_H_MODULE +#define BITSTREAM_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + +/* +* This API consists of small unitary functions, which must be inlined for best performance. +* Since link-time-optimization is not available for all compilers, +* these functions are defined into a .h to be included. +*/ + +/*-**************************************** +* Dependencies +******************************************/ +#include "mem.h" /* unaligned access routines */ +#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ +#include "error_private.h" /* error codes and messages */ + + +/*========================================= +* Target specific +=========================================*/ +#if defined(__BMI__) && defined(__GNUC__) +# include /* support for bextr (experimental) */ +#endif + +#define STREAM_ACCUMULATOR_MIN_32 25 +#define STREAM_ACCUMULATOR_MIN_64 57 +#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) + + +/*-****************************************** +* bitStream encoding API (write forward) +********************************************/ +/* bitStream can mix input from multiple sources. + * A critical property of these streams is that they encode and decode in **reverse** direction. + * So the first bit sequence you add will be the last to be read, like a LIFO stack. + */ +typedef struct { + size_t bitContainer; + unsigned bitPos; + char* startPtr; + char* ptr; + char* endPtr; +} BIT_CStream_t; + +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits); +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); + +/* Start with initCStream, providing the size of buffer to write into. +* bitStream will never write outside of this buffer. +* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. +* +* bits are first added to a local register. +* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems. +* Writing data into memory is an explicit operation, performed by the flushBits function. +* Hence keep track how many bits are potentially stored into local register to avoid register overflow. +* After a flushBits, a maximum of 7 bits might still be stored into local register. +* +* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. +* +* Last operation is to close the bitStream. +* The function returns the final size of CStream in bytes. +* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) +*/ + + +/*-******************************************** +* bitStream decoding API (read backward) +**********************************************/ +typedef struct { + size_t bitContainer; + unsigned bitsConsumed; + const char* ptr; + const char* start; + const char* limitPtr; +} BIT_DStream_t; + +typedef enum { BIT_DStream_unfinished = 0, + BIT_DStream_endOfBuffer = 1, + BIT_DStream_completed = 2, + BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */ + /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ + +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); + + +/* Start by invoking BIT_initDStream(). +* A chunk of the bitStream is then stored into a local register. +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +* You can then retrieve bitFields stored into the local register, **in reverse order**. +* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. +* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. +* Otherwise, it can be less than that, so proceed accordingly. +* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). +*/ + + +/*-**************************************** +* unsafe API +******************************************/ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits); +/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ + +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); +/* unsafe version; does not check buffer overflow */ + +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); +/* faster, but works only if nbBits >= 1 */ + + + +/*-************************************************************** +* Internal functions +****************************************************************/ +MEM_STATIC unsigned BIT_highbit32 (U32 val) +{ + assert(val != 0); + { +# if defined(_MSC_VER) /* Visual */ + unsigned long r=0; + _BitScanReverse ( &r, val ); + return (unsigned) r; +# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ + return 31 - __builtin_clz (val); +# else /* Software version */ + static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31 }; + U32 v = val; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; +# endif + } +} + +/*===== Local Constants =====*/ +static const unsigned BIT_mask[] = { + 0, 1, 3, 7, 0xF, 0x1F, + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, + 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, + 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */ +#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0])) + +/*-************************************************************** +* bitStream encoding +****************************************************************/ +/*! BIT_initCStream() : + * `dstCapacity` must be > sizeof(size_t) + * @return : 0 if success, + * otherwise an error code (can be tested using ERR_isError()) */ +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + bitC->bitContainer = 0; + bitC->bitPos = 0; + bitC->startPtr = (char*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer); + if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall); + return 0; +} + +/*! BIT_addBits() : + * can add up to 31 bits into `bitC`. + * Note : does not check for register overflow ! */ +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, + size_t value, unsigned nbBits) +{ + MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32); + assert(nbBits < BIT_MASK_SIZE); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_addBitsFast() : + * works only if `value` is _clean_, + * meaning all high bits above nbBits are 0 */ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, + size_t value, unsigned nbBits) +{ + assert((value>>nbBits) == 0); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= value << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_flushBitsFast() : + * assumption : bitContainer has not overflowed + * unsafe version; does not check buffer overflow */ +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + assert(bitC->ptr <= bitC->endPtr); + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_flushBits() : + * assumption : bitContainer has not overflowed + * safe version; check for buffer overflow, and prevents it. + * note : does not signal buffer overflow. + * overflow will be revealed later on using BIT_closeCStream() */ +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_closeCStream() : + * @return : size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) +{ + BIT_addBitsFast(bitC, 1, 1); /* endMark */ + BIT_flushBits(bitC); + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); +} + + +/*-******************************************************** +* bitStream decoding +**********************************************************/ +/*! BIT_initDStream() : + * Initialize a BIT_DStream_t. + * `bitD` : a pointer to an already allocated BIT_DStream_t structure. + * `srcSize` must be the *exact* size of the bitStream, in bytes. + * @return : size of stream (== srcSize), or an errorCode if a problem is detected + */ +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) +{ + if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } + + bitD->start = (const char*)srcBuffer; + bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); + + if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); + bitD->bitContainer = MEM_readLEST(bitD->ptr); + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ + if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } + } else { + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE*)(bitD->start); + switch(srcSize) + { + case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); + /* fall-through */ + + case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); + /* fall-through */ + + case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); + /* fall-through */ + + case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; + /* fall-through */ + + case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; + /* fall-through */ + + case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; + /* fall-through */ + + default: break; + } + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; + if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */ + } + bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; + } + + return srcSize; +} + +MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) +{ + return bitContainer >> start; +} + +MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) +{ +#if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */ +# if defined(__x86_64__) + if (sizeof(bitContainer)==8) + return _bextr_u64(bitContainer, start, nbBits); + else +# endif + return _bextr_u32(bitContainer, start, nbBits); +#else + assert(nbBits < BIT_MASK_SIZE); + return (bitContainer >> start) & BIT_mask[nbBits]; +#endif +} + +MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) +{ + assert(nbBits < BIT_MASK_SIZE); + return bitContainer & BIT_mask[nbBits]; +} + +/*! BIT_lookBits() : + * Provides next n bits from local register. + * local register is not modified. + * On 32-bits, maxNbBits==24. + * On 64-bits, maxNbBits==56. + * @return : value extracted */ +MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) +{ +#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */ + return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); +#else + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask); +#endif +} + +/*! BIT_lookBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) +{ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + assert(nbBits >= 1); + return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); +} + +MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +{ + bitD->bitsConsumed += nbBits; +} + +/*! BIT_readBits() : + * Read (consume) next n bits from local register and update. + * Pay attention to not read more than nbBits contained into local register. + * @return : extracted value. */ +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) +{ + size_t const value = BIT_lookBits(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_readBitsFast() : + * unsafe version; only works only if nbBits >= 1 */ +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) +{ + size_t const value = BIT_lookBitsFast(bitD, nbBits); + assert(nbBits >= 1); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_reloadDStream() : + * Refill `bitD` from buffer previously set in BIT_initDStream() . + * This function is safe, it guarantees it will not read beyond src buffer. + * @return : status of `BIT_DStream_t` internal register. + * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +{ + if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */ + return BIT_DStream_overflow; + + if (bitD->ptr >= bitD->limitPtr) { + bitD->ptr -= bitD->bitsConsumed >> 3; + bitD->bitsConsumed &= 7; + bitD->bitContainer = MEM_readLEST(bitD->ptr); + return BIT_DStream_unfinished; + } + if (bitD->ptr == bitD->start) { + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; + return BIT_DStream_completed; + } + /* start < ptr < limitPtr */ + { U32 nbBytes = bitD->bitsConsumed >> 3; + BIT_DStream_status result = BIT_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = BIT_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes*8; + bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */ + return result; + } +} + +/*! BIT_endOfDStream() : + * @return : 1 if DStream has _exactly_ reached its end (all bits consumed). + */ +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) +{ + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); +} + +#if defined (__cplusplus) +} +#endif + +#endif /* BITSTREAM_H_MODULE */ diff --git a/grub-core/lib/zstd/compiler.h b/grub-core/lib/zstd/compiler.h new file mode 100644 index 000000000..07f875e4d --- /dev/null +++ b/grub-core/lib/zstd/compiler.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPILER_H +#define ZSTD_COMPILER_H + +/*-******************************************************* +* Compiler specifics +*********************************************************/ +/* force inlining */ +#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# define INLINE_KEYWORD inline +#else +# define INLINE_KEYWORD +#endif + +#if defined(__GNUC__) +# define FORCE_INLINE_ATTR __attribute__((always_inline)) +#elif defined(_MSC_VER) +# define FORCE_INLINE_ATTR __forceinline +#else +# define FORCE_INLINE_ATTR +#endif + +/** + * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant + * parameters. They must be inlined for the compiler to elimininate the constant + * branches. + */ +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR +/** + * HINT_INLINE is used to help the compiler generate better code. It is *not* + * used for "templates", so it can be tweaked based on the compilers + * performance. + * + * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the + * always_inline attribute. + * + * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline + * attribute. + */ +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 +# define HINT_INLINE static INLINE_KEYWORD +#else +# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR +#endif + +/* force no inlining */ +#ifdef _MSC_VER +# define FORCE_NOINLINE static __declspec(noinline) +#else +# ifdef __GNUC__ +# define FORCE_NOINLINE static __attribute__((__noinline__)) +# else +# define FORCE_NOINLINE static +# endif +#endif + +/* target attribute */ +#ifndef __has_attribute + #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ +#endif +#if defined(__GNUC__) +# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) +#else +# define TARGET_ATTRIBUTE(target) +#endif + +/* Enable runtime BMI2 dispatch based on the CPU. + * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. + */ +#ifndef DYNAMIC_BMI2 + #if ((defined(__clang__) && __has_attribute(__target__)) \ + || (defined(__GNUC__) \ + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ + && (defined(__x86_64__) || defined(_M_X86)) \ + && !defined(__BMI2__) + # define DYNAMIC_BMI2 1 + #else + # define DYNAMIC_BMI2 0 + #endif +#endif + +/* prefetch + * can be disabled, by declaring NO_PREFETCH macro + * All prefetch invocations use a single default locality 2, + * generating instruction prefetcht1, + * which, according to Intel, means "load data into L2 cache". + * This is a good enough "middle ground" for the time being, + * though in theory, it would be better to specialize locality depending on data being prefetched. + * Tests could not determine any sensible difference based on locality value. */ +#if defined(NO_PREFETCH) +# define PREFETCH(ptr) (void)(ptr) /* disabled */ +#else +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) +# else +# define PREFETCH(ptr) (void)(ptr) /* disabled */ +# endif +#endif /* NO_PREFETCH */ + +#define CACHELINE_SIZE 64 + +#define PREFETCH_AREA(p, s) { \ + const char* const _ptr = (const char*)(p); \ + size_t const _size = (size_t)(s); \ + size_t _pos; \ + for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ + PREFETCH(_ptr + _pos); \ + } \ +} + +/* disable warnings */ +#ifdef _MSC_VER /* Visual Studio */ +# include /* For Visual 2005 */ +# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ +# pragma warning(disable : 4324) /* disable: C4324: padded structure */ +#endif + +#endif /* ZSTD_COMPILER_H */ diff --git a/grub-core/lib/zstd/cpu.h b/grub-core/lib/zstd/cpu.h new file mode 100644 index 000000000..eeb428ad5 --- /dev/null +++ b/grub-core/lib/zstd/cpu.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMMON_CPU_H +#define ZSTD_COMMON_CPU_H + +/** + * Implementation taken from folly/CpuId.h + * https://github.com/facebook/folly/blob/master/folly/CpuId.h + */ + +#include + +#include "mem.h" + +#ifdef _MSC_VER +#include +#endif + +typedef struct { + U32 f1c; + U32 f1d; + U32 f7b; + U32 f7c; +} ZSTD_cpuid_t; + +MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { + U32 f1c = 0; + U32 f1d = 0; + U32 f7b = 0; + U32 f7c = 0; +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) + int reg[4]; + __cpuid((int*)reg, 0); + { + int const n = reg[0]; + if (n >= 1) { + __cpuid((int*)reg, 1); + f1c = (U32)reg[2]; + f1d = (U32)reg[3]; + } + if (n >= 7) { + __cpuidex((int*)reg, 7, 0); + f7b = (U32)reg[1]; + f7c = (U32)reg[2]; + } + } +#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__) + /* The following block like the normal cpuid branch below, but gcc + * reserves ebx for use of its pic register so we must specially + * handle the save and restore to avoid clobbering the register + */ + U32 n; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(n) + : "a"(0) + : "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1)); + } + if (n >= 7) { + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %%eax\n\r" + "popl %%ebx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__) + U32 n; + __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx"); + } + if (n >= 7) { + U32 f7a; + __asm__("cpuid" + : "=a"(f7a), "=b"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#endif + { + ZSTD_cpuid_t cpuid; + cpuid.f1c = f1c; + cpuid.f1d = f1d; + cpuid.f7b = f7b; + cpuid.f7c = f7c; + return cpuid; + } +} + +#define X(name, r, bit) \ + MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \ + return ((cpuid.r) & (1U << bit)) != 0; \ + } + +/* cpuid(1): Processor Info and Feature Bits. */ +#define C(name, bit) X(name, f1c, bit) + C(sse3, 0) + C(pclmuldq, 1) + C(dtes64, 2) + C(monitor, 3) + C(dscpl, 4) + C(vmx, 5) + C(smx, 6) + C(eist, 7) + C(tm2, 8) + C(ssse3, 9) + C(cnxtid, 10) + C(fma, 12) + C(cx16, 13) + C(xtpr, 14) + C(pdcm, 15) + C(pcid, 17) + C(dca, 18) + C(sse41, 19) + C(sse42, 20) + C(x2apic, 21) + C(movbe, 22) + C(popcnt, 23) + C(tscdeadline, 24) + C(aes, 25) + C(xsave, 26) + C(osxsave, 27) + C(avx, 28) + C(f16c, 29) + C(rdrand, 30) +#undef C +#define D(name, bit) X(name, f1d, bit) + D(fpu, 0) + D(vme, 1) + D(de, 2) + D(pse, 3) + D(tsc, 4) + D(msr, 5) + D(pae, 6) + D(mce, 7) + D(cx8, 8) + D(apic, 9) + D(sep, 11) + D(mtrr, 12) + D(pge, 13) + D(mca, 14) + D(cmov, 15) + D(pat, 16) + D(pse36, 17) + D(psn, 18) + D(clfsh, 19) + D(ds, 21) + D(acpi, 22) + D(mmx, 23) + D(fxsr, 24) + D(sse, 25) + D(sse2, 26) + D(ss, 27) + D(htt, 28) + D(tm, 29) + D(pbe, 31) +#undef D + +/* cpuid(7): Extended Features. */ +#define B(name, bit) X(name, f7b, bit) + B(bmi1, 3) + B(hle, 4) + B(avx2, 5) + B(smep, 7) + B(bmi2, 8) + B(erms, 9) + B(invpcid, 10) + B(rtm, 11) + B(mpx, 14) + B(avx512f, 16) + B(avx512dq, 17) + B(rdseed, 18) + B(adx, 19) + B(smap, 20) + B(avx512ifma, 21) + B(pcommit, 22) + B(clflushopt, 23) + B(clwb, 24) + B(avx512pf, 26) + B(avx512er, 27) + B(avx512cd, 28) + B(sha, 29) + B(avx512bw, 30) + B(avx512vl, 31) +#undef B +#define C(name, bit) X(name, f7c, bit) + C(prefetchwt1, 0) + C(avx512vbmi, 1) +#undef C + +#undef X + +#endif /* ZSTD_COMMON_CPU_H */ diff --git a/grub-core/lib/zstd/debug.c b/grub-core/lib/zstd/debug.c new file mode 100644 index 000000000..3ebdd1cb1 --- /dev/null +++ b/grub-core/lib/zstd/debug.c @@ -0,0 +1,44 @@ +/* ****************************************************************** + debug + Part of FSE library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + + +/* + * This module only hosts one global variable + * which can be used to dynamically influence the verbosity of traces, + * such as DEBUGLOG and RAWLOG + */ + +#include "debug.h" + +int g_debuglevel = DEBUGLEVEL; diff --git a/grub-core/lib/zstd/debug.h b/grub-core/lib/zstd/debug.h new file mode 100644 index 000000000..0c04ad2cc --- /dev/null +++ b/grub-core/lib/zstd/debug.h @@ -0,0 +1,123 @@ +/* ****************************************************************** + debug + Part of FSE library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + + +/* + * The purpose of this header is to enable debug functions. + * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, + * and DEBUG_STATIC_ASSERT() for compile-time. + * + * By default, DEBUGLEVEL==0, which means run-time debug is disabled. + * + * Level 1 enables assert() only. + * Starting level 2, traces can be generated and pushed to stderr. + * The higher the level, the more verbose the traces. + * + * It's possible to dynamically adjust level using variable g_debug_level, + * which is only declared if DEBUGLEVEL>=2, + * and is a global variable, not multi-thread protected (use with care) + */ + +#ifndef DEBUG_H_12987983217 +#define DEBUG_H_12987983217 + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* static assert is triggered at compile time, leaving no runtime artefact, + * but can only work with compile-time constants. + * This variant can only be used inside a function. */ +#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) + + +/* DEBUGLEVEL is expected to be defined externally, + * typically through compiler command line. + * Value must be a number. */ +#ifndef DEBUGLEVEL +# define DEBUGLEVEL 0 +#endif + +/* recommended values for DEBUGLEVEL : + * 0 : no debug, all run-time functions disabled + * 1 : no display, enables assert() only + * 2 : reserved, for currently active debug path + * 3 : events once per object lifetime (CCtx, CDict, etc.) + * 4 : events once per frame + * 5 : events once per block + * 6 : events once per sequence (verbose) + * 7+: events at every position (*very* verbose) + * + * It's generally inconvenient to output traces > 5. + * In which case, it's possible to selectively enable higher verbosity levels + * by modifying g_debug_level. + */ + +#if (DEBUGLEVEL>=1) +# include +#else +# ifndef assert /* assert may be already defined, due to prior #include */ +# define assert(condition) ((void)0) /* disable assert (default) */ +# endif +#endif + +#if (DEBUGLEVEL>=2) +# include +extern int g_debuglevel; /* here, this variable is only declared, + it actually lives in debug.c, + and is shared by the whole process. + It's typically used to enable very verbose levels + on selective conditions (such as position in src) */ + +# define RAWLOG(l, ...) { \ + if (l<=g_debuglevel) { \ + fprintf(stderr, __VA_ARGS__); \ + } } +# define DEBUGLOG(l, ...) { \ + if (l<=g_debuglevel) { \ + fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ + fprintf(stderr, " \n"); \ + } } +#else +# define RAWLOG(l, ...) {} /* disabled */ +# define DEBUGLOG(l, ...) {} /* disabled */ +#endif + + +#if defined (__cplusplus) +} +#endif + +#endif /* DEBUG_H_12987983217 */ diff --git a/grub-core/lib/zstd/entropy_common.c b/grub-core/lib/zstd/entropy_common.c new file mode 100644 index 000000000..b12944e1d --- /dev/null +++ b/grub-core/lib/zstd/entropy_common.c @@ -0,0 +1,236 @@ +/* + Common functions of New Generation Entropy library + Copyright (C) 2016, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +*************************************************************************** */ + +/* ************************************* +* Dependencies +***************************************/ +#include "mem.h" +#include "error_private.h" /* ERR_*, ERROR */ +#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ +#include "fse.h" +#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */ +#include "huf.h" + + +/*=== Version ===*/ +unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } + + +/*=== Error Management ===*/ +unsigned FSE_isError(size_t code) { return ERR_isError(code); } +const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } + +unsigned HUF_isError(size_t code) { return ERR_isError(code); } +const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } + + +/*-************************************************************** +* FSE NCount encoding-decoding +****************************************************************/ +size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + const BYTE* const istart = (const BYTE*) headerBuffer; + const BYTE* const iend = istart + hbSize; + const BYTE* ip = istart; + int nbBits; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + int previous0 = 0; + + if (hbSize < 4) { + /* This function only works when hbSize >= 4 */ + char buffer[4]; + memset(buffer, 0, sizeof(buffer)); + memcpy(buffer, headerBuffer, hbSize); + { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, + buffer, sizeof(buffer)); + if (FSE_isError(countSize)) return countSize; + if (countSize > hbSize) return ERROR(corruption_detected); + return countSize; + } } + assert(hbSize >= 4); + + /* init */ + memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ + bitStream = MEM_readLE32(ip); + nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ + if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1<1) & (charnum<=*maxSVPtr)) { + if (previous0) { + unsigned n0 = charnum; + while ((bitStream & 0xFFFF) == 0xFFFF) { + n0 += 24; + if (ip < iend-5) { + ip += 2; + bitStream = MEM_readLE32(ip) >> bitCount; + } else { + bitStream >>= 16; + bitCount += 16; + } } + while ((bitStream & 3) == 3) { + n0 += 3; + bitStream >>= 2; + bitCount += 2; + } + n0 += bitStream & 3; + bitCount += 2; + if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); + while (charnum < n0) normalizedCounter[charnum++] = 0; + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + assert((bitCount >> 3) <= 3); /* For first condition to work */ + ip += bitCount>>3; + bitCount &= 7; + bitStream = MEM_readLE32(ip) >> bitCount; + } else { + bitStream >>= 2; + } } + { int const max = (2*threshold-1) - remaining; + int count; + + if ((bitStream & (threshold-1)) < (U32)max) { + count = bitStream & (threshold-1); + bitCount += nbBits-1; + } else { + count = bitStream & (2*threshold-1); + if (count >= threshold) count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + remaining -= count < 0 ? -count : count; /* -1 means +1 */ + normalizedCounter[charnum++] = (short)count; + previous0 = !count; + while (remaining < threshold) { + nbBits--; + threshold >>= 1; + } + + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> (bitCount & 31); + } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */ + if (remaining != 1) return ERROR(corruption_detected); + if (bitCount > 32) return ERROR(corruption_detected); + *maxSVPtr = charnum-1; + + ip += (bitCount+7)>>3; + return ip-istart; +} + + +/*! HUF_readStats() : + Read compact Huffman tree, saved by HUF_writeCTable(). + `huffWeight` is destination buffer. + `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableX?() . +*/ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize) +{ + U32 weightTotal; + const BYTE* ip = (const BYTE*) src; + size_t iSize; + size_t oSize; + + if (!srcSize) return ERROR(srcSize_wrong); + iSize = ip[0]; + /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ + + if (iSize >= 128) { /* special header */ + oSize = iSize - 127; + iSize = ((oSize+1)/2); + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + if (oSize >= hwSize) return ERROR(corruption_detected); + ip += 1; + { U32 n; + for (n=0; n> 4; + huffWeight[n+1] = ip[n/2] & 15; + } } } + else { /* header compressed with FSE (normal case) */ + FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ + if (FSE_isError(oSize)) return oSize; + } + + /* collect weight stats */ + memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); + weightTotal = 0; + { U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } } + if (weightTotal == 0) return ERROR(corruption_detected); + + /* get last non-null symbol weight (implied, total must be 2^n) */ + { U32 const tableLog = BIT_highbit32(weightTotal) + 1; + if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); + *tableLogPtr = tableLog; + /* determine last weight */ + { U32 const total = 1 << tableLog; + U32 const rest = total - weightTotal; + U32 const verif = 1 << BIT_highbit32(rest); + U32 const lastWeight = BIT_highbit32(rest) + 1; + if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } } + + /* check tree construction validity */ + if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ + + /* results */ + *nbSymbolsPtr = (U32)(oSize+1); + return iSize+1; +} diff --git a/grub-core/lib/zstd/error_private.c b/grub-core/lib/zstd/error_private.c new file mode 100644 index 000000000..d004ee636 --- /dev/null +++ b/grub-core/lib/zstd/error_private.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* The purpose of this file is to have a single list of error strings embedded in binary */ + +#include "error_private.h" + +const char* ERR_getErrorString(ERR_enum code) +{ + static const char* const notErrorCode = "Unspecified error code"; + switch( code ) + { + case PREFIX(no_error): return "No error detected"; + case PREFIX(GENERIC): return "Error (generic)"; + case PREFIX(prefix_unknown): return "Unknown frame descriptor"; + case PREFIX(version_unsupported): return "Version not supported"; + case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; + case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; + case PREFIX(corruption_detected): return "Corrupted block detected"; + case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; + case PREFIX(parameter_unsupported): return "Unsupported parameter"; + case PREFIX(parameter_outOfBound): return "Parameter is out of bound"; + case PREFIX(init_missing): return "Context should be init first"; + case PREFIX(memory_allocation): return "Allocation error : not enough memory"; + case PREFIX(workSpace_tooSmall): return "workSpace buffer is not large enough"; + case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; + case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; + case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; + case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; + case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; + case PREFIX(dictionary_wrong): return "Dictionary mismatch"; + case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; + case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; + case PREFIX(srcSize_wrong): return "Src size is incorrect"; + /* following error codes are not stable and may be removed or changed in a future version */ + case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; + case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; + case PREFIX(maxCode): + default: return notErrorCode; + } +} diff --git a/grub-core/lib/zstd/error_private.h b/grub-core/lib/zstd/error_private.h new file mode 100644 index 000000000..0d2fa7e34 --- /dev/null +++ b/grub-core/lib/zstd/error_private.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* Note : this module is expected to remain private, do not expose it */ + +#ifndef ERROR_H_MODULE +#define ERROR_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* **************************************** +* Dependencies +******************************************/ +#include /* size_t */ +#include "zstd_errors.h" /* enum list */ + + +/* **************************************** +* Compiler-specific +******************************************/ +#if defined(__GNUC__) +# define ERR_STATIC static __attribute__((unused)) +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define ERR_STATIC static inline +#elif defined(_MSC_VER) +# define ERR_STATIC static __inline +#else +# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + + +/*-**************************************** +* Customization (error_public.h) +******************************************/ +typedef ZSTD_ErrorCode ERR_enum; +#define PREFIX(name) ZSTD_error_##name + + +/*-**************************************** +* Error codes handling +******************************************/ +#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */ +#define ERROR(name) ZSTD_ERROR(name) +#define ZSTD_ERROR(name) ((size_t)-PREFIX(name)) + +ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } + +ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); } + + +/*-**************************************** +* Error Strings +******************************************/ + +const char* ERR_getErrorString(ERR_enum code); /* error_private.c */ + +ERR_STATIC const char* ERR_getErrorName(size_t code) +{ + return ERR_getErrorString(ERR_getErrorCode(code)); +} + +#if defined (__cplusplus) +} +#endif + +#endif /* ERROR_H_MODULE */ diff --git a/grub-core/lib/zstd/fse.h b/grub-core/lib/zstd/fse.h new file mode 100644 index 000000000..a5a6b6d4d --- /dev/null +++ b/grub-core/lib/zstd/fse.h @@ -0,0 +1,708 @@ +/* ****************************************************************** + FSE : Finite State Entropy codec + Public Prototypes declaration + Copyright (C) 2013-2016, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef FSE_H +#define FSE_H + + +/*-***************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ + + +/*-***************************************** +* FSE_PUBLIC_API : control library symbols visibility +******************************************/ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define FSE_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define FSE_PUBLIC_API +#endif + +/*------ Version ------*/ +#define FSE_VERSION_MAJOR 0 +#define FSE_VERSION_MINOR 9 +#define FSE_VERSION_RELEASE 0 + +#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE +#define FSE_QUOTE(str) #str +#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) +#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) + +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ + + +/*-**************************************** +* FSE simple functions +******************************************/ +/*! FSE_compress() : + Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'. + 'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize). + @return : size of compressed data (<= dstCapacity). + Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! + if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead. + if FSE_isError(return), compression failed (more details using FSE_getErrorName()) +*/ +FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +/*! FSE_decompress(): + Decompress FSE data from buffer 'cSrc', of size 'cSrcSize', + into already allocated destination buffer 'dst', of size 'dstCapacity'. + @return : size of regenerated data (<= maxDstSize), + or an error code, which can be tested using FSE_isError() . + + ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!! + Why ? : making this distinction requires a header. + Header management is intentionally delegated to the user layer, which can better manage special cases. +*/ +FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity, + const void* cSrc, size_t cSrcSize); + + +/*-***************************************** +* Tool functions +******************************************/ +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ + +/* Error Management */ +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ +FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ + + +/*-***************************************** +* FSE advanced functions +******************************************/ +/*! FSE_compress2() : + Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog' + Both parameters can be defined as '0' to mean : use default value + @return : size of compressed data + Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!! + if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression. + if FSE_isError(return), it's an error code. +*/ +FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); + + +/*-***************************************** +* FSE detailed API +******************************************/ +/*! +FSE_compress() does the following: +1. count symbol occurrence from source[] into table count[] (see hist.h) +2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) +3. save normalized counters to memory buffer using writeNCount() +4. build encoding table 'CTable' from normalized counters +5. encode the data stream using encoding table 'CTable' + +FSE_decompress() does the following: +1. read normalized counters with readNCount() +2. build decoding table 'DTable' from normalized counters +3. decode the data stream using decoding table 'DTable' + +The following API allows targeting specific sub-functions for advanced tasks. +For example, it's possible to compress several blocks using the same 'CTable', +or to save and provide normalized distribution using external method. +*/ + +/* *** COMPRESSION *** */ + +/*! FSE_optimalTableLog(): + dynamically downsize 'tableLog' when conditions are met. + It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. + @return : recommended tableLog (necessarily <= 'maxTableLog') */ +FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_normalizeCount(): + normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) + 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). + @return : tableLog, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_NCountWriteBound(): + Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. + Typically useful for allocation purpose. */ +FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_writeNCount(): + Compactly save 'normalizedCounter' into 'buffer'. + @return : size of the compressed table, + or an errorCode, which can be tested using FSE_isError(). */ +FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, + unsigned maxSymbolValue, unsigned tableLog); + +/*! Constructor and Destructor of FSE_CTable. + Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ +typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ +FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct); + +/*! FSE_buildCTable(): + Builds `ct`, which must be already allocated, using FSE_createCTable(). + @return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_compress_usingCTable(): + Compress `src` using `ct` into `dst` which must be already allocated. + @return : size of compressed data (<= `dstCapacity`), + or 0 if compressed data could not fit into `dst`, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); + +/*! +Tutorial : +---------- +The first step is to count all symbols. FSE_count() does this job very fast. +Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. +'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] +maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) +FSE_count() will return the number of occurrence of the most frequent symbol. +This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). + +The next step is to normalize the frequencies. +FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. +It also guarantees a minimum of 1 to any Symbol with frequency >= 1. +You can use 'tableLog'==0 to mean "use default tableLog value". +If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), +which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). + +The result of FSE_normalizeCount() will be saved into a table, +called 'normalizedCounter', which is a table of signed short. +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. +The return value is tableLog if everything proceeded as expected. +It is 0 if there is a single symbol within distribution. +If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). + +'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). +'buffer' must be already allocated. +For guaranteed success, buffer size must be at least FSE_headerBound(). +The result of the function is the number of bytes written into 'buffer'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). + +'normalizedCounter' can then be used to create the compression table 'CTable'. +The space required by 'CTable' must be already allocated, using FSE_createCTable(). +You can then use FSE_buildCTable() to fill 'CTable'. +If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). + +'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). +Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' +The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. +If it returns '0', compressed data could not fit into 'dst'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). +*/ + + +/* *** DECOMPRESSION *** */ + +/*! FSE_readNCount(): + Read compactly saved 'normalizedCounter' from 'rBuffer'. + @return : size read from 'rBuffer', + or an errorCode, which can be tested using FSE_isError(). + maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ +FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize); + +/*! Constructor and Destructor of FSE_DTable. + Note that its size depends on 'tableLog' */ +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ +FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog); +FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt); + +/*! FSE_buildDTable(): + Builds 'dt', which must be already allocated, using FSE_createDTable(). + return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_decompress_usingDTable(): + Decompress compressed source `cSrc` of size `cSrcSize` using `dt` + into `dst` which must be already allocated. + @return : size of regenerated data (necessarily <= `dstCapacity`), + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt); + +/*! +Tutorial : +---------- +(Note : these functions only decompress FSE-compressed blocks. + If block is uncompressed, use memcpy() instead + If block is a single repeated byte, use memset() instead ) + +The first step is to obtain the normalized frequencies of symbols. +This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. +In practice, that means it's necessary to know 'maxSymbolValue' beforehand, +or size the table to handle worst case situations (typically 256). +FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. +The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. +Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. +This is performed by the function FSE_buildDTable(). +The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). +`cSrcSize` must be strictly correct, otherwise decompression will fail. +FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) +*/ + +#endif /* FSE_H */ + +#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) +#define FSE_H_FSE_STATIC_LINKING_ONLY + +/* *** Dependency *** */ +#include "bitstream.h" + + +/* ***************************************** +* Static allocation +*******************************************/ +/* FSE buffer bounds */ +#define FSE_NCOUNTBOUND 512 +#define FSE_BLOCKBOUND(size) (size + (size>>7)) +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1< 12) ? (1 << (maxTableLog - 2)) : 1024) ) +size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); + +size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits); +/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ + +size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); +/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * `wkspSize` must be >= `(1<= BIT_DStream_completed + +When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. +Checking if DStream has reached its end is performed by : + BIT_endOfDStream(&DStream); +Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. + FSE_endOfDState(&DState); +*/ + + +/* ***************************************** +* FSE unsafe API +*******************************************/ +static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); +/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ + + +/* ***************************************** +* Implementation of inlined functions +*******************************************/ +typedef struct { + int deltaFindState; + U32 deltaNbBits; +} FSE_symbolCompressionTransform; /* total 8 bytes */ + +MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) +{ + const void* ptr = ct; + const U16* u16ptr = (const U16*) ptr; + const U32 tableLog = MEM_read16(ptr); + statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2; + statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1)); + statePtr->stateLog = tableLog; +} + + +/*! FSE_initCState2() : +* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) +* uses the smallest state value possible, saving the cost of this symbol */ +MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) +{ + FSE_initCState(statePtr, ct); + { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* stateTable = (const U16*)(statePtr->stateTable); + U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); + statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; + statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; + } +} + +MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol) +{ + FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* const stateTable = (const U16*)(statePtr->stateTable); + U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); + BIT_addBits(bitC, statePtr->value, nbBitsOut); + statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; +} + +MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) +{ + BIT_addBits(bitC, statePtr->value, statePtr->stateLog); + BIT_flushBits(bitC); +} + + +/* FSE_getMaxNbBits() : + * Approximate maximum cost of a symbol, in bits. + * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16; +} + +/* FSE_bitCost() : + * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; + U32 const threshold = (minNbBits+1) << 16; + assert(tableLog < 16); + assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */ + { U32 const tableSize = 1 << tableLog; + U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); + U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */ + U32 const bitMultiplier = 1 << accuracyLog; + assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); + assert(normalizedDeltaFromThreshold <= bitMultiplier); + return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold; + } +} + + +/* ====== Decompression ====== */ + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +typedef struct +{ + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + +MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + return DInfo.symbol; +} + +MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = DInfo.newState + lowBits; +} + +MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +/*! FSE_decodeSymbolFast() : + unsafe, only works if no symbol has a probability > 50% */ +MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) +{ + return DStatePtr->state == 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/* ************************************************************** +* Tuning parameters +****************************************************************/ +/*!MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#ifndef FSE_MAX_MEMORY_USAGE +# define FSE_MAX_MEMORY_USAGE 14 +#endif +#ifndef FSE_DEFAULT_MEMORY_USAGE +# define FSE_DEFAULT_MEMORY_USAGE 13 +#endif + +/*!FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#ifndef FSE_MAX_SYMBOL_VALUE +# define FSE_MAX_SYMBOL_VALUE 255 +#endif + +/* ************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION +#define FSE_DECODE_TYPE FSE_decode_t + + +#endif /* !FSE_COMMONDEFS_ONLY */ + + +/* *************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) +#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX +# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + +#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3) + + +#endif /* FSE_STATIC_LINKING_ONLY */ + + +#if defined (__cplusplus) +} +#endif diff --git a/grub-core/lib/zstd/fse_decompress.c b/grub-core/lib/zstd/fse_decompress.c new file mode 100644 index 000000000..2227b84bc --- /dev/null +++ b/grub-core/lib/zstd/fse_decompress.c @@ -0,0 +1,309 @@ +/* ****************************************************************** + FSE : Finite State Entropy decoder + Copyright (C) 2013-2015, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + - Public forum : https://groups.google.com/forum/#!forum/lz4c +****************************************************************** */ + + +/* ************************************************************** +* Includes +****************************************************************/ +#include /* malloc, free, qsort */ +#include /* memcpy, memset */ +#include "bitstream.h" +#include "compiler.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "error_private.h" + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError +#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + +/* check and forward error code */ +#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; } + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + +/* Function templates */ +FSE_DTable* FSE_createDTable (unsigned tableLog) +{ + if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; + return (FSE_DTable*)calloc( FSE_DTABLE_SIZE_U32(tableLog), sizeof (U32) ); +} + +void FSE_freeDTable (FSE_DTable* dt) +{ + free(dt); +} + +size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ + FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); + U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize-1; + + /* Sanity Checks */ + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + + /* Init, lay down lowprob symbols */ + { FSE_DTableHeader DTableH; + DTableH.tableLog = (U16)tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + symbolNext[s] = normalizedCounter[s]; + } } } + memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + { U32 const tableMask = tableSize-1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } } + if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { U32 u; + for (u=0; utableLog = 0; + DTableH->fastMode = 0; + + cell->newState = 0; + cell->symbol = symbolValue; + cell->nbBits = 0; + + return 0; +} + + +size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits) +{ + void* ptr = dt; + FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr; + void* dPtr = dt + 1; + FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr; + const unsigned tableSize = 1 << nbBits; + const unsigned tableMask = tableSize - 1; + const unsigned maxSV1 = tableMask+1; + unsigned s; + + /* Sanity checks */ + if (nbBits < 1) return ERROR(GENERIC); /* min size */ + + /* Build Decoding Table */ + DTableH->tableLog = (U16)nbBits; + DTableH->fastMode = 1; + for (s=0; s sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ + while (1) { + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state1); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state2); + break; + } + + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state2); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state1); + break; + } } + + return op-ostart; +} + + +size_t FSE_decompress_usingDTable(void* dst, size_t originalSize, + const void* cSrc, size_t cSrcSize, + const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; + const U32 fastMode = DTableH->fastMode; + + /* select fast mode (static) */ + if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); + return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); +} + + +size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog) +{ + const BYTE* const istart = (const BYTE*)cSrc; + const BYTE* ip = istart; + short counting[FSE_MAX_SYMBOL_VALUE+1]; + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + + /* normal FSE decoding mode */ + size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(NCountLength)) return NCountLength; + //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */ + if (tableLog > maxLog) return ERROR(tableLog_tooLarge); + ip += NCountLength; + cSrcSize -= NCountLength; + + CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) ); + + return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ +} + + +typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; + +size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize) +{ + DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ + return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG); +} + + + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/grub-core/lib/zstd/huf.h b/grub-core/lib/zstd/huf.h new file mode 100644 index 000000000..de9464111 --- /dev/null +++ b/grub-core/lib/zstd/huf.h @@ -0,0 +1,334 @@ +/* ****************************************************************** + huff0 huffman codec, + part of Finite State Entropy library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef HUF_H_298734234 +#define HUF_H_298734234 + +/* *** Dependencies *** */ +#include /* size_t */ + + +/* *** library symbols visibility *** */ +/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual, + * HUF symbols remain "private" (internal symbols for library only). + * Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define HUF_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define HUF_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define HUF_PUBLIC_API __declspec(dllimport) /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */ +#else +# define HUF_PUBLIC_API +#endif + + +/* ========================== */ +/* *** simple functions *** */ +/* ========================== */ + +/** HUF_compress() : + * Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'. + * 'dst' buffer must be already allocated. + * Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize). + * `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB. + * @return : size of compressed data (<= `dstCapacity`). + * Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!! + * if HUF_isError(return), compression failed (more details using HUF_getErrorName()) + */ +HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +/** HUF_decompress() : + * Decompress HUF data from buffer 'cSrc', of size 'cSrcSize', + * into already allocated buffer 'dst', of minimum size 'dstSize'. + * `originalSize` : **must** be the ***exact*** size of original (uncompressed) data. + * Note : in contrast with FSE, HUF_decompress can regenerate + * RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, + * because it knows size to regenerate (originalSize). + * @return : size of regenerated data (== originalSize), + * or an error code, which can be tested using HUF_isError() + */ +HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize, + const void* cSrc, size_t cSrcSize); + + +/* *** Tool functions *** */ +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ +HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ + +/* Error Management */ +HUF_PUBLIC_API unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ +HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ + + +/* *** Advanced function *** */ + +/** HUF_compress2() : + * Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`. + * `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX . + * `tableLog` must be `<= HUF_TABLELOG_MAX` . */ +HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog); + +/** HUF_compress4X_wksp() : + * Same as HUF_compress2(), but uses externally allocated `workSpace`. + * `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */ +#define HUF_WORKSPACE_SIZE (6 << 10) +#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) +HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize); + +#endif /* HUF_H_298734234 */ + +/* ****************************************************************** + * WARNING !! + * The following section contains advanced and experimental definitions + * which shall never be used in the context of a dynamic library, + * because they are not guaranteed to remain stable in the future. + * Only consider them in association with static linking. + * *****************************************************************/ +#if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY) +#define HUF_H_HUF_STATIC_LINKING_ONLY + +/* *** Dependencies *** */ +#include "mem.h" /* U32 */ + + +/* *** Constants *** */ +#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ +#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ +#define HUF_SYMBOLVALUE_MAX 255 + +#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) +# error "HUF_TABLELOG_MAX is too large !" +#endif + + +/* **************************************** +* Static allocation +******************************************/ +/* HUF buffer bounds */ +#define HUF_CTABLEBOUND 129 +#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */ +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* static allocation of HUF's Compression Table */ +#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */ +#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32)) +#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ + U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \ + void* name##hv = &(name##hb); \ + HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */ + +/* static allocation of HUF's DTable */ +typedef U32 HUF_DTable; +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) +#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } +#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } + + +/* **************************************** +* Advanced decompression functions +******************************************/ +size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ + +size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */ +size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */ +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */ +size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ +size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ + + +/* **************************************** + * HUF detailed API + * ****************************************/ + +/*! HUF_compress() does the following: + * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") + * 2. (optional) refine tableLog using HUF_optimalTableLog() + * 3. build Huffman table from count using HUF_buildCTable() + * 4. save Huffman table to memory buffer using HUF_writeCTable() + * 5. encode the data stream using HUF_compress4X_usingCTable() + * + * The following API allows targeting specific sub-functions for advanced tasks. + * For example, it's possible to compress several blocks using the same 'CTable', + * or to save and regenerate 'CTable' using external methods. + */ +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); +typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ +size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */ +size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog); +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); + +typedef enum { + HUF_repeat_none, /**< Cannot use the previous table */ + HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */ + HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } HUF_repeat; +/** HUF_compress4X_repeat() : + * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress4X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE. + */ +#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1) +#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_buildCTable_wksp (HUF_CElt* tree, + const U32* count, U32 maxSymbolValue, U32 maxNbBits, + void* workSpace, size_t wkspSize); + +/*! HUF_readStats() : + * Read compact Huffman tree, saved by HUF_writeCTable(). + * `huffWeight` is destination buffer. + * @return : size read from `src` , or an error Code . + * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize); + +/** HUF_readCTable() : + * Loading a CTable saved with HUF_writeCTable() */ +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize); + +/** HUF_getNbBits() : + * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX + * Note 1 : is not inlined, as HUF_CElt definition is private + * Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */ +U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue); + +/* + * HUF_decompress() does the following: + * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics + * 2. build Huffman table from save, using HUF_readDTableX?() + * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable() + */ + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); + +/** + * The minimum workspace size for the `workSpace` used in + * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp(). + * + * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when + * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. + * Buffer overflow errors may potentially occur if code modifications result in + * a required workspace size greater than that specified in the following + * macro. + */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) + +size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize); +size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); +size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize); +size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); + +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); + + +/* ====================== */ +/* single stream variants */ +/* ====================== */ + +size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); +size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); +/** HUF_compress1X_repeat() : + * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress1X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); + +size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ +size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ + +size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); +size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); +size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ +size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ + +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ +size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); +size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); + +/* BMI2 variants. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); +size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); +size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2); +size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); + +#endif /* HUF_STATIC_LINKING_ONLY */ + +#if defined (__cplusplus) +} +#endif diff --git a/grub-core/lib/zstd/huf_decompress.c b/grub-core/lib/zstd/huf_decompress.c new file mode 100644 index 000000000..83ecaff01 --- /dev/null +++ b/grub-core/lib/zstd/huf_decompress.c @@ -0,0 +1,1096 @@ +/* ****************************************************************** + huff0 huffman decoder, + part of Finite State Entropy library + Copyright (C) 2013-present, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy +****************************************************************** */ + +/* ************************************************************** +* Dependencies +****************************************************************/ +#include /* memcpy, memset */ +#include "compiler.h" +#include "bitstream.h" /* BIT_* */ +#include "fse.h" /* to compress headers */ +#define HUF_STATIC_LINKING_ONLY +#include "huf.h" +#include "error_private.h" + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_isError ERR_isError +#define CHECK_F(f) { size_t const err_ = (f); if (HUF_isError(err_)) return err_; } + + +/* ************************************************************** +* Byte alignment for workSpace management +****************************************************************/ +#define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1) +#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + + +/*-***************************/ +/* generic DTableDesc */ +/*-***************************/ +typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc; + +static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) +{ + DTableDesc dtd; + memcpy(&dtd, table, sizeof(dtd)); + return dtd; +} + + +/*-***************************/ +/* single-symbol decoding */ +/*-***************************/ +typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decoding */ + +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize) +{ + U32 tableLog = 0; + U32 nbSymbols = 0; + size_t iSize; + void* const dtPtr = DTable + 1; + HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr; + + U32* rankVal; + BYTE* huffWeight; + size_t spaceUsed32 = 0; + + rankVal = (U32 *)workSpace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; + huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32); + spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); + + DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); + /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize); + if (HUF_isError(iSize)) return iSize; + + /* Table header */ + { DTableDesc dtd = HUF_getDTableDesc(DTable); + if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ + dtd.tableType = 0; + dtd.tableLog = (BYTE)tableLog; + memcpy(DTable, &dtd, sizeof(dtd)); + } + + /* Calculate starting value for each rank */ + { U32 n, nextRankStart = 0; + for (n=1; n> 1; + U32 u; + HUF_DEltX1 D; + D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w); + for (u = rankVal[w]; u < rankVal[w] + length; u++) + dt[u] = D; + rankVal[w] += length; + } } + + return iSize; +} + +size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_readDTableX1_wksp(DTable, src, srcSize, + workSpace, sizeof(workSpace)); +} + +FORCE_INLINE_TEMPLATE BYTE +HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ + BYTE const c = dt[val].byte; + BIT_skipBits(Dstream, dt[val].nbBits); + return c; +} + +#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \ + *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) + +#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \ + if (MEM_64bits()) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) + +HINT_INLINE size_t +HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 4 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) { + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_1(p, bitDPtr); + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + } + + /* [0-3] symbols remaining */ + if (MEM_32bits()) + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd)) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + /* no more data to retrieve from bitstream, no need to reload */ + while (p < pEnd) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + return pEnd-pStart; +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BYTE* op = (BYTE*)dst; + BYTE* const oend = op + dstSize; + const void* dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + BIT_DStream_t bitD; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog); + + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + return dstSize; +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + /* Check */ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + const void* const dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + const size_t segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + U32 endSignal = BIT_DStream_unfinished; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */ + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + while ( (endSignal==BIT_DStream_unfinished) && (op4<(oend-3)) ) { + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_1(op1, &bitD1); + HUF_DECODE_SYMBOLX1_1(op2, &bitD2); + HUF_DECODE_SYMBOLX1_1(op3, &bitD3); + HUF_DECODE_SYMBOLX1_1(op4, &bitD4); + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_0(op1, &bitD1); + HUF_DECODE_SYMBOLX1_0(op2, &bitD2); + HUF_DECODE_SYMBOLX1_0(op3, &bitD3); + HUF_DECODE_SYMBOLX1_0(op4, &bitD4); + BIT_reloadDStream(&bitD1); + BIT_reloadDStream(&bitD2); + BIT_reloadDStream(&bitD3); + BIT_reloadDStream(&bitD4); + } + + /* check corruption */ + /* note : should not be necessary : op# advance in lock step, and we control op4. + * but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 supposed already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX1(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + + +typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize, + const void *cSrc, + size_t cSrcSize, + const HUF_DTable *DTable); +#if DYNAMIC_BMI2 + +#define HUF_DGEN(fn) \ + \ + static size_t fn##_default( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static TARGET_ATTRIBUTE("bmi2") size_t fn##_bmi2( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int bmi2) \ + { \ + if (bmi2) { \ + return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#else + +#define HUF_DGEN(fn) \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int bmi2) \ + { \ + (void)bmi2; \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#endif + +HUF_DGEN(HUF_decompress1X1_usingDTable_internal) +HUF_DGEN(HUF_decompress4X1_usingDTable_internal) + + + +size_t HUF_decompress1X1_usingDTable( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 0) return ERROR(GENERIC); + return HUF_decompress1X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); +} + +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(DCtx, cSrc, cSrcSize, workSpace, wkspSize); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0); +} + + +size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); + return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize); +} + +size_t HUF_decompress4X1_usingDTable( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 0) return ERROR(GENERIC); + return HUF_decompress4X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); +} + +static size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int bmi2) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp (dctx, cSrc, cSrcSize, + workSpace, wkspSize); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2); +} + +size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, 0); +} + + +size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} +size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX); + return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); +} + + +/* *************************/ +/* double-symbols decoding */ +/* *************************/ + +typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */ +typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t; +typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; +typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX]; + + +/* HUF_fillDTableX2Level2() : + * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ +static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed, + const U32* rankValOrigin, const int minWeight, + const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, + U32 nbBitsBaseline, U16 baseSeq) +{ + HUF_DEltX2 DElt; + U32 rankVal[HUF_TABLELOG_MAX + 1]; + + /* get pre-calculated rankVal */ + memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + + /* fill skipped values */ + if (minWeight>1) { + U32 i, skipSize = rankVal[minWeight]; + MEM_writeLE16(&(DElt.sequence), baseSeq); + DElt.nbBits = (BYTE)(consumed); + DElt.length = 1; + for (i = 0; i < skipSize; i++) + DTable[i] = DElt; + } + + /* fill DTable */ + { U32 s; for (s=0; s= 1 */ + + rankVal[weight] += length; + } } +} + + +static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog, + const sortedSymbol_t* sortedList, const U32 sortedListSize, + const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight, + const U32 nbBitsBaseline) +{ + U32 rankVal[HUF_TABLELOG_MAX + 1]; + const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ + const U32 minBits = nbBitsBaseline - maxWeight; + U32 s; + + memcpy(rankVal, rankValOrigin, sizeof(rankVal)); + + /* fill DTable */ + for (s=0; s= minBits) { /* enough room for a second symbol */ + U32 sortedRank; + int minWeight = nbBits + scaleLog; + if (minWeight < 1) minWeight = 1; + sortedRank = rankStart[minWeight]; + HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits, + rankValOrigin[nbBits], minWeight, + sortedList+sortedRank, sortedListSize-sortedRank, + nbBitsBaseline, symbol); + } else { + HUF_DEltX2 DElt; + MEM_writeLE16(&(DElt.sequence), symbol); + DElt.nbBits = (BYTE)(nbBits); + DElt.length = 1; + { U32 const end = start + length; + U32 u; + for (u = start; u < end; u++) DTable[u] = DElt; + } } + rankVal[weight] += length; + } +} + +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + U32 tableLog, maxW, sizeOfSort, nbSymbols; + DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 const maxTableLog = dtd.maxTableLog; + size_t iSize; + void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */ + HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; + U32 *rankStart; + + rankValCol_t* rankVal; + U32* rankStats; + U32* rankStart0; + sortedSymbol_t* sortedSymbol; + BYTE* weightList; + size_t spaceUsed32 = 0; + + rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32); + spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2; + rankStats = (U32 *)workSpace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 1; + rankStart0 = (U32 *)workSpace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 2; + sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t); + spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; + weightList = (BYTE *)((U32 *)workSpace + spaceUsed32); + spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); + + rankStart = rankStart0 + 1; + memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); + + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ + if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); + if (HUF_isError(iSize)) return iSize; + + /* check result */ + if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ + + /* find maxWeight */ + for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */ + + /* Get start index of each weight */ + { U32 w, nextRankStart = 0; + for (w=1; w> consumed; + } } } } + + HUF_fillDTableX2(dt, maxTableLog, + sortedSymbol, sizeOfSort, + rankStart0, rankVal, maxW, + tableLog+1); + + dtd.tableLog = (BYTE)maxTableLog; + dtd.tableType = 1; + memcpy(DTable, &dtd, sizeof(dtd)); + return iSize; +} + +size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_readDTableX2_wksp(DTable, src, srcSize, + workSpace, sizeof(workSpace)); +} + + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + memcpy(op, dt+val, 2); + BIT_skipBits(DStream, dt[val].nbBits); + return dt[val].length; +} + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + memcpy(op, dt+val, 1); + if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits); + else { + if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { + BIT_skipBits(DStream, dt[val].nbBits); + if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) + /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ + DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); + } } + return 1; +} + +#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) + +#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ + if (MEM_64bits()) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog) + +HINT_INLINE size_t +HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, + const HUF_DEltX2* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 8 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + + /* closer to end : up to 2 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2)) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + while (p <= pEnd-2) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + + if (p < pEnd) + p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog); + + return p-pStart; +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BIT_DStream_t bitD; + + /* Init */ + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + /* decode */ + { BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */ + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog); + } + + /* check */ + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; +} + + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + const void* const dtPtr = DTable+1; + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + size_t const segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + U32 endSignal; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) { + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + } + + /* check corruption */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + +HUF_DGEN(HUF_decompress1X2_usingDTable_internal) +HUF_DGEN(HUF_decompress4X2_usingDTable_internal) + +size_t HUF_decompress1X2_usingDTable( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 1) return ERROR(GENERIC); + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); +} + +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, + workSpace, wkspSize); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0); +} + + +size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); + return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); +} + +size_t HUF_decompress4X2_usingDTable( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + DTableDesc dtd = HUF_getDTableDesc(DTable); + if (dtd.tableType != 1) return ERROR(GENERIC); + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); +} + +static size_t HUF_decompress4X2_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int bmi2) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, + workSpace, wkspSize); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2); +} + +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, /* bmi2 */ 0); +} + + +size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + +size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); + return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize); +} + + +/* ***********************************/ +/* Universal decompression selectors */ +/* ***********************************/ + +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); + return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) : + HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); +} + +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); + return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) : + HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0); +} + + +typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; +static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] = +{ + /* single, double, quad */ + {{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */ + {{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */ + {{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */ + {{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */ + {{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */ + {{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */ + {{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */ + {{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */ + {{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */ + {{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */ + {{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */ + {{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */ + {{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */ + {{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */ + {{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */ + {{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */ +}; + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) +{ + assert(dstSize > 0); + assert(dstSize <= 128*1024); + /* decoder timing evaluation */ + { U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */ + U32 const D256 = (U32)(dstSize >> 8); + U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256); + U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256); + DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, to reduce cache eviction */ + return DTime1 < DTime0; +} } + + +typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); + +size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 }; + + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return decompress[algoNb](dst, dstSize, cSrc, cSrcSize); + } +} + +size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : + HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ; + } +} + +size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + + +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, + size_t dstSize, const void* cSrc, + size_t cSrcSize, void* workSpace, + size_t wkspSize) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize == 0) return ERROR(corruption_detected); + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize): + HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize); + } +} + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize): + HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize); + } +} + +size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + + +size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); + return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) : + HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2); +} + +size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2); +} + +size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); + return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) : + HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2); +} + +size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize == 0) return ERROR(corruption_detected); + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2) : + HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2); + } +} diff --git a/grub-core/lib/zstd/mem.h b/grub-core/lib/zstd/mem.h new file mode 100644 index 000000000..2051bcad1 --- /dev/null +++ b/grub-core/lib/zstd/mem.h @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +#if defined (__cplusplus) +extern "C" { +#endif + +/*-**************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ +#include /* memcpy */ + + +/*-**************************************** +* Compiler specifics +******************************************/ +#if defined(_MSC_VER) /* Visual Studio */ +# include /* _byteswap_ulong */ +# include /* _byteswap_* */ +#endif +#if defined(__GNUC__) +# define MEM_STATIC static __inline __attribute__((unused)) +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define MEM_STATIC static inline +#elif defined(_MSC_VER) +# define MEM_STATIC static __inline +#else +# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + +/* code only tested on 32 and 64 bits systems */ +#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; } +MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } + + +/*-************************************************************** +* Basic Types +*****************************************************************/ +#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef int16_t S16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; + typedef int64_t S64; +#else +# include +#if CHAR_BIT != 8 +# error "this implementation requires char to be exactly 8-bit type" +#endif + typedef unsigned char BYTE; +#if USHRT_MAX != 65535 +# error "this implementation requires short to be exactly 16-bit type" +#endif + typedef unsigned short U16; + typedef signed short S16; +#if UINT_MAX != 4294967295 +# error "this implementation requires int to be exactly 32-bit type" +#endif + typedef unsigned int U32; + typedef signed int S32; +/* note : there are no limits defined for long long type in C90. + * limits exist in C99, however, in such case, is preferred */ + typedef unsigned long long U64; + typedef signed long long S64; +#endif + + +/*-************************************************************** +* Memory I/O +*****************************************************************/ +/* MEM_FORCE_MEMORY_ACCESS : + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets depending on alignment. + * In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6) + * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define MEM_FORCE_MEMORY_ACCESS 2 +# elif defined(__INTEL_COMPILER) || defined(__GNUC__) +# define MEM_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } +MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } + +MEM_STATIC unsigned MEM_isLittleEndian(void) +{ + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +} + +#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) + +/* violates C standard, by lying on structure alignment. +Only use if no other choice to achieve best performance on target platform */ +MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } +MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } +MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } +MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } + +#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32)) + __pragma( pack(push, 1) ) + typedef struct { U16 v; } unalign16; + typedef struct { U32 v; } unalign32; + typedef struct { U64 v; } unalign64; + typedef struct { size_t v; } unalignArch; + __pragma( pack(pop) ) +#else + typedef struct { U16 v; } __attribute__((packed)) unalign16; + typedef struct { U32 v; } __attribute__((packed)) unalign32; + typedef struct { U64 v; } __attribute__((packed)) unalign64; + typedef struct { size_t v; } __attribute__((packed)) unalignArch; +#endif + +MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; } +MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; } +MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; } +MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; } + +#else + +/* default method, safe and standard. + can sometimes prove slower */ + +MEM_STATIC U16 MEM_read16(const void* memPtr) +{ + U16 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U32 MEM_read32(const void* memPtr) +{ + U32 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U64 MEM_read64(const void* memPtr) +{ + U64 val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC size_t MEM_readST(const void* memPtr) +{ + size_t val; memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write32(void* memPtr, U32 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write64(void* memPtr, U64 value) +{ + memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* MEM_FORCE_MEMORY_ACCESS */ + +MEM_STATIC U32 MEM_swap32(U32 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_ulong(in); +#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) + return __builtin_bswap32(in); +#else + return ((in << 24) & 0xff000000 ) | + ((in << 8) & 0x00ff0000 ) | + ((in >> 8) & 0x0000ff00 ) | + ((in >> 24) & 0x000000ff ); +#endif +} + +MEM_STATIC U64 MEM_swap64(U64 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_uint64(in); +#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403) + return __builtin_bswap64(in); +#else + return ((in << 56) & 0xff00000000000000ULL) | + ((in << 40) & 0x00ff000000000000ULL) | + ((in << 24) & 0x0000ff0000000000ULL) | + ((in << 8) & 0x000000ff00000000ULL) | + ((in >> 8) & 0x00000000ff000000ULL) | + ((in >> 24) & 0x0000000000ff0000ULL) | + ((in >> 40) & 0x000000000000ff00ULL) | + ((in >> 56) & 0x00000000000000ffULL); +#endif +} + +MEM_STATIC size_t MEM_swapST(size_t in) +{ + if (MEM_32bits()) + return (size_t)MEM_swap32((U32)in); + else + return (size_t)MEM_swap64((U64)in); +} + +/*=== Little endian r/w ===*/ + +MEM_STATIC U16 MEM_readLE16(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read16(memPtr); + else { + const BYTE* p = (const BYTE*)memPtr; + return (U16)(p[0] + (p[1]<<8)); + } +} + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) +{ + if (MEM_isLittleEndian()) { + MEM_write16(memPtr, val); + } else { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE)val; + p[1] = (BYTE)(val>>8); + } +} + +MEM_STATIC U32 MEM_readLE24(const void* memPtr) +{ + return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16); +} + +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) +{ + MEM_writeLE16(memPtr, (U16)val); + ((BYTE*)memPtr)[2] = (BYTE)(val>>16); +} + +MEM_STATIC U32 MEM_readLE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read32(memPtr); + else + return MEM_swap32(MEM_read32(memPtr)); +} + +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, val32); + else + MEM_write32(memPtr, MEM_swap32(val32)); +} + +MEM_STATIC U64 MEM_readLE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read64(memPtr); + else + return MEM_swap64(MEM_read64(memPtr)); +} + +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, val64); + else + MEM_write64(memPtr, MEM_swap64(val64)); +} + +MEM_STATIC size_t MEM_readLEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readLE32(memPtr); + else + return (size_t)MEM_readLE64(memPtr); +} + +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeLE32(memPtr, (U32)val); + else + MEM_writeLE64(memPtr, (U64)val); +} + +/*=== Big endian r/w ===*/ + +MEM_STATIC U32 MEM_readBE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap32(MEM_read32(memPtr)); + else + return MEM_read32(memPtr); +} + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, MEM_swap32(val32)); + else + MEM_write32(memPtr, val32); +} + +MEM_STATIC U64 MEM_readBE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap64(MEM_read64(memPtr)); + else + return MEM_read64(memPtr); +} + +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, MEM_swap64(val64)); + else + MEM_write64(memPtr, val64); +} + +MEM_STATIC size_t MEM_readBEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readBE32(memPtr); + else + return (size_t)MEM_readBE64(memPtr); +} + +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeBE32(memPtr, (U32)val); + else + MEM_writeBE64(memPtr, (U64)val); +} + + +#if defined (__cplusplus) +} +#endif + +#endif /* MEM_H_MODULE */ diff --git a/grub-core/lib/zstd/module.c b/grub-core/lib/zstd/module.c new file mode 100644 index 000000000..e64d068f4 --- /dev/null +++ b/grub-core/lib/zstd/module.c @@ -0,0 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +GRUB_MOD_LICENSE ("GPLv3"); diff --git a/grub-core/lib/zstd/xxhash.c b/grub-core/lib/zstd/xxhash.c new file mode 100644 index 000000000..532b81619 --- /dev/null +++ b/grub-core/lib/zstd/xxhash.c @@ -0,0 +1,876 @@ +/* +* xxHash - Fast Hash algorithm +* Copyright (C) 2012-2016, Yann Collet +* +* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following disclaimer +* in the documentation and/or other materials provided with the +* distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* You can contact the author at : +* - xxHash homepage: http://www.xxhash.com +* - xxHash source repository : https://github.com/Cyan4973/xxHash +*/ + + +/* ************************************* +* Tuning parameters +***************************************/ +/*!XXH_FORCE_MEMORY_ACCESS : + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. + * It can generate buggy code on targets which do not support unaligned memory accesses. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See http://stackoverflow.com/a/32095106/646947 for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define XXH_FORCE_MEMORY_ACCESS 2 +# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ + (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# define XXH_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +/*!XXH_ACCEPT_NULL_INPUT_POINTER : + * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. + * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. + * By default, this option is disabled. To enable it, uncomment below define : + */ +/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */ + +/*!XXH_FORCE_NATIVE_FORMAT : + * By default, xxHash library provides endian-independant Hash values, based on little-endian convention. + * Results are therefore identical for little-endian and big-endian CPU. + * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. + * Should endian-independance be of no importance for your application, you may set the #define below to 1, + * to improve speed for Big-endian CPU. + * This option has no impact on Little_Endian CPU. + */ +#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ +# define XXH_FORCE_NATIVE_FORMAT 0 +#endif + +/*!XXH_FORCE_ALIGN_CHECK : + * This is a minor performance trick, only useful with lots of very small keys. + * It means : check for aligned/unaligned input. + * The check costs one initial branch per hash; set to 0 when the input data + * is guaranteed to be aligned. + */ +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ +# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +# define XXH_FORCE_ALIGN_CHECK 0 +# else +# define XXH_FORCE_ALIGN_CHECK 1 +# endif +#endif + + +/* ************************************* +* Includes & Memory related functions +***************************************/ +/* Modify the local functions below should you wish to use some other memory routines */ +/* for malloc(), free() */ +#include +#include /* size_t */ +static void* XXH_malloc(size_t s) { return malloc(s); } +static void XXH_free (void* p) { free(p); } +/* for memcpy() */ +#include +static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } + +#ifndef XXH_STATIC_LINKING_ONLY +# define XXH_STATIC_LINKING_ONLY +#endif +#include "xxhash.h" + + +/* ************************************* +* Compiler Specific Options +***************************************/ +#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# define INLINE_KEYWORD inline +#else +# define INLINE_KEYWORD +#endif + +#if defined(__GNUC__) +# define FORCE_INLINE_ATTR __attribute__((always_inline)) +#elif defined(_MSC_VER) +# define FORCE_INLINE_ATTR __forceinline +#else +# define FORCE_INLINE_ATTR +#endif + +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR + + +#ifdef _MSC_VER +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + + +/* ************************************* +* Basic Types +***************************************/ +#ifndef MEM_MODULE +# define MEM_MODULE +# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; +# else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; + typedef signed int S32; + typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */ +# endif +#endif + + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } +static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign; + +static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } +static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } + +#else + +/* portable and safe solution. Generally efficient. + * see : http://stackoverflow.com/a/32095106/646947 + */ + +static U32 XXH_read32(const void* memPtr) +{ + U32 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +static U64 XXH_read64(const void* memPtr) +{ + U64 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + + +/* **************************************** +* Compiler-specific Functions and Macros +******************************************/ +#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ +#if defined(_MSC_VER) +# define XXH_rotl32(x,r) _rotl(x,r) +# define XXH_rotl64(x,r) _rotl64(x,r) +#else +# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) +# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) +#endif + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap32 _byteswap_ulong +# define XXH_swap64 _byteswap_uint64 +#elif GCC_VERSION >= 403 +# define XXH_swap32 __builtin_bswap32 +# define XXH_swap64 __builtin_bswap64 +#else +static U32 XXH_swap32 (U32 x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +static U64 XXH_swap64 (U64 x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif + + +/* ************************************* +* Architecture Macros +***************************************/ +typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; + +/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ +#ifndef XXH_CPU_LITTLE_ENDIAN + static const int g_one = 1; +# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one)) +#endif + + +/* *************************** +* Memory reads +*****************************/ +typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; + +FORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); + else + return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); +} + +FORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) +{ + return XXH_readLE32_align(ptr, endian, XXH_unaligned); +} + +static U32 XXH_readBE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); +} + +FORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); + else + return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); +} + +FORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) +{ + return XXH_readLE64_align(ptr, endian, XXH_unaligned); +} + +static U64 XXH_readBE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); +} + + +/* ************************************* +* Macros +***************************************/ +#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ + + +/* ************************************* +* Constants +***************************************/ +static const U32 PRIME32_1 = 2654435761U; +static const U32 PRIME32_2 = 2246822519U; +static const U32 PRIME32_3 = 3266489917U; +static const U32 PRIME32_4 = 668265263U; +static const U32 PRIME32_5 = 374761393U; + +static const U64 PRIME64_1 = 11400714785074694791ULL; +static const U64 PRIME64_2 = 14029467366897019727ULL; +static const U64 PRIME64_3 = 1609587929392839161ULL; +static const U64 PRIME64_4 = 9650029242287828579ULL; +static const U64 PRIME64_5 = 2870177450012600261ULL; + +XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } + + +/* ************************** +* Utils +****************************/ +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + + +/* *************************** +* Simple Hash Functions +*****************************/ + +static U32 XXH32_round(U32 seed, U32 input) +{ + seed += input * PRIME32_2; + seed = XXH_rotl32(seed, 13); + seed *= PRIME32_1; + return seed; +} + +FORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U32 h32; +#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) { + len=0; + bEnd=p=(const BYTE*)(size_t)16; + } +#endif + + if (len>=16) { + const BYTE* const limit = bEnd - 16; + U32 v1 = seed + PRIME32_1 + PRIME32_2; + U32 v2 = seed + PRIME32_2; + U32 v3 = seed + 0; + U32 v4 = seed - PRIME32_1; + + do { + v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; + v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; + v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; + v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; + } while (p<=limit); + + h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + } else { + h32 = seed + PRIME32_5; + } + + h32 += (U32) len; + + while (p+4<=bEnd) { + h32 += XXH_get32bits(p) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH32_CREATESTATE_STATIC(state); + XXH32_reset(state, seed); + XXH32_update(state, input, len); + return XXH32_digest(state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + + +static U64 XXH64_round(U64 acc, U64 input) +{ + acc += input * PRIME64_2; + acc = XXH_rotl64(acc, 31); + acc *= PRIME64_1; + return acc; +} + +static U64 XXH64_mergeRound(U64 acc, U64 val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * PRIME64_1 + PRIME64_4; + return acc; +} + +FORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + U64 h64; +#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (p==NULL) { + len=0; + bEnd=p=(const BYTE*)(size_t)32; + } +#endif + + if (len>=32) { + const BYTE* const limit = bEnd - 32; + U64 v1 = seed + PRIME64_1 + PRIME64_2; + U64 v2 = seed + PRIME64_2; + U64 v3 = seed + 0; + U64 v4 = seed - PRIME64_1; + + do { + v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; + v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; + v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; + v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; + } while (p<=limit); + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + + } else { + h64 = seed + PRIME64_5; + } + + h64 += (U64) len; + + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_get64bits(p)); + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) { + h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + + +XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH64_CREATESTATE_STATIC(state); + XXH64_reset(state, seed); + XXH64_update(state, input, len); + return XXH64_digest(state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + + +/* ************************************************** +* Advanced Hash Functions +****************************************************/ + +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) +{ + return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) +{ + return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + + +/*** Hash feed ***/ + +XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) +{ + XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */ + state.v1 = seed + PRIME32_1 + PRIME32_2; + state.v2 = seed + PRIME32_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME32_1; + memcpy(statePtr, &state, sizeof(state)); + return XXH_OK; +} + + +XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) +{ + XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */ + state.v1 = seed + PRIME64_1 + PRIME64_2; + state.v2 = seed + PRIME64_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME64_1; + memcpy(statePtr, &state, sizeof(state)); + return XXH_OK; +} + + +FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len_32 += (unsigned)len; + state->large_len |= (len>=16) | (state->total_len_32>=16); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); + state->memsize += (unsigned)len; + return XXH_OK; + } + + if (state->memsize) { /* some data left from previous update */ + XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); + { const U32* p32 = state->mem32; + state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; + state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; + state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; + state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++; + } + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= bEnd-16) { + const BYTE* const limit = bEnd - 16; + U32 v1 = state->v1; + U32 v2 = state->v2; + U32 v3 = state->v3; + U32 v4 = state->v4; + + do { + v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; + v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; + v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; + v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH32_update_endian(state_in, input, len, XXH_bigEndian); +} + + + +FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) +{ + const BYTE * p = (const BYTE*)state->mem32; + const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; + U32 h32; + + if (state->large_len) { + h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); + } else { + h32 = state->v3 /* == seed */ + PRIME32_5; + } + + h32 += state->total_len_32; + + while (p+4<=bEnd) { + h32 += XXH_readLE32(p, endian) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_digest_endian(state_in, XXH_littleEndian); + else + return XXH32_digest_endian(state_in, XXH_bigEndian); +} + + + +/* **** XXH64 **** */ + +FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + +#ifdef XXH_ACCEPT_NULL_INPUT_POINTER + if (input==NULL) return XXH_ERROR; +#endif + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); + state->memsize += (U32)len; + return XXH_OK; + } + + if (state->memsize) { /* tmp buffer is full */ + XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); + state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); + state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); + state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); + state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); + p += 32-state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) { + const BYTE* const limit = bEnd - 32; + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + do { + v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; + v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; + v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; + v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH64_update_endian(state_in, input, len, XXH_bigEndian); +} + + + +FORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) +{ + const BYTE * p = (const BYTE*)state->mem64; + const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; + U64 h64; + + if (state->total_len >= 32) { + U64 const v1 = state->v1; + U64 const v2 = state->v2; + U64 const v3 = state->v3; + U64 const v4 = state->v4; + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + } else { + h64 = state->v3 + PRIME64_5; + } + + h64 += (U64) state->total_len; + + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian)); + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) { + h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + + +XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_digest_endian(state_in, XXH_littleEndian); + else + return XXH64_digest_endian(state_in, XXH_bigEndian); +} + + +/* ************************** +* Canonical representation +****************************/ + +/*! Default XXH result types are basic unsigned 32 and 64 bits. +* The canonical representation follows human-readable write convention, aka big-endian (large digits first). +* These functions allow transformation of hash result into and from its canonical format. +* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs. +*/ + +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); + memcpy(dst, &hash, sizeof(*dst)); +} + +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); + memcpy(dst, &hash, sizeof(*dst)); +} + +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) +{ + return XXH_readBE32(src); +} + +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) +{ + return XXH_readBE64(src); +} diff --git a/grub-core/lib/zstd/xxhash.h b/grub-core/lib/zstd/xxhash.h new file mode 100644 index 000000000..9bad1f59f --- /dev/null +++ b/grub-core/lib/zstd/xxhash.h @@ -0,0 +1,305 @@ +/* + xxHash - Extremely Fast Hash algorithm + Header File + Copyright (C) 2012-2016, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - xxHash source repository : https://github.com/Cyan4973/xxHash +*/ + +/* Notice extracted from xxHash homepage : + +xxHash is an extremely fast Hash algorithm, running at RAM speed limits. +It also successfully passes all tests from the SMHasher suite. + +Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) + +Name Speed Q.Score Author +xxHash 5.4 GB/s 10 +CrapWow 3.2 GB/s 2 Andrew +MumurHash 3a 2.7 GB/s 10 Austin Appleby +SpookyHash 2.0 GB/s 10 Bob Jenkins +SBox 1.4 GB/s 9 Bret Mulvey +Lookup3 1.2 GB/s 9 Bob Jenkins +SuperFastHash 1.2 GB/s 1 Paul Hsieh +CityHash64 1.05 GB/s 10 Pike & Alakuijala +FNV 0.55 GB/s 5 Fowler, Noll, Vo +CRC32 0.43 GB/s 9 +MD5-32 0.33 GB/s 10 Ronald L. Rivest +SHA1-32 0.28 GB/s 10 + +Q.Score is a measure of quality of the hash function. +It depends on successfully passing SMHasher test set. +10 is a perfect score. + +A 64-bits version, named XXH64, is available since r35. +It offers much better speed, but for 64-bits applications only. +Name Speed on 64 bits Speed on 32 bits +XXH64 13.8 GB/s 1.9 GB/s +XXH32 6.8 GB/s 6.0 GB/s +*/ + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef XXHASH_H_5627135585666179 +#define XXHASH_H_5627135585666179 1 + + +/* **************************** +* Definitions +******************************/ +#include /* size_t */ +typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; + + +/* **************************** +* API modifier +******************************/ +/** XXH_PRIVATE_API +* This is useful if you want to include xxhash functions in `static` mode +* in order to inline them, and remove their symbol from the public list. +* Methodology : +* #define XXH_PRIVATE_API +* #include "xxhash.h" +* `xxhash.c` is automatically included. +* It's not useful to compile and link it as a separate module anymore. +*/ +#ifdef XXH_PRIVATE_API +# ifndef XXH_STATIC_LINKING_ONLY +# define XXH_STATIC_LINKING_ONLY +# endif +# if defined(__GNUC__) +# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define XXH_PUBLIC_API static inline +# elif defined(_MSC_VER) +# define XXH_PUBLIC_API static __inline +# else +# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */ +# endif +#else +# define XXH_PUBLIC_API /* do nothing */ +#endif /* XXH_PRIVATE_API */ + +/*!XXH_NAMESPACE, aka Namespace Emulation : + +If you want to include _and expose_ xxHash functions from within your own library, +but also want to avoid symbol collisions with another library which also includes xxHash, + +you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library +with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values). + +Note that no change is required within the calling program as long as it includes `xxhash.h` : +regular symbol name will be automatically translated by this header. +*/ +#ifdef XXH_NAMESPACE +# define XXH_CAT(A,B) A##B +# define XXH_NAME2(A,B) XXH_CAT(A,B) +# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) +# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) +# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) +# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) +# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) +# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) +# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) +# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) +# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) +# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) +# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) +# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) +# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) +# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) +# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) +# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) +# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) +# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) +#endif + + +/* ************************************* +* Version +***************************************/ +#define XXH_VERSION_MAJOR 0 +#define XXH_VERSION_MINOR 6 +#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) +XXH_PUBLIC_API unsigned XXH_versionNumber (void); + + +/* **************************** +* Simple Hash Functions +******************************/ +typedef unsigned int XXH32_hash_t; +typedef unsigned long long XXH64_hash_t; + +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); +XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); + +/*! +XXH32() : + Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". + The memory between input & input+length must be valid (allocated and read-accessible). + "seed" can be used to alter the result predictably. + Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s +XXH64() : + Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". + "seed" can be used to alter the result predictably. + This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark). +*/ + + +/* **************************** +* Streaming Hash Functions +******************************/ +typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ +typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ + +/*! State allocation, compatible with dynamic libraries */ + +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); + +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); + + +/* hash streaming */ + +XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); + +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); + +/* +These functions generate the xxHash of an input provided in multiple segments. +Note that, for small input, they are slower than single-call functions, due to state management. +For small input, prefer `XXH32()` and `XXH64()` . + +XXH state must first be allocated, using XXH*_createState() . + +Start a new hash by initializing state with a seed, using XXH*_reset(). + +Then, feed the hash state by calling XXH*_update() as many times as necessary. +Obviously, input must be allocated and read accessible. +The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. + +Finally, a hash value can be produced anytime, by using XXH*_digest(). +This function returns the nn-bits hash as an int or long long. + +It's still possible to continue inserting input into the hash state after a digest, +and generate some new hashes later on, by calling again XXH*_digest(). + +When done, free XXH state space if it was allocated dynamically. +*/ + + +/* ************************** +* Utils +****************************/ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */ +# define restrict /* disable restrict */ +#endif + +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state); +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state); + + +/* ************************** +* Canonical representation +****************************/ +/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. +* The canonical representation uses human-readable write convention, aka big-endian (large digits first). +* These functions allow transformation of hash result into and from its canonical format. +* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. +*/ +typedef struct { unsigned char digest[4]; } XXH32_canonical_t; +typedef struct { unsigned char digest[8]; } XXH64_canonical_t; + +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); + +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); + +#endif /* XXHASH_H_5627135585666179 */ + + + +/* ================================================================================================ + This section contains definitions which are not guaranteed to remain stable. + They may change in future versions, becoming incompatible with a different version of the library. + They shall only be used with static linking. + Never use these definitions in association with dynamic linking ! +=================================================================================================== */ +#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXH_STATIC_H_3543687687345) +#define XXH_STATIC_H_3543687687345 + +/* These definitions are only meant to allow allocation of XXH state + statically, on stack, or in a struct for example. + Do not use members directly. */ + + struct XXH32_state_s { + unsigned total_len_32; + unsigned large_len; + unsigned v1; + unsigned v2; + unsigned v3; + unsigned v4; + unsigned mem32[4]; /* buffer defined as U32 for alignment */ + unsigned memsize; + unsigned reserved; /* never read nor write, will be removed in a future version */ + }; /* typedef'd to XXH32_state_t */ + + struct XXH64_state_s { + unsigned long long total_len; + unsigned long long v1; + unsigned long long v2; + unsigned long long v3; + unsigned long long v4; + unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ + unsigned memsize; + unsigned reserved[2]; /* never read nor write, will be removed in a future version */ + }; /* typedef'd to XXH64_state_t */ + + +# ifdef XXH_PRIVATE_API +# include "xxhash.c" /* include xxhash functions as `static`, for inlining */ +# endif + +#endif /* XXH_STATIC_LINKING_ONLY && XXH_STATIC_H_3543687687345 */ + + +#if defined (__cplusplus) +} +#endif diff --git a/grub-core/lib/zstd/zstd.h b/grub-core/lib/zstd/zstd.h new file mode 100644 index 000000000..7b6964be3 --- /dev/null +++ b/grub-core/lib/zstd/zstd.h @@ -0,0 +1,1516 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef ZSTD_H_235446 +#define ZSTD_H_235446 + +/* ====== Dependency ======*/ +#include /* size_t */ + + +/* ===== ZSTDLIB_API : control library symbols visibility ===== */ +#ifndef ZSTDLIB_VISIBILITY +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default"))) +# else +# define ZSTDLIB_VISIBILITY +# endif +#endif +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZSTDLIB_API ZSTDLIB_VISIBILITY +#endif + + +/******************************************************************************* + Introduction + + zstd, short for Zstandard, is a fast lossless compression algorithm, targeting + real-time compression scenarios at zlib-level and better compression ratios. + The zstd compression library provides in-memory compression and decompression + functions. + + The library supports regular compression levels from 1 up to ZSTD_maxCLevel(), + which is currently 22. Levels >= 20, labeled `--ultra`, should be used with + caution, as they require more memory. The library also offers negative + compression levels, which extend the range of speed vs. ratio preferences. + The lower the level, the faster the speed (at the cost of compression). + + Compression can be done in: + - a single step (described as Simple API) + - a single step, reusing a context (described as Explicit context) + - unbounded multiple steps (described as Streaming compression) + + The compression ratio achievable on small data can be highly improved using + a dictionary. Dictionary compression can be performed in: + - a single step (described as Simple dictionary API) + - a single step, reusing a dictionary (described as Bulk-processing + dictionary API) + + Advanced experimental functions can be accessed using + `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h. + + Advanced experimental APIs should never be used with a dynamically-linked + library. They are not "stable"; their definitions or signatures may change in + the future. Only static linking is allowed. +*******************************************************************************/ + +/*------ Version ------*/ +#define ZSTD_VERSION_MAJOR 1 +#define ZSTD_VERSION_MINOR 3 +#define ZSTD_VERSION_RELEASE 6 + +#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) +ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< useful to check dll version */ + +#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE +#define ZSTD_QUOTE(str) #str +#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) +#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) +ZSTDLIB_API const char* ZSTD_versionString(void); /* v1.3.0+ */ + +/*************************************** +* Default constant +***************************************/ +#ifndef ZSTD_CLEVEL_DEFAULT +# define ZSTD_CLEVEL_DEFAULT 3 +#endif + +/*************************************** +* Simple API +***************************************/ +/*! ZSTD_compress() : + * Compresses `src` content as a single zstd compressed frame into already allocated `dst`. + * Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. + * @return : compressed size written into `dst` (<= `dstCapacity), + * or an error code if it fails (which can be tested using ZSTD_isError()). */ +ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel); + +/*! ZSTD_decompress() : + * `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames. + * `dstCapacity` is an upper bound of originalSize to regenerate. + * If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. + * @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), + * or an errorCode if it fails (which can be tested using ZSTD_isError()). */ +ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity, + const void* src, size_t compressedSize); + +/*! ZSTD_getFrameContentSize() : added in v1.3.0 + * `src` should point to the start of a ZSTD encoded frame. + * `srcSize` must be at least as large as the frame header. + * hint : any size >= `ZSTD_frameHeaderSize_max` is large enough. + * @return : - decompressed size of `src` frame content, if known + * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) + * note 1 : a 0 return value means the frame is valid but "empty". + * note 2 : decompressed size is an optional field, it may not be present, typically in streaming mode. + * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. + * In which case, it's necessary to use streaming mode to decompress data. + * Optionally, application can rely on some implicit limit, + * as ZSTD_decompress() only needs an upper bound of decompressed size. + * (For example, data could be necessarily cut into blocks <= 16 KB). + * note 3 : decompressed size is always present when compression is completed using single-pass functions, + * such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict(). + * note 4 : decompressed size can be very large (64-bits value), + * potentially larger than what local system can handle as a single memory segment. + * In which case, it's necessary to use streaming mode to decompress data. + * note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified. + * Always ensure return value fits within application's authorized limits. + * Each application can set its own limits. + * note 6 : This function replaces ZSTD_getDecompressedSize() */ +#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) +#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) +ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); + +/*! ZSTD_getDecompressedSize() : + * NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize(). + * Both functions work the same way, but ZSTD_getDecompressedSize() blends + * "empty", "unknown" and "error" results to the same return value (0), + * while ZSTD_getFrameContentSize() gives them separate return values. + * @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */ +ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); + + +/*====== Helper functions ======*/ +#define ZSTD_COMPRESSBOUND(srcSize) ((srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */ +ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ +ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ +ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */ +ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */ + + +/*************************************** +* Explicit context +***************************************/ +/*= Compression context + * When compressing many times, + * it is recommended to allocate a context just once, and re-use it for each successive compression operation. + * This will make workload friendlier for system's memory. + * Use one context per thread for parallel execution in multi-threaded environments. */ +typedef struct ZSTD_CCtx_s ZSTD_CCtx; +ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void); +ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); + +/*! ZSTD_compressCCtx() : + * Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */ +ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel); + +/*= Decompression context + * When decompressing many times, + * it is recommended to allocate a context only once, + * and re-use it for each successive compression operation. + * This will make workload friendlier for system's memory. + * Use one context per thread for parallel execution. */ +typedef struct ZSTD_DCtx_s ZSTD_DCtx; +ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void); +ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); + +/*! ZSTD_decompressDCtx() : + * Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()) */ +ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + + +/************************** +* Simple dictionary API +***************************/ +/*! ZSTD_compress_usingDict() : + * Compression using a predefined Dictionary (see dictBuilder/zdict.h). + * Note : This function loads the dictionary, resulting in significant startup delay. + * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ +ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + int compressionLevel); + +/*! ZSTD_decompress_usingDict() : + * Decompression using a predefined Dictionary (see dictBuilder/zdict.h). + * Dictionary must be identical to the one used during compression. + * Note : This function loads the dictionary, resulting in significant startup delay. + * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ +ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize); + + +/********************************** + * Bulk processing dictionary API + *********************************/ +typedef struct ZSTD_CDict_s ZSTD_CDict; + +/*! ZSTD_createCDict() : + * When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. + * ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. + * ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only. + * `dictBuffer` can be released after ZSTD_CDict creation, since its content is copied within CDict + * Note : A ZSTD_CDict can be created with an empty dictionary, but it is inefficient for small data. */ +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, + int compressionLevel); + +/*! ZSTD_freeCDict() : + * Function frees memory allocated by ZSTD_createCDict(). */ +ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict); + +/*! ZSTD_compress_usingCDict() : + * Compression using a digested Dictionary. + * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. + * Note that compression level is decided during dictionary creation. + * Frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) + * Note : ZSTD_compress_usingCDict() can be used with a ZSTD_CDict created from an empty dictionary. + * But it is inefficient for small data, and it is recommended to use ZSTD_compressCCtx(). */ +ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict); + + +typedef struct ZSTD_DDict_s ZSTD_DDict; + +/*! ZSTD_createDDict() : + * Create a digested dictionary, ready to start decompression operation without startup delay. + * dictBuffer can be released after DDict creation, as its content is copied inside DDict */ +ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize); + +/*! ZSTD_freeDDict() : + * Function frees memory allocated with ZSTD_createDDict() */ +ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict); + +/*! ZSTD_decompress_usingDDict() : + * Decompression using a digested Dictionary. + * Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */ +ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_DDict* ddict); + + +/**************************** +* Streaming +****************************/ + +typedef struct ZSTD_inBuffer_s { + const void* src; /**< start of input buffer */ + size_t size; /**< size of input buffer */ + size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */ +} ZSTD_inBuffer; + +typedef struct ZSTD_outBuffer_s { + void* dst; /**< start of output buffer */ + size_t size; /**< size of output buffer */ + size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */ +} ZSTD_outBuffer; + + + +/*-*********************************************************************** +* Streaming compression - HowTo +* +* A ZSTD_CStream object is required to track streaming operation. +* Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources. +* ZSTD_CStream objects can be reused multiple times on consecutive compression operations. +* It is recommended to re-use ZSTD_CStream in situations where many streaming operations will be achieved consecutively, +* since it will play nicer with system's memory, by re-using already allocated memory. +* Use one separate ZSTD_CStream per thread for parallel execution. +* +* Start a new compression by initializing ZSTD_CStream context. +* Use ZSTD_initCStream() to start a new compression operation. +* Use variants ZSTD_initCStream_usingDict() or ZSTD_initCStream_usingCDict() for streaming with dictionary (experimental section) +* +* Use ZSTD_compressStream() as many times as necessary to consume input stream. +* The function will automatically update both `pos` fields within `input` and `output`. +* Note that the function may not consume the entire input, +* for example, because the output buffer is already full, +* in which case `input.pos < input.size`. +* The caller must check if input has been entirely consumed. +* If not, the caller must make some room to receive more compressed data, +* typically by emptying output buffer, or allocating a new output buffer, +* and then present again remaining input data. +* @return : a size hint, preferred nb of bytes to use as input for next function call +* or an error code, which can be tested using ZSTD_isError(). +* Note 1 : it's just a hint, to help latency a little, any other value will work fine. +* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() +* +* At any moment, it's possible to flush whatever data might remain stuck within internal buffer, +* using ZSTD_flushStream(). `output->pos` will be updated. +* Note that, if `output->size` is too small, a single invocation of ZSTD_flushStream() might not be enough (return code > 0). +* In which case, make some room to receive more compressed data, and call again ZSTD_flushStream(). +* @return : 0 if internal buffers are entirely flushed, +* >0 if some data still present within internal buffer (the value is minimal estimation of remaining size), +* or an error code, which can be tested using ZSTD_isError(). +* +* ZSTD_endStream() instructs to finish a frame. +* It will perform a flush and write frame epilogue. +* The epilogue is required for decoders to consider a frame completed. +* flush() operation is the same, and follows same rules as ZSTD_flushStream(). +* @return : 0 if frame fully completed and fully flushed, +* >0 if some data still present within internal buffer (the value is minimal estimation of remaining size), +* or an error code, which can be tested using ZSTD_isError(). +* +* *******************************************************************/ + +typedef ZSTD_CCtx ZSTD_CStream; /**< CCtx and CStream are now effectively same object (>= v1.3.0) */ + /* Continue to distinguish them for compatibility with older versions <= v1.2.0 */ +/*===== ZSTD_CStream management functions =====*/ +ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void); +ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); + +/*===== Streaming compression functions =====*/ +ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel); +ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); +ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output); +ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output); + +ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */ +ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */ + + + +/*-*************************************************************************** +* Streaming decompression - HowTo +* +* A ZSTD_DStream object is required to track streaming operations. +* Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources. +* ZSTD_DStream objects can be re-used multiple times. +* +* Use ZSTD_initDStream() to start a new decompression operation, +* or ZSTD_initDStream_usingDict() if decompression requires a dictionary. +* @return : recommended first input size +* +* Use ZSTD_decompressStream() repetitively to consume your input. +* The function will update both `pos` fields. +* If `input.pos < input.size`, some input has not been consumed. +* It's up to the caller to present again remaining data. +* If `output.pos < output.size`, decoder has flushed everything it could. +* @return : 0 when a frame is completely decoded and fully flushed, +* an error code, which can be tested using ZSTD_isError(), +* any other value > 0, which means there is still some decoding to do to complete current frame. +* The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame. +* *******************************************************************************/ + +typedef ZSTD_DCtx ZSTD_DStream; /**< DCtx and DStream are now effectively same object (>= v1.3.0) */ + /* For compatibility with versions <= v1.2.0, continue to consider them separated. */ +/*===== ZSTD_DStream management functions =====*/ +ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void); +ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds); + +/*===== Streaming decompression functions =====*/ +ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds); +ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); + +ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */ +ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */ + +#endif /* ZSTD_H_235446 */ + + + + +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY + +/**************************************************************************************** + * ADVANCED AND EXPERIMENTAL FUNCTIONS + **************************************************************************************** + * The definitions in this section are considered experimental. + * They should never be used with a dynamic library, as prototypes may change in the future. + * They are provided for advanced scenarios. + * Use them only in association with static linking. + * ***************************************************************************************/ + +ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed */ + +/* --- Constants ---*/ +#define ZSTD_MAGICNUMBER 0xFD2FB528 /* v0.8+ */ +#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* v0.7+ */ +#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U + +#define ZSTD_BLOCKSIZELOG_MAX 17 +#define ZSTD_BLOCKSIZE_MAX (1<= first frame size + * @return : the compressed size of the first frame starting at `src`, + * suitable to pass to `ZSTD_decompress` or similar, + * or an error code if input is invalid */ +ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize); + +/*! ZSTD_findDecompressedSize() : + * `src` should point the start of a series of ZSTD encoded and/or skippable frames + * `srcSize` must be the _exact_ size of this series + * (i.e. there should be a frame boundary exactly at `srcSize` bytes after `src`) + * @return : - decompressed size of all data in all successive frames + * - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN + * - if an error occurred: ZSTD_CONTENTSIZE_ERROR + * + * note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. + * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. + * In which case, it's necessary to use streaming mode to decompress data. + * note 2 : decompressed size is always present when compression is done with ZSTD_compress() + * note 3 : decompressed size can be very large (64-bits value), + * potentially larger than what local system can handle as a single memory segment. + * In which case, it's necessary to use streaming mode to decompress data. + * note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. + * Always ensure result fits within application's authorized limits. + * Each application can set its own limits. + * note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to + * read each contained frame header. This is fast as most of the data is skipped, + * however it does mean that all frame data must be present and valid. */ +ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize); + +/*! ZSTD_frameHeaderSize() : + * srcSize must be >= ZSTD_frameHeaderSize_prefix. + * @return : size of the Frame Header, + * or an error code (if srcSize is too small) */ +ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); + + +/*************************************** +* Memory management +***************************************/ + +/*! ZSTD_sizeof_*() : + * These functions give the current memory usage of selected object. + * Object memory usage can evolve when re-used. */ +ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); +ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx); +ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs); +ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds); +ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict); +ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); + +/*! ZSTD_estimate*() : + * These functions make it possible to estimate memory usage + * of a future {D,C}Ctx, before its creation. + * ZSTD_estimateCCtxSize() will provide a budget large enough for any compression level up to selected one. + * It will also consider src size to be arbitrarily "large", which is worst case. + * If srcSize is known to always be small, ZSTD_estimateCCtxSize_usingCParams() can provide a tighter estimation. + * ZSTD_estimateCCtxSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. + * ZSTD_estimateCCtxSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbWorkers is >= 1. + * Note : CCtx size estimation is only correct for single-threaded compression. */ +ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel); +ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams); +ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params); +ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); + +/*! ZSTD_estimateCStreamSize() : + * ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one. + * It will also consider src size to be arbitrarily "large", which is worst case. + * If srcSize is known to always be small, ZSTD_estimateCStreamSize_usingCParams() can provide a tighter estimation. + * ZSTD_estimateCStreamSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. + * ZSTD_estimateCStreamSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbWorkers is >= 1. + * Note : CStream size estimation is only correct for single-threaded compression. + * ZSTD_DStream memory budget depends on window Size. + * This information can be passed manually, using ZSTD_estimateDStreamSize, + * or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame(); + * Note : if streaming is init with function ZSTD_init?Stream_usingDict(), + * an internal ?Dict will be created, which additional size is not estimated here. + * In this case, get total size by adding ZSTD_estimate?DictSize */ +ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel); +ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams); +ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params); +ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize); +ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize); + +/*! ZSTD_estimate?DictSize() : + * ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict(). + * ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced(). + * Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller. + */ +ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel); +ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod); +ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod); + +/*! ZSTD_initStatic*() : + * Initialize an object using a pre-allocated fixed-size buffer. + * workspace: The memory area to emplace the object into. + * Provided pointer *must be 8-bytes aligned*. + * Buffer must outlive object. + * workspaceSize: Use ZSTD_estimate*Size() to determine + * how large workspace must be to support target scenario. + * @return : pointer to object (same address as workspace, just different type), + * or NULL if error (size too small, incorrect alignment, etc.) + * Note : zstd will never resize nor malloc() when using a static buffer. + * If the object requires more memory than available, + * zstd will just error out (typically ZSTD_error_memory_allocation). + * Note 2 : there is no corresponding "free" function. + * Since workspace is allocated externally, it must be freed externally too. + * Note 3 : cParams : use ZSTD_getCParams() to convert a compression level + * into its associated cParams. + * Limitation 1 : currently not compatible with internal dictionary creation, triggered by + * ZSTD_CCtx_loadDictionary(), ZSTD_initCStream_usingDict() or ZSTD_initDStream_usingDict(). + * Limitation 2 : static cctx currently not compatible with multi-threading. + * Limitation 3 : static dctx is incompatible with legacy support. + */ +ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); +ZSTDLIB_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */ + +ZSTDLIB_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize); +ZSTDLIB_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticDCtx() */ + +ZSTDLIB_API const ZSTD_CDict* ZSTD_initStaticCDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams); + +ZSTDLIB_API const ZSTD_DDict* ZSTD_initStaticDDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType); + +/*! Custom memory allocation : + * These prototypes make it possible to pass your own allocation/free functions. + * ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below. + * All allocation/free operations will be completed using these custom variants instead of regular ones. + */ +typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); +typedef void (*ZSTD_freeFunction) (void* opaque, void* address); +typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; +static ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */ + +ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); +ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); +ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem); +ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem); + +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem); + +ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_customMem customMem); + + + +/*************************************** +* Advanced compression functions +***************************************/ + +/*! ZSTD_createCDict_byReference() : + * Create a digested dictionary for compression + * Dictionary content is simply referenced, and therefore stays in dictBuffer. + * It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict */ +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); + +/*! ZSTD_getCParams() : +* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. +* `estimatedSrcSize` value is optional, select 0 if not known */ +ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); + +/*! ZSTD_getParams() : +* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. +* All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */ +ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); + +/*! ZSTD_checkCParams() : +* Ensure param values remain within authorized range */ +ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); + +/*! ZSTD_adjustCParams() : + * optimize params for a given `srcSize` and `dictSize`. + * both values are optional, select `0` if unknown. */ +ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); + +/*! ZSTD_compress_advanced() : +* Same as ZSTD_compress_usingDict(), with fine-tune control over each compression parameter */ +ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + ZSTD_parameters params); + +/*! ZSTD_compress_usingCDict_advanced() : +* Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters */ +ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, ZSTD_frameParameters fParams); + + +/*--- Advanced decompression functions ---*/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size); + +/*! ZSTD_createDDict_byReference() : + * Create a digested dictionary, ready to start decompression operation without startup delay. + * Dictionary content is referenced, and therefore stays in dictBuffer. + * It is important that dictBuffer outlives DDict, + * it must remain read accessible throughout the lifetime of DDict */ +ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize); + + +/*! ZSTD_getDictID_fromDict() : + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize); + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict); + +/*! ZSTD_getDictID_fromFrame() : + * Provides the dictID required to decompressed the frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary to be decoded (most common case). + * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); + + +/******************************************************************** +* Advanced streaming functions +********************************************************************/ + +/*===== Advanced Streaming compression functions =====*/ +ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct. If it is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs, "0" also disables frame content size field. It may be enabled in the future. */ +ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. Note: dict is loaded with ZSTD_dm_auto (treated as a full zstd dictionary if it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.*/ +ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, + ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct. If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. dict is loaded with ZSTD_dm_auto and ZSTD_dlm_byCopy. */ +ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */ +ZSTDLIB_API size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters. pledgedSrcSize must be correct. If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. */ + +/*! ZSTD_resetCStream() : + * start a new compression job, using same parameters from previous job. + * This is typically useful to skip dictionary loading stage, since it will re-use it in-place. + * Note that zcs must be init at least once before using ZSTD_resetCStream(). + * If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN. + * If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end. + * For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs, + * but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead. + * @return : 0, or an error code (which can be tested using ZSTD_isError()) + */ +ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); + + +typedef struct { + unsigned long long ingested; /* nb input bytes read and buffered */ + unsigned long long consumed; /* nb input bytes actually compressed */ + unsigned long long produced; /* nb of compressed bytes generated and buffered */ + unsigned long long flushed; /* nb of compressed bytes flushed : not provided; can be tracked from caller side */ + unsigned currentJobID; /* MT only : latest started job nb */ + unsigned nbActiveWorkers; /* MT only : nb of workers actively compressing at probe time */ +} ZSTD_frameProgression; + +/* ZSTD_getFrameProgression() : + * tells how much data has been ingested (read from input) + * consumed (input actually compressed) and produced (output) for current frame. + * Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed. + * Aggregates progression inside active worker threads. + */ +ZSTDLIB_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx); + +/*! ZSTD_toFlushNow() : + * Tell how many bytes are ready to be flushed immediately. + * Useful for multithreading scenarios (nbWorkers >= 1). + * Probe the oldest active job, defined as oldest job not yet entirely flushed, + * and check its output buffer. + * @return : amount of data stored in oldest job and ready to be flushed immediately. + * if @return == 0, it means either : + * + there is no active job (could be checked with ZSTD_frameProgression()), or + * + oldest job is still actively compressing data, + * but everything it has produced has also been flushed so far, + * therefore flushing speed is currently limited by production speed of oldest job + * irrespective of the speed of concurrent newer jobs. + */ +ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); + + + +/*===== Advanced Streaming decompression functions =====*/ +typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e; +ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue); /* obsolete : this API will be removed in a future version */ +ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: no dictionary will be used if dict == NULL or dictSize < 8 */ +ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); /**< note : ddict is referenced, it must outlive decompression session */ +ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); /**< re-use decompression parameters from previous init; saves dictionary loading */ + + +/********************************************************************* +* Buffer-less and synchronous inner streaming functions +* +* This is an advanced API, giving full control over buffer management, for users which need direct control over memory. +* But it's also a complex one, with several restrictions, documented below. +* Prefer normal streaming API for an easier experience. +********************************************************************* */ + +/** + Buffer-less streaming compression (synchronous mode) + + A ZSTD_CCtx object is required to track streaming operations. + Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. + ZSTD_CCtx object can be re-used multiple times within successive compression operations. + + Start by initializing a context. + Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression, + or ZSTD_compressBegin_advanced(), for finer parameter control. + It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx() + + Then, consume your input using ZSTD_compressContinue(). + There are some important considerations to keep in mind when using this advanced function : + - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only. + - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks. + - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario. + Worst case evaluation is provided by ZSTD_compressBound(). + ZSTD_compressContinue() doesn't guarantee recover after a failed compression. + - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog). + It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks) + - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps. + In which case, it will "discard" the relevant memory section from its history. + + Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum. + It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame. + Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders. + + `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress again. +*/ + +/*===== Buffer-less streaming compression functions =====*/ +ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); +ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); +ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */ +ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ +ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */ +ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + + +/*- + Buffer-less streaming decompression (synchronous mode) + + A ZSTD_DCtx object is required to track streaming operations. + Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. + A ZSTD_DCtx object can be re-used multiple times. + + First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader(). + Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough. + Data fragment must be large enough to ensure successful decoding. + `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough. + @result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled. + >0 : `srcSize` is too small, please provide at least @result bytes on next attempt. + errorCode, which can be tested using ZSTD_isError(). + + It fills a ZSTD_frameHeader structure with important information to correctly decode the frame, + such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`). + Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information. + As a consequence, check that values remain within valid application range. + For example, do not allocate memory blindly, check that `windowSize` is within expectation. + Each application can set its own limits, depending on local restrictions. + For extended interoperability, it is recommended to support `windowSize` of at least 8 MB. + + ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes. + ZSTD_decompressContinue() is very sensitive to contiguity, + if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place, + or that previous contiguous segment is large enough to properly handle maximum back-reference distance. + There are multiple ways to guarantee this condition. + + The most memory efficient way is to use a round buffer of sufficient size. + Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(), + which can @return an error code if required value is too large for current system (in 32-bits mode). + In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one, + up to the moment there is not enough room left in the buffer to guarantee decoding another full block, + which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`. + At which point, decoding can resume from the beginning of the buffer. + Note that already decoded data stored in the buffer should be flushed before being overwritten. + + There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory. + + Finally, if you control the compression process, you can also ignore all buffer size rules, + as long as the encoder and decoder progress in "lock-step", + aka use exactly the same buffer sizes, break contiguity at the same place, etc. + + Once buffers are setup, start decompression, with ZSTD_decompressBegin(). + If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict(). + + Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively. + ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue(). + ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail. + + @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity). + It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item. + It can also be an error code, which can be tested with ZSTD_isError(). + + A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. + Context can then be reset to start a new decompression. + + Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). + This information is not required to properly decode a frame. + + == Special case : skippable frames == + + Skippable frames allow integration of user-defined data into a flow of concatenated frames. + Skippable frames will be ignored (skipped) by decompressor. + The format of skippable frames is as follows : + a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F + b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits + c) Frame Content - any content (User Data) of length equal to Frame Size + For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame. + For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content. +*/ + +/*===== Buffer-less streaming decompression functions =====*/ +typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e; +typedef struct { + unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */ + unsigned long long windowSize; /* can be very large, up to <= frameContentSize */ + unsigned blockSizeMax; + ZSTD_frameType_e frameType; /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */ + unsigned headerSize; + unsigned dictID; + unsigned checksumFlag; +} ZSTD_frameHeader; +/** ZSTD_getFrameHeader() : + * decode Frame Header, or requires larger `srcSize`. + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, + * or an error code, which can be tested using ZSTD_isError() */ +ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */ +ZSTDLIB_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); +ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + +ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx); +ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* misc */ +ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); +typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; +ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); + + + +/* ============================================ */ +/** New advanced API (experimental) */ +/* ============================================ */ + +/* API design : + * In this advanced API, parameters are pushed one by one into an existing context, + * using ZSTD_CCtx_set*() functions. + * Pushed parameters are sticky : they are applied to next job, and any subsequent job. + * It's possible to reset parameters to "default" using ZSTD_CCtx_reset(). + * Important : "sticky" parameters only work with `ZSTD_compress_generic()` ! + * For any other entry point, "sticky" parameters are ignored ! + * + * This API is intended to replace all others advanced / experimental API entry points. + */ + +/* note on enum design : + * All enum will be pinned to explicit values before reaching "stable API" status */ + +typedef enum { + /* Opened question : should we have a format ZSTD_f_auto ? + * Today, it would mean exactly the same as ZSTD_f_zstd1. + * But, in the future, should several formats become supported, + * on the compression side, it would mean "default format". + * On the decompression side, it would mean "automatic format detection", + * so that ZSTD_f_zstd1 would mean "accept *only* zstd frames". + * Since meaning is a little different, another option could be to define different enums for compression and decompression. + * This question could be kept for later, when there are actually multiple formats to support, + * but there is also the question of pinning enum values, and pinning value `0` is especially important */ + ZSTD_f_zstd1 = 0, /* zstd frame format, specified in zstd_compression_format.md (default) */ + ZSTD_f_zstd1_magicless, /* Variant of zstd frame format, without initial 4-bytes magic number. + * Useful to save 4 bytes per generated frame. + * Decoder cannot recognise automatically this format, requiring instructions. */ +} ZSTD_format_e; + +typedef enum { + /* compression format */ + ZSTD_p_format = 10, /* See ZSTD_format_e enum definition. + * Cast selected format as unsigned for ZSTD_CCtx_setParameter() compatibility. */ + + /* compression parameters */ + ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table + * Default level is ZSTD_CLEVEL_DEFAULT==3. + * Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT. + * Note 1 : it's possible to pass a negative compression level by casting it to unsigned type. + * Note 2 : setting a level sets all default values of other compression parameters. + * Note 3 : setting compressionLevel automatically updates ZSTD_p_compressLiterals. */ + ZSTD_p_windowLog, /* Maximum allowed back-reference distance, expressed as power of 2. + * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. + * Special: value 0 means "use default windowLog". + * Note: Using a window size greater than ZSTD_MAXWINDOWSIZE_DEFAULT (default: 2^27) + * requires explicitly allowing such window size during decompression stage. */ + ZSTD_p_hashLog, /* Size of the initial probe table, as a power of 2. + * Resulting table size is (1 << (hashLog+2)). + * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. + * Larger tables improve compression ratio of strategies <= dFast, + * and improve speed of strategies > dFast. + * Special: value 0 means "use default hashLog". */ + ZSTD_p_chainLog, /* Size of the multi-probe search table, as a power of 2. + * Resulting table size is (1 << (chainLog+2)). + * Must be clamped between ZSTD_CHAINLOG_MIN and ZSTD_CHAINLOG_MAX. + * Larger tables result in better and slower compression. + * This parameter is useless when using "fast" strategy. + * Note it's still useful when using "dfast" strategy, + * in which case it defines a secondary probe table. + * Special: value 0 means "use default chainLog". */ + ZSTD_p_searchLog, /* Number of search attempts, as a power of 2. + * More attempts result in better and slower compression. + * This parameter is useless when using "fast" and "dFast" strategies. + * Special: value 0 means "use default searchLog". */ + ZSTD_p_minMatch, /* Minimum size of searched matches (note : repCode matches can be smaller). + * Larger values make faster compression and decompression, but decrease ratio. + * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX. + * Note that currently, for all strategies < btopt, effective minimum is 4. + * , for all strategies > fast, effective maximum is 6. + * Special: value 0 means "use default minMatchLength". */ + ZSTD_p_targetLength, /* Impact of this field depends on strategy. + * For strategies btopt & btultra: + * Length of Match considered "good enough" to stop search. + * Larger values make compression stronger, and slower. + * For strategy fast: + * Distance between match sampling. + * Larger values make compression faster, and weaker. + * Special: value 0 means "use default targetLength". */ + ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition. + * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility. + * The higher the value of selected strategy, the more complex it is, + * resulting in stronger and slower compression. + * Special: value 0 means "use default strategy". */ + + ZSTD_p_enableLongDistanceMatching=160, /* Enable long distance matching. + * This parameter is designed to improve compression ratio + * for large inputs, by finding large matches at long distance. + * It increases memory usage and window size. + * Note: enabling this parameter increases ZSTD_p_windowLog to 128 MB + * except when expressly set to a different value. */ + ZSTD_p_ldmHashLog, /* Size of the table for long distance matching, as a power of 2. + * Larger values increase memory usage and compression ratio, + * but decrease compression speed. + * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX + * default: windowlog - 7. + * Special: value 0 means "automatically determine hashlog". */ + ZSTD_p_ldmMinMatch, /* Minimum match size for long distance matcher. + * Larger/too small values usually decrease compression ratio. + * Must be clamped between ZSTD_LDM_MINMATCH_MIN and ZSTD_LDM_MINMATCH_MAX. + * Special: value 0 means "use default value" (default: 64). */ + ZSTD_p_ldmBucketSizeLog, /* Log size of each bucket in the LDM hash table for collision resolution. + * Larger values improve collision resolution but decrease compression speed. + * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX . + * Special: value 0 means "use default value" (default: 3). */ + ZSTD_p_ldmHashEveryLog, /* Frequency of inserting/looking up entries in the LDM hash table. + * Must be clamped between 0 and (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN). + * Default is MAX(0, (windowLog - ldmHashLog)), optimizing hash table usage. + * Larger values improve compression speed. + * Deviating far from default value will likely result in a compression ratio decrease. + * Special: value 0 means "automatically determine hashEveryLog". */ + + /* frame parameters */ + ZSTD_p_contentSizeFlag=200, /* Content size will be written into frame header _whenever known_ (default:1) + * Content size must be known at the beginning of compression, + * it is provided using ZSTD_CCtx_setPledgedSrcSize() */ + ZSTD_p_checksumFlag, /* A 32-bits checksum of content is written at end of frame (default:0) */ + ZSTD_p_dictIDFlag, /* When applicable, dictionary's ID is written into frame header (default:1) */ + + /* multi-threading parameters */ + /* These parameters are only useful if multi-threading is enabled (ZSTD_MULTITHREAD). + * They return an error otherwise. */ + ZSTD_p_nbWorkers=400, /* Select how many threads will be spawned to compress in parallel. + * When nbWorkers >= 1, triggers asynchronous mode : + * ZSTD_compress_generic() consumes some input, flush some output if possible, and immediately gives back control to caller, + * while compression work is performed in parallel, within worker threads. + * (note : a strong exception to this rule is when first invocation sets ZSTD_e_end : it becomes a blocking call). + * More workers improve speed, but also increase memory usage. + * Default value is `0`, aka "single-threaded mode" : no worker is spawned, compression is performed inside Caller's thread, all invocations are blocking */ + ZSTD_p_jobSize, /* Size of a compression job. This value is enforced only in non-blocking mode. + * Each compression job is completed in parallel, so this value indirectly controls the nb of active threads. + * 0 means default, which is dynamically determined based on compression parameters. + * Job size must be a minimum of overlapSize, or 1 MB, whichever is largest. + * The minimum size is automatically and transparently enforced */ + ZSTD_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job. + * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */ + + /* =================================================================== */ + /* experimental parameters - no stability guaranteed */ + /* =================================================================== */ + + ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize, + * even when referencing into Dictionary content (default:0) */ + ZSTD_p_forceAttachDict, /* ZSTD supports usage of a CDict in-place + * (avoiding having to copy the compression tables + * from the CDict into the working context). Using + * a CDict in this way saves an initial setup step, + * but comes at the cost of more work per byte of + * input. ZSTD has a simple internal heuristic that + * guesses which strategy will be faster. You can + * use this flag to override that guess. + * + * Note that the by-reference, in-place strategy is + * only used when reusing a compression context + * with compatible compression parameters. (If + * incompatible / uninitialized, the working + * context needs to be cleared anyways, which is + * about as expensive as overwriting it with the + * dictionary context, so there's no savings in + * using the CDict by-ref.) + * + * Values greater than 0 force attaching the dict. + * Values less than 0 force copying the dict. + * 0 selects the default heuristic-guided behavior. + */ + +} ZSTD_cParameter; + + +/*! ZSTD_CCtx_setParameter() : + * Set one compression parameter, selected by enum ZSTD_cParameter. + * Setting a parameter is generally only possible during frame initialization (before starting compression). + * Exception : when using multi-threading mode (nbThreads >= 1), + * following parameters can be updated _during_ compression (within same frame): + * => compressionLevel, hashLog, chainLog, searchLog, minMatch, targetLength and strategy. + * new parameters will be active on next job, or after a flush(). + * Note : when `value` type is not unsigned (int, or enum), cast it to unsigned for proper type checking. + * @result : informational value (typically, value being set, correctly clamped), + * or an error code (which can be tested with ZSTD_isError()). */ +ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value); + +/*! ZSTD_CCtx_getParameter() : + * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned* value); + +/*! ZSTD_CCtx_setPledgedSrcSize() : + * Total input data size to be compressed as a single frame. + * This value will be controlled at the end, and result in error if not respected. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Note 1 : 0 means zero, empty. + * In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. + * ZSTD_CONTENTSIZE_UNKNOWN is default value for any new compression job. + * Note 2 : If all data is provided and consumed in a single round, + * this value is overriden by srcSize instead. */ +ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize); + +/*! ZSTD_CCtx_loadDictionary() : + * Create an internal CDict from `dict` buffer. + * Decompression will have to use same dictionary. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: Adding a NULL (or 0-size) dictionary invalidates previous dictionary, + * meaning "return to no-dictionary mode". + * Note 1 : Dictionary will be used for all future compression jobs. + * To return to "no-dictionary" situation, load a NULL dictionary + * Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters. + * For this reason, compression parameters cannot be changed anymore after loading a dictionary. + * It's also a CPU consuming operation, with non-negligible impact on latency. + * Note 3 :`dict` content will be copied internally. + * Use ZSTD_CCtx_loadDictionary_byReference() to reference dictionary content instead. + * In such a case, dictionary buffer must outlive its users. + * Note 4 : Use ZSTD_CCtx_loadDictionary_advanced() + * to precisely select how dictionary content must be interpreted. */ +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); + + +/*! ZSTD_CCtx_refCDict() : + * Reference a prepared dictionary, to be used for all next compression jobs. + * Note that compression parameters are enforced from within CDict, + * and supercede any compression parameter previously set within CCtx. + * The dictionary will remain valid for future compression jobs using same CCtx. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special : adding a NULL CDict means "return to no-dictionary mode". + * Note 1 : Currently, only one dictionary can be managed. + * Adding a new dictionary effectively "discards" any previous one. + * Note 2 : CDict is just referenced, its lifetime must outlive CCtx. */ +ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); + +/*! ZSTD_CCtx_refPrefix() : + * Reference a prefix (single-usage dictionary) for next compression job. + * Decompression will need same prefix to properly regenerate data. + * Compressing with a prefix is similar in outcome as performing a diff and compressing it, + * but performs much faster, especially during decompression (compression speed is tunable with compression level). + * Note that prefix is **only used once**. Tables are discarded at end of compression job (ZSTD_e_end). + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary + * Note 1 : Prefix buffer is referenced. It **must** outlive compression job. + * Its contain must remain unmodified up to end of compression (ZSTD_e_end). + * Note 2 : If the intention is to diff some large src data blob with some prior version of itself, + * ensure that the window size is large enough to contain the entire source. + * See ZSTD_p_windowLog. + * Note 3 : Referencing a prefix involves building tables, which are dependent on compression parameters. + * It's a CPU consuming operation, with non-negligible impact on latency. + * If there is a need to use same prefix multiple times, consider loadDictionary instead. + * Note 4 : By default, the prefix is treated as raw content (ZSTD_dm_rawContent). + * Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode. */ +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, + const void* prefix, size_t prefixSize); +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, + const void* prefix, size_t prefixSize, + ZSTD_dictContentType_e dictContentType); + +/*! ZSTD_CCtx_reset() : + * Return a CCtx to clean state. + * Useful after an error, or to interrupt an ongoing compression job and start a new one. + * Any internal data not yet flushed is cancelled. + * The parameters and dictionary are kept unchanged, to reset them use ZSTD_CCtx_resetParameters(). + */ +ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx); + +/*! ZSTD_CCtx_resetParameters() : + * All parameters are back to default values (compression level is ZSTD_CLEVEL_DEFAULT). + * Dictionary (if any) is dropped. + * Resetting parameters is only possible during frame initialization (before starting compression). + * To reset the context use ZSTD_CCtx_reset(). + * @return 0 or an error code (which can be checked with ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx); + + + +typedef enum { + ZSTD_e_continue=0, /* collect more data, encoder decides when to output compressed result, for optimal conditions */ + ZSTD_e_flush, /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */ + ZSTD_e_end /* flush any remaining data and close current frame. Any additional data starts a new frame. */ +} ZSTD_EndDirective; + +/*! ZSTD_compress_generic() : + * Behave about the same as ZSTD_compressStream. To note : + * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_setParameter() + * - Compression parameters cannot be changed once compression is started. + * - outpot->pos must be <= dstCapacity, input->pos must be <= srcSize + * - outpot->pos and input->pos will be updated. They are guaranteed to remain below their respective limit. + * - In single-thread mode (default), function is blocking : it completed its job before returning to caller. + * - In multi-thread mode, function is non-blocking : it just acquires a copy of input, and distribute job to internal worker threads, + * and then immediately returns, just indicating that there is some data remaining to be flushed. + * The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte. + * - Exception : in multi-threading mode, if the first call requests a ZSTD_e_end directive, it is blocking : it will complete compression before giving back control to caller. + * - @return provides a minimum amount of data remaining to be flushed from internal buffers + * or an error code, which can be tested using ZSTD_isError(). + * if @return != 0, flush is not fully completed, there is still some data left within internal buffers. + * This is useful for ZSTD_e_flush, since in this case more flushes are necessary to empty all buffers. + * For ZSTD_e_end, @return == 0 when internal buffers are fully flushed and frame is completed. + * - after a ZSTD_e_end directive, if internal buffer is not fully flushed (@return != 0), + * only ZSTD_e_end or ZSTD_e_flush operations are allowed. + * Before starting a new compression job, or changing compression parameters, + * it is required to fully flush internal buffers. + */ +ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp); + + +/*! ZSTD_compress_generic_simpleArgs() : + * Same as ZSTD_compress_generic(), + * but using only integral types as arguments. + * Argument list is larger than ZSTD_{in,out}Buffer, + * but can be helpful for binders from dynamic languages + * which have troubles handling structures containing memory pointers. + */ +ZSTDLIB_API size_t ZSTD_compress_generic_simpleArgs ( + ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, size_t* dstPos, + const void* src, size_t srcSize, size_t* srcPos, + ZSTD_EndDirective endOp); + + +/*! ZSTD_CCtx_params : + * Quick howto : + * - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure + * - ZSTD_CCtxParam_setParameter() : Push parameters one by one into + * an existing ZSTD_CCtx_params structure. + * This is similar to + * ZSTD_CCtx_setParameter(). + * - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to + * an existing CCtx. + * These parameters will be applied to + * all subsequent compression jobs. + * - ZSTD_compress_generic() : Do compression using the CCtx. + * - ZSTD_freeCCtxParams() : Free the memory. + * + * This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() + * for static allocation for single-threaded compression. + */ +ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void); +ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); + + +/*! ZSTD_CCtxParams_reset() : + * Reset params to default values. + */ +ZSTDLIB_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params); + +/*! ZSTD_CCtxParams_init() : + * Initializes the compression parameters of cctxParams according to + * compression level. All other parameters are reset to their default values. + */ +ZSTDLIB_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel); + +/*! ZSTD_CCtxParams_init_advanced() : + * Initializes the compression and frame parameters of cctxParams according to + * params. All other parameters are reset to their default values. + */ +ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); + + +/*! ZSTD_CCtxParam_setParameter() : + * Similar to ZSTD_CCtx_setParameter. + * Set one compression parameter, selected by enum ZSTD_cParameter. + * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams(). + * Note : when `value` is an enum, cast it to unsigned for proper type checking. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value); + +/*! ZSTD_CCtxParam_getParameter() : + * Similar to ZSTD_CCtx_getParameter. + * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_CCtxParam_getParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned* value); + +/*! ZSTD_CCtx_setParametersUsingCCtxParams() : + * Apply a set of ZSTD_CCtx_params to the compression context. + * This can be done even after compression is started, + * if nbWorkers==0, this will have no impact until a new compression is started. + * if nbWorkers>=1, new parameters will be picked up at next job, + * with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated). + */ +ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams( + ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params); + + +/* ==================================== */ +/*=== Advanced decompression API ===*/ +/* ==================================== */ + +/* The following API works the same way as the advanced compression API : + * a context is created, parameters are pushed into it one by one, + * then the context can be used to decompress data using an interface similar to the straming API. + */ + +/*! ZSTD_DCtx_loadDictionary() : + * Create an internal DDict from dict buffer, + * to be used to decompress next frames. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, + * meaning "return to no-dictionary mode". + * Note 1 : `dict` content will be copied internally. + * Use ZSTD_DCtx_loadDictionary_byReference() + * to reference dictionary content instead. + * In which case, the dictionary buffer must outlive its users. + * Note 2 : Loading a dictionary involves building tables, + * which has a non-negligible impact on CPU usage and latency. + * Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to select + * how dictionary content will be interpreted and loaded. + */ +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); + + +/*! ZSTD_DCtx_refDDict() : + * Reference a prepared dictionary, to be used to decompress next frames. + * The dictionary remains active for decompression of future frames using same DCtx. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Note 1 : Currently, only one dictionary can be managed. + * Referencing a new dictionary effectively "discards" any previous one. + * Special : adding a NULL DDict means "return to no-dictionary mode". + * Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx. + */ +ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + + +/*! ZSTD_DCtx_refPrefix() : + * Reference a prefix (single-usage dictionary) for next compression job. + * This is the reverse operation of ZSTD_CCtx_refPrefix(), + * and must use the same prefix as the one used during compression. + * Prefix is **only used once**. Reference is discarded at end of frame. + * End of frame is reached when ZSTD_DCtx_decompress_generic() returns 0. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary + * Note 2 : Prefix buffer is referenced. It **must** outlive decompression job. + * Prefix buffer must remain unmodified up to the end of frame, + * reached when ZSTD_DCtx_decompress_generic() returns 0. + * Note 3 : By default, the prefix is treated as raw content (ZSTD_dm_rawContent). + * Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode. + * Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost. + * A fulldict prefix is more costly though. + */ +ZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, + const void* prefix, size_t prefixSize); +ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, + const void* prefix, size_t prefixSize, + ZSTD_dictContentType_e dictContentType); + + +/*! ZSTD_DCtx_setMaxWindowSize() : + * Refuses allocating internal buffers for frames requiring a window size larger than provided limit. + * This is useful to prevent a decoder context from reserving too much memory for itself (potential attack scenario). + * This parameter is only useful in streaming mode, since no internal buffer is allocated in direct mode. + * By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_MAX) + * @return : 0, or an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize); + + +/*! ZSTD_DCtx_setFormat() : + * Instruct the decoder context about what kind of data to decode next. + * This instruction is mandatory to decode data without a fully-formed header, + * such ZSTD_f_zstd1_magicless for example. + * @return : 0, or an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); + + +/*! ZSTD_getFrameHeader_advanced() : + * same as ZSTD_getFrameHeader(), + * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ +ZSTDLIB_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, + const void* src, size_t srcSize, ZSTD_format_e format); + + +/*! ZSTD_decompress_generic() : + * Behave the same as ZSTD_decompressStream. + * Decompression parameters cannot be changed once decompression is started. + * @return : an error code, which can be tested using ZSTD_isError() + * if >0, a hint, nb of expected input bytes for next invocation. + * `0` means : a frame has just been fully decoded and flushed. + */ +ZSTDLIB_API size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input); + + +/*! ZSTD_decompress_generic_simpleArgs() : + * Same as ZSTD_decompress_generic(), + * but using only integral types as arguments. + * Argument list is larger than ZSTD_{in,out}Buffer, + * but can be helpful for binders from dynamic languages + * which have troubles handling structures containing memory pointers. + */ +ZSTDLIB_API size_t ZSTD_decompress_generic_simpleArgs ( + ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, size_t* dstPos, + const void* src, size_t srcSize, size_t* srcPos); + + +/*! ZSTD_DCtx_reset() : + * Return a DCtx to clean state. + * If a decompression was ongoing, any internal data not yet flushed is cancelled. + * All parameters are back to default values, including sticky ones. + * Dictionary (if any) is dropped. + * Parameters can be modified again after a reset. + */ +ZSTDLIB_API void ZSTD_DCtx_reset(ZSTD_DCtx* dctx); + + + +/* ============================ */ +/** Block level API */ +/* ============================ */ + +/*! + Block functions produce and decode raw zstd blocks, without frame metadata. + Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes). + User will have to take in charge required information to regenerate data, such as compressed and content sizes. + + A few rules to respect : + - Compressing and decompressing require a context structure + + Use ZSTD_createCCtx() and ZSTD_createDCtx() + - It is necessary to init context before starting + + compression : any ZSTD_compressBegin*() variant, including with dictionary + + decompression : any ZSTD_decompressBegin*() variant, including with dictionary + + copyCCtx() and copyDCtx() can be used too + - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB + + If input is larger than a block size, it's necessary to split input data into multiple blocks + + For inputs larger than a single block size, consider using the regular ZSTD_compress() instead. + Frame metadata is not that costly, and quickly becomes negligible as source size grows larger. + - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero. + In which case, nothing is produced into `dst`. + + User must test for such outcome and deal directly with uncompressed data + + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!! + + In case of multiple successive blocks, should some of them be uncompressed, + decoder must be informed of their existence in order to follow proper history. + Use ZSTD_insertBlock() for such a case. +*/ + +/*===== Raw zstd block functions =====*/ +ZSTDLIB_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); +ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ + + +#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ + +#if defined (__cplusplus) +} +#endif diff --git a/grub-core/lib/zstd/zstd_common.c b/grub-core/lib/zstd/zstd_common.c new file mode 100644 index 000000000..6f05d240e --- /dev/null +++ b/grub-core/lib/zstd/zstd_common.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + + +/*-************************************* +* Dependencies +***************************************/ +#include /* malloc, calloc, free */ +#include /* memset */ +#include "error_private.h" +#include "zstd_internal.h" + + +/*-**************************************** +* Version +******************************************/ +unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; } + +const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; } + + +/*-**************************************** +* ZSTD Error Management +******************************************/ +/*! ZSTD_isError() : + * tells if a return value is an error code */ +unsigned ZSTD_isError(size_t code) { return ERR_isError(code); } + +/*! ZSTD_getErrorName() : + * provides error code string from function result (useful for debugging) */ +const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); } + +/*! ZSTD_getError() : + * convert a `size_t` function result into a proper ZSTD_errorCode enum */ +ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } + +/*! ZSTD_getErrorString() : + * provides error code string from enum */ +const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } + + + +/*=************************************************************** +* Custom allocator +****************************************************************/ +void* ZSTD_malloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) + return customMem.customAlloc(customMem.opaque, size); + return malloc(size); +} + +void* ZSTD_calloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) { + /* calloc implemented as malloc+memset; + * not as efficient as calloc, but next best guess for custom malloc */ + void* const ptr = customMem.customAlloc(customMem.opaque, size); + memset(ptr, 0, size); + return ptr; + } + return calloc(1, size); +} + +void ZSTD_free(void* ptr, ZSTD_customMem customMem) +{ + if (ptr!=NULL) { + if (customMem.customFree) + customMem.customFree(customMem.opaque, ptr); + else + free(ptr); + } +} diff --git a/grub-core/lib/zstd/zstd_decompress.c b/grub-core/lib/zstd/zstd_decompress.c new file mode 100644 index 000000000..e4b5670c2 --- /dev/null +++ b/grub-core/lib/zstd/zstd_decompress.c @@ -0,0 +1,3108 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ +/*! + * HEAPMODE : + * Select how default decompression function ZSTD_decompress() allocates its context, + * on stack (0), or into heap (1, default; requires malloc()). + * Note that functions with explicit context such as ZSTD_decompressDCtx() are unaffected. + */ +#ifndef ZSTD_HEAPMODE +# define ZSTD_HEAPMODE 1 +#endif + +/*! +* LEGACY_SUPPORT : +* if set to 1+, ZSTD_decompress() can decode older formats (v0.1+) +*/ +#ifndef ZSTD_LEGACY_SUPPORT +# define ZSTD_LEGACY_SUPPORT 0 +#endif + +/*! + * MAXWINDOWSIZE_DEFAULT : + * maximum window size accepted by DStream __by default__. + * Frames requiring more memory will be rejected. + * It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize(). + */ +#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT +# define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_DEFAULTMAX) + 1) +#endif + +/*! + * NO_FORWARD_PROGRESS_MAX : + * maximum allowed nb of calls to ZSTD_decompressStream() and ZSTD_decompress_generic() + * without any forward progress + * (defined as: no byte read from input, and no byte flushed to output) + * before triggering an error. + */ +#ifndef ZSTD_NO_FORWARD_PROGRESS_MAX +# define ZSTD_NO_FORWARD_PROGRESS_MAX 16 +#endif + + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include /* memcpy, memmove, memset */ +#include "compiler.h" /* prefetch */ +#include "cpu.h" /* bmi2 */ +#include "mem.h" /* low level memory routines */ +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#define HUF_STATIC_LINKING_ONLY +#include "huf.h" +#include "zstd_internal.h" + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) +# include "zstd_legacy.h" +#endif + +static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict); +static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict); + + +/*-************************************* +* Errors +***************************************/ +#define ZSTD_isError ERR_isError /* for inlining */ +#define FSE_isError ERR_isError +#define HUF_isError ERR_isError + + +/*_******************************************************* +* Memory operations +**********************************************************/ +static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); } + + +/*-************************************************************* +* Context management +***************************************************************/ +typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, + ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock, + ZSTDds_decompressLastBlock, ZSTDds_checkChecksum, + ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage; + +typedef enum { zdss_init=0, zdss_loadHeader, + zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; + + +typedef struct { + U32 fastMode; + U32 tableLog; +} ZSTD_seqSymbol_header; + +typedef struct { + U16 nextState; + BYTE nbAdditionalBits; + BYTE nbBits; + U32 baseValue; +} ZSTD_seqSymbol; + +#define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log))) + +typedef struct { + ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */ + ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */ + ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */ + HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ + U32 rep[ZSTD_REP_NUM]; +} ZSTD_entropyDTables_t; + +struct ZSTD_DCtx_s +{ + const ZSTD_seqSymbol* LLTptr; + const ZSTD_seqSymbol* MLTptr; + const ZSTD_seqSymbol* OFTptr; + const HUF_DTable* HUFptr; + ZSTD_entropyDTables_t entropy; + U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; /* space needed when building huffman tables */ + const void* previousDstEnd; /* detect continuity */ + const void* prefixStart; /* start of current segment */ + const void* virtualStart; /* virtual start of previous segment if it was just before current one */ + const void* dictEnd; /* end of previous segment */ + size_t expected; + ZSTD_frameHeader fParams; + U64 decodedSize; + blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */ + ZSTD_dStage stage; + U32 litEntropy; + U32 fseEntropy; + XXH64_state_t xxhState; + size_t headerSize; + ZSTD_format_e format; + const BYTE* litPtr; + ZSTD_customMem customMem; + size_t litSize; + size_t rleSize; + size_t staticSize; + int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ + + /* dictionary */ + ZSTD_DDict* ddictLocal; + const ZSTD_DDict* ddict; /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */ + U32 dictID; + int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */ + + /* streaming */ + ZSTD_dStreamStage streamStage; + char* inBuff; + size_t inBuffSize; + size_t inPos; + size_t maxWindowSize; + char* outBuff; + size_t outBuffSize; + size_t outStart; + size_t outEnd; + size_t lhSize; + void* legacyContext; + U32 previousLegacyVersion; + U32 legacyVersion; + U32 hostageByte; + int noForwardProgress; + + /* workspace */ + BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH]; + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; +}; /* typedef'd to ZSTD_DCtx within "zstd.h" */ + +size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support sizeof NULL */ + return sizeof(*dctx) + + ZSTD_sizeof_DDict(dctx->ddictLocal) + + dctx->inBuffSize + dctx->outBuffSize; +} + +size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } + + +static size_t ZSTD_startingInputLength(ZSTD_format_e format) +{ + size_t const startingInputLength = (format==ZSTD_f_zstd1_magicless) ? + ZSTD_frameHeaderSize_prefix - ZSTD_FRAMEIDSIZE : + ZSTD_frameHeaderSize_prefix; + ZSTD_STATIC_ASSERT(ZSTD_FRAMEHEADERSIZE_PREFIX >= ZSTD_FRAMEIDSIZE); + /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */ + assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) ); + return startingInputLength; +} + +static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) +{ + dctx->format = ZSTD_f_zstd1; /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */ + dctx->staticSize = 0; + dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; + dctx->ddict = NULL; + dctx->ddictLocal = NULL; + dctx->dictEnd = NULL; + dctx->ddictIsCold = 0; + dctx->inBuff = NULL; + dctx->inBuffSize = 0; + dctx->outBuffSize = 0; + dctx->streamStage = zdss_init; + dctx->legacyContext = NULL; + dctx->previousLegacyVersion = 0; + dctx->noForwardProgress = 0; + dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); +} + +ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) +{ + ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace; + + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */ + + ZSTD_initDCtx_internal(dctx); + dctx->staticSize = workspaceSize; + dctx->inBuff = (char*)(dctx+1); + return dctx; +} + +ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +{ + if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + + { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem); + if (!dctx) return NULL; + dctx->customMem = customMem; + ZSTD_initDCtx_internal(dctx); + return dctx; + } +} + +ZSTD_DCtx* ZSTD_createDCtx(void) +{ + DEBUGLOG(3, "ZSTD_createDCtx"); + return ZSTD_createDCtx_advanced(ZSTD_defaultCMem); +} + +size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support free on NULL */ + if (dctx->staticSize) return ERROR(memory_allocation); /* not compatible with static DCtx */ + { ZSTD_customMem const cMem = dctx->customMem; + ZSTD_freeDDict(dctx->ddictLocal); + dctx->ddictLocal = NULL; + ZSTD_free(dctx->inBuff, cMem); + dctx->inBuff = NULL; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (dctx->legacyContext) + ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion); +#endif + ZSTD_free(dctx, cMem); + return 0; + } +} + +/* no longer useful */ +void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) +{ + size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); + memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ +} + + +/*-************************************************************* + * Frame header decoding + ***************************************************************/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +unsigned ZSTD_isFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if (magic == ZSTD_MAGICNUMBER) return 1; + if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(buffer, size)) return 1; +#endif + return 0; +} + +/** ZSTD_frameHeaderSize_internal() : + * srcSize must be large enough to reach header size fields. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless. + * @return : size of the Frame Header + * or an error code, which can be tested with ZSTD_isError() */ +static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format) +{ + size_t const minInputSize = ZSTD_startingInputLength(format); + if (srcSize < minInputSize) return ERROR(srcSize_wrong); + + { BYTE const fhd = ((const BYTE*)src)[minInputSize-1]; + U32 const dictID= fhd & 3; + U32 const singleSegment = (fhd >> 5) & 1; + U32 const fcsId = fhd >> 6; + return minInputSize + !singleSegment + + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] + + (singleSegment && !fcsId); + } +} + +/** ZSTD_frameHeaderSize() : + * srcSize must be >= ZSTD_frameHeaderSize_prefix. + * @return : size of the Frame Header, + * or an error code (if srcSize is too small) */ +size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) +{ + return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1); +} + + +/** ZSTD_getFrameHeader_advanced() : + * decode Frame Header, or require larger `srcSize`. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, + * or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format) +{ + const BYTE* ip = (const BYTE*)src; + size_t const minInputSize = ZSTD_startingInputLength(format); + + memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */ + if (srcSize < minInputSize) return minInputSize; + if (src==NULL) return ERROR(GENERIC); /* invalid parameter */ + + if ( (format != ZSTD_f_zstd1_magicless) + && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) { + if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame */ + if (srcSize < ZSTD_skippableHeaderSize) + return ZSTD_skippableHeaderSize; /* magic number + frame length */ + memset(zfhPtr, 0, sizeof(*zfhPtr)); + zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE); + zfhPtr->frameType = ZSTD_skippableFrame; + return 0; + } + return ERROR(prefix_unknown); + } + + /* ensure there is enough `srcSize` to fully read/decode frame header */ + { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format); + if (srcSize < fhsize) return fhsize; + zfhPtr->headerSize = (U32)fhsize; + } + + { BYTE const fhdByte = ip[minInputSize-1]; + size_t pos = minInputSize; + U32 const dictIDSizeCode = fhdByte&3; + U32 const checksumFlag = (fhdByte>>2)&1; + U32 const singleSegment = (fhdByte>>5)&1; + U32 const fcsID = fhdByte>>6; + U64 windowSize = 0; + U32 dictID = 0; + U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + if ((fhdByte & 0x08) != 0) + return ERROR(frameParameter_unsupported); /* reserved bits, must be zero */ + + if (!singleSegment) { + BYTE const wlByte = ip[pos++]; + U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; + if (windowLog > ZSTD_WINDOWLOG_MAX) + return ERROR(frameParameter_windowTooLarge); + windowSize = (1ULL << windowLog); + windowSize += (windowSize >> 3) * (wlByte&7); + } + switch(dictIDSizeCode) + { + default: assert(0); /* impossible */ + case 0 : break; + case 1 : dictID = ip[pos]; pos++; break; + case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; + case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break; + } + switch(fcsID) + { + default: assert(0); /* impossible */ + case 0 : if (singleSegment) frameContentSize = ip[pos]; break; + case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; + case 2 : frameContentSize = MEM_readLE32(ip+pos); break; + case 3 : frameContentSize = MEM_readLE64(ip+pos); break; + } + if (singleSegment) windowSize = frameContentSize; + + zfhPtr->frameType = ZSTD_frame; + zfhPtr->frameContentSize = frameContentSize; + zfhPtr->windowSize = windowSize; + zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); + zfhPtr->dictID = dictID; + zfhPtr->checksumFlag = checksumFlag; + } + return 0; +} + +/** ZSTD_getFrameHeader() : + * decode Frame Header, or require larger `srcSize`. + * note : this function does not consume input, it only reads it. + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, + * or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize) +{ + return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1); +} + + +/** ZSTD_getFrameContentSize() : + * compatible with legacy mode + * @return : decompressed size of the single frame pointed to be `src` if known, otherwise + * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */ +unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize) +{ +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(src, srcSize)) { + unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize); + return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret; + } +#endif + { ZSTD_frameHeader zfh; + if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0) + return ZSTD_CONTENTSIZE_ERROR; + if (zfh.frameType == ZSTD_skippableFrame) { + return 0; + } else { + return zfh.frameContentSize; + } } +} + +/** ZSTD_findDecompressedSize() : + * compatible with legacy mode + * `srcSize` must be the exact length of some number of ZSTD compressed and/or + * skippable frames + * @return : decompressed size of the frames contained */ +unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) +{ + unsigned long long totalDstSize = 0; + + while (srcSize >= ZSTD_frameHeaderSize_prefix) { + U32 const magicNumber = MEM_readLE32(src); + + if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + size_t skippableSize; + if (srcSize < ZSTD_skippableHeaderSize) + return ERROR(srcSize_wrong); + skippableSize = MEM_readLE32((const BYTE *)src + ZSTD_FRAMEIDSIZE) + + ZSTD_skippableHeaderSize; + if (srcSize < skippableSize) { + return ZSTD_CONTENTSIZE_ERROR; + } + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; + } + + { unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); + if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret; + + /* check for overflow */ + if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR; + totalDstSize += ret; + } + { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); + if (ZSTD_isError(frameSrcSize)) { + return ZSTD_CONTENTSIZE_ERROR; + } + + src = (const BYTE *)src + frameSrcSize; + srcSize -= frameSrcSize; + } + } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ + + if (srcSize) return ZSTD_CONTENTSIZE_ERROR; + + return totalDstSize; +} + +/** ZSTD_getDecompressedSize() : +* compatible with legacy mode +* @return : decompressed size if known, 0 otherwise + note : 0 can mean any of the following : + - frame content is empty + - decompressed size field is not present in frame header + - frame header unknown / not supported + - frame header not complete (`srcSize` too small) */ +unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize) +{ + unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN); + return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret; +} + + +/** ZSTD_decodeFrameHeader() : +* `headerSize` must be the size provided by ZSTD_frameHeaderSize(). +* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ +static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize) +{ + size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format); + if (ZSTD_isError(result)) return result; /* invalid header */ + if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */ + if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) + return ERROR(dictionary_wrong); + if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0); + return 0; +} + + +/*-************************************************************* + * Block decoding + ***************************************************************/ + +/*! ZSTD_getcBlockSize() : +* Provides the size of compressed block from block header `src` */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr) +{ + if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong); + { U32 const cBlockHeader = MEM_readLE24(src); + U32 const cSize = cBlockHeader >> 3; + bpPtr->lastBlock = cBlockHeader & 1; + bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3); + bpPtr->origSize = cSize; /* only useful for RLE */ + if (bpPtr->blockType == bt_rle) return 1; + if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected); + return cSize; + } +} + + +static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + if (dst==NULL) return ERROR(dstSize_tooSmall); + if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall); + memcpy(dst, src, srcSize); + return srcSize; +} + + +static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + size_t regenSize) +{ + if (srcSize != 1) return ERROR(srcSize_wrong); + if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall); + memset(dst, *(const BYTE*)src, regenSize); + return regenSize; +} + +/* Hidden declaration for fullbench */ +size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, + const void* src, size_t srcSize); +/*! ZSTD_decodeLiteralsBlock() : + * @return : nb of bytes read from src (< srcSize ) + * note : symbol not declared but exposed for fullbench */ +size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, + const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */ +{ + if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected); + + { const BYTE* const istart = (const BYTE*) src; + symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3); + + switch(litEncType) + { + case set_repeat: + if (dctx->litEntropy==0) return ERROR(dictionary_corrupted); + /* fall-through */ + + case set_compressed: + if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */ + { size_t lhSize, litSize, litCSize; + U32 singleStream=0; + U32 const lhlCode = (istart[0] >> 2) & 3; + U32 const lhc = MEM_readLE32(istart); + switch(lhlCode) + { + case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */ + /* 2 - 2 - 10 - 10 */ + singleStream = !lhlCode; + lhSize = 3; + litSize = (lhc >> 4) & 0x3FF; + litCSize = (lhc >> 14) & 0x3FF; + break; + case 2: + /* 2 - 2 - 14 - 14 */ + lhSize = 4; + litSize = (lhc >> 4) & 0x3FFF; + litCSize = lhc >> 18; + break; + case 3: + /* 2 - 2 - 18 - 18 */ + lhSize = 5; + litSize = (lhc >> 4) & 0x3FFFF; + litCSize = (lhc >> 22) + (istart[4] << 10); + break; + } + if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected); + if (litCSize + lhSize > srcSize) return ERROR(corruption_detected); + + /* prefetch huffman table if cold */ + if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) { + PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable)); + } + + if (HUF_isError((litEncType==set_repeat) ? + ( singleStream ? + HUF_decompress1X_usingDTable_bmi2(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr, dctx->bmi2) : + HUF_decompress4X_usingDTable_bmi2(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr, dctx->bmi2) ) : + ( singleStream ? + HUF_decompress1X1_DCtx_wksp_bmi2(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->workspace, sizeof(dctx->workspace), dctx->bmi2) : + HUF_decompress4X_hufOnly_wksp_bmi2(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->workspace, sizeof(dctx->workspace), dctx->bmi2)))) + return ERROR(corruption_detected); + + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + dctx->litEntropy = 1; + if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); + return litCSize + lhSize; + } + + case set_basic: + { size_t litSize, lhSize; + U32 const lhlCode = ((istart[0]) >> 2) & 3; + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + litSize = MEM_readLE24(istart) >> 4; + break; + } + + if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ + if (litSize+lhSize > srcSize) return ERROR(corruption_detected); + memcpy(dctx->litBuffer, istart+lhSize, litSize); + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); + return lhSize+litSize; + } + /* direct reference into compressed stream */ + dctx->litPtr = istart+lhSize; + dctx->litSize = litSize; + return lhSize+litSize; + } + + case set_rle: + { U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t litSize, lhSize; + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + litSize = MEM_readLE24(istart) >> 4; + if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */ + break; + } + if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected); + memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize+1; + } + default: + return ERROR(corruption_detected); /* impossible */ + } + } +} + +/* Default FSE distribution tables. + * These are pre-calculated FSE decoding tables using default distributions as defined in specification : + * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions + * They were generated programmatically with following method : + * - start from default distributions, present in /lib/common/zstd_internal.h + * - generate tables normally, using ZSTD_buildFSETable() + * - printout the content of tables + * - pretify output, report below, test with fuzzer to ensure it's correct */ + +/* Default FSE distribution table for Literal Lengths */ +static const ZSTD_seqSymbol LL_defaultDTable[(1<tableLog = 0; + DTableH->fastMode = 0; + + cell->nbBits = 0; + cell->nextState = 0; + assert(nbAddBits < 255); + cell->nbAdditionalBits = (BYTE)nbAddBits; + cell->baseValue = baseValue; +} + + +/* ZSTD_buildFSETable() : + * generate FSE decoding table for one symbol (ll, ml or off) */ +static void +ZSTD_buildFSETable(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U32* nbAdditionalBits, + unsigned tableLog) +{ + ZSTD_seqSymbol* const tableDecode = dt+1; + U16 symbolNext[MaxSeq+1]; + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize-1; + + /* Sanity Checks */ + assert(maxSymbolValue <= MaxSeq); + assert(tableLog <= MaxFSELog); + + /* Init, lay down lowprob symbols */ + { ZSTD_seqSymbol_header DTableH; + DTableH.tableLog = tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + symbolNext[s] = normalizedCounter[s]; + } } } + memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + { U32 const tableMask = tableSize-1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } } + assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { U32 u; + for (u=0; u max) return ERROR(corruption_detected); + { U32 const symbol = *(const BYTE*)src; + U32 const baseline = baseValue[symbol]; + U32 const nbBits = nbAdditionalBits[symbol]; + ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits); + } + *DTablePtr = DTableSpace; + return 1; + case set_basic : + *DTablePtr = defaultTable; + return 0; + case set_repeat: + if (!flagRepeatTable) return ERROR(corruption_detected); + /* prefetch FSE table if used */ + if (ddictIsCold && (nbSeq > 24 /* heuristic */)) { + const void* const pStart = *DTablePtr; + size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog)); + PREFETCH_AREA(pStart, pSize); + } + return 0; + case set_compressed : + { U32 tableLog; + S16 norm[MaxSeq+1]; + size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); + if (FSE_isError(headerSize)) return ERROR(corruption_detected); + if (tableLog > maxLog) return ERROR(corruption_detected); + ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog); + *DTablePtr = DTableSpace; + return headerSize; + } + default : /* impossible */ + assert(0); + return ERROR(GENERIC); + } +} + +static const U32 LL_base[MaxLL+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, + 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 }; + +static const U32 OF_base[MaxOff+1] = { + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; + +static const U32 OF_bits[MaxOff+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31 }; + +static const U32 ML_base[MaxML+1] = { + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 37, 39, 41, 43, 47, 51, 59, + 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; + +/* Hidden delcaration for fullbench */ +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize); + +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize) +{ + const BYTE* const istart = (const BYTE* const)src; + const BYTE* const iend = istart + srcSize; + const BYTE* ip = istart; + int nbSeq; + DEBUGLOG(5, "ZSTD_decodeSeqHeaders"); + + /* check */ + if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong); + + /* SeqHead */ + nbSeq = *ip++; + if (!nbSeq) { *nbSeqPtr=0; return 1; } + if (nbSeq > 0x7F) { + if (nbSeq == 0xFF) { + if (ip+2 > iend) return ERROR(srcSize_wrong); + nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2; + } else { + if (ip >= iend) return ERROR(srcSize_wrong); + nbSeq = ((nbSeq-0x80)<<8) + *ip++; + } + } + *nbSeqPtr = nbSeq; + + /* FSE table descriptors */ + if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */ + { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6); + symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3); + symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3); + ip++; + + /* Build DTables */ + { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, + LLtype, MaxLL, LLFSELog, + ip, iend-ip, + LL_base, LL_bits, + LL_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq); + if (ZSTD_isError(llhSize)) return ERROR(corruption_detected); + ip += llhSize; + } + + { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, + OFtype, MaxOff, OffFSELog, + ip, iend-ip, + OF_base, OF_bits, + OF_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq); + if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected); + ip += ofhSize; + } + + { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, + MLtype, MaxML, MLFSELog, + ip, iend-ip, + ML_base, ML_bits, + ML_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq); + if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected); + ip += mlhSize; + } + } + + /* prefetch dictionary content */ + if (dctx->ddictIsCold) { + size_t const dictSize = (const char*)dctx->prefixStart - (const char*)dctx->virtualStart; + size_t const psmin = MIN(dictSize, (size_t)(64*nbSeq) /* heuristic */ ); + size_t const pSize = MIN(psmin, 128 KB /* protection */ ); + const void* const pStart = (const char*)dctx->dictEnd - pSize; + PREFETCH_AREA(pStart, pSize); + dctx->ddictIsCold = 0; + } + + return ip-istart; +} + + +typedef struct { + size_t litLength; + size_t matchLength; + size_t offset; + const BYTE* match; +} seq_t; + +typedef struct { + size_t state; + const ZSTD_seqSymbol* table; +} ZSTD_fseState; + +typedef struct { + BIT_DStream_t DStream; + ZSTD_fseState stateLL; + ZSTD_fseState stateOffb; + ZSTD_fseState stateML; + size_t prevOffset[ZSTD_REP_NUM]; + const BYTE* prefixStart; + const BYTE* dictEnd; + size_t pos; +} seqState_t; + + +FORCE_NOINLINE +size_t ZSTD_execSequenceLast7(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + /* check */ + if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */ + + /* copy literals */ + if (op < oend_w) { + ZSTD_wildcopy(op, *litPtr, oend_w - op); + *litPtr += oend_w - op; + op = oend_w; + } + while (op < oLitEnd) *op++ = *(*litPtr)++; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - base)) { + /* offset beyond prefix */ + if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); + match = dictEnd - (base-match); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = base; + } } + while (op < oMatchEnd) *op++ = *match++; + return sequenceLength; +} + + +HINT_INLINE +size_t ZSTD_execSequence(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + /* check */ + if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* copy Literals */ + ZSTD_copy8(op, *litPtr); + if (sequence.litLength > 8) + ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + if (sequence.offset > (size_t)(oLitEnd - virtualStart)) + return ERROR(corruption_detected); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + if (op > oend_w || sequence.matchLength < MINMATCH) { + U32 i; + for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; + return sequenceLength; + } + } } + /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ + + /* match within prefix */ + if (sequence.offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ + int const sub2 = dec64table[sequence.offset]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[sequence.offset]; + ZSTD_copy4(op+4, match); + match -= sub2; + } else { + ZSTD_copy8(op, match); + } + op += 8; match += 8; + + if (oMatchEnd > oend-(16-MINMATCH)) { + if (op < oend_w) { + ZSTD_wildcopy(op, match, oend_w - op); + match += oend_w - op; + op = oend_w; + } + while (op < oMatchEnd) *op++ = *match++; + } else { + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ + } + return sequenceLength; +} + + +HINT_INLINE +size_t ZSTD_execSequenceLong(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const dictStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = sequence.match; + + /* check */ + if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ + if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ + if (oLitEnd > oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, dictStart, dictEnd); + + /* copy Literals */ + ZSTD_copy8(op, *litPtr); /* note : op <= oLitEnd <= oend_w == oend - 8 */ + if (sequence.litLength > 8) + ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + if (sequence.offset > (size_t)(oLitEnd - dictStart)) return ERROR(corruption_detected); + if (match + sequence.matchLength <= dictEnd) { + memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + if (op > oend_w || sequence.matchLength < MINMATCH) { + U32 i; + for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; + return sequenceLength; + } + } } + assert(op <= oend_w); + assert(sequence.matchLength >= MINMATCH); + + /* match within prefix */ + if (sequence.offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ + int const sub2 = dec64table[sequence.offset]; + op[0] = match[0]; + op[1] = match[1]; + op[2] = match[2]; + op[3] = match[3]; + match += dec32table[sequence.offset]; + ZSTD_copy4(op+4, match); + match -= sub2; + } else { + ZSTD_copy8(op, match); + } + op += 8; match += 8; + + if (oMatchEnd > oend-(16-MINMATCH)) { + if (op < oend_w) { + ZSTD_wildcopy(op, match, oend_w - op); + match += oend_w - op; + op = oend_w; + } + while (op < oMatchEnd) *op++ = *match++; + } else { + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ + } + return sequenceLength; +} + +static void +ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) +{ + const void* ptr = dt; + const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits", + (U32)DStatePtr->state, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +FORCE_INLINE_TEMPLATE void +ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD) +{ + ZSTD_seqSymbol const DInfo = DStatePtr->table[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = DInfo.nextState + lowBits; +} + +/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum + * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1) + * bits before reloading. This value is the maximum number of bytes we read + * after reloading when we are decoding long offets. + */ +#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \ + (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \ + ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \ + : 0) + +typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; + +FORCE_INLINE_TEMPLATE seq_t +ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) +{ + seq_t seq = {0}; + U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits; + U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits; + U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits; + U32 const totalBits = llBits+mlBits+ofBits; + U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue; + U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue; + U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue; + + /* sequence */ + { size_t offset; + if (!ofBits) + offset = 0; + else { + ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); + ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); + assert(ofBits <= MaxOff); + if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { + U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed); + offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); + BIT_reloadDStream(&seqState->DStream); + if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); + assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */ + } else { + offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); + } + } + + if (ofBits <= 1) { + offset += (llBase==0); + if (offset) { + size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } else { /* offset == 0 */ + offset = seqState->prevOffset[0]; + } + } else { + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } + seq.offset = offset; + } + + seq.matchLength = mlBase + + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/) : 0); /* <= 16 bits */ + if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) + BIT_reloadDStream(&seqState->DStream); + if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ + ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); + + seq.litLength = llBase + + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits/*>0*/) : 0); /* <= 16 bits */ + if (MEM_32bits()) + BIT_reloadDStream(&seqState->DStream); + + DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + + /* ANS state update */ + ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ + ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ + + return seq; +} + +FORCE_INLINE_TEMPLATE size_t +ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE* const)dst; + BYTE* const oend = ostart + maxDstSize; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const vBase = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_body"); + + /* Regen sequences */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i=0; ientropy.rep[i]; } + CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { + nbSeq--; + { seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } } + + /* check if reached exact end */ + DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq); + if (nbSeq) return ERROR(corruption_detected); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + { size_t const lastLLSize = litEnd - litPtr; + if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); + memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + + return op-ostart; +} + +static size_t +ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + + + +FORCE_INLINE_TEMPLATE seq_t +ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets) +{ + seq_t seq; + U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits; + U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits; + U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits; + U32 const totalBits = llBits+mlBits+ofBits; + U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue; + U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue; + U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue; + + /* sequence */ + { size_t offset; + if (!ofBits) + offset = 0; + else { + ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); + ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); + assert(ofBits <= MaxOff); + if (MEM_32bits() && longOffsets) { + U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1); + offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); + if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream); + if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); + } else { + offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); + } + } + + if (ofBits <= 1) { + offset += (llBase==0); + if (offset) { + size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } else { + offset = seqState->prevOffset[0]; + } + } else { + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } + seq.offset = offset; + } + + seq.matchLength = mlBase + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ + if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) + BIT_reloadDStream(&seqState->DStream); + if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */ + ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); + + seq.litLength = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ + if (MEM_32bits()) + BIT_reloadDStream(&seqState->DStream); + + { size_t const pos = seqState->pos + seq.litLength; + const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart; + seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. + * No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */ + seqState->pos = pos + seq.matchLength; + } + + /* ANS state update */ + ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ + ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ + + return seq; +} + +FORCE_INLINE_TEMPLATE size_t +ZSTD_decompressSequencesLong_body( + ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE* const)dst; + BYTE* const oend = ostart + maxDstSize; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 4 +#define STOSEQ_MASK (STORED_SEQS-1) +#define ADVANCED_SEQS 4 + seq_t sequences[STORED_SEQS]; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; + dctx->fseEntropy = 1; + { U32 i; for (i=0; ientropy.rep[i]; } + seqState.prefixStart = prefixStart; + seqState.pos = (size_t)(op-prefixStart); + seqState.dictEnd = dictEnd; + CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + /* prepare in advance */ + for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNbentropy.rep[i] = (U32)(seqState.prevOffset[i]); } +#undef STORED_SEQS +#undef STOSEQ_MASK +#undef ADVANCED_SEQS + } + + /* last literal segment */ + { size_t const lastLLSize = litEnd - litPtr; + if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); + memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + + return op-ostart; +} + +static size_t +ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + + + +#if DYNAMIC_BMI2 + +static TARGET_ATTRIBUTE("bmi2") size_t +ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + +static TARGET_ATTRIBUTE("bmi2") size_t +ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + +#endif + +typedef size_t (*ZSTD_decompressSequences_t)( + ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, + const void *seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset); + +static size_t ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequences"); +#if DYNAMIC_BMI2 + if (dctx->bmi2) { + return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + +static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesLong"); +#if DYNAMIC_BMI2 + if (dctx->bmi2) { + return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + +/* ZSTD_getLongOffsetsShare() : + * condition : offTable must be valid + * @return : "share" of long offsets (arbitrarily defined as > (1<<23)) + * compared to maximum possible of (1< 22) total += 1; + } + + assert(tableLog <= OffFSELog); + total <<= (OffFSELog - tableLog); /* scale to OffFSELog */ + + return total; +} + + +static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, const int frame) +{ /* blockType == blockCompressed */ + const BYTE* ip = (const BYTE*)src; + /* isLongOffset must be true if there are long offsets. + * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN. + * We don't expect that to be the case in 64-bit mode. + * In block mode, window size is not known, so we have to be conservative. + * (note: but it could be evaluated from current-lowLimit) + */ + ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))); + DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize); + + if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); + + /* Decode literals section */ + { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); + DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize); + if (ZSTD_isError(litCSize)) return litCSize; + ip += litCSize; + srcSize -= litCSize; + } + + /* Build Decoding Tables */ + { int nbSeq; + size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize); + if (ZSTD_isError(seqHSize)) return seqHSize; + ip += seqHSize; + srcSize -= seqHSize; + + if ( (!frame || dctx->fParams.windowSize > (1<<24)) + && (nbSeq>0) ) { /* could probably use a larger nbSeq limit */ + U32 const shareLongOffsets = ZSTD_getLongOffsetsShare(dctx->OFTptr); + U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */ + if (shareLongOffsets >= minShare) + return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); + } + + return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); + } +} + + +static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) +{ + if (dst != dctx->previousDstEnd) { /* not contiguous */ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dst; + dctx->previousDstEnd = dst; + } +} + +size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + size_t dSize; + ZSTD_checkContinuity(dctx, dst); + dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0); + dctx->previousDstEnd = (char*)dst + dSize; + return dSize; +} + + +/** ZSTD_insertBlock() : + insert `src` block into `dctx` history. Useful to track uncompressed blocks. */ +ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize) +{ + ZSTD_checkContinuity(dctx, blockStart); + dctx->previousDstEnd = (const char*)blockStart + blockSize; + return blockSize; +} + + +static size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE value, size_t length) +{ + if (length > dstCapacity) return ERROR(dstSize_tooSmall); + memset(dst, value, length); + return length; +} + +/** ZSTD_findFrameCompressedSize() : + * compatible with legacy mode + * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame + * `srcSize` must be at least as large as the frame contained + * @return : the compressed size of the frame starting at `src` */ +size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize) +{ +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(src, srcSize)) + return ZSTD_findFrameCompressedSizeLegacy(src, srcSize); +#endif + if ( (srcSize >= ZSTD_skippableHeaderSize) + && (MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START ) { + return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + ZSTD_FRAMEIDSIZE); + } else { + const BYTE* ip = (const BYTE*)src; + const BYTE* const ipstart = ip; + size_t remainingSize = srcSize; + ZSTD_frameHeader zfh; + + /* Extract Frame Header */ + { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize); + if (ZSTD_isError(ret)) return ret; + if (ret > 0) return ERROR(srcSize_wrong); + } + + ip += zfh.headerSize; + remainingSize -= zfh.headerSize; + + /* Loop on each block */ + while (1) { + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + + if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) + return ERROR(srcSize_wrong); + + ip += ZSTD_blockHeaderSize + cBlockSize; + remainingSize -= ZSTD_blockHeaderSize + cBlockSize; + + if (blockProperties.lastBlock) break; + } + + if (zfh.checksumFlag) { /* Final frame content checksum */ + if (remainingSize < 4) return ERROR(srcSize_wrong); + ip += 4; + } + + return ip - ipstart; + } +} + +/*! ZSTD_decompressFrame() : +* @dctx must be properly initialized */ +static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void** srcPtr, size_t *srcSizePtr) +{ + const BYTE* ip = (const BYTE*)(*srcPtr); + BYTE* const ostart = (BYTE* const)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + size_t remainingSize = *srcSizePtr; + + /* check */ + if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) + return ERROR(srcSize_wrong); + + /* Frame Header */ + { size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix); + if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize; + if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize) + return ERROR(srcSize_wrong); + CHECK_F( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) ); + ip += frameHeaderSize; remainingSize -= frameHeaderSize; + } + + /* Loop on each block */ + while (1) { + size_t decodedSize; + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + + ip += ZSTD_blockHeaderSize; + remainingSize -= ZSTD_blockHeaderSize; + if (cBlockSize > remainingSize) return ERROR(srcSize_wrong); + + switch(blockProperties.blockType) + { + case bt_compressed: + decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize, /* frame */ 1); + break; + case bt_raw : + decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize); + break; + case bt_rle : + decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize); + break; + case bt_reserved : + default: + return ERROR(corruption_detected); + } + + if (ZSTD_isError(decodedSize)) return decodedSize; + if (dctx->fParams.checksumFlag) + XXH64_update(&dctx->xxhState, op, decodedSize); + op += decodedSize; + ip += cBlockSize; + remainingSize -= cBlockSize; + if (blockProperties.lastBlock) break; + } + + if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) { + if ((U64)(op-ostart) != dctx->fParams.frameContentSize) { + return ERROR(corruption_detected); + } } + if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */ + U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState); + U32 checkRead; + if (remainingSize<4) return ERROR(checksum_wrong); + checkRead = MEM_readLE32(ip); + if (checkRead != checkCalc) return ERROR(checksum_wrong); + ip += 4; + remainingSize -= 4; + } + + /* Allow caller to get size read */ + *srcPtr = ip; + *srcSizePtr = remainingSize; + return op-ostart; +} + +static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + const ZSTD_DDict* ddict) +{ + void* const dststart = dst; + int moreThan1Frame = 0; + + DEBUGLOG(5, "ZSTD_decompressMultiFrame"); + assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */ + + if (ddict) { + dict = ZSTD_DDictDictContent(ddict); + dictSize = ZSTD_DDictDictSize(ddict); + } + + while (srcSize >= ZSTD_frameHeaderSize_prefix) { + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(src, srcSize)) { + size_t decodedSize; + size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize); + if (ZSTD_isError(frameSize)) return frameSize; + /* legacy support is not compatible with static dctx */ + if (dctx->staticSize) return ERROR(memory_allocation); + + decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize); + + dst = (BYTE*)dst + decodedSize; + dstCapacity -= decodedSize; + + src = (const BYTE*)src + frameSize; + srcSize -= frameSize; + + continue; + } +#endif + + { U32 const magicNumber = MEM_readLE32(src); + DEBUGLOG(4, "reading magic number %08X (expecting %08X)", + (U32)magicNumber, (U32)ZSTD_MAGICNUMBER); + if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { + size_t skippableSize; + if (srcSize < ZSTD_skippableHeaderSize) + return ERROR(srcSize_wrong); + skippableSize = MEM_readLE32((const BYTE*)src + ZSTD_FRAMEIDSIZE) + + ZSTD_skippableHeaderSize; + if (srcSize < skippableSize) return ERROR(srcSize_wrong); + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; + } } + + if (ddict) { + /* we were called from ZSTD_decompress_usingDDict */ + CHECK_F(ZSTD_decompressBegin_usingDDict(dctx, ddict)); + } else { + /* this will initialize correctly with no dict if dict == NULL, so + * use this in all cases but ddict */ + CHECK_F(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize)); + } + ZSTD_checkContinuity(dctx, dst); + + { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, + &src, &srcSize); + if ( (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown) + && (moreThan1Frame==1) ) { + /* at least one frame successfully completed, + * but following bytes are garbage : + * it's more likely to be a srcSize error, + * specifying more bytes than compressed size of frame(s). + * This error message replaces ERROR(prefix_unknown), + * which would be confusing, as the first header is actually correct. + * Note that one could be unlucky, it might be a corruption error instead, + * happening right at the place where we expect zstd magic bytes. + * But this is _much_ less likely than a srcSize field error. */ + return ERROR(srcSize_wrong); + } + if (ZSTD_isError(res)) return res; + /* no need to bound check, ZSTD_decompressFrame already has */ + dst = (BYTE*)dst + res; + dstCapacity -= res; + } + moreThan1Frame = 1; + } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ + + if (srcSize) return ERROR(srcSize_wrong); /* input not entirely consumed */ + + return (BYTE*)dst - (BYTE*)dststart; +} + +size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize) +{ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL); +} + + +size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0); +} + + +size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ +#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1) + size_t regenSize; + ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + if (dctx==NULL) return ERROR(memory_allocation); + regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize); + ZSTD_freeDCtx(dctx); + return regenSize; +#else /* stack mode */ + ZSTD_DCtx dctx; + ZSTD_initDCtx_internal(&dctx); + return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize); +#endif +} + + +/*-************************************** +* Advanced Streaming Decompression API +* Bufferless and synchronous +****************************************/ +size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; } + +ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { + switch(dctx->stage) + { + default: /* should not happen */ + assert(0); + case ZSTDds_getFrameHeaderSize: + case ZSTDds_decodeFrameHeader: + return ZSTDnit_frameHeader; + case ZSTDds_decodeBlockHeader: + return ZSTDnit_blockHeader; + case ZSTDds_decompressBlock: + return ZSTDnit_block; + case ZSTDds_decompressLastBlock: + return ZSTDnit_lastBlock; + case ZSTDds_checkChecksum: + return ZSTDnit_checksum; + case ZSTDds_decodeSkippableHeader: + case ZSTDds_skipFrame: + return ZSTDnit_skippableFrame; + } +} + +static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } + +/** ZSTD_decompressContinue() : + * srcSize : must be the exact nb of bytes expected (see ZSTD_nextSrcSizeToDecompress()) + * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity) + * or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (U32)srcSize); + /* Sanity check */ + if (srcSize != dctx->expected) return ERROR(srcSize_wrong); /* not allowed */ + if (dstCapacity) ZSTD_checkContinuity(dctx, dst); + + switch (dctx->stage) + { + case ZSTDds_getFrameHeaderSize : + assert(src != NULL); + if (dctx->format == ZSTD_f_zstd1) { /* allows header */ + assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */ + if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ + memcpy(dctx->headerBuffer, src, srcSize); + dctx->expected = ZSTD_skippableHeaderSize - srcSize; /* remaining to load to get full skippable frame header */ + dctx->stage = ZSTDds_decodeSkippableHeader; + return 0; + } } + dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format); + if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize; + memcpy(dctx->headerBuffer, src, srcSize); + dctx->expected = dctx->headerSize - srcSize; + dctx->stage = ZSTDds_decodeFrameHeader; + return 0; + + case ZSTDds_decodeFrameHeader: + assert(src != NULL); + memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize); + CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize)); + dctx->expected = ZSTD_blockHeaderSize; + dctx->stage = ZSTDds_decodeBlockHeader; + return 0; + + case ZSTDds_decodeBlockHeader: + { blockProperties_t bp; + size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + dctx->expected = cBlockSize; + dctx->bType = bp.blockType; + dctx->rleSize = bp.origSize; + if (cBlockSize) { + dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock; + return 0; + } + /* empty block */ + if (bp.lastBlock) { + if (dctx->fParams.checksumFlag) { + dctx->expected = 4; + dctx->stage = ZSTDds_checkChecksum; + } else { + dctx->expected = 0; /* end of frame */ + dctx->stage = ZSTDds_getFrameHeaderSize; + } + } else { + dctx->expected = ZSTD_blockHeaderSize; /* jump to next header */ + dctx->stage = ZSTDds_decodeBlockHeader; + } + return 0; + } + + case ZSTDds_decompressLastBlock: + case ZSTDds_decompressBlock: + DEBUGLOG(5, "ZSTD_decompressContinue: case ZSTDds_decompressBlock"); + { size_t rSize; + switch(dctx->bType) + { + case bt_compressed: + DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed"); + rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1); + break; + case bt_raw : + rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize); + break; + case bt_rle : + rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize); + break; + case bt_reserved : /* should never happen */ + default: + return ERROR(corruption_detected); + } + if (ZSTD_isError(rSize)) return rSize; + DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (U32)rSize); + dctx->decodedSize += rSize; + if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize); + + if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */ + DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (U32)dctx->decodedSize); + if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) { + if (dctx->decodedSize != dctx->fParams.frameContentSize) { + return ERROR(corruption_detected); + } } + if (dctx->fParams.checksumFlag) { /* another round for frame checksum */ + dctx->expected = 4; + dctx->stage = ZSTDds_checkChecksum; + } else { + dctx->expected = 0; /* ends here */ + dctx->stage = ZSTDds_getFrameHeaderSize; + } + } else { + dctx->stage = ZSTDds_decodeBlockHeader; + dctx->expected = ZSTD_blockHeaderSize; + dctx->previousDstEnd = (char*)dst + rSize; + } + return rSize; + } + + case ZSTDds_checkChecksum: + assert(srcSize == 4); /* guaranteed by dctx->expected */ + { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState); + U32 const check32 = MEM_readLE32(src); + DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", h32, check32); + if (check32 != h32) return ERROR(checksum_wrong); + dctx->expected = 0; + dctx->stage = ZSTDds_getFrameHeaderSize; + return 0; + } + + case ZSTDds_decodeSkippableHeader: + assert(src != NULL); + assert(srcSize <= ZSTD_skippableHeaderSize); + memcpy(dctx->headerBuffer + (ZSTD_skippableHeaderSize - srcSize), src, srcSize); /* complete skippable header */ + dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */ + dctx->stage = ZSTDds_skipFrame; + return 0; + + case ZSTDds_skipFrame: + dctx->expected = 0; + dctx->stage = ZSTDds_getFrameHeaderSize; + return 0; + + default: + return ERROR(GENERIC); /* impossible */ + } +} + + +static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dict; + dctx->previousDstEnd = (const char*)dict + dictSize; + return 0; +} + +/*! ZSTD_loadEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * @return : size of entropy tables read */ +static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, + const void* const dict, size_t const dictSize) +{ + const BYTE* dictPtr = (const BYTE*)dict; + const BYTE* const dictEnd = dictPtr + dictSize; + + if (dictSize <= 8) return ERROR(dictionary_corrupted); + assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */ + dictPtr += 8; /* skip header = magic + dictID */ + + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable)); + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable)); + ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE); + { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */ + size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable); + size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable, + dictPtr, dictEnd - dictPtr, + workspace, workspaceSize); + if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); + dictPtr += hSize; + } + + { short offcodeNCount[MaxOff+1]; + U32 offcodeMaxValue = MaxOff, offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); + if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); + if (offcodeMaxValue > MaxOff) return ERROR(dictionary_corrupted); + if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); + ZSTD_buildFSETable( entropy->OFTable, + offcodeNCount, offcodeMaxValue, + OF_base, OF_bits, + offcodeLog); + dictPtr += offcodeHeaderSize; + } + + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); + if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); + if (matchlengthMaxValue > MaxML) return ERROR(dictionary_corrupted); + if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); + ZSTD_buildFSETable( entropy->MLTable, + matchlengthNCount, matchlengthMaxValue, + ML_base, ML_bits, + matchlengthLog); + dictPtr += matchlengthHeaderSize; + } + + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); + if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); + if (litlengthMaxValue > MaxLL) return ERROR(dictionary_corrupted); + if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); + ZSTD_buildFSETable( entropy->LLTable, + litlengthNCount, litlengthMaxValue, + LL_base, LL_bits, + litlengthLog); + dictPtr += litlengthHeaderSize; + } + + if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted); + { int i; + size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12)); + for (i=0; i<3; i++) { + U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4; + if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted); + entropy->rep[i] = rep; + } } + + return dictPtr - (const BYTE*)dict; +} + +static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); + { U32 const magic = MEM_readLE32(dict); + if (magic != ZSTD_MAGIC_DICTIONARY) { + return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ + } } + dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + { size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize); + if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted); + dict = (const char*)dict + eSize; + dictSize -= eSize; + } + dctx->litEntropy = dctx->fseEntropy = 1; + + /* reference dictionary content */ + return ZSTD_refDictContent(dctx, dict, dictSize); +} + +size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) +{ + assert(dctx != NULL); + dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */ + dctx->stage = ZSTDds_getFrameHeaderSize; + dctx->decodedSize = 0; + dctx->previousDstEnd = NULL; + dctx->prefixStart = NULL; + dctx->virtualStart = NULL; + dctx->dictEnd = NULL; + dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ + dctx->litEntropy = dctx->fseEntropy = 0; + dctx->dictID = 0; + ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); + memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ + dctx->LLTptr = dctx->entropy.LLTable; + dctx->MLTptr = dctx->entropy.MLTable; + dctx->OFTptr = dctx->entropy.OFTable; + dctx->HUFptr = dctx->entropy.hufTable; + return 0; +} + +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + CHECK_F( ZSTD_decompressBegin(dctx) ); + if (dict && dictSize) + CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted); + return 0; +} + + +/* ====== ZSTD_DDict ====== */ + +struct ZSTD_DDict_s { + void* dictBuffer; + const void* dictContent; + size_t dictSize; + ZSTD_entropyDTables_t entropy; + U32 dictID; + U32 entropyPresent; + ZSTD_customMem cMem; +}; /* typedef'd to ZSTD_DDict within "zstd.h" */ + +static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictContent; +} + +static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictSize; +} + +size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict"); + assert(dctx != NULL); + if (ddict) { + dctx->ddictIsCold = (dctx->dictEnd != (const char*)ddict->dictContent + ddict->dictSize); + DEBUGLOG(4, "DDict is %s", + dctx->ddictIsCold ? "~cold~" : "hot!"); + } + CHECK_F( ZSTD_decompressBegin(dctx) ); + if (ddict) { /* NULL ddict is equivalent to no dictionary */ + dctx->dictID = ddict->dictID; + dctx->prefixStart = ddict->dictContent; + dctx->virtualStart = ddict->dictContent; + dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize; + dctx->previousDstEnd = dctx->dictEnd; + if (ddict->entropyPresent) { + dctx->litEntropy = 1; + dctx->fseEntropy = 1; + dctx->LLTptr = ddict->entropy.LLTable; + dctx->MLTptr = ddict->entropy.MLTable; + dctx->OFTptr = ddict->entropy.OFTable; + dctx->HUFptr = ddict->entropy.hufTable; + dctx->entropy.rep[0] = ddict->entropy.rep[0]; + dctx->entropy.rep[1] = ddict->entropy.rep[1]; + dctx->entropy.rep[2] = ddict->entropy.rep[2]; + } else { + dctx->litEntropy = 0; + dctx->fseEntropy = 0; + } + } + return 0; +} + +static size_t +ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict, + ZSTD_dictContentType_e dictContentType) +{ + ddict->dictID = 0; + ddict->entropyPresent = 0; + if (dictContentType == ZSTD_dct_rawContent) return 0; + + if (ddict->dictSize < 8) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + { U32 const magic = MEM_readLE32(ddict->dictContent); + if (magic != ZSTD_MAGIC_DICTIONARY) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + } + ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + CHECK_E( ZSTD_loadEntropy(&ddict->entropy, + ddict->dictContent, ddict->dictSize), + dictionary_corrupted ); + ddict->entropyPresent = 1; + return 0; +} + + +static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) { + ddict->dictBuffer = NULL; + ddict->dictContent = dict; + if (!dict) dictSize = 0; + } else { + void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem); + ddict->dictBuffer = internalBuffer; + ddict->dictContent = internalBuffer; + if (!internalBuffer) return ERROR(memory_allocation); + memcpy(internalBuffer, dict, dictSize); + } + ddict->dictSize = dictSize; + ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ + + /* parse dictionary content */ + CHECK_F( ZSTD_loadEntropy_inDDict(ddict, dictContentType) ); + + return 0; +} + +ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_customMem customMem) +{ + if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + + { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem); + if (ddict == NULL) return NULL; + ddict->cMem = customMem; + { size_t const initResult = ZSTD_initDDict_internal(ddict, + dict, dictSize, + dictLoadMethod, dictContentType); + if (ZSTD_isError(initResult)) { + ZSTD_freeDDict(ddict); + return NULL; + } } + return ddict; + } +} + +/*! ZSTD_createDDict() : +* Create a digested dictionary, to start decompression without startup delay. +* `dict` content is copied inside DDict. +* Consequently, `dict` can be released after `ZSTD_DDict` creation */ +ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator); +} + +/*! ZSTD_createDDict_byReference() : + * Create a digested dictionary, to start decompression without startup delay. + * Dictionary content is simply referenced, it will be accessed during decompression. + * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */ +ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator); +} + + +const ZSTD_DDict* ZSTD_initStaticDDict( + void* sBuffer, size_t sBufferSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + size_t const neededSpace = sizeof(ZSTD_DDict) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); + ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer; + assert(sBuffer != NULL); + assert(dict != NULL); + if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */ + if (sBufferSize < neededSpace) return NULL; + if (dictLoadMethod == ZSTD_dlm_byCopy) { + memcpy(ddict+1, dict, dictSize); /* local copy */ + dict = ddict+1; + } + if (ZSTD_isError( ZSTD_initDDict_internal(ddict, + dict, dictSize, + ZSTD_dlm_byRef, dictContentType) )) + return NULL; + return ddict; +} + + +size_t ZSTD_freeDDict(ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support free on NULL */ + { ZSTD_customMem const cMem = ddict->cMem; + ZSTD_free(ddict->dictBuffer, cMem); + ZSTD_free(ddict, cMem); + return 0; + } +} + +/*! ZSTD_estimateDDictSize() : + * Estimate amount of memory that will be needed to create a dictionary for decompression. + * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */ +size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod) +{ + return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); +} + +size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support sizeof on NULL */ + return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ; +} + +/*! ZSTD_getDictID_fromDict() : + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) +{ + if (dictSize < 8) return 0; + if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0; + return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); +} + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; + return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize); +} + +/*! ZSTD_getDictID_fromFrame() : + * Provides the dictID required to decompresse frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary (most common case). + * - The frame was built with dictID intentionally removed. + * Needed dictionary is a hidden information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, frame header could not be decoded. + * Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`. + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to use + * ZSTD_getFrameHeader(), which will provide a more precise error code. */ +unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize) +{ + ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 }; + size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize); + if (ZSTD_isError(hError)) return 0; + return zfp.dictID; +} + + +/*! ZSTD_decompress_usingDDict() : +* Decompression using a pre-digested Dictionary +* Use dictionary without significant overhead. */ +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_DDict* ddict) +{ + /* pass content and size in case legacy frames are encountered */ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, + NULL, 0, + ddict); +} + + +/*===================================== +* Streaming decompression +*====================================*/ + +ZSTD_DStream* ZSTD_createDStream(void) +{ + DEBUGLOG(3, "ZSTD_createDStream"); + return ZSTD_createDStream_advanced(ZSTD_defaultCMem); +} + +ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize) +{ + return ZSTD_initStaticDCtx(workspace, workspaceSize); +} + +ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createDCtx_advanced(customMem); +} + +size_t ZSTD_freeDStream(ZSTD_DStream* zds) +{ + return ZSTD_freeDCtx(zds); +} + + +/* *** Initialization *** */ + +size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; } +size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; } + +size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); + ZSTD_freeDDict(dctx->ddictLocal); + if (dict && dictSize >= 8) { + dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem); + if (dctx->ddictLocal == NULL) return ERROR(memory_allocation); + } else { + dctx->ddictLocal = NULL; + } + dctx->ddict = dctx->ddictLocal; + return 0; +} + +size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); +} + +size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); +} + +size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType) +{ + return ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType); +} + +size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize) +{ + return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent); +} + + +/* ZSTD_initDStream_usingDict() : + * return : expected size, aka ZSTD_frameHeaderSize_prefix. + * this function cannot fail */ +size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize) +{ + DEBUGLOG(4, "ZSTD_initDStream_usingDict"); + zds->streamStage = zdss_init; + zds->noForwardProgress = 0; + CHECK_F( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) ); + return ZSTD_frameHeaderSize_prefix; +} + +/* note : this variant can't fail */ +size_t ZSTD_initDStream(ZSTD_DStream* zds) +{ + DEBUGLOG(4, "ZSTD_initDStream"); + return ZSTD_initDStream_usingDict(zds, NULL, 0); +} + +/* ZSTD_initDStream_usingDDict() : + * ddict will just be referenced, and must outlive decompression session + * this function cannot fail */ +size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict) +{ + size_t const initResult = ZSTD_initDStream(dctx); + dctx->ddict = ddict; + return initResult; +} + +/* ZSTD_resetDStream() : + * return : expected size, aka ZSTD_frameHeaderSize_prefix. + * this function cannot fail */ +size_t ZSTD_resetDStream(ZSTD_DStream* dctx) +{ + DEBUGLOG(4, "ZSTD_resetDStream"); + dctx->streamStage = zdss_loadHeader; + dctx->lhSize = dctx->inPos = dctx->outStart = dctx->outEnd = 0; + dctx->legacyVersion = 0; + dctx->hostageByte = 0; + return ZSTD_frameHeaderSize_prefix; +} + +size_t ZSTD_setDStreamParameter(ZSTD_DStream* dctx, + ZSTD_DStreamParameter_e paramType, unsigned paramValue) +{ + if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); + switch(paramType) + { + default : return ERROR(parameter_unsupported); + case DStream_p_maxWindowSize : + DEBUGLOG(4, "setting maxWindowSize = %u KB", paramValue >> 10); + dctx->maxWindowSize = paramValue ? paramValue : (U32)(-1); + break; + } + return 0; +} + +size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); + dctx->ddict = ddict; + return 0; +} + +size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize) +{ + if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); + dctx->maxWindowSize = maxWindowSize; + return 0; +} + +size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format) +{ + DEBUGLOG(4, "ZSTD_DCtx_setFormat : %u", (unsigned)format); + if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); + dctx->format = format; + return 0; +} + + +size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx) +{ + return ZSTD_sizeof_DCtx(dctx); +} + +size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize) +{ + size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); + unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2); + unsigned long long const neededSize = MIN(frameContentSize, neededRBSize); + size_t const minRBSize = (size_t) neededSize; + if ((unsigned long long)minRBSize != neededSize) return ERROR(frameParameter_windowTooLarge); + return minRBSize; +} + +size_t ZSTD_estimateDStreamSize(size_t windowSize) +{ + size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX); + size_t const inBuffSize = blockSize; /* no block can be larger */ + size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN); + return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize; +} + +size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize) +{ + U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable */ + ZSTD_frameHeader zfh; + size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize); + if (ZSTD_isError(err)) return err; + if (err>0) return ERROR(srcSize_wrong); + if (zfh.windowSize > windowSizeMax) + return ERROR(frameParameter_windowTooLarge); + return ZSTD_estimateDStreamSize((size_t)zfh.windowSize); +} + + +/* ***** Decompression ***** */ + +MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + size_t const length = MIN(dstCapacity, srcSize); + memcpy(dst, src, length); + return length; +} + + +size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + const char* const istart = (const char*)(input->src) + input->pos; + const char* const iend = (const char*)(input->src) + input->size; + const char* ip = istart; + char* const ostart = (char*)(output->dst) + output->pos; + char* const oend = (char*)(output->dst) + output->size; + char* op = ostart; + U32 someMoreWork = 1; + + DEBUGLOG(5, "ZSTD_decompressStream"); + if (input->pos > input->size) { /* forbidden */ + DEBUGLOG(5, "in: pos: %u vs size: %u", + (U32)input->pos, (U32)input->size); + return ERROR(srcSize_wrong); + } + if (output->pos > output->size) { /* forbidden */ + DEBUGLOG(5, "out: pos: %u vs size: %u", + (U32)output->pos, (U32)output->size); + return ERROR(dstSize_tooSmall); + } + DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos)); + + while (someMoreWork) { + switch(zds->streamStage) + { + case zdss_init : + DEBUGLOG(5, "stage zdss_init => transparent reset "); + ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ + /* fall-through */ + + case zdss_loadHeader : + DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip)); +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + if (zds->legacyVersion) { + /* legacy support is incompatible with static dctx */ + if (zds->staticSize) return ERROR(memory_allocation); + { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input); + if (hint==0) zds->streamStage = zdss_init; + return hint; + } } +#endif + { size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format); + DEBUGLOG(5, "header size : %u", (U32)hSize); + if (ZSTD_isError(hSize)) { +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart); + if (legacyVersion) { + const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL; + size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0; + DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion); + /* legacy support is incompatible with static dctx */ + if (zds->staticSize) return ERROR(memory_allocation); + CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, + zds->previousLegacyVersion, legacyVersion, + dict, dictSize)); + zds->legacyVersion = zds->previousLegacyVersion = legacyVersion; + { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input); + if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */ + return hint; + } } +#endif + return hSize; /* error */ + } + if (hSize != 0) { /* need more input */ + size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */ + size_t const remainingInput = (size_t)(iend-ip); + assert(iend >= ip); + if (toLoad > remainingInput) { /* not enough input to load full header */ + if (remainingInput > 0) { + memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput); + zds->lhSize += remainingInput; + } + input->pos = input->size; + return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ + } + assert(ip != NULL); + memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; + break; + } } + + /* check for single-pass mode opportunity */ + if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */ + && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) { + size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart); + if (cSize <= (size_t)(iend-istart)) { + /* shortcut : using single-pass mode */ + size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, zds->ddict); + if (ZSTD_isError(decompressedSize)) return decompressedSize; + DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()") + ip = istart + cSize; + op += decompressedSize; + zds->expected = 0; + zds->streamStage = zdss_init; + someMoreWork = 0; + break; + } } + + /* Consume header (see ZSTDds_decodeFrameHeader) */ + DEBUGLOG(4, "Consume header"); + CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict)); + + if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ + zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE); + zds->stage = ZSTDds_skipFrame; + } else { + CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize)); + zds->expected = ZSTD_blockHeaderSize; + zds->stage = ZSTDds_decodeBlockHeader; + } + + /* control buffer memory usage */ + DEBUGLOG(4, "Control max memory usage (%u KB <= max %u KB)", + (U32)(zds->fParams.windowSize >>10), + (U32)(zds->maxWindowSize >> 10) ); + zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); + if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge); + + /* Adapt buffer sizes to frame header instructions */ + { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */); + size_t const neededOutBuffSize = ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize); + if ((zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize)) { + size_t const bufferSize = neededInBuffSize + neededOutBuffSize; + DEBUGLOG(4, "inBuff : from %u to %u", + (U32)zds->inBuffSize, (U32)neededInBuffSize); + DEBUGLOG(4, "outBuff : from %u to %u", + (U32)zds->outBuffSize, (U32)neededOutBuffSize); + if (zds->staticSize) { /* static DCtx */ + DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize); + assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */ + if (bufferSize > zds->staticSize - sizeof(ZSTD_DCtx)) + return ERROR(memory_allocation); + } else { + ZSTD_free(zds->inBuff, zds->customMem); + zds->inBuffSize = 0; + zds->outBuffSize = 0; + zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem); + if (zds->inBuff == NULL) return ERROR(memory_allocation); + } + zds->inBuffSize = neededInBuffSize; + zds->outBuff = zds->inBuff + zds->inBuffSize; + zds->outBuffSize = neededOutBuffSize; + } } + zds->streamStage = zdss_read; + /* fall-through */ + + case zdss_read: + DEBUGLOG(5, "stage zdss_read"); + { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); + DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize); + if (neededInSize==0) { /* end of frame */ + zds->streamStage = zdss_init; + someMoreWork = 0; + break; + } + if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */ + int const isSkipFrame = ZSTD_isSkipFrame(zds); + size_t const decodedSize = ZSTD_decompressContinue(zds, + zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart), + ip, neededInSize); + if (ZSTD_isError(decodedSize)) return decodedSize; + ip += neededInSize; + if (!decodedSize && !isSkipFrame) break; /* this was just a header */ + zds->outEnd = zds->outStart + decodedSize; + zds->streamStage = zdss_flush; + break; + } } + if (ip==iend) { someMoreWork = 0; break; } /* no more input */ + zds->streamStage = zdss_load; + /* fall-through */ + + case zdss_load: + { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); + size_t const toLoad = neededInSize - zds->inPos; + int const isSkipFrame = ZSTD_isSkipFrame(zds); + size_t loadedSize; + if (isSkipFrame) { + loadedSize = MIN(toLoad, (size_t)(iend-ip)); + } else { + if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */ + loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip); + } + ip += loadedSize; + zds->inPos += loadedSize; + if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */ + + /* decode loaded input */ + { size_t const decodedSize = ZSTD_decompressContinue(zds, + zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart, + zds->inBuff, neededInSize); + if (ZSTD_isError(decodedSize)) return decodedSize; + zds->inPos = 0; /* input is consumed */ + if (!decodedSize && !isSkipFrame) { zds->streamStage = zdss_read; break; } /* this was just a header */ + zds->outEnd = zds->outStart + decodedSize; + } } + zds->streamStage = zdss_flush; + /* fall-through */ + + case zdss_flush: + { size_t const toFlushSize = zds->outEnd - zds->outStart; + size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize); + op += flushedSize; + zds->outStart += flushedSize; + if (flushedSize == toFlushSize) { /* flush completed */ + zds->streamStage = zdss_read; + if ( (zds->outBuffSize < zds->fParams.frameContentSize) + && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) { + DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)", + (int)(zds->outBuffSize - zds->outStart), + (U32)zds->fParams.blockSizeMax); + zds->outStart = zds->outEnd = 0; + } + break; + } } + /* cannot complete flush */ + someMoreWork = 0; + break; + + default: return ERROR(GENERIC); /* impossible */ + } } + + /* result */ + input->pos = (size_t)(ip - (const char*)(input->src)); + output->pos = (size_t)(op - (char*)(output->dst)); + if ((ip==istart) && (op==ostart)) { /* no forward progress */ + zds->noForwardProgress ++; + if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) { + if (op==oend) return ERROR(dstSize_tooSmall); + if (ip==iend) return ERROR(srcSize_wrong); + assert(0); + } + } else { + zds->noForwardProgress = 0; + } + { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds); + if (!nextSrcSizeHint) { /* frame fully decoded */ + if (zds->outEnd == zds->outStart) { /* output fully flushed */ + if (zds->hostageByte) { + if (input->pos >= input->size) { + /* can't release hostage (not present) */ + zds->streamStage = zdss_read; + return 1; + } + input->pos++; /* release hostage */ + } /* zds->hostageByte */ + return 0; + } /* zds->outEnd == zds->outStart */ + if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */ + input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */ + zds->hostageByte=1; + } + return 1; + } /* nextSrcSizeHint==0 */ + nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */ + assert(zds->inPos <= nextSrcSizeHint); + nextSrcSizeHint -= zds->inPos; /* part already loaded*/ + return nextSrcSizeHint; + } +} + + +size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + return ZSTD_decompressStream(dctx, output, input); +} + +size_t ZSTD_decompress_generic_simpleArgs ( + ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, size_t* dstPos, + const void* src, size_t srcSize, size_t* srcPos) +{ + ZSTD_outBuffer output = { dst, dstCapacity, *dstPos }; + ZSTD_inBuffer input = { src, srcSize, *srcPos }; + /* ZSTD_compress_generic() will check validity of dstPos and srcPos */ + size_t const cErr = ZSTD_decompress_generic(dctx, &output, &input); + *dstPos = output.pos; + *srcPos = input.pos; + return cErr; +} + +void ZSTD_DCtx_reset(ZSTD_DCtx* dctx) +{ + (void)ZSTD_initDStream(dctx); + dctx->format = ZSTD_f_zstd1; + dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; +} diff --git a/grub-core/lib/zstd/zstd_errors.h b/grub-core/lib/zstd/zstd_errors.h new file mode 100644 index 000000000..57533f286 --- /dev/null +++ b/grub-core/lib/zstd/zstd_errors.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_ERRORS_H_398273423 +#define ZSTD_ERRORS_H_398273423 + +#if defined (__cplusplus) +extern "C" { +#endif + +/*===== dependency =====*/ +#include /* size_t */ + + +/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */ +#ifndef ZSTDERRORLIB_VISIBILITY +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility ("default"))) +# else +# define ZSTDERRORLIB_VISIBILITY +# endif +#endif +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBILITY +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBILITY +#endif + +/*-********************************************* + * Error codes list + *-********************************************* + * Error codes _values_ are pinned down since v1.3.1 only. + * Therefore, don't rely on values if you may link to any version < v1.3.1. + * + * Only values < 100 are considered stable. + * + * note 1 : this API shall be used with static linking only. + * dynamic linking is not yet officially supported. + * note 2 : Prefer relying on the enum than on its value whenever possible + * This is the only supported way to use the error list < v1.3.1 + * note 3 : ZSTD_isError() is always correct, whatever the library version. + **********************************************/ +typedef enum { + ZSTD_error_no_error = 0, + ZSTD_error_GENERIC = 1, + ZSTD_error_prefix_unknown = 10, + ZSTD_error_version_unsupported = 12, + ZSTD_error_frameParameter_unsupported = 14, + ZSTD_error_frameParameter_windowTooLarge = 16, + ZSTD_error_corruption_detected = 20, + ZSTD_error_checksum_wrong = 22, + ZSTD_error_dictionary_corrupted = 30, + ZSTD_error_dictionary_wrong = 32, + ZSTD_error_dictionaryCreation_failed = 34, + ZSTD_error_parameter_unsupported = 40, + ZSTD_error_parameter_outOfBound = 42, + ZSTD_error_tableLog_tooLarge = 44, + ZSTD_error_maxSymbolValue_tooLarge = 46, + ZSTD_error_maxSymbolValue_tooSmall = 48, + ZSTD_error_stage_wrong = 60, + ZSTD_error_init_missing = 62, + ZSTD_error_memory_allocation = 64, + ZSTD_error_workSpace_tooSmall= 66, + ZSTD_error_dstSize_tooSmall = 70, + ZSTD_error_srcSize_wrong = 72, + /* following error codes are __NOT STABLE__, they can be removed or changed in future versions */ + ZSTD_error_frameIndex_tooLarge = 100, + ZSTD_error_seekableIO = 102, + ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */ +} ZSTD_ErrorCode; + +/*! ZSTD_getErrorCode() : + convert a `size_t` function result into a `ZSTD_ErrorCode` enum type, + which can be used to compare with enum list published above */ +ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); +ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ERRORS_H_398273423 */ diff --git a/grub-core/lib/zstd/zstd_internal.h b/grub-core/lib/zstd/zstd_internal.h new file mode 100644 index 000000000..e75adfa61 --- /dev/null +++ b/grub-core/lib/zstd/zstd_internal.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CCOMMON_H_MODULE +#define ZSTD_CCOMMON_H_MODULE + +/* this module contains definitions which must be identical + * across compression, decompression and dictBuilder. + * It also contains a few functions useful to at least 2 of them + * and which benefit from being inlined */ + +/*-************************************* +* Dependencies +***************************************/ +#include "compiler.h" +#include "mem.h" +#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */ +#include "error_private.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#define HUF_STATIC_LINKING_ONLY +#include "huf.h" +#ifndef XXH_STATIC_LINKING_ONLY +# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */ +#endif +#include "xxhash.h" /* XXH_reset, update, digest */ + + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ---- static assert (debug) --- */ +#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) + + +/*-************************************* +* shared macros +***************************************/ +#undef MIN +#undef MAX +#define MIN(a,b) ((a)<(b) ? (a) : (b)) +#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; } /* check and Forward error code */ +#define CHECK_E(f, e) { size_t const errcod = f; if (ERR_isError(errcod)) return ERROR(e); } /* check and send Error code */ + + +/*-************************************* +* Common constants +***************************************/ +#define ZSTD_OPT_NUM (1<<12) + +#define ZSTD_REP_NUM 3 /* number of repcodes */ +#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) +static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define BIT7 128 +#define BIT6 64 +#define BIT5 32 +#define BIT4 16 +#define BIT1 2 +#define BIT0 1 + +#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10 +#define ZSTD_WINDOWLOG_DEFAULTMAX 27 /* Default maximum allowed window log */ +static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 }; +static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 }; + +#define ZSTD_FRAMEIDSIZE 4 /* magic number size */ + +#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */ +static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; +typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; + +#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ +#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */ + +#define HufLog 12 +typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e; + +#define LONGNBSEQ 0x7F00 + +#define MINMATCH 3 + +#define Litbits 8 +#define MaxLit ((1<= 3) /* GCC Intrinsic */ + return 31 - __builtin_clz(val); +# else /* Software version */ + static const U32 DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; + U32 v = val; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + return DeBruijnClz[(v * 0x07C4ACDDU) >> 27]; +# endif + } +} + + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */ + + +typedef struct { + blockType_e blockType; + U32 lastBlock; + U32 origSize; +} blockProperties_t; + +/*! ZSTD_getcBlockSize() : + * Provides the size of compressed block from block header `src` */ +/* Used by: decompress, fullbench (does not get its definition from here) */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr); + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c index 5b39f02bb..19ddedbc2 100644 --- a/grub-core/loader/arm/linux.c +++ b/grub-core/loader/arm/linux.c @@ -26,8 +26,10 @@ #include #include #include +#include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -42,21 +44,18 @@ static grub_size_t linux_size; static char *linux_args; static grub_uint32_t machine_type; -static void *fdt_addr; +static const void *current_fdt; typedef void (*kernel_entry_t) (int, unsigned long, void *); -#define LINUX_ZIMAGE_OFFSET 0x24 -#define LINUX_ZIMAGE_MAGIC 0x016f2818 - #define LINUX_PHYS_OFFSET (0x00008000) -#define LINUX_INITRD_PHYS_OFFSET (LINUX_PHYS_OFFSET + 0x02000000) +#define LINUX_INITRD_PHYS_OFFSET (LINUX_PHYS_OFFSET + 0x03000000) #define LINUX_FDT_PHYS_OFFSET (LINUX_INITRD_PHYS_OFFSET - 0x10000) static grub_size_t -get_atag_size (grub_uint32_t *atag) +get_atag_size (const grub_uint32_t *atag) { - grub_uint32_t *atag0 = atag; + const grub_uint32_t *atag0 = atag; while (atag[0] && atag[1]) atag += atag[0]; return atag - atag0; @@ -68,10 +67,11 @@ get_atag_size (grub_uint32_t *atag) * Merges in command line parameters and sets up initrd addresses. */ static grub_err_t -linux_prepare_atag (void) +linux_prepare_atag (void *target_atag) { - grub_uint32_t *atag_orig = (grub_uint32_t *) fdt_addr; - grub_uint32_t *tmp_atag, *from, *to; + const grub_uint32_t *atag_orig = (const grub_uint32_t *) current_fdt; + grub_uint32_t *tmp_atag, *to; + const grub_uint32_t *from; grub_size_t tmp_size; grub_size_t arg_size = grub_strlen (linux_args); char *cmdline_orig = NULL; @@ -79,7 +79,7 @@ linux_prepare_atag (void) /* 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; @@ -142,7 +142,7 @@ linux_prepare_atag (void) to += 2; /* Copy updated FDT to its launch location */ - grub_memcpy (atag_orig, tmp_atag, sizeof (grub_uint32_t) * (to - tmp_atag)); + grub_memcpy (target_atag, tmp_atag, sizeof (grub_uint32_t) * (to - tmp_atag)); grub_free (tmp_atag); grub_dprintf ("loader", "ATAG updated for Linux boot\n"); @@ -156,19 +156,19 @@ linux_prepare_atag (void) * Merges in command line parameters and sets up initrd addresses. */ static grub_err_t -linux_prepare_fdt (void) +linux_prepare_fdt (void *target_fdt) { int node; int retval; int tmp_size; void *tmp_fdt; - tmp_size = grub_fdt_get_totalsize (fdt_addr) + 0x100 + grub_strlen (linux_args); + tmp_size = grub_fdt_get_totalsize (current_fdt) + 0x100 + grub_strlen (linux_args); tmp_fdt = grub_malloc (tmp_size); if (!tmp_fdt) return grub_errno; - grub_memcpy (tmp_fdt, fdt_addr, grub_fdt_get_totalsize (fdt_addr)); + grub_memcpy (tmp_fdt, current_fdt, grub_fdt_get_totalsize (current_fdt)); grub_fdt_set_totalsize (tmp_fdt, tmp_size); /* Find or create '/chosen' node */ @@ -209,7 +209,7 @@ linux_prepare_fdt (void) } /* Copy updated FDT to its launch location */ - grub_memcpy (fdt_addr, tmp_fdt, tmp_size); + grub_memcpy (target_fdt, tmp_fdt, tmp_size); grub_free (tmp_fdt); grub_dprintf ("loader", "FDT updated for Linux boot\n"); @@ -226,16 +226,17 @@ linux_boot (void) { kernel_entry_t linuxmain; int fdt_valid, atag_valid; + void *target_fdt = 0; - fdt_valid = (fdt_addr && grub_fdt_check_header_nosize (fdt_addr) == 0); - atag_valid = ((((grub_uint16_t *) fdt_addr)[3] & ~3) == 0x5440 - && *((grub_uint32_t *) fdt_addr)); + fdt_valid = (current_fdt && grub_fdt_check_header_nosize (current_fdt) == 0); + atag_valid = ((((const grub_uint16_t *) current_fdt)[3] & ~3) == 0x5440 + && *((const grub_uint32_t *) current_fdt)); grub_dprintf ("loader", "atag: %p, %x, %x, %s, %s\n", - fdt_addr, - ((grub_uint16_t *) fdt_addr)[3], - *((grub_uint32_t *) fdt_addr), - (char *) fdt_addr, - (char *) fdt_addr + 1); + current_fdt, + ((const grub_uint16_t *) current_fdt)[3], + *((const grub_uint32_t *) current_fdt), + (const char *) current_fdt, + (const char *) current_fdt + 1); if (!fdt_valid && machine_type == GRUB_ARM_MACHINE_TYPE_FDT) return grub_error (GRUB_ERR_FILE_NOT_FOUND, @@ -245,23 +246,40 @@ linux_boot (void) grub_dprintf ("loader", "Kernel at: 0x%x\n", linux_addr); + if (fdt_valid || atag_valid) + { +#ifdef GRUB_MACHINE_EFI + grub_size_t size; + if (fdt_valid) + size = grub_fdt_get_totalsize (current_fdt); + else + size = 4 * get_atag_size (current_fdt); + size += grub_strlen (linux_args) + 256; + target_fdt = grub_efi_allocate_loader_memory (LINUX_FDT_PHYS_OFFSET, size); + if (!target_fdt) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); +#else + target_fdt = (void *) LINUX_FDT_ADDRESS; +#endif + } + if (fdt_valid) { grub_err_t err; - err = linux_prepare_fdt (); + err = linux_prepare_fdt (target_fdt); if (err) return err; - grub_dprintf ("loader", "FDT @ 0x%p\n", fdt_addr); + grub_dprintf ("loader", "FDT @ %p\n", target_fdt); } else if (atag_valid) { grub_err_t err; - err = linux_prepare_atag (); + err = linux_prepare_atag (target_fdt); if (err) return err; - grub_dprintf ("loader", "ATAG @ 0x%p\n", fdt_addr); + grub_dprintf ("loader", "ATAG @ %p\n", target_fdt); } grub_dprintf ("loader", "Jumping to Linux...\n"); @@ -274,18 +292,9 @@ linux_boot (void) */ linuxmain = (kernel_entry_t) linux_addr; -#ifdef GRUB_MACHINE_EFI - { - grub_err_t err; - err = grub_efi_prepare_platform(); - if (err != GRUB_ERR_NONE) - return err; - } -#endif - grub_arm_disable_caches_mmu (); - linuxmain (0, machine_type, fdt_addr); + linuxmain (0, machine_type, target_fdt); return grub_error (GRUB_ERR_BAD_OS, "Linux call returned"); } @@ -296,17 +305,12 @@ linux_boot (void) static grub_err_t linux_load (const char *filename, grub_file_t file) { + struct linux_arch_kernel_header *lh; int size; size = grub_file_size (file); -#ifdef GRUB_MACHINE_EFI - linux_addr = (grub_addr_t) grub_efi_allocate_loader_memory (LINUX_PHYS_OFFSET, size); - if (!linux_addr) - return grub_errno; -#else linux_addr = LINUX_ADDRESS; -#endif grub_dprintf ("loader", "Loading Linux to 0x%08x\n", (grub_addr_t) linux_addr); @@ -318,9 +322,10 @@ linux_load (const char *filename, grub_file_t file) return grub_errno; } - if (size > LINUX_ZIMAGE_OFFSET + 4 - && *(grub_uint32_t *) (linux_addr + LINUX_ZIMAGE_OFFSET) - == LINUX_ZIMAGE_MAGIC) + lh = (void *) linux_addr; + + if ((grub_size_t) size > sizeof (*lh) && + lh->magic == GRUB_LINUX_ARM_MAGIC_SIGNATURE) ; else if (size > 0x8000 && *(grub_uint32_t *) (linux_addr) == 0xea000006 && machine_type == GRUB_ARM_MACHINE_TYPE_RASPBERRY_PI) @@ -359,7 +364,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (!file) goto fail; @@ -380,8 +385,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Create kernel command line. */ grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_args + sizeof (LINUX_IMAGE) - 1, size); + err = grub_create_loader_cmdline (argc, argv, + linux_args + sizeof (LINUX_IMAGE) - 1, size, + GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + goto fail; return GRUB_ERR_NONE; @@ -401,7 +409,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_INITRD); if (!file) return grub_errno; @@ -410,25 +418,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), size = grub_get_initrd_size (&initrd_ctx); -#ifdef GRUB_MACHINE_EFI - if (initrd_start) - grub_efi_free_pages (initrd_start, - (initrd_end - initrd_start + 0xfff) >> 12); - initrd_start = (grub_addr_t) grub_efi_allocate_loader_memory (LINUX_INITRD_PHYS_OFFSET, size); - - if (!initrd_start) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } -#else initrd_start = LINUX_INITRD_ADDRESS; -#endif 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; @@ -444,11 +439,26 @@ fail: static grub_err_t load_dtb (grub_file_t dtb, int size) { - if ((grub_file_read (dtb, fdt_addr, size) != size) - || (grub_fdt_check_header (fdt_addr, size) != 0)) - return grub_error (GRUB_ERR_BAD_OS, N_("invalid device tree")); + void *new_fdt = grub_zalloc (size); + if (!new_fdt) + return grub_errno; + grub_dprintf ("loader", "Loading device tree to %p\n", + new_fdt); + if ((grub_file_read (dtb, new_fdt, size) != size) + || (grub_fdt_check_header (new_fdt, size) != 0)) + { + grub_free (new_fdt); + return grub_error (GRUB_ERR_BAD_OS, N_("invalid device tree")); + } + + grub_fdt_set_totalsize (new_fdt, size); + current_fdt = new_fdt; + /* + * We've successfully loaded an FDT, so any machine type passed + * from firmware is now obsolete. + */ + machine_type = GRUB_ARM_MACHINE_TYPE_FDT; - grub_fdt_set_totalsize (fdt_addr, size); return GRUB_ERR_NONE; } @@ -462,44 +472,15 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)), if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - dtb = grub_file_open (argv[0]); + dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE_IMAGE); if (!dtb) - goto out; + return grub_errno; size = grub_file_size (dtb); if (size == 0) - { - grub_error (GRUB_ERR_BAD_OS, "empty file"); - goto out; - } - -#ifdef GRUB_MACHINE_EFI - fdt_addr = grub_efi_allocate_loader_memory (LINUX_FDT_PHYS_OFFSET, size); - if (!fdt_addr) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto out; - } -#else - fdt_addr = (void *) LINUX_FDT_ADDRESS; -#endif - - grub_dprintf ("loader", "Loading device tree to 0x%08x\n", - (grub_addr_t) fdt_addr); - load_dtb (dtb, size); - if (grub_errno != GRUB_ERR_NONE) - { - fdt_addr = NULL; - goto out; - } - - /* - * We've successfully loaded an FDT, so any machine type passed - * from firmware is now obsolete. - */ - machine_type = GRUB_ARM_MACHINE_TYPE_FDT; - - out: + grub_error (GRUB_ERR_BAD_OS, "empty file"); + else + load_dtb (dtb, size); grub_file_close (dtb); return grub_errno; @@ -513,11 +494,11 @@ 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; - fdt_addr = (void *) grub_arm_firmware_get_boot_data (); + 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/linux.c b/grub-core/loader/arm64/linux.c deleted file mode 100644 index 9519d2e4d..000000000 --- a/grub-core/loader/arm64/linux.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static int loaded; - -static void *kernel_addr; -static grub_uint64_t kernel_size; - -static char *linux_args; -static grub_uint32_t cmdline_size; - -static grub_addr_t initrd_start; -static grub_addr_t initrd_end; - -grub_err_t -grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header * lh) -{ - if (lh->magic != GRUB_ARM64_LINUX_MAGIC) - return grub_error(GRUB_ERR_BAD_OS, "invalid magic number"); - - if ((lh->code0 & 0xffff) != GRUB_EFI_PE_MAGIC) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled")); - - grub_dprintf ("linux", "UEFI stub kernel:\n"); - grub_dprintf ("linux", "text_offset = 0x%012llx\n", - (long long unsigned) lh->text_offset); - grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); - - return GRUB_ERR_NONE; -} - -static grub_err_t -finalize_params_linux (void) -{ - int node, retval; - - void *fdt; - - fdt = grub_fdt_load (0x400); - - 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) - { - grub_dprintf ("linux", "Initrd @ 0x%012lx-0x%012lx\n", - initrd_start, initrd_end); - - retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", - initrd_start); - if (retval) - goto failure; - retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", - initrd_end); - if (retval) - goto failure; - } - - if (grub_fdt_install() != GRUB_ERR_NONE) - goto failure; - - return GRUB_ERR_NONE; - -failure: - grub_fdt_unload(); - return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -} - -grub_err_t -grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, char *args) -{ - grub_efi_memory_mapped_device_path_t *mempath; - grub_efi_handle_t image_handle; - grub_efi_boot_services_t *b; - grub_efi_status_t status; - grub_efi_loaded_image_t *loaded_image; - int len; - - mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); - if (!mempath) - return grub_errno; - - mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; - mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; - mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); - mempath[0].memory_type = GRUB_EFI_LOADER_DATA; - mempath[0].start_address = addr; - mempath[0].end_address = addr + size; - - mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; - mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; - mempath[1].header.length = sizeof (grub_efi_device_path_t); - - b = grub_efi_system_table->boot_services; - status = b->load_image (0, grub_efi_image_handle, - (grub_efi_device_path_t *) mempath, - (void *) addr, size, &image_handle); - if (status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); - - grub_dprintf ("linux", "linux command line: '%s'\n", args); - - /* Convert command line to UCS-2 */ - loaded_image = grub_efi_get_loaded_image (image_handle); - loaded_image->load_options_size = len = - (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); - loaded_image->load_options = - grub_efi_allocate_pages (0, - GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); - if (!loaded_image->load_options) - return grub_errno; - - loaded_image->load_options_size = - 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, - (grub_uint8_t *) args, len, NULL); - - grub_dprintf ("linux", "starting image %p\n", image_handle); - status = b->start_image (image_handle, 0, NULL); - - /* When successful, not reached */ - b->unload_image (image_handle); - grub_efi_free_pages ((grub_efi_physical_address_t) loaded_image->load_options, - GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); - - return grub_errno; -} - -static grub_err_t -grub_linux_boot (void) -{ - if (finalize_params_linux () != GRUB_ERR_NONE) - return grub_errno; - - return (grub_arm64_uefi_boot_image((grub_addr_t)kernel_addr, - kernel_size, linux_args)); -} - -static grub_err_t -grub_linux_unload (void) -{ - grub_dl_unref (my_mod); - loaded = 0; - if (initrd_start) - grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start, - GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); - initrd_start = initrd_end = 0; - grub_free (linux_args); - if (kernel_addr) - grub_efi_free_pages ((grub_efi_physical_address_t) kernel_addr, - GRUB_EFI_BYTES_TO_PAGES (kernel_size)); - grub_fdt_unload (); - return GRUB_ERR_NONE; -} - -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; - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - if (!loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("you need to load the kernel first")); - goto fail; - } - - if (grub_initrd_init (argc, argv, &initrd_ctx)) - goto fail; - - initrd_size = grub_get_initrd_size (&initrd_ctx); - grub_dprintf ("linux", "Loading initrd\n"); - - initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); - initrd_mem = grub_efi_allocate_pages (0, initrd_pages); - if (!initrd_mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - - if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) - 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); - - fail: - grub_initrd_close (&initrd_ctx); - if (initrd_mem && !initrd_start) - grub_efi_free_pages ((grub_efi_physical_address_t) initrd_mem, - initrd_pages); - - return grub_errno; -} - -static grub_err_t -grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - struct grub_arm64_linux_kernel_header lh; - - grub_dl_ref (my_mod); - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - goto fail; - } - - file = grub_file_open (argv[0]); - if (!file) - goto fail; - - kernel_size = grub_file_size (file); - - if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) - return grub_errno; - - if (grub_arm64_uefi_check_image (&lh) != GRUB_ERR_NONE) - goto fail; - - grub_loader_unset(); - - grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); - kernel_addr = grub_efi_allocate_pages (0, GRUB_EFI_BYTES_TO_PAGES (kernel_size)); - grub_dprintf ("linux", "kernel numpages: %lld\n", - (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); - if (!kernel_addr) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - - grub_file_seek (file, 0); - if (grub_file_read (file, kernel_addr, kernel_size) - < (grub_int64_t) kernel_size) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); - goto fail; - } - - grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); - - cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); - linux_args = grub_malloc (cmdline_size); - if (!linux_args) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_args + sizeof (LINUX_IMAGE) - 1, - cmdline_size); - - if (grub_errno == GRUB_ERR_NONE) - { - grub_loader_set (grub_linux_boot, grub_linux_unload, 0); - loaded = 1; - } - -fail: - if (file) - grub_file_close (file); - - if (grub_errno != GRUB_ERR_NONE) - { - grub_dl_unref (my_mod); - loaded = 0; - } - - if (linux_args && !loaded) - grub_free (linux_args); - - if (kernel_addr && !loaded) - grub_efi_free_pages ((grub_efi_physical_address_t) kernel_addr, - GRUB_EFI_BYTES_TO_PAGES (kernel_size)); - - return grub_errno; -} - - -static grub_command_t cmd_linux, cmd_initrd; - -GRUB_MOD_INIT (linux) -{ - cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, - N_("Load Linux.")); - cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0, - N_("Load initrd.")); - my_mod = mod; -} - -GRUB_MOD_FINI (linux) -{ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_initrd); -} diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c index a914eb8e2..26e1472c9 100644 --- a/grub-core/loader/arm64/xen_boot.c +++ b/grub-core/loader/arm64/xen_boot.c @@ -27,10 +27,9 @@ #include #include #include -#include -#include #include -#include /* required by struct xen_hypervisor_header */ +#include +#include #include #include @@ -64,18 +63,6 @@ enum module_type }; typedef enum module_type module_type_t; -struct xen_hypervisor_header -{ - struct grub_arm64_linux_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; @@ -115,6 +102,17 @@ prepare_xen_hypervisor_params (void *xen_boot_fdt) if (chosen_node < 1) return grub_error (GRUB_ERR_IO, "failed to get chosen node in FDT"); + /* + * The address and size are always written using 64-bits value. Set + * #address-cells and #size-cells accordingly. + */ + retval = grub_fdt_set_prop32 (xen_boot_fdt, chosen_node, "#address-cells", 2); + if (retval) + return grub_error (GRUB_ERR_IO, "failed to set #address-cells"); + retval = grub_fdt_set_prop32 (xen_boot_fdt, chosen_node, "#size-cells", 2); + if (retval) + return grub_error (GRUB_ERR_IO, "failed to set #size-cells"); + grub_dprintf ("xen_loader", "Xen Hypervisor cmdline : %s @ %p size:%d\n", xen_hypervisor->cmdline, xen_hypervisor->cmdline, @@ -156,7 +154,7 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt) grub_fdt_add_subnode (xen_boot_fdt, chosen_node, module_name); retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "compatible", - MODULE_CUSTOM_COMPATIBLE, sizeof(MODULE_CUSTOM_COMPATIBLE) - 1); + MODULE_CUSTOM_COMPATIBLE, sizeof(MODULE_CUSTOM_COMPATIBLE)); if (retval) return grub_error (GRUB_ERR_IO, "failed to update FDT"); @@ -253,9 +251,9 @@ xen_boot (void) if (err) return err; - return grub_arm64_uefi_boot_image (xen_hypervisor->start, - xen_hypervisor->size, - xen_hypervisor->cmdline); + return grub_arch_efi_linux_boot_image (xen_hypervisor->start, + xen_hypervisor->size, + xen_hypervisor->cmdline); } static void @@ -324,10 +322,9 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file, grub_dprintf ("xen_loader", "Xen_boot file size: 0x%lx\n", binary->size); binary->start - = (grub_addr_t) grub_efi_allocate_pages (0, - GRUB_EFI_BYTES_TO_PAGES - (binary->size + - binary->align)); + = (grub_addr_t) grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES + (binary->size + + binary->align)); if (!binary->start) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); @@ -357,7 +354,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file, return; } grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline, - binary->cmdline_size); + binary->cmdline_size, + GRUB_VERIFY_KERNEL_CMDLINE); grub_dprintf ("xen_loader", "Xen_boot cmdline @ %p %s, size: %d\n", binary->cmdline, binary->cmdline, binary->cmdline_size); @@ -379,6 +377,20 @@ grub_cmd_xen_module (grub_command_t cmd __attribute__((unused)), struct xen_boot_binary *module = NULL; grub_file_t file = 0; + int nounzip = 0; + + if (!argc) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + if (grub_strcmp (argv[0], "--nounzip") == 0) + { + argv++; + argc--; + nounzip = 1; + } if (!argc) { @@ -403,7 +415,9 @@ grub_cmd_xen_module (grub_command_t cmd __attribute__((unused)), grub_dprintf ("xen_loader", "Init module and node info\n"); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_XEN_MODULE + | (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); if (!file) goto fail; @@ -424,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); @@ -435,14 +449,11 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)), goto fail; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_XEN_HYPERVISOR); if (!file) goto fail; - if (grub_file_read (file, &sh, sizeof (sh)) != (long) sizeof (sh)) - goto fail; - if (grub_arm64_uefi_check_image - ((struct grub_arm64_linux_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); @@ -456,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 adc856366..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,32 +95,39 @@ 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) { - grub_efi_char16_t *p; + grub_efi_char16_t *p, *path_name; grub_efi_uint16_t size; fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; - size = grub_utf8_to_utf16 (fp->path_name, len * GRUB_MAX_UTF16_PER_UTF8, + path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); + if (!path_name) + 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); - for (p = fp->path_name; p < fp->path_name + size; p++) + for (p = path_name; p < path_name + size; p++) if (*p == '/') *p = '\\'; + grub_memcpy (fp->path_name, path_name, size * sizeof (*fp->path_name)); /* File Path is NULL terminated */ 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 * @@ -133,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) @@ -150,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); @@ -173,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); @@ -200,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")); @@ -212,23 +233,17 @@ 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); + file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE); if (! file) goto fail; /* 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) { @@ -251,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) { @@ -271,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) @@ -330,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) @@ -354,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; @@ -386,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: @@ -397,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/arm64/fdt.c b/grub-core/loader/efi/fdt.c similarity index 50% rename from grub-core/loader/arm64/fdt.c rename to grub-core/loader/efi/fdt.c index db49cf649..e510b3491 100644 --- a/grub-core/loader/arm64/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,26 +19,43 @@ #include #include -#include +#include #include #include #include +#include #include #include +#include +#include +#include static void *loaded_fdt; static void *fdt; +#define FDT_ADDR_CELLS_STRING "#address-cells" +#define FDT_SIZE_CELLS_STRING "#size-cells" +#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ + sizeof (FDT_ADDR_CELLS_STRING) + \ + sizeof (FDT_SIZE_CELLS_STRING)) + +static const struct grub_arg_option options_fdtdump[] = { + {"prop", 'p', 0, N_("Get property."), N_("prop"), ARG_TYPE_STRING}, + {"set", '\0', 0, N_("Store the value in the given variable name."), + N_("variable"), ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + void * grub_fdt_load (grub_size_t additional_size) { void *raw_fdt; - grub_size_t size; + unsigned int size; if (fdt) { size = GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (fdt)); - grub_efi_free_pages ((grub_efi_physical_address_t) fdt, size); + grub_efi_free_pages ((grub_addr_t) fdt, size); } if (loaded_fdt) @@ -45,23 +63,31 @@ grub_fdt_load (grub_size_t additional_size) else raw_fdt = grub_efi_get_firmware_fdt(); - size = - raw_fdt ? grub_fdt_get_totalsize (raw_fdt) : GRUB_FDT_EMPTY_TREE_SZ; + if (raw_fdt) + size = grub_fdt_get_totalsize (raw_fdt); + else + size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA; + size += additional_size; - grub_dprintf ("linux", "allocating %ld bytes for fdt\n", size); - fdt = grub_efi_allocate_pages (0, GRUB_EFI_BYTES_TO_PAGES (size)); + grub_dprintf ("linux", "allocating %d bytes for fdt\n", size); + fdt = grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, + GRUB_EFI_BYTES_TO_PAGES (size), + GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_ACPI_RECLAIM_MEMORY); if (!fdt) return NULL; if (raw_fdt) { - grub_memmove (fdt, raw_fdt, size); + grub_memmove (fdt, raw_fdt, size - additional_size); grub_fdt_set_totalsize (fdt, size); } else { grub_fdt_create_empty_tree (fdt, size); + grub_fdt_set_prop32 (fdt, 0, FDT_ADDR_CELLS_STRING, 2); + grub_fdt_set_prop32 (fdt, 0, FDT_SIZE_CELLS_STRING, 2); } return fdt; } @@ -70,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; } @@ -88,7 +117,7 @@ grub_fdt_unload (void) { if (!fdt) { return; } - grub_efi_free_pages ((grub_efi_physical_address_t) fdt, + grub_efi_free_pages ((grub_addr_t) fdt, GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (fdt))); fdt = NULL; } @@ -111,7 +140,7 @@ grub_cmd_devicetree (grub_command_t cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } - dtb = grub_file_open (argv[0]); + dtb = grub_file_open (argv[0], GRUB_FILE_TYPE_DEVICE_TREE_IMAGE); if (!dtb) goto out; @@ -148,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/efi/linux.c b/grub-core/loader/efi/linux.c new file mode 100644 index 000000000..78ea07ca8 --- /dev/null +++ b/grub-core/loader/efi/linux.c @@ -0,0 +1,594 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_dl_t my_mod; +static int loaded; + +static void *kernel_addr; +static grub_uint64_t kernel_size; + +static char *linux_args; +static grub_uint32_t cmdline_size; + +static grub_addr_t initrd_start; +static grub_addr_t initrd_end; + +static struct grub_linux_initrd_context initrd_ctx = {0, 0, 0}; +static grub_efi_handle_t initrd_lf2_handle = NULL; +static bool initrd_use_loadfile2 = false; + +static grub_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID; +static grub_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID; + +static initrd_media_device_path_t initrd_lf2_device_path = { + { + { + GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, + GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE, + sizeof(grub_efi_vendor_media_device_path_t), + }, + LINUX_EFI_INITRD_MEDIA_GUID + }, { + GRUB_EFI_END_DEVICE_PATH_TYPE, + GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, + sizeof(grub_efi_device_path_t) + } +}; + +extern grub_err_t +grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]); + +extern grub_err_t +grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]); + +static grub_efi_status_t __grub_efi_api +grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this, + grub_efi_device_path_t *device_path, + grub_efi_boolean_t boot_policy, + grub_efi_uintn_t *buffer_size, + void *buffer); + +static grub_efi_load_file2_t initrd_lf2 = { + grub_efi_initrd_load_file2 +}; + +grub_err_t +grub_arch_efi_linux_load_image_header (grub_file_t file, + struct linux_arch_kernel_header * lh) +{ + grub_file_seek (file, 0); + if (grub_file_read (file, lh, sizeof (*lh)) < (grub_ssize_t) sizeof (*lh)) + return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image header"); + + if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled")); + + grub_dprintf ("linux", "UEFI stub kernel:\n"); + grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); + + /* + * The PE/COFF spec permits the COFF header to appear anywhere in the file, so + * we need to double check whether it was where we expected it, and if not, we + * must load it from the correct offset into the pe_image_header field of + * struct linux_arch_kernel_header. + */ + if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) &lh->pe_image_header) + { + if (grub_file_seek (file, lh->hdr_offset) == (grub_off_t) -1 + || grub_file_read (file, &lh->pe_image_header, + sizeof (struct grub_pe_image_header)) + != sizeof (struct grub_pe_image_header)) + return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header"); + } + + if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported"); + + /* + * Linux kernels built for any architecture are guaranteed to support the + * LoadFile2 based initrd loading protocol if the image version is >= 1. + */ + if (lh->pe_image_header.optional_header.major_image_version >= 1) + initrd_use_loadfile2 = true; + else + initrd_use_loadfile2 = false; + + grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n", + initrd_use_loadfile2 ? "en" : "dis"); + + return GRUB_ERR_NONE; +} + +#if !defined(__i386__) && !defined(__x86_64__) +static grub_err_t +finalize_params_linux (void) +{ + int node, retval; + + void *fdt; + + /* Set initrd info */ + if (initrd_start && initrd_end > initrd_start) + { + fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); + + if (!fdt) + goto failure; + + node = grub_fdt_find_subnode (fdt, 0, "chosen"); + if (node < 0) + node = grub_fdt_add_subnode (fdt, 0, "chosen"); + + if (node < 1) + goto failure; + + grub_dprintf ("linux", "Initrd @ %p-%p\n", + (void *) initrd_start, (void *) initrd_end); + + retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", + initrd_start); + if (retval) + goto failure; + retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", + initrd_end); + if (retval) + goto failure; + } + + if (grub_fdt_install() != GRUB_ERR_NONE) + goto failure; + + return GRUB_ERR_NONE; + +failure: + grub_fdt_unload(); + return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); +} +#endif + +grub_err_t +grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) +{ + grub_efi_memory_mapped_device_path_t *mempath; + grub_efi_handle_t image_handle; + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_loaded_image_t *loaded_image; + int len; + + mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); + if (!mempath) + return grub_errno; + + mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; + mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; + mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); + mempath[0].memory_type = GRUB_EFI_LOADER_DATA; + mempath[0].start_address = addr; + mempath[0].end_address = addr + size; + + mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; + mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + mempath[1].header.length = sizeof (grub_efi_device_path_t); + + b = grub_efi_system_table->boot_services; + status = b->load_image (0, grub_efi_image_handle, + (grub_efi_device_path_t *) mempath, + (void *) addr, size, &image_handle); + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + + grub_dprintf ("linux", "linux command line: '%s'\n", args); + + /* Convert command line to UTF-16. */ + loaded_image = grub_efi_get_loaded_image (image_handle); + if (loaded_image == NULL) + { + grub_error (GRUB_ERR_BAD_FIRMWARE, "missing loaded_image proto"); + goto unload; + } + 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 (len)); + if (!loaded_image->load_options) + return grub_errno; + + loaded_image->load_options_size = + 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, + (grub_uint8_t *) args, len, NULL); + + grub_dprintf ("linux", "starting image %p\n", image_handle); + status = b->start_image (image_handle, 0, NULL); + + /* When successful, not reached */ + grub_error (GRUB_ERR_BAD_OS, "start_image() returned 0x%" PRIxGRUB_EFI_UINTN_T, status); + grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, + GRUB_EFI_BYTES_TO_PAGES (len)); + loaded_image->load_options = NULL; +unload: + b->unload_image (image_handle); + + return grub_errno; +} + +static grub_err_t +grub_linux_boot (void) +{ +#if !defined(__i386__) && !defined(__x86_64__) + if (finalize_params_linux () != GRUB_ERR_NONE) + return grub_errno; +#endif + + return grub_arch_efi_linux_boot_image ((grub_addr_t) kernel_addr, + kernel_size, linux_args); +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; + + grub_dl_unref (my_mod); + loaded = 0; + if (initrd_start) + grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start, + GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); + initrd_start = initrd_end = 0; + grub_free (linux_args); + if (kernel_addr) + grub_efi_free_pages ((grub_addr_t) kernel_addr, + GRUB_EFI_BYTES_TO_PAGES (kernel_size)); +#if !defined(__i386__) && !defined(__x86_64__) + grub_fdt_unload (); +#endif + + if (initrd_lf2_handle != NULL) + { + b->uninstall_multiple_protocol_interfaces (initrd_lf2_handle, + &load_file2_guid, + &initrd_lf2, + &device_path_guid, + &initrd_lf2_device_path, + NULL); + initrd_lf2_handle = NULL; + initrd_use_loadfile2 = false; + } + return GRUB_ERR_NONE; +} + +#if !defined(__i386__) && !defined(__x86_64__) +/* + * As per linux/Documentation/arm/Booting + * ARM initrd needs to be covered by kernel linear mapping, + * so place it in the first 512MB of DRAM. + * + * As per linux/Documentation/arm64/booting.txt + * ARM64 initrd needs to be contained entirely within a 1GB aligned window + * of up to 32GB of size that covers the kernel image as well. + * Since the EFI stub loader will attempt to load the kernel near start of + * RAM, place the buffer in the first 32GB of RAM. + */ +#ifdef __arm__ +#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024) +#else /* __aarch64__ */ +#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) +#endif + +/* + * This function returns a pointer to a legally allocated initrd buffer, + * or NULL if unsuccessful + */ +static void * +allocate_initrd_mem (int initrd_pages) +{ + grub_addr_t max_addr; + + if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) + return NULL; + + max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; + + return grub_efi_allocate_pages_real (max_addr, initrd_pages, + GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); +} +#endif + +static grub_efi_status_t __grub_efi_api +grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this, + grub_efi_device_path_t *device_path, + grub_efi_boolean_t boot_policy, + grub_efi_uintn_t *buffer_size, + void *buffer) +{ + grub_efi_status_t status = GRUB_EFI_SUCCESS; + grub_efi_uintn_t initrd_size; + + if (this != &initrd_lf2 || buffer_size == NULL) + return GRUB_EFI_INVALID_PARAMETER; + + if (device_path->type != GRUB_EFI_END_DEVICE_PATH_TYPE || + device_path->subtype != GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE) + return GRUB_EFI_NOT_FOUND; + + if (boot_policy) + return GRUB_EFI_UNSUPPORTED; + + initrd_size = grub_get_initrd_size (&initrd_ctx); + if (buffer == NULL || *buffer_size < initrd_size) + { + *buffer_size = initrd_size; + return GRUB_EFI_BUFFER_TOO_SMALL; + } + + grub_dprintf ("linux", "Providing initrd via EFI_LOAD_FILE2_PROTOCOL\n"); + + if (grub_initrd_load (&initrd_ctx, buffer)) + status = GRUB_EFI_DEVICE_ERROR; + + grub_initrd_close (&initrd_ctx); + return status; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int __attribute__ ((unused)) initrd_size, initrd_pages; + void *__attribute__ ((unused)) initrd_mem = NULL; + grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; + grub_efi_status_t status; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + +#if defined(__i386__) || defined(__x86_64__) + if (!initrd_use_loadfile2) + return grub_cmd_initrd_x86_legacy (cmd, argc, argv); +#endif + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); + goto fail; + } + + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + + if (initrd_use_loadfile2) + { + if (initrd_lf2_handle == NULL) + { + status = b->install_multiple_protocol_interfaces (&initrd_lf2_handle, + &load_file2_guid, + &initrd_lf2, + &device_path_guid, + &initrd_lf2_device_path, + NULL); + if (status == GRUB_EFI_OUT_OF_RESOURCES) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + else if (status != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("failed to install protocols")); + goto fail; + } + } + grub_dprintf ("linux", "Using LoadFile2 initrd loading protocol\n"); + return GRUB_ERR_NONE; + } + +#if !defined(__i386__) && !defined(__x86_64__) + initrd_size = grub_get_initrd_size (&initrd_ctx); + grub_dprintf ("linux", "Loading initrd\n"); + + initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); + initrd_mem = allocate_initrd_mem (initrd_pages); + + if (!initrd_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + + if (grub_initrd_load (&initrd_ctx, initrd_mem)) + { + grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); + goto fail; + } + + initrd_start = (grub_addr_t) initrd_mem; + initrd_end = initrd_start + initrd_size; + grub_dprintf ("linux", "[addr=%p, size=0x%x]\n", + (void *) initrd_start, initrd_size); +#endif + + fail: + grub_initrd_close (&initrd_ctx); + + return grub_errno; +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_arch_kernel_header lh; + grub_err_t err; + + grub_dl_ref (my_mod); + + if (grub_is_shim_lock_enabled () == true) + { +#if defined(__i386__) || defined(__x86_64__) + grub_dprintf ("linux", "shim_lock enabled, falling back to legacy Linux kernel loader\n"); + + err = grub_cmd_linux_x86_legacy (cmd, argc, argv); + + if (err == GRUB_ERR_NONE) + return GRUB_ERR_NONE; + else + goto fail; +#else + grub_dprintf ("linux", "shim_lock enabled, trying Linux kernel EFI stub loader\n"); +#endif + } + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (!file) + goto fail; + + kernel_size = grub_file_size (file); + + if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE) +#if !defined(__i386__) && !defined(__x86_64__) + goto fail; +#else + goto fallback; + + if (!initrd_use_loadfile2) + { + /* + * This is a EFI stub image but it is too old to implement the LoadFile2 + * based initrd loading scheme, and Linux/x86 does not support the DT + * based method either. So fall back to the x86-specific loader that + * enters Linux in EFI mode but without going through its EFI stub. + */ +fallback: + grub_file_close (file); + return grub_cmd_linux_x86_legacy (cmd, argc, argv); + } +#endif + + grub_loader_unset(); + + grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); + kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + grub_dprintf ("linux", "kernel numpages: %lld\n", + (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + if (!kernel_addr) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + + grub_file_seek (file, 0); + if (grub_file_read (file, kernel_addr, kernel_size) + < (grub_int64_t) kernel_size) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); + goto fail; + } + + grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); + + cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); + linux_args = grub_malloc (cmdline_size); + if (!linux_args) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + err = grub_create_loader_cmdline (argc, argv, + linux_args + sizeof (LINUX_IMAGE) - 1, + cmdline_size, + GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + goto fail; + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + loaded = 1; + } + +fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } + + if (linux_args && !loaded) + grub_free (linux_args); + + if (kernel_addr && !loaded) + grub_efi_free_pages ((grub_addr_t) kernel_addr, + GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + + return grub_errno; +} + + +static grub_command_t cmd_linux, cmd_initrd; + +GRUB_MOD_INIT (linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, + N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0, + N_("Load initrd.")); + my_mod = mod; +} + +GRUB_MOD_FINI (linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c 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 7f96515da..4b7c436d4 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #ifdef GRUB_MACHINE_PCBIOS #include #endif @@ -133,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. @@ -166,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. @@ -229,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; @@ -261,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) @@ -416,6 +418,8 @@ grub_freebsd_add_meta_module (const char *filename, const char *type, grub_addr_t addr, grub_uint32_t size) { const char *name; + grub_err_t err; + name = grub_strrchr (filename, '/'); if (name) name++; @@ -431,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; } @@ -469,6 +473,9 @@ grub_freebsd_add_meta_module (const char *filename, const char *type, *(p++) = ' '; } *p = 0; + err = grub_verify_string (cmdline, GRUB_VERIFY_MODULE_CMDLINE); + if (err) + return err; } } @@ -574,9 +581,9 @@ freebsd_get_zfs (void) fs = grub_fs_probe (dev); if (!fs) return; - if (!fs->uuid || grub_strcmp (fs->name, "zfs") != 0) + if (!fs->fs_uuid || grub_strcmp (fs->name, "zfs") != 0) return; - err = fs->uuid (dev, &uuid); + err = fs->fs_uuid (dev, &uuid); if (err) return; if (!uuid) @@ -626,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 @@ -671,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 @@ -721,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; @@ -760,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; @@ -835,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; @@ -922,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; @@ -1006,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; @@ -1328,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; @@ -1358,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; @@ -1419,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); @@ -1457,7 +1475,7 @@ grub_bsd_load (int argc, char *argv[]) goto fail; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_BSD_KERNEL); if (!file) goto fail; @@ -1488,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; } @@ -1525,16 +1543,14 @@ 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); if (err) return err; - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_BSD_KERNEL); if (! file) return grub_errno; @@ -1593,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; @@ -1609,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"); @@ -1627,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; @@ -1646,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; @@ -1656,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; } @@ -1693,7 +1709,7 @@ grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) { grub_file_t file; - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_BSD_KERNEL); if (! file) return grub_errno; @@ -1729,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"); @@ -1743,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 @@ -1802,7 +1818,7 @@ grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)), goto fail; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_FREEBSD_ENV); if ((!file) || (!file->size)) goto fail; @@ -1907,13 +1923,13 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)), return 0; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_FREEBSD_MODULE); if ((!file) || (!file->size)) goto fail; { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, + err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, file->size); if (err) goto fail; @@ -1958,13 +1974,13 @@ grub_netbsd_module_load (char *filename, grub_uint32_t type) void *src; grub_err_t err; - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_NETBSD_MODULE); if ((!file) || (!file->size)) goto fail; { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, + err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end, file->size); if (err) goto fail; @@ -2048,7 +2064,7 @@ grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)), return 0; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_FREEBSD_MODULE_ELF); if (!file) return grub_errno; if (!file->size) @@ -2088,7 +2104,7 @@ grub_cmd_openbsd_ramdisk (grub_command_t cmd __attribute__ ((unused)), if (!openbsd_ramdisk.max_size) return grub_error (GRUB_ERR_BAD_OS, "your kOpenBSD doesn't support ramdisk"); - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_OPENBSD_RAMDISK); if (! file) return grub_errno; @@ -2098,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 d4cc40b7f..4a5179806 100644 --- a/grub-core/loader/i386/coreboot/chainloader.c +++ b/grub-core/loader/i386/coreboot/chainloader.c @@ -384,6 +384,7 @@ load_chewed (grub_file_t file, const char *filename) segment.len = 0; segment.offset = 0; segment.len = 0; + /* Fallthrough. */ case PAYLOAD_SEGMENT_CODE: case PAYLOAD_SEGMENT_DATA: { @@ -438,7 +439,7 @@ grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), grub_loader_unset (); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_COREBOOT_CHAINLOADER); if (!file) return grub_errno; @@ -460,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 b15b8cca5..12731feb2 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -44,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 @@ -101,55 +104,6 @@ page_align (grub_size_t size) return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); } -#ifdef GRUB_MACHINE_EFI -/* Find the optimal number of pages for the memory map. Is it better to - move this code to efi/mm.c? */ -static grub_efi_uintn_t -find_efi_mmap_size (void) -{ - static grub_efi_uintn_t mmap_size = 0; - - if (mmap_size != 0) - return mmap_size; - - mmap_size = (1 << 12); - while (1) - { - int ret; - grub_efi_memory_descriptor_t *mmap; - grub_efi_uintn_t desc_size; - grub_efi_uintn_t cur_mmap_size = mmap_size; - - mmap = grub_malloc (cur_mmap_size); - if (! mmap) - return 0; - - ret = grub_efi_get_memory_map (&cur_mmap_size, mmap, 0, &desc_size, 0); - grub_free (mmap); - - if (ret < 0) - { - grub_error (GRUB_ERR_IO, "cannot get memory map"); - return 0; - } - else if (ret > 0) - break; - - if (mmap_size < cur_mmap_size) - mmap_size = cur_mmap_size; - mmap_size += (1 << 12); - } - - /* Increase the size a bit for safety, because GRUB allocates more on - later, and EFI itself may allocate more. */ - mmap_size += (3 << 12); - - mmap_size = page_align (mmap_size); - return mmap_size; -} - -#endif - /* Helper for find_mmap_size. */ static int count_hook (grub_uint64_t addr __attribute__ ((unused)), @@ -170,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. */ @@ -228,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); @@ -259,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; @@ -300,37 +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->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536); + params->screen_info.lfb_base = (grub_size_t) framebuffer; - params->red_mask_size = mode_info.red_mask_size; - params->red_field_pos = mode_info.red_field_pos; - params->green_mask_size = mode_info.green_mask_size; - params->green_field_pos = mode_info.green_field_pos; - params->blue_mask_size = mode_info.blue_mask_size; - params->blue_field_pos = mode_info.blue_field_pos; - params->reserved_mask_size = mode_info.reserved_mask_size; - params->reserved_field_pos = mode_info.reserved_field_pos; +#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) + params->screen_info.ext_lfb_base = (grub_size_t) (((grub_uint64_t)(grub_size_t) framebuffer) >> 32); + params->screen_info.capabilities |= VIDEO_CAPABILITY_64BIT_BASE; +#endif + + params->screen_info.lfb_size = ALIGN_UP (params->screen_info.lfb_linelength * params->screen_info.lfb_height, 65536); + + params->screen_info.red_size = mode_info.red_mask_size; + params->screen_info.red_pos = mode_info.red_field_pos; + params->screen_info.green_size = mode_info.green_mask_size; + params->screen_info.green_pos = mode_info.green_field_pos; + params->screen_info.blue_size = mode_info.blue_mask_size; + params->screen_info.blue_pos = mode_info.blue_field_pos; + params->screen_info.rsvd_size = mode_info.reserved_mask_size; + params->screen_info.rsvd_pos = mode_info.reserved_field_pos; if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y')) - params->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. */ @@ -348,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; } } @@ -373,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 @@ -432,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; @@ -464,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 @@ -512,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; @@ -535,32 +494,36 @@ 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; } } +#ifdef GRUB_KERNEL_USE_RSDP_ADDR + linux_params.acpi_rsdp_addr = grub_le_to_cpu64 (grub_rsdp_addr); +#endif + mmap_size = find_mmap_size (); /* Make sure that each size is aligned to a page boundary. */ cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096); - if (cl_offset < ((grub_size_t) linux_params.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); #ifdef GRUB_MACHINE_EFI - efi_mmap_size = find_efi_mmap_size (); + efi_mmap_size = grub_efi_find_mmap_size (); if (efi_mmap_size == 0) return grub_errno; #endif @@ -585,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); @@ -600,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); } @@ -678,7 +660,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; - struct linux_kernel_header lh; + struct linux_i386_kernel_header lh; grub_uint8_t setup_sects; grub_size_t real_size, prot_size, prot_file_size; grub_ssize_t len; @@ -695,7 +677,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (! file) goto fail; @@ -721,7 +703,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and still not support 32-bit boot. */ - if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) + if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0203) { grub_error (GRUB_ERR_BAD_OS, "version too old for 32-bit boot" @@ -766,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; @@ -781,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; } @@ -799,14 +778,26 @@ 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 *) &lh.jump + 1); - len = sizeof (linux_params) - sizeof (lh); - if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len) + /* Verify the struct is big enough so we do not write past the end. */ + if (len > (char *) &linux_params.edd_mbr_sig_buffer - (char *) &linux_params) { + grub_error (GRUB_ERR_BAD_OS, "Linux setup header too big"); + goto fail; + } + + grub_memcpy (&linux_params.hdr.setup_sects, &lh.setup_sects, len - 0x1F1); + + /* We've already read lh so there is no need to read it second time. */ + len -= sizeof(lh); + + if ((len > 0) && + (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)) { if (!grub_errno) grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), @@ -814,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 @@ -967,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); @@ -984,10 +979,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), { case 'g': shift += 10; + /* FALLTHROUGH */ case 'm': shift += 10; + /* FALLTHROUGH */ case 'k': shift += 10; + /* FALLTHROUGH */ default: break; } @@ -1001,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. */ @@ -1009,11 +1007,17 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (!linux_cmdline) goto fail; grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_cmdline - + sizeof (LINUX_IMAGE) - 1, - maximal_cmdline_size - - (sizeof (LINUX_IMAGE) - 1)); + { + grub_err_t err; + err = grub_create_loader_cmdline (argc, argv, + linux_cmdline + + sizeof (LINUX_IMAGE) - 1, + maximal_cmdline_size + - (sizeof (LINUX_IMAGE) - 1), + GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + goto fail; + } len = prot_file_size; if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) @@ -1070,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 @@ -1094,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"); @@ -1111,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); @@ -1132,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) @@ -1148,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 fd7b41b0c..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,8 +241,8 @@ 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) - + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) + + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + + grub_multiboot_get_mmap_count () * sizeof (struct multiboot_mmap_entry) + elf_sec_entsize * elf_sec_num + 256 * sizeof (struct multiboot_color) #if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT @@ -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_get_multiboot_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; @@ -673,10 +675,8 @@ grub_multiboot_init_mbi (int argc, char *argv[]) return grub_errno; cmdline_size = len; - grub_create_loader_cmdline (argc, argv, cmdline, - cmdline_size); - - return GRUB_ERR_NONE; + return grub_create_loader_cmdline (argc, argv, cmdline, + cmdline_size, GRUB_VERIFY_KERNEL_CMDLINE); } grub_err_t @@ -685,6 +685,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, { struct module *newmod; grub_size_t len = 0; + grub_err_t err; newmod = grub_malloc (sizeof (*newmod)); if (!newmod) @@ -704,8 +705,13 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, newmod->cmdline_size = len; total_modcmd += ALIGN_UP (len, 4); - grub_create_loader_cmdline (argc, argv, newmod->cmdline, - newmod->cmdline_size); + err = grub_create_loader_cmdline (argc, argv, newmod->cmdline, + newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE); + if (err) + { + grub_free (newmod); + return grub_errno; + } if (modules_last) modules_last->next = newmod; @@ -747,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 c79c4fe0f..a38389999 100644 --- a/grub-core/loader/i386/pc/chainloader.c +++ b/grub-core/loader/i386/pc/chainloader.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -56,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, @@ -86,9 +87,16 @@ grub_chainloader_unload (void) void grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl) { - grub_uint32_t part_start = 0; + grub_uint32_t part_start = 0, heads = 0, sectors = 0; if (dev && dev->disk) - part_start = grub_partition_get_start (dev->disk->partition); + { + part_start = grub_partition_get_start (dev->disk->partition); + if (dev->disk->data) + { + heads = ((struct grub_biosdisk_data *)(dev->disk->data))->heads; + sectors = ((struct grub_biosdisk_data *)(dev->disk->data))->sectors; + } + } if (grub_memcmp ((char *) &((struct grub_ntfs_bpb *) bs)->oem_name, "NTFS", 4) == 0) { @@ -110,14 +118,14 @@ 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; if (bpb->num_reserved_sectors == 0) break; - if (bpb->num_total_sectors_16 == 0 || bpb->num_total_sectors_32 == 0) + if (bpb->num_total_sectors_16 == 0 && bpb->num_total_sectors_32 == 0) break; if (bpb->num_fats == 0) @@ -127,12 +135,20 @@ grub_chainloader_patch_bpb (void *bs, grub_device_t dev, grub_uint8_t dl) { bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); bpb->version_specific.fat12_or_fat16.num_ph_drive = dl; + if (sectors) + bpb->sectors_per_track = grub_cpu_to_le16 (sectors); + if (heads) + bpb->num_heads = grub_cpu_to_le16 (heads); return; } if (bpb->version_specific.fat32.sectors_per_fat_32) { bpb->num_hidden_sectors = grub_cpu_to_le32 (part_start); bpb->version_specific.fat32.num_ph_drive = dl; + if (sectors) + bpb->sectors_per_track = grub_cpu_to_le16 (sectors); + if (heads) + bpb->num_heads = grub_cpu_to_le16 (heads); return; } break; @@ -156,8 +172,8 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) grub_dl_ref (my_mod); - grub_file_filter_disable_compression (); - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_PCCHAINLOADER + | GRUB_FILE_TYPE_NO_DECOMPRESS); if (! file) goto fail; @@ -227,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 478f3c513..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, @@ -110,7 +110,7 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), if (!rel) goto fail; - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_FREEDOS); if (! file) goto fail; @@ -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 a293b17aa..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); } @@ -121,7 +122,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; - struct linux_kernel_header lh; + struct linux_i386_kernel_header lh; grub_uint8_t setup_sects; grub_size_t real_size; grub_ssize_t len; @@ -139,7 +140,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (! file) goto fail; @@ -169,7 +170,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), maximal_cmdline_size = 256; - if (lh.header == grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) + if (lh.header == grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) && grub_le_to_cpu16 (lh.version) >= 0x0200) { grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL); @@ -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; } @@ -236,10 +242,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), (unsigned) real_size, (unsigned) grub_linux16_prot_size); - relocator = grub_relocator_new (); - if (!relocator) - goto fail; - for (i = 1; i < argc; i++) if (grub_memcmp (argv[i], "vga=", 4) == 0) { @@ -263,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); @@ -299,6 +301,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } } + relocator = grub_relocator_new (); + if (!relocator) + goto fail; + { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_addr (relocator, &ch, @@ -322,7 +328,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) + if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0200) /* Clear the heap space. */ grub_memset (grub_linux_real_chunk @@ -334,11 +340,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Create kernel command line. */ grub_memcpy ((char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - (char *)grub_linux_real_chunk - + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1, - maximal_cmdline_size - - (sizeof (LINUX_IMAGE) - 1)); + err = grub_create_loader_cmdline (argc, argv, + (char *)grub_linux_real_chunk + + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1, + maximal_cmdline_size + - (sizeof (LINUX_IMAGE) - 1), + GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + goto fail; if (grub_linux_is_bzimage) grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR; @@ -355,8 +364,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } len = grub_linux16_prot_size; - if (grub_file_read (file, grub_linux_prot_chunk, grub_linux16_prot_size) - != (grub_ssize_t) grub_linux16_prot_size && !grub_errno) + if (grub_file_read (file, grub_linux_prot_chunk, len) != len && !grub_errno) grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); @@ -387,7 +395,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), { grub_size_t size = 0; grub_addr_t addr_max, addr_min; - struct linux_kernel_header *lh; + struct linux_i386_kernel_header *lh; grub_uint8_t *initrd_chunk; grub_addr_t initrd_addr; grub_err_t err; @@ -405,9 +413,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), goto fail; } - lh = (struct linux_kernel_header *) grub_linux_real_chunk; + lh = (struct linux_i386_kernel_header *) grub_linux_real_chunk; - if (!(lh->header == grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) + if (!(lh->header == grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) && grub_le_to_cpu16 (lh->version) >= 0x0200)) { grub_error (GRUB_ERR_BAD_OS, "the kernel is too old for initrd"); @@ -446,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 1b88f40d8..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, @@ -90,7 +90,7 @@ grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)), if (!rel) goto fail; - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_NTLDR); if (! file) goto fail; @@ -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 814a49d50..960e866f4 100644 --- a/grub-core/loader/i386/pc/plan9.c +++ b/grub-core/loader/i386/pc/plan9.c @@ -33,6 +33,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -55,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} @@ -77,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, @@ -121,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; @@ -301,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"); @@ -330,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 @@ -413,7 +414,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) if (!rel) goto fail; - fill_ctx.file = grub_file_open (argv[0]); + fill_ctx.file = grub_file_open (argv[0], GRUB_FILE_TYPE_PLAN9_KERNEL); if (! fill_ctx.file) goto fail; @@ -505,6 +506,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) configptr = grub_stpcpy (configptr, "bootfile="); configptr = grub_stpcpy (configptr, bootpath); *configptr++ = '\n'; + char *cmdline = configptr; { int i; for (i = 1; i < argc; i++) @@ -513,6 +515,15 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) *configptr++ = '\n'; } } + + { + grub_err_t err; + *configptr = '\0'; + err = grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + goto fail; + } + configptr = grub_stpcpy (configptr, fill_ctx.pmap); { diff --git a/grub-core/loader/i386/pc/pxechainloader.c b/grub-core/loader/i386/pc/pxechainloader.c index e60c62b1b..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, @@ -99,7 +99,7 @@ grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)), if (!rel) goto fail; - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_PXECHAINLOADER); if (! file) goto fail; @@ -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 9ea4fde42..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, @@ -99,7 +99,7 @@ grub_cmd_truecrypt (grub_command_t cmd __attribute__ ((unused)), grub_dl_ref (my_mod); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_TRUECRYPT); if (! file) goto fail; @@ -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 3073f64d5..dcdf005df 100644 --- a/grub-core/loader/i386/xen.c +++ b/grub-core/loader/i386/xen.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -90,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) @@ -101,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 @@ -140,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; @@ -227,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--) { @@ -245,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); @@ -322,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 { @@ -378,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, @@ -411,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) @@ -429,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; @@ -459,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)); @@ -513,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, @@ -536,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); @@ -635,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")); @@ -644,11 +646,14 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), grub_xen_reset (); - grub_create_loader_cmdline (argc - 1, argv + 1, - (char *) xen_state.next_start.cmd_line, - sizeof (xen_state.next_start.cmd_line) - 1); + err = grub_create_loader_cmdline (argc - 1, argv + 1, + (char *) xen_state.next_start.cmd_line, + sizeof (xen_state.next_start.cmd_line) - 1, + GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + return err; - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (!file) return grub_errno; @@ -671,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; @@ -694,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); @@ -718,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 - @@ -797,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; } @@ -807,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 = @@ -817,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); @@ -871,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; @@ -891,11 +901,10 @@ 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); - if (nounzip) - grub_file_filter_disable_compression (); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_INITRD | + (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS : GRUB_FILE_TYPE_NONE)); if (!file) return grub_errno; size = grub_file_size (file); @@ -907,12 +916,15 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), if (err) goto fail; - grub_create_loader_cmdline (argc - 1, argv + 1, - get_virtual_current_address (ch), cmdline_len); + err = grub_create_loader_cmdline (argc - 1, argv + 1, + get_virtual_current_address (ch), cmdline_len, + GRUB_VERIFY_MODULE_CMDLINE); + if (err) + goto fail; xen_state.module_info_page[xen_state.n_modules].cmdline = xen_state.max_addr - xen_state.modules_target_start; - xen_state.max_addr = ALIGN_UP (xen_state.max_addr + cmdline_len, PAGE_SIZE); + xen_state.max_addr = ALIGN_UP (xen_state.max_addr + cmdline_len, GRUB_PAGE_SIZE); if (size) { @@ -939,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_file.c b/grub-core/loader/i386/xen_file.c index 99fad4cad..9af5d66df 100644 --- a/grub-core/loader/i386/xen_file.c +++ b/grub-core/loader/i386/xen_file.c @@ -26,7 +26,7 @@ grub_elf_t grub_xen_file (grub_file_t file) { grub_elf_t elf; - struct linux_kernel_header lh; + struct linux_i386_kernel_header lh; grub_file_t off_file; grub_uint32_t payload_offset, payload_length; grub_uint8_t magic[6]; @@ -43,7 +43,7 @@ grub_xen_file (grub_file_t file) goto fail; if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55) - || lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_MAGIC_SIGNATURE) + || lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0208) { grub_error (GRUB_ERR_BAD_OS, "version too old for xen boot"); @@ -78,7 +78,7 @@ grub_xen_file (grub_file_t file) Trim it. */ if (grub_memcmp (magic, XZ_MAGIC, sizeof (XZ_MAGIC) - 1) == 0) payload_length -= 4; - off_file = grub_file_offset_open (file, payload_offset, + off_file = grub_file_offset_open (file, GRUB_FILE_TYPE_LINUX_KERNEL, payload_offset, payload_length); if (!off_file) goto fail; diff --git a/grub-core/loader/i386/xen_fileXX.c b/grub-core/loader/i386/xen_fileXX.c index fb66e66fe..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; @@ -344,6 +344,23 @@ grub_xen_get_infoXX (grub_elf_t elf, struct grub_xen_file_info *xi) s = (Elf_Shdr *) ((char *) s0 + elf->ehdr.ehdrXX.e_shstrndx * shentsize); stroff = s->sh_offset; + for (s = s0; s < (Elf_Shdr *) ((char *) s0 + shnum * shentsize); + s = (Elf_Shdr *) ((char *) s + shentsize)) + { + if (s->sh_type == SHT_NOTE) + { + err = parse_note (elf, xi, s->sh_offset, s->sh_size); + if (err) + goto cleanup; + } + } + + if (xi->has_note) + { + err = GRUB_ERR_NONE; + goto cleanup; + } + for (s = s0; s < (Elf_Shdr *) ((char *) s0 + shnum * shentsize); s = (Elf_Shdr *) ((char *) s + shentsize)) { diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index 59ef73a73..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); @@ -487,7 +486,7 @@ grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)), if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_XNU_DEVPROP); if (! file) return grub_errno; size = grub_file_size (file); @@ -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 efaa42ccd..99cb244d8 100644 --- a/grub-core/loader/ia64/efi/linux.c +++ b/grub-core/loader/ia64/efi/linux.c @@ -33,6 +33,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -105,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} }; @@ -113,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, @@ -130,49 +131,7 @@ query_fpswa (void) grub_printf ("%s\n", _("FPSWA protocol wasn't able to find the interface")); return; - } -} - -/* Find the optimal number of pages for the memory map. Is it better to - move this code to efi/mm.c? */ -static grub_efi_uintn_t -find_mmap_size (void) -{ - static grub_efi_uintn_t mmap_size = 0; - - if (mmap_size != 0) - return mmap_size; - - mmap_size = (1 << 12); - while (1) - { - int ret; - grub_efi_memory_descriptor_t *mmap; - grub_efi_uintn_t desc_size; - - mmap = grub_malloc (mmap_size); - if (! mmap) - return 0; - - ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); - grub_free (mmap); - - if (ret < 0) - { - grub_error (GRUB_ERR_IO, "cannot get memory map"); - return 0; - } - else if (ret > 0) - break; - - mmap_size += (1 << 12); } - - /* Increase the size a bit for safety, because GRUB allocates more on - later, and EFI itself may allocate more. */ - mmap_size += (1 << 12); - - return page_align (mmap_size); } static void @@ -212,7 +171,7 @@ allocate_pages (grub_uint64_t align, grub_uint64_t size_pages, size = size_pages << 12; - mmap_size = find_mmap_size (); + mmap_size = grub_efi_find_mmap_size (); if (!mmap_size) return 0; @@ -229,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; @@ -252,7 +211,7 @@ allocate_pages (grub_uint64_t align, grub_uint64_t size_pages, aligned_start += align; if (aligned_start + size > end) continue; - mem = grub_efi_allocate_pages (aligned_start, size_pages); + mem = grub_efi_allocate_fixed (aligned_start, size_pages); if (! mem) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory"); @@ -281,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) @@ -291,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; @@ -323,10 +282,10 @@ grub_linux_boot (void) /* MDT. Must be done after grub_machine_fini because map_key is used by exit_boot_services. */ - mmap_size = find_mmap_size (); + mmap_size = grub_efi_find_mmap_size (); if (! mmap_size) return grub_errno; - mmap_buf = grub_efi_allocate_pages (0, page_align (mmap_size) >> 12); + mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12); if (! mmap_buf) return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, &map_key, @@ -341,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; } @@ -422,8 +381,9 @@ grub_load_elf64 (grub_file_t file, void *buffer, const char *filename) relocate = grub_env_get ("linux_relocate"); if (!relocate || grub_strcmp (relocate, "force") != 0) { - kernel_mem = grub_efi_allocate_pages (low_addr, kernel_pages); + 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)) @@ -452,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; @@ -465,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), @@ -494,14 +454,14 @@ 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")); goto fail; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (! file) goto fail; @@ -524,7 +484,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), len += grub_strlen (argv[i]) + 1; len += sizeof (struct ia64_boot_param) + 512; /* Room for extensions. */ boot_param_pages = page_align (len) >> 12; - boot_param = grub_efi_allocate_pages (0, boot_param_pages); + boot_param = grub_efi_allocate_any_pages (boot_param_pages); if (boot_param == 0) { grub_error (GRUB_ERR_OUT_OF_MEMORY, @@ -543,7 +503,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), p = grub_stpcpy (p, argv[i]); } cmdline[10] = '='; - + + *p = '\0'; + + if (grub_verify_string (cmdline, GRUB_VERIFY_KERNEL_CMDLINE)) + goto fail; + boot_param->command_line = (grub_uint64_t) cmdline; boot_param->efi_systab = (grub_uint64_t) grub_efi_system_table; @@ -575,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")); @@ -589,17 +554,17 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_dprintf ("linux", "Loading initrd\n"); initrd_pages = (page_align (initrd_size) >> 12); - initrd_mem = grub_efi_allocate_pages (0, initrd_pages); + initrd_mem = grub_efi_allocate_any_pages (initrd_pages); if (! initrd_mem) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate pages"); goto fail; } - + grub_dprintf ("linux", "[addr=0x%lx, size=0x%lx]\n", (grub_uint64_t) initrd_mem, initrd_size); - if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + if (grub_initrd_load (&initrd_ctx, initrd_mem)) goto fail; fail: grub_initrd_close (&initrd_ctx); @@ -625,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 be6fa0f4d..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,33 +194,40 @@ grub_initrd_init (int argc, char *argv[], eptr = grub_strchr (ptr, ':'); if (eptr) { - grub_file_filter_disable_compression (); + 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; } - grub_file_filter_disable_compression (); - initrd_ctx->components[i].file = grub_file_open (fname); + initrd_ctx->components[i].file = grub_file_open (fname, + GRUB_FILE_TYPE_LINUX_INITRD + | GRUB_FILE_TYPE_NO_DECOMPRESS); if (!initrd_ctx->components[i].file) { grub_initrd_close (initrd_ctx); @@ -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 59b195e27..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, @@ -188,12 +188,12 @@ fail: } grub_macho_t -grub_macho_open (const char *name, int is_64bit) +grub_macho_open (const char *name, enum grub_file_type type, int is_64bit) { grub_file_t file; grub_macho_t macho; - file = grub_file_open (name); + file = grub_file_open (name, type); if (! file) return 0; diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 5f383be3d..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; @@ -237,7 +237,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - elf = grub_elf_open (argv[0]); + elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (! elf) return grub_errno; @@ -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); @@ -314,7 +314,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_memcpy (params, LINUX_IMAGE, sizeof (LINUX_IMAGE)); grub_create_loader_cmdline (argc, argv, params + sizeof (LINUX_IMAGE) - 1, - size); + size, GRUB_VERIFY_KERNEL_CMDLINE); #else linux_argv = extra; argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground; @@ -327,6 +327,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_argv++; linux_args += ALIGN_UP (sizeof ("a0"), 4); + char *params = linux_args; + #ifdef GRUB_MACHINE_MIPS_LOONGSON { unsigned mtype = grub_arch_machine; @@ -352,6 +354,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); } + *linux_args = '\0'; + + err = grub_verify_string (params, GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + return err; + /* Reserve space for rd arguments. */ rd_addr_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground; linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); @@ -434,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; @@ -447,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 bd9d5b3e6..36b27a906 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -28,7 +28,15 @@ #include #include +#ifdef GRUB_USE_MULTIBOOT2 +#include +#define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER +#define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT +#define GRUB_MULTIBOOT(x) grub_multiboot2_ ## x +#else #include +#define GRUB_MULTIBOOT(x) grub_multiboot_ ## x +#endif #include #include #include @@ -49,8 +57,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); #include #endif -struct grub_relocator *grub_multiboot_relocator = NULL; -grub_uint32_t grub_multiboot_payload_eip; +struct grub_relocator *GRUB_MULTIBOOT (relocator) = NULL; +grub_uint32_t GRUB_MULTIBOOT (payload_eip); #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) #define DEFAULT_VIDEO_MODE "text" #else @@ -78,7 +86,7 @@ count_hook (grub_uint64_t addr __attribute__ ((unused)), /* Return the length of the Multiboot mmap that will be needed to allocate our platform's map. */ grub_uint32_t -grub_get_multiboot_mmap_count (void) +GRUB_MULTIBOOT (get_mmap_count) (void) { grub_size_t count = 0; @@ -88,7 +96,7 @@ grub_get_multiboot_mmap_count (void) } grub_err_t -grub_multiboot_set_video_mode (void) +GRUB_MULTIBOOT (set_video_mode) (void) { grub_err_t err; const char *modevar; @@ -130,9 +138,12 @@ static void efi_boot (struct grub_relocator *rel, grub_uint32_t target) { +#ifdef GRUB_USE_MULTIBOOT2 + struct grub_relocator_efi_state state_efi = MULTIBOOT2_EFI_INITIAL_STATE; +#else struct grub_relocator_efi_state state_efi = MULTIBOOT_EFI_INITIAL_STATE; - - state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = grub_multiboot_payload_eip; +#endif + state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = GRUB_MULTIBOOT (payload_eip); state_efi.MULTIBOOT_EFI_MBI_REGISTER = target; grub_relocator_efi_boot (rel, state_efi); @@ -164,19 +175,23 @@ static grub_err_t grub_multiboot_boot (void) { grub_err_t err; + +#ifdef GRUB_USE_MULTIBOOT2 + struct grub_relocator32_state state = MULTIBOOT2_INITIAL_STATE; +#else struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE; +#endif + state.MULTIBOOT_ENTRY_REGISTER = GRUB_MULTIBOOT (payload_eip); - state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip; - - err = grub_multiboot_make_mbi (&state.MULTIBOOT_MBI_REGISTER); + err = GRUB_MULTIBOOT (make_mbi) (&state.MULTIBOOT_MBI_REGISTER); if (err) return err; if (grub_efi_is_finished) - normal_boot (grub_multiboot_relocator, state); + normal_boot (GRUB_MULTIBOOT (relocator), state); else - efi_boot (grub_multiboot_relocator, state.MULTIBOOT_MBI_REGISTER); + efi_boot (GRUB_MULTIBOOT (relocator), state.MULTIBOOT_MBI_REGISTER); /* Not reached. */ return GRUB_ERR_NONE; @@ -185,10 +200,10 @@ grub_multiboot_boot (void) static grub_err_t grub_multiboot_unload (void) { - grub_multiboot_free_mbi (); + GRUB_MULTIBOOT (free_mbi) (); - grub_relocator_unload (grub_multiboot_relocator); - grub_multiboot_relocator = NULL; + grub_relocator_unload (GRUB_MULTIBOOT (relocator)); + GRUB_MULTIBOOT (relocator) = NULL; grub_dl_unref (my_mod); @@ -207,7 +222,7 @@ static grub_uint64_t highest_load; /* Load ELF32 or ELF64. */ grub_err_t -grub_multiboot_load_elf (mbi_load_data_t *mld) +GRUB_MULTIBOOT (load_elf) (mbi_load_data_t *mld) { if (grub_multiboot_is_elf32 (mld->buffer)) return grub_multiboot_load_elf32 (mld); @@ -218,12 +233,12 @@ grub_multiboot_load_elf (mbi_load_data_t *mld) } grub_err_t -grub_multiboot_set_console (int console_type, int accepted_consoles, - int width, int height, int depth, - int console_req) +GRUB_MULTIBOOT (set_console) (int console_type, int accepted_consoles, + int width, int height, int depth, + int console_req) { console_required = console_req; - if (!(accepted_consoles + if (!(accepted_consoles & (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER | (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0)))) { @@ -306,26 +321,26 @@ grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_MULTIBOOT_KERNEL); if (! file) return grub_errno; grub_dl_ref (my_mod); /* Skip filename. */ - grub_multiboot_init_mbi (argc - 1, argv + 1); + GRUB_MULTIBOOT (init_mbi) (argc - 1, argv + 1); - grub_relocator_unload (grub_multiboot_relocator); - grub_multiboot_relocator = grub_relocator_new (); + grub_relocator_unload (GRUB_MULTIBOOT (relocator)); + GRUB_MULTIBOOT (relocator) = grub_relocator_new (); - if (!grub_multiboot_relocator) + if (!GRUB_MULTIBOOT (relocator)) goto fail; - err = grub_multiboot_load (file, argv[0]); + err = GRUB_MULTIBOOT (load) (file, argv[0]); if (err) goto fail; - grub_multiboot_set_bootdev (); + GRUB_MULTIBOOT (set_bootdev) (); grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); @@ -335,8 +350,8 @@ grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)), if (grub_errno != GRUB_ERR_NONE) { - grub_relocator_unload (grub_multiboot_relocator); - grub_multiboot_relocator = NULL; + grub_relocator_unload (GRUB_MULTIBOOT (relocator)); + GRUB_MULTIBOOT (relocator) = NULL; grub_dl_unref (my_mod); } @@ -368,14 +383,12 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); - if (!grub_multiboot_relocator) + if (!GRUB_MULTIBOOT (relocator)) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); - if (nounzip) - grub_file_filter_disable_compression (); - - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_MULTIBOOT_MODULE + | (nounzip ? GRUB_FILE_TYPE_NO_DECOMPRESS : GRUB_FILE_TYPE_NONE)); if (! file) return grub_errno; @@ -389,8 +402,8 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), if (size) { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, - lowest_addr, (0xffffffff - size) + 1, + err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, + lowest_addr, UP_TO_TOP32 (size), size, MULTIBOOT_MOD_ALIGN, GRUB_RELOCATOR_PREFERENCE_NONE, 1); if (err) @@ -407,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); @@ -424,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 5e649ed25..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,9 +67,12 @@ 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, load_size; - int i; - void *source; + grub_uint32_t load_offset = 0, load_size = 0; + Elf_Shnum shnum; + Elf_Word shstrndx, phnum; + grub_off_t phlimit; + unsigned int i; + void *source = NULL; if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 @@ -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); @@ -97,41 +123,41 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border"); #endif - load_size = highest_load - mld->link_base_addr; - if (mld->relocatable) { + load_size = highest_load - mld->link_base_addr; + + grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, " + "load_size=0x%x, avoid_efi_boot_services=%d\n", + (long) mld->align, mld->preference, load_size, + mld->avoid_efi_boot_services); + if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size) return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); - err = grub_relocator_alloc_chunk_align (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 != GRUB_ERR_NONE) + { + grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); + return err; + } + + mld->load_base_addr = get_physical_target_address (ch); + source = get_virtual_current_address (ch); } else - err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch, - mld->link_base_addr, load_size); + mld->load_base_addr = mld->link_base_addr; - if (err) - { - grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); - return err; - } - - mld->load_base_addr = get_physical_target_address (ch); - source = get_virtual_current_address (ch); - - grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, " - "load_size=0x%x, relocatable=%d\n", mld->link_base_addr, - mld->load_base_addr, load_size, mld->relocatable); - - if (mld->relocatable) - grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n", - (long) mld->align, mld->preference, mld->avoid_efi_boot_services); + grub_dprintf ("multiboot_loader", "relocatable=%d, link_base_addr=0x%x, " + "load_base_addr=0x%x\n", mld->relocatable, + mld->link_base_addr, mld->load_base_addr); /* Load every loadable segment in memory. */ - for (i = 0; i < ehdr->e_phnum; i++) + for (i = 0; i < phnum; i++) { if (phdr(i)->p_type == PT_LOAD) { @@ -139,7 +165,25 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n", i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr); - load_offset = phdr(i)->p_paddr - mld->link_base_addr; + if (mld->relocatable) + { + load_offset = phdr(i)->p_paddr - mld->link_base_addr; + grub_dprintf ("multiboot_loader", "segment %d: load_offset=0x%x\n", i, load_offset); + } + else + { + load_size = phdr(i)->p_memsz; + err = grub_relocator_alloc_chunk_addr (GRUB_MULTIBOOT (relocator), &ch, + phdr(i)->p_paddr, load_size); + + if (err != GRUB_ERR_NONE) + { + grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n"); + return err; + } + + source = get_virtual_current_address (ch); + } if (phdr(i)->p_filesz != 0) { @@ -158,16 +202,22 @@ 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) { - grub_multiboot_payload_eip = (ehdr->e_entry - phdr(i)->p_vaddr) + GRUB_MULTIBOOT (payload_eip) = (ehdr->e_entry - phdr(i)->p_vaddr) + phdr(i)->p_paddr; #ifdef MULTIBOOT_LOAD_ELF64 # ifdef __mips @@ -185,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; + 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; @@ -227,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, + err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0, + UP_TO_TOP32 (sh->sh_size), sh->sh_size, sh->sh_addralign, GRUB_RELOCATOR_PREFERENCE_NONE, mld->avoid_efi_boot_services); - if (err) + 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) @@ -260,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 @@ -279,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 b0679a9f6..00a48413c 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -22,7 +22,7 @@ #include #include #endif -#include +#include #include #include #include @@ -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; @@ -71,7 +77,7 @@ static int keep_bs = 0; static grub_uint32_t load_base_addr; void -grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize, +grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize, unsigned shndx, void *data) { elf_sec_num = num; @@ -90,17 +96,17 @@ find_header (grub_properly_aligned_t *buffer, grub_ssize_t len) ((char *) header <= (char *) buffer + len - 12); header = (struct multiboot_header *) ((grub_uint32_t *) header + MULTIBOOT_HEADER_ALIGN / 4)) { - if (header->magic == MULTIBOOT_HEADER_MAGIC + if (header->magic == MULTIBOOT2_HEADER_MAGIC && !(header->magic + header->architecture + header->header_length + header->checksum) - && header->architecture == MULTIBOOT_ARCHITECTURE_CURRENT) + && header->architecture == MULTIBOOT2_ARCHITECTURE_CURRENT) return header; } return NULL; } grub_err_t -grub_multiboot_load (grub_file_t file, const char *filename) +grub_multiboot2_load (grub_file_t file, const char *filename) { grub_ssize_t len; struct multiboot_header *header; @@ -112,7 +118,7 @@ grub_multiboot_load (grub_file_t file, const char *filename) grub_addr_t entry = 0, efi_entry = 0; grub_uint32_t console_required = 0; struct multiboot_header_tag_framebuffer *fbtag = NULL; - int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT; + int accepted_consoles = GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT; mbi_load_data_t mld; mld.mbi_ver = 2; @@ -190,7 +196,7 @@ grub_multiboot_load (grub_file_t file, const char *filename) } break; } - + case MULTIBOOT_HEADER_TAG_ADDRESS: addr_tag = (struct multiboot_header_tag_address *) tag; break; @@ -210,7 +216,7 @@ grub_multiboot_load (grub_file_t file, const char *filename) case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS: if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags & MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED)) - accepted_consoles &= ~GRUB_MULTIBOOT_CONSOLE_EGA_TEXT; + accepted_consoles &= ~GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT; if (((struct multiboot_header_tag_console_flags *) tag)->console_flags & MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED) console_required = 1; @@ -218,7 +224,7 @@ grub_multiboot_load (grub_file_t file, const char *filename) case MULTIBOOT_HEADER_TAG_FRAMEBUFFER: fbtag = (struct multiboot_header_tag_framebuffer *) tag; - accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER; + accepted_consoles |= GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER; break; case MULTIBOOT_HEADER_TAG_RELOCATABLE: @@ -268,7 +274,7 @@ grub_multiboot_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,13 +301,13 @@ grub_multiboot_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_multiboot_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_multiboot_relocator, + err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator, &ch, load_addr, code_size); if (err) { @@ -343,7 +349,7 @@ grub_multiboot_load (grub_file_t file, const char *filename) mld.file = file; mld.filename = filename; mld.avoid_efi_boot_services = keep_bs; - err = grub_multiboot_load_elf (&mld); + err = grub_multiboot2_load_elf (&mld); if (err) { grub_free (mld.buffer); @@ -354,9 +360,9 @@ grub_multiboot_load (grub_file_t file, const char *filename) load_base_addr = mld.load_base_addr; if (keep_bs && efi_entry_specified) - grub_multiboot_payload_eip = efi_entry; + grub_multiboot2_payload_eip = efi_entry; else if (entry_specified) - grub_multiboot_payload_eip = entry; + grub_multiboot2_payload_eip = entry; if (mld.relocatable) { @@ -370,20 +376,20 @@ grub_multiboot_load (grub_file_t file, const char *filename) * 64-bit int here. */ if (mld.load_base_addr >= mld.link_base_addr) - grub_multiboot_payload_eip += mld.load_base_addr - mld.link_base_addr; + grub_multiboot2_payload_eip += mld.load_base_addr - mld.link_base_addr; else - grub_multiboot_payload_eip -= mld.link_base_addr - mld.load_base_addr; + grub_multiboot2_payload_eip -= mld.link_base_addr - mld.load_base_addr; } if (fbtag) - err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, - accepted_consoles, - fbtag->width, fbtag->height, - fbtag->depth, console_required); + err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER, + accepted_consoles, + fbtag->width, fbtag->height, + fbtag->depth, console_required); else - err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, - accepted_consoles, - 0, 0, 0, console_required); + err = grub_multiboot2_set_console (GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT, + accepted_consoles, + 0, 0, 0, console_required); return err; } @@ -407,42 +413,6 @@ acpiv2_size (void) static grub_efi_uintn_t efi_mmap_size = 0; -/* Find the optimal number of pages for the memory map. Is it better to - move this code to efi/mm.c? */ -static void -find_efi_mmap_size (void) -{ - efi_mmap_size = (1 << 12); - while (1) - { - int ret; - grub_efi_memory_descriptor_t *mmap; - grub_efi_uintn_t desc_size; - grub_efi_uintn_t cur_mmap_size = efi_mmap_size; - - mmap = grub_malloc (cur_mmap_size); - if (! mmap) - return; - - ret = grub_efi_get_memory_map (&cur_mmap_size, mmap, 0, &desc_size, 0); - grub_free (mmap); - - if (ret < 0) - return; - else if (ret > 0) - break; - - if (efi_mmap_size < cur_mmap_size) - efi_mmap_size = cur_mmap_size; - efi_mmap_size += (1 << 12); - } - - /* Increase the size a bit for safety, because GRUB allocates more on - later, and EFI itself may allocate more. */ - efi_mmap_size += (3 << 12); - - efi_mmap_size = ALIGN_UP (efi_mmap_size, 4096); -} #endif static grub_size_t @@ -459,11 +429,11 @@ net_size (void) } static grub_size_t -grub_multiboot_get_mbi_size (void) +grub_multiboot2_get_mbi_size (void) { #ifdef GRUB_MACHINE_EFI if (!keep_bs && !efi_mmap_size) - find_efi_mmap_size (); + efi_mmap_size = grub_efi_find_mmap_size (); #endif return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag) + sizeof (struct multiboot_tag) @@ -478,7 +448,7 @@ grub_multiboot_get_mbi_size (void) + ALIGN_UP (sizeof (struct multiboot_tag_elf_sections), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (elf_sec_entsize * elf_sec_num, MULTIBOOT_TAG_ALIGN) + ALIGN_UP ((sizeof (struct multiboot_tag_mmap) - + grub_get_multiboot_mmap_count () + + grub_multiboot2_get_mmap_count () * sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (sizeof (struct multiboot_tag_old_acpi) @@ -522,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_get_multiboot_mmap_count (); + + sizeof (struct multiboot_mmap_entry) * grub_multiboot2_get_mmap_count (); tag->entry_size = sizeof (struct multiboot_mmap_entry); tag->entry_version = 0; @@ -534,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) @@ -568,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); @@ -588,7 +558,7 @@ retrieve_video_parameters (grub_properly_aligned_t **ptrorig) struct multiboot_tag_framebuffer *tag = (struct multiboot_tag_framebuffer *) *ptrorig; - err = grub_multiboot_set_video_mode (); + err = grub_multiboot2_set_video_mode (); if (err) { grub_print_error (); @@ -607,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) @@ -646,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; @@ -694,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; @@ -731,7 +701,7 @@ retrieve_video_parameters (grub_properly_aligned_t **ptrorig) } grub_err_t -grub_multiboot_make_mbi (grub_uint32_t *target) +grub_multiboot2_make_mbi (grub_uint32_t *target) { grub_properly_aligned_t *ptrorig; grub_properly_aligned_t *mbistart; @@ -739,12 +709,12 @@ grub_multiboot_make_mbi (grub_uint32_t *target) grub_size_t bufsize; grub_relocator_chunk_t ch; - bufsize = grub_multiboot_get_mbi_size (); + bufsize = grub_multiboot2_get_mbi_size (); COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0); - err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, - 0, 0xffffffff - bufsize, + err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, + MBI_MIN_ADDR, UP_TO_TOP32 (bufsize), bufsize, MULTIBOOT_TAG_ALIGN, GRUB_RELOCATOR_PREFERENCE_NONE, 1); if (err) @@ -778,7 +748,7 @@ grub_multiboot_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); @@ -787,7 +757,7 @@ grub_multiboot_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); @@ -801,7 +771,7 @@ grub_multiboot_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; @@ -894,7 +864,7 @@ grub_multiboot_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; @@ -1039,7 +1009,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) } void -grub_multiboot_free_mbi (void) +grub_multiboot2_free_mbi (void) { struct module *cur, *next; @@ -1061,11 +1031,11 @@ grub_multiboot_free_mbi (void) } grub_err_t -grub_multiboot_init_mbi (int argc, char *argv[]) +grub_multiboot2_init_mbi (int argc, char *argv[]) { grub_ssize_t len = 0; - grub_multiboot_free_mbi (); + grub_multiboot2_free_mbi (); len = grub_loader_cmdline_size (argc, argv); @@ -1074,18 +1044,17 @@ grub_multiboot_init_mbi (int argc, char *argv[]) return grub_errno; cmdline_size = len; - grub_create_loader_cmdline (argc, argv, cmdline, - cmdline_size); - - return GRUB_ERR_NONE; + return grub_create_loader_cmdline (argc, argv, cmdline, cmdline_size, + GRUB_VERIFY_KERNEL_CMDLINE); } grub_err_t -grub_multiboot_add_module (grub_addr_t start, grub_size_t size, +grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, int argc, char *argv[]) { struct module *newmod; grub_size_t len = 0; + grub_err_t err; newmod = grub_malloc (sizeof (*newmod)); if (!newmod) @@ -1104,8 +1073,14 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, newmod->cmdline_size = len; total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN); - grub_create_loader_cmdline (argc, argv, newmod->cmdline, - newmod->cmdline_size); + err = grub_create_loader_cmdline (argc, argv, newmod->cmdline, + newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE); + if (err) + { + grub_free (newmod->cmdline); + grub_free (newmod); + return err; + } if (modules_last) modules_last->next = newmod; @@ -1119,7 +1094,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, } void -grub_multiboot_set_bootdev (void) +grub_multiboot2_set_bootdev (void) { grub_device_t dev; diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c index 6e814649f..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"); @@ -270,7 +281,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto out; } - elf = grub_elf_open (argv[0]); + elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (! elf) goto out; @@ -302,8 +313,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Create kernel command line. */ grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1, - size); + if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1, + size, GRUB_VERIFY_KERNEL_CMDLINE)) + goto out; out: @@ -352,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/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c index 67ef04883..ac2206f3c 100644 --- a/grub-core/loader/sparc64/ieee1275/linux.c +++ b/grub-core/loader/sparc64/ieee1275/linux.c @@ -306,7 +306,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto out; } - file = grub_file_open (argv[0]); + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); if (!file) goto out; @@ -340,8 +340,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* Create kernel command line. */ grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1, - size); + if (grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1, + size, GRUB_VERIFY_KERNEL_CMDLINE)) + goto out; out: if (elf) @@ -412,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 c9885b1bc..80831386e 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -58,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; @@ -223,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; @@ -251,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. */ @@ -351,7 +371,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), grub_xnu_unload (); - macho = grub_macho_open (args[0], 0); + macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL, 0); if (! macho) return grub_errno; @@ -425,6 +445,10 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)), if (ptr != grub_xnu_cmdline) *(ptr - 1) = 0; + err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + return err; + #if defined (__i386) && !defined (GRUB_MACHINE_EFI) err = grub_efiemu_autocore (); if (err) @@ -456,7 +480,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), grub_xnu_unload (); - macho = grub_macho_open (args[0], 1); + macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL, 1); if (! macho) return grub_errno; @@ -534,6 +558,10 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)), if (ptr != grub_xnu_cmdline) *(ptr - 1) = 0; + err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + return err; + #if defined (__i386) && !defined (GRUB_MACHINE_EFI) err = grub_efiemu_autocore (); if (err) @@ -642,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, '/'); @@ -673,10 +704,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile, else macho = 0; - if (infoplistname) - infoplist = grub_file_open (infoplistname); - else - infoplist = 0; + infoplist = grub_file_open (infoplistname, GRUB_FILE_TYPE_XNU_INFO_PLIST); grub_errno = GRUB_ERR_NONE; if (infoplist) { @@ -771,7 +799,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), if (! grub_xnu_heap_size) return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first")); - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_MKEXT); if (! file) return grub_errno; @@ -791,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); @@ -885,7 +913,7 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)), if (! grub_xnu_heap_size) return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first")); - file = grub_file_open (args[0]); + file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_RAMDISK); if (! file) return grub_errno; @@ -925,7 +953,7 @@ grub_xnu_check_os_bundle_required (char *plistname, if (binname) *binname = 0; - file = grub_file_open (plistname); + file = grub_file_open (plistname, GRUB_FILE_TYPE_XNU_INFO_PLIST); if (! file) return 0; @@ -1093,7 +1121,7 @@ grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired, path++; if (fs) - (fs->dir) (dev, path, grub_xnu_scan_dir_for_kexts_load, &ctx); + (fs->fs_dir) (dev, path, grub_xnu_scan_dir_for_kexts_load, &ctx); grub_device_close (dev); } grub_free (device_name); @@ -1192,7 +1220,7 @@ grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired, /* Look at the directory. */ if (fs) - (fs->dir) (dev, path, grub_xnu_load_kext_from_dir_load, &ctx); + (fs->fs_dir) (dev, path, grub_xnu_load_kext_from_dir_load, &ctx); if (ctx.plistname && grub_xnu_check_os_bundle_required (ctx.plistname, osbundlerequired, &binsuffix)) @@ -1210,7 +1238,7 @@ grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired, grub_strcpy (binname + grub_strlen (binname), "/"); grub_strcpy (binname + grub_strlen (binname), binsuffix); grub_dprintf ("xnu", "%s:%s\n", ctx.plistname, binname); - binfile = grub_file_open (binname); + binfile = grub_file_open (binname, GRUB_FILE_TYPE_XNU_KEXT); if (! binfile) grub_errno = GRUB_ERR_NONE; @@ -1230,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; } @@ -1253,7 +1282,7 @@ grub_cmd_xnu_kext (grub_command_t cmd __attribute__ ((unused)), /* User explicitly specified plist and binary. */ if (grub_strcmp (args[1], "-") != 0) { - binfile = grub_file_open (args[1]); + binfile = grub_file_open (args[1], GRUB_FILE_TYPE_XNU_KEXT); if (! binfile) return grub_errno; } @@ -1371,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; @@ -1473,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 534a74438..d648ef0cd 100644 --- a/grub-core/loader/xnu_resume.c +++ b/grub-core/loader/xnu_resume.c @@ -53,8 +53,8 @@ grub_xnu_resume (char *imagename) grub_addr_t target_image; grub_err_t err; - grub_file_filter_disable_compression (); - file = grub_file_open (imagename); + file = grub_file_open (imagename, GRUB_FILE_TYPE_XNU_HIBERNATE_IMAGE + | GRUB_FILE_TYPE_NO_DECOMPRESS); if (! file) return 0; @@ -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 609994516..b9c5b0a00 100644 --- a/grub-core/mmap/i386/pc/mmap.c +++ b/grub-core/mmap/i386/pc/mmap.c @@ -42,14 +42,6 @@ extern grub_uint16_t grub_machine_mmaphook_kblow; extern grub_uint16_t grub_machine_mmaphook_kbin16mb; extern grub_uint16_t grub_machine_mmaphook_64kbin4gb; -struct grub_e820_mmap_entry -{ - grub_uint64_t addr; - grub_uint64_t len; - grub_uint32_t type; -} GRUB_PACKED; - - /* Helper for preboot. */ static int fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, void *data) @@ -88,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); @@ -102,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; @@ -116,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/modinfo.sh.in b/grub-core/modinfo.sh.in index faf0ad30e..f6cd657ce 100644 --- a/grub-core/modinfo.sh.in +++ b/grub-core/modinfo.sh.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ # User-controllable options grub_modinfo_target_cpu=@target_cpu@ diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c index 4b68c4151..1d367436c 100644 --- a/grub-core/net/arp.c +++ b/grub-core/net/arp.c @@ -111,8 +111,8 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, } grub_err_t -grub_net_arp_receive (struct grub_net_buff *nb, - struct grub_net_card *card) +grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, + grub_uint16_t *vlantag) { struct arppkt *arp_packet = (struct arppkt *) nb->data; grub_net_network_level_address_t sender_addr, target_addr; @@ -128,6 +128,8 @@ grub_net_arp_receive (struct grub_net_buff *nb, 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; @@ -138,6 +140,14 @@ grub_net_arp_receive (struct grub_net_buff *nb, FOR_NET_NETWORK_LEVEL_INTERFACES (inf) { + /* Verify vlantag id */ + if (inf->card == card && inf->vlantag != *vlantag) + { + grub_dprintf ("net", "invalid vlantag! %x != %x\n", + inf->vlantag, *vlantag); + break; + } + /* Am I the protocol address target? */ if (grub_net_addr_cmp (&inf->address, &target_addr) == 0 && arp_packet->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index 9e2fdb795..2f45a3cc2 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -24,26 +24,124 @@ #include #include #include +#include -static void -parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask) +struct grub_dhcp_discover_options { - const grub_uint8_t *ptr, *ptr0; + grub_uint8_t magic[4]; + struct + { + grub_uint8_t code; + grub_uint8_t len; + grub_uint8_t data; + } GRUB_PACKED message_type; + grub_uint8_t end; +} GRUB_PACKED; - ptr = ptr0 = vend; +struct grub_dhcp_request_options +{ + grub_uint8_t magic[4]; + struct + { + grub_uint8_t code; + grub_uint8_t len; + grub_uint8_t data; + } GRUB_PACKED message_type; + struct + { + grub_uint8_t type; + grub_uint8_t len; + grub_uint32_t data; + } GRUB_PACKED server_identifier; + struct + { + grub_uint8_t type; + grub_uint8_t len; + grub_uint32_t data; + } GRUB_PACKED requested_ip; + struct + { + grub_uint8_t type; + grub_uint8_t len; + grub_uint8_t data[7]; + } GRUB_PACKED parameter_request; + grub_uint8_t end; +} GRUB_PACKED; + +enum +{ + GRUB_DHCP_OPT_OVERLOAD_FILE = 1, + GRUB_DHCP_OPT_OVERLOAD_SNAME = 2, +}; +enum +{ + GRUB_DHCP_MESSAGE_UNKNOWN, + GRUB_DHCP_MESSAGE_DISCOVER, + GRUB_DHCP_MESSAGE_OFFER, + GRUB_DHCP_MESSAGE_REQUEST, + GRUB_DHCP_MESSAGE_DECLINE, + GRUB_DHCP_MESSAGE_ACK, + GRUB_DHCP_MESSAGE_NAK, + GRUB_DHCP_MESSAGE_RELEASE, + GRUB_DHCP_MESSAGE_INFORM, +}; + +#define GRUB_BOOTP_MAX_OPTIONS_SIZE 64 + +/* Max timeout when waiting for BOOTP/DHCP reply */ +#define GRUB_DHCP_MAX_PACKET_TIMEOUT 32 + +#define GRUB_BOOTP_MAX_OPTIONS_SIZE 64 + +/* Max timeout when waiting for BOOTP/DHCP reply */ +#define GRUB_DHCP_MAX_PACKET_TIMEOUT 32 + +static char +hexdigit (grub_uint8_t val) +{ + if (val < 10) + return val + '0'; + return val + 'a' - 10; +} + +static const void * +find_dhcp_option (const struct grub_net_bootp_packet *bp, grub_size_t size, + grub_uint8_t opt_code, grub_uint8_t *opt_len) +{ + const grub_uint8_t *ptr; + grub_uint8_t overload = 0; + int end = 0; + grub_size_t i; + + if (opt_len) + *opt_len = 0; + + /* Is the packet big enough to hold at least the magic cookie? */ + if (size < sizeof (*bp) + sizeof (grub_uint32_t)) + return NULL; + + /* + * Pointer arithmetic to point behind the common stub packet, where + * the options start. + */ + ptr = (grub_uint8_t *) (bp + 1); if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) - return; - ptr = ptr + sizeof (grub_uint32_t); - while (ptr - ptr0 < limit) + return NULL; + + size -= sizeof (*bp); + i = sizeof (grub_uint32_t); + +again: + while (i < size) { grub_uint8_t tagtype; grub_uint8_t taglength; - tagtype = *ptr++; + tagtype = ptr[i++]; /* Pad tag. */ if (tagtype == GRUB_NET_BOOTP_PAD) @@ -51,81 +149,78 @@ parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask) /* End tag. */ if (tagtype == GRUB_NET_BOOTP_END) - return; - - taglength = *ptr++; - - switch (tagtype) { - case GRUB_NET_BOOTP_NETMASK: - if (taglength == 4) - { - int i; - for (i = 0; i < 32; i++) - if (!(ptr[i / 8] & (1 << (7 - (i % 8))))) - break; - *mask = i; - } + end = 1; break; - - case GRUB_NET_BOOTP_ROUTER: - if (taglength == 4) - { - grub_net_network_level_netaddress_t target; - grub_net_network_level_address_t gw; - char *rname; - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = 0; - target.ipv4.masksize = 0; - gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - grub_memcpy (&gw.ipv4, ptr, sizeof (gw.ipv4)); - rname = grub_xasprintf ("%s:default", name); - if (rname) - grub_net_add_route_gw (rname, target, gw, NULL); - grub_free (rname); - } - break; - case GRUB_NET_BOOTP_DNS: - { - int i; - for (i = 0; i < taglength / 4; i++) - { - struct grub_net_network_level_address s; - s.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - s.ipv4 = grub_get_unaligned32 (ptr); - s.option = DNS_OPTION_PREFER_IPV4; - grub_net_add_dns_server (&s); - ptr += 4; - } - } - continue; - case GRUB_NET_BOOTP_HOSTNAME: - grub_env_set_net_property (name, "hostname", (const char *) ptr, - taglength); - break; - - case GRUB_NET_BOOTP_DOMAIN: - grub_env_set_net_property (name, "domain", (const char *) ptr, - taglength); - break; - - case GRUB_NET_BOOTP_ROOT_PATH: - grub_env_set_net_property (name, "rootpath", (const char *) ptr, - taglength); - break; - - case GRUB_NET_BOOTP_EXTENSIONS_PATH: - grub_env_set_net_property (name, "extensionspath", (const char *) ptr, - taglength); - break; - - /* If you need any other options please contact GRUB - development team. */ } - ptr += taglength; + if (i >= size) + return NULL; + + taglength = ptr[i++]; + if (i + taglength >= size) + return NULL; + + grub_dprintf("net", "DHCP option %u (0x%02x) found with length %u.\n", + tagtype, tagtype, taglength); + + /* FIXME RFC 3396 options concatentation */ + if (tagtype == opt_code) + { + if (opt_len) + *opt_len = taglength; + return &ptr[i]; + } + + if (tagtype == GRUB_NET_DHCP_OVERLOAD && taglength == 1) + overload = ptr[i]; + + i += taglength; } + + if (!end) + return NULL; + + /* RFC2131, 4.1, 23ff: + * If the options in a DHCP message extend into the 'sname' and 'file' + * fields, the 'option overload' option MUST appear in the 'options' + * field, with value 1, 2 or 3, as specified in RFC 1533. If the + * 'option overload' option is present in the 'options' field, the + * options in the 'options' field MUST be terminated by an 'end' option, + * and MAY contain one or more 'pad' options to fill the options field. + * The options in the 'sname' and 'file' fields (if in use as indicated + * by the 'options overload' option) MUST begin with the first octet of + * the field, MUST be terminated by an 'end' option, and MUST be + * followed by 'pad' options to fill the remainder of the field. Any + * individual option in the 'options', 'sname' and 'file' fields MUST be + * entirely contained in that field. The options in the 'options' field + * MUST be interpreted first, so that any 'option overload' options may + * be interpreted. The 'file' field MUST be interpreted next (if the + * 'option overload' option indicates that the 'file' field contains + * DHCP options), followed by the 'sname' field. + * + * FIXME: We do not explicitly check for trailing 'pad' options here. + */ + end = 0; + if (overload & GRUB_DHCP_OPT_OVERLOAD_FILE) + { + overload &= ~GRUB_DHCP_OPT_OVERLOAD_FILE; + ptr = (grub_uint8_t *) &bp->boot_file[0]; + size = sizeof (bp->boot_file); + i = 0; + goto again; + } + + if (overload & GRUB_DHCP_OPT_OVERLOAD_SNAME) + { + overload &= ~GRUB_DHCP_OPT_OVERLOAD_SNAME; + ptr = (grub_uint8_t *) &bp->server_name[0]; + size = sizeof (bp->server_name); + i = 0; + goto again; + } + + return NULL; } #define OFFSET_OF(x, y) ((grub_size_t)((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y))) @@ -143,9 +238,14 @@ grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_network_level_interface *inter; int mask = -1; char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; + const grub_uint8_t *opt; + grub_uint8_t opt_len, overload = 0; + const char *boot_file = 0, *server_name = 0; + grub_size_t boot_file_len, server_name_len; addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bp->your_ip; + addr.option = 0; if (device) *device = 0; @@ -161,38 +261,36 @@ grub_net_configure_by_dhcp_ack (const char *name, if (!inter) return 0; -#if 0 - /* This is likely based on misunderstanding. gateway_ip refers to - address of BOOTP relay and should not be used after BOOTP transaction - is complete. - See RFC1542, 3.4 Interpretation of the 'giaddr' field - */ - if (bp->gateway_ip) + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_OVERLOAD, &opt_len); + if (opt && opt_len == 1) + overload = *opt; + + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_TFTP_SERVER_NAME, &opt_len); + if (opt && opt_len) { - grub_net_network_level_netaddress_t target; - grub_net_network_level_address_t gw; - char *rname; - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = bp->server_ip; - target.ipv4.masksize = 32; - gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - gw.ipv4 = bp->gateway_ip; - rname = grub_xasprintf ("%s:gw", name); - if (rname) - grub_net_add_route_gw (rname, target, gw); - grub_free (rname); - - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4.base = bp->gateway_ip; - target.ipv4.masksize = 32; - grub_net_add_route (name, target, inter); + server_name = (const char *) opt; + server_name_len = opt_len; + } + else if (size > OFFSET_OF (server_name, bp) && !(overload & GRUB_DHCP_OPT_OVERLOAD_SNAME) && + bp->server_name[0]) + { + server_name = bp->server_name; + server_name_len = sizeof (bp->server_name); + } + + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_BOOTFILE_NAME, &opt_len); + if (opt && opt_len) + { + boot_file = (const char *) opt; + boot_file_len = opt_len; + } + else if (size > OFFSET_OF (boot_file, bp) && !(overload && GRUB_DHCP_OPT_OVERLOAD_FILE) && + bp->boot_file[0]) + { + boot_file = bp->boot_file; + boot_file_len = sizeof (bp->boot_file); } -#endif - if (size > OFFSET_OF (boot_file, bp)) - grub_env_set_net_property (name, "boot_file", bp->boot_file, - sizeof (bp->boot_file)); if (bp->server_ip) { grub_snprintf (server_ip, sizeof (server_ip), "%d.%d.%d.%d", @@ -223,41 +321,137 @@ grub_net_configure_by_dhcp_ack (const char *name, *device = grub_xasprintf ("tftp,%s", server_ip); grub_print_error (); } - if (size > OFFSET_OF (server_name, bp) - && bp->server_name[0]) + + if (server_name) { - grub_env_set_net_property (name, "dhcp_server_name", bp->server_name, - sizeof (bp->server_name)); + grub_env_set_net_property (name, "dhcp_server_name", server_name, server_name_len); if (is_def && !grub_net_default_server) { - grub_net_default_server = grub_strdup (bp->server_name); + grub_net_default_server = grub_strdup (server_name); grub_print_error (); } if (device && !*device) { - *device = grub_xasprintf ("tftp,%s", bp->server_name); + *device = grub_xasprintf ("tftp,%s", server_name); grub_print_error (); } } - if (size > OFFSET_OF (boot_file, bp) && path) + if (boot_file) { - *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); - grub_print_error (); - if (*path) + grub_env_set_net_property (name, "boot_file", boot_file, boot_file_len); + if (path) { - char *slash; - slash = grub_strrchr (*path, '/'); - if (slash) - *slash = 0; - else - **path = 0; + *path = grub_strndup (boot_file, boot_file_len); + grub_print_error (); + if (*path) + { + char *slash; + slash = grub_strrchr (*path, '/'); + if (slash) + *slash = 0; + else + **path = 0; + } } } - if (size > OFFSET_OF (vendor, bp)) - parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask); + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_NETMASK, &opt_len); + if (opt && opt_len == 4) + { + int i; + for (i = 0; i < 32; i++) + if (!(opt[i / 8] & (1 << (7 - (i % 8))))) + break; + mask = i; + } grub_net_add_ipv4_local (inter, mask); - + + /* We do not implement dead gateway detection and the first entry SHOULD + be preferred one */ + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_ROUTER, &opt_len); + if (opt && opt_len && !(opt_len & 3)) + { + grub_net_network_level_netaddress_t target; + grub_net_network_level_address_t gw; + char *rname; + + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4.base = 0; + target.ipv4.masksize = 0; + gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + gw.ipv4 = grub_get_unaligned32 (opt); + rname = grub_xasprintf ("%s:default", name); + if (rname) + grub_net_add_route_gw (rname, target, gw, 0); + grub_free (rname); + } + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_DNS, &opt_len); + if (opt && opt_len && !(opt_len & 3)) + { + int i; + for (i = 0; i < opt_len / 4; i++) + { + struct grub_net_network_level_address s; + + s.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + s.ipv4 = grub_get_unaligned32 (opt); + s.option = DNS_OPTION_PREFER_IPV4; + grub_net_add_dns_server (&s); + opt += 4; + } + } + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_HOSTNAME, &opt_len); + if (opt && opt_len) + grub_env_set_net_property (name, "hostname", (const char *) opt, opt_len); + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_DOMAIN, &opt_len); + if (opt && opt_len) + grub_env_set_net_property (name, "domain", (const char *) opt, opt_len); + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_ROOT_PATH, &opt_len); + if (opt && opt_len) + grub_env_set_net_property (name, "rootpath", (const char *) opt, opt_len); + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_EXTENSIONS_PATH, &opt_len); + if (opt && opt_len) + grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len); + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_CLIENT_ID, &opt_len); + if (opt && opt_len) + grub_env_set_net_property (name, "clientid", (const char *) opt, opt_len); + + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_CLIENT_UUID, &opt_len); + if (opt && opt_len == 17) + { + /* The format is 9cfe245e-d0c8-bd45-a79f-54ea5fbd3d97 */ + char *val; + int i, j = 0; + + opt += 1; + opt_len -= 1; + + val = grub_malloc (2 * opt_len + 4 + 1); + if (!val) + return inter; + + for (i = 0; i < opt_len; i++) + { + val[2 * i + j] = hexdigit (opt[i] >> 4); + val[2 * i + 1 + j] = hexdigit (opt[i] & 0xf); + + if ((i == 3) || (i == 5) || (i == 7) || (i == 9)) + { + j++; + val[2 * i + 1+ j] = '-'; + } + } + grub_env_set_net_property (name, "clientuuid", (char *) val, 2 * opt_len + 4); + grub_free (val); + } + inter->dhcp_ack = grub_malloc (size); if (inter->dhcp_ack) { @@ -270,44 +464,219 @@ grub_net_configure_by_dhcp_ack (const char *name, return inter; } -void -grub_net_process_dhcp (struct grub_net_buff *nb, - struct grub_net_card *card) +static grub_err_t +send_dhcp_packet (struct grub_net_network_level_interface *iface) { - char *name; - struct grub_net_network_level_interface *inf; + grub_err_t err; + struct grub_net_bootp_packet *pack; + struct grub_datetime date; + grub_int64_t t = 0; + struct grub_net_buff *nb; + struct udphdr *udph; + grub_net_network_level_address_t target; + grub_net_link_level_address_t ll_target; - name = grub_xasprintf ("%s:dhcp", card->name); - if (!name) + static struct grub_dhcp_discover_options discover_options = { - grub_print_error (); - return; + { + GRUB_NET_BOOTP_RFC1048_MAGIC_0, + GRUB_NET_BOOTP_RFC1048_MAGIC_1, + GRUB_NET_BOOTP_RFC1048_MAGIC_2, + GRUB_NET_BOOTP_RFC1048_MAGIC_3, + }, + { + GRUB_NET_DHCP_MESSAGE_TYPE, + sizeof (discover_options.message_type.data), + GRUB_DHCP_MESSAGE_DISCOVER, + }, + GRUB_NET_BOOTP_END, + }; + + static struct grub_dhcp_request_options request_options = + { + { + GRUB_NET_BOOTP_RFC1048_MAGIC_0, + GRUB_NET_BOOTP_RFC1048_MAGIC_1, + GRUB_NET_BOOTP_RFC1048_MAGIC_2, + GRUB_NET_BOOTP_RFC1048_MAGIC_3, + }, + { + GRUB_NET_DHCP_MESSAGE_TYPE, + sizeof (request_options.message_type.data), + GRUB_DHCP_MESSAGE_REQUEST, + }, + { + GRUB_NET_DHCP_SERVER_IDENTIFIER, + sizeof (request_options.server_identifier.data), + 0, + }, + { + GRUB_NET_DHCP_REQUESTED_IP_ADDRESS, + sizeof (request_options.requested_ip.data), + 0, + }, + { + GRUB_NET_DHCP_PARAMETER_REQUEST_LIST, + sizeof (request_options.parameter_request.data), + { + GRUB_NET_BOOTP_NETMASK, + GRUB_NET_BOOTP_ROUTER, + GRUB_NET_BOOTP_DNS, + GRUB_NET_BOOTP_DOMAIN, + GRUB_NET_BOOTP_HOSTNAME, + GRUB_NET_BOOTP_ROOT_PATH, + GRUB_NET_BOOTP_EXTENSIONS_PATH, + }, + }, + GRUB_NET_BOOTP_END, + }; + + COMPILE_TIME_ASSERT (sizeof (discover_options) <= GRUB_BOOTP_MAX_OPTIONS_SIZE); + COMPILE_TIME_ASSERT (sizeof (request_options) <= GRUB_BOOTP_MAX_OPTIONS_SIZE); + + nb = grub_netbuff_alloc (sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); + if (!nb) + return grub_errno; + + err = grub_netbuff_reserve (nb, sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); + if (err) + goto out; + + err = grub_netbuff_push (nb, GRUB_BOOTP_MAX_OPTIONS_SIZE); + if (err) + goto out; + + grub_memset (nb->data, 0, GRUB_BOOTP_MAX_OPTIONS_SIZE); + if (!iface->srv_id) + { + grub_memcpy (nb->data, &discover_options, sizeof (discover_options)); } - grub_net_configure_by_dhcp_ack (name, card, - 0, (const struct grub_net_bootp_packet *) nb->data, - (nb->tail - nb->data), 0, 0, 0); - grub_free (name); - if (grub_errno) - grub_print_error (); else { - FOR_NET_NETWORK_LEVEL_INTERFACES(inf) - if (grub_memcmp (inf->name, card->name, grub_strlen (card->name)) == 0 - && grub_memcmp (inf->name + grub_strlen (card->name), - ":dhcp_tmp", sizeof (":dhcp_tmp") - 1) == 0) - { - grub_net_network_level_interface_unregister (inf); - break; - } + struct grub_dhcp_request_options *ro = (struct grub_dhcp_request_options *) nb->data; + + grub_memcpy (nb->data, &request_options, sizeof (request_options)); + /* my_ip and srv_id are stored in network order so do not need conversion. */ + grub_set_unaligned32 (&ro->server_identifier.data, iface->srv_id); + grub_set_unaligned32 (&ro->requested_ip.data, iface->my_ip); } + + err = grub_netbuff_push (nb, sizeof (*pack)); + if (err) + goto out; + + pack = (void *) nb->data; + grub_memset (pack, 0, sizeof (*pack)); + pack->opcode = 1; + pack->hw_type = 1; + pack->hw_len = 6; + err = grub_get_datetime (&date); + if (err || !grub_datetime2unixtime (&date, &t)) + { + grub_errno = GRUB_ERR_NONE; + t = 0; + } + pack->seconds = grub_cpu_to_be16 (t); + if (!iface->srv_id) + iface->xid = pack->ident = grub_cpu_to_be32 (t); + else + pack->ident = iface->xid; + + grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6); + + err = grub_netbuff_push (nb, sizeof (*udph)); + if (err) + goto out; + + udph = (struct udphdr *) nb->data; + udph->src = grub_cpu_to_be16_compile_time (68); + udph->dst = grub_cpu_to_be16_compile_time (67); + udph->chksum = 0; + udph->len = grub_cpu_to_be16 (nb->tail - nb->data); + target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + target.ipv4 = 0xffffffff; + err = grub_net_link_layer_resolve (iface, &target, &ll_target); + if (err) + goto out; + + udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, + &iface->address, + &target); + + err = grub_net_send_ip_packet (iface, &target, &ll_target, nb, + GRUB_NET_IP_UDP); + +out: + grub_netbuff_free (nb); + return err; } -static char -hexdigit (grub_uint8_t val) +/* + * This is called directly from net/ip.c:handle_dgram(), because those + * BOOTP/DHCP packets are a bit special due to their improper + * sender/receiver IP fields. + */ +void +grub_net_process_dhcp (struct grub_net_buff *nb, + struct grub_net_network_level_interface *iface) { - if (val < 10) - return val + '0'; - return val + 'a' - 10; + char *name; + struct grub_net_card *card = iface->card; + const struct grub_net_bootp_packet *bp = (const struct grub_net_bootp_packet *) nb->data; + grub_size_t size = nb->tail - nb->data; + const grub_uint8_t *opt; + grub_uint8_t opt_len, type; + grub_uint32_t srv_id = 0; + + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_MESSAGE_TYPE, &opt_len); + if (opt && opt_len == 1) + type = *opt; + else + type = GRUB_DHCP_MESSAGE_UNKNOWN; + + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_SERVER_IDENTIFIER, &opt_len); + if (opt && opt_len == sizeof (srv_id)) + srv_id = grub_get_unaligned32 (opt); + + /* + * If we received BOOTP reply or DHCPACK, proceed with configuration. + * Otherwise store offered address and server id for later processing + * of DHCPACK. + * xid and srv_id are stored in network order so do not need conversion. + */ + if ((!iface->srv_id && type == GRUB_DHCP_MESSAGE_UNKNOWN) + || (iface->srv_id && type == GRUB_DHCP_MESSAGE_ACK + && bp->ident == iface->xid + && srv_id == iface->srv_id)) + { + name = grub_xasprintf ("%s:dhcp", card->name); + if (!name) + { + grub_print_error (); + return; + } + grub_net_configure_by_dhcp_ack (name, card, 0, bp, size, 0, 0, 0); + grub_free (name); + if (grub_errno) + grub_print_error (); + else + grub_net_network_level_interface_unregister (iface); + } + else if (!iface->srv_id && type == GRUB_DHCP_MESSAGE_OFFER && srv_id) + { + iface->srv_id = srv_id; + iface->my_ip = bp->your_ip; + /* Reset retransmission timer */ + iface->dhcp_tmo = iface->dhcp_tmo_left = 1; + } + else if (iface->srv_id && type == GRUB_DHCP_MESSAGE_NAK + && bp->ident == iface->xid + && srv_id == iface->srv_id) + { + iface->xid = iface->srv_id = iface->my_ip = 0; + /* Reset retransmission timer */ + iface->dhcp_tmo = iface->dhcp_tmo_left = 1; + } } static grub_err_t @@ -315,9 +684,10 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { struct grub_net_network_level_interface *inter; - int num; - grub_uint8_t *ptr; + 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, @@ -334,49 +704,37 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), if (!inter->dhcp_ack) return grub_error (GRUB_ERR_IO, N_("no DHCP info found")); - if (inter->dhcp_acklen <= OFFSET_OF (vendor, inter->dhcp_ack)) + ptr = inter->dhcp_ack->vendor; + + /* This duplicates check in find_dhcp_option to preserve previous error return */ + if (inter->dhcp_acklen < OFFSET_OF (vendor, inter->dhcp_ack) + sizeof (grub_uint32_t) + || ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 + || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 + || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 + || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); num = grub_strtoul (args[2], 0, 0); if (grub_errno) return grub_errno; - ptr = inter->dhcp_ack->vendor; + /* Exclude PAD (0) and END (255) option codes */ + if (num == 0 || num > 254) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid DHCP option code")); - if (ptr[0] != GRUB_NET_BOOTP_RFC1048_MAGIC_0 - || ptr[1] != GRUB_NET_BOOTP_RFC1048_MAGIC_1 - || ptr[2] != GRUB_NET_BOOTP_RFC1048_MAGIC_2 - || ptr[3] != GRUB_NET_BOOTP_RFC1048_MAGIC_3) - return grub_error (GRUB_ERR_IO, N_("no DHCP options found")); - ptr = ptr + sizeof (grub_uint32_t); - while (1) - { - grub_uint8_t tagtype; - - if (ptr >= ((grub_uint8_t *) inter->dhcp_ack) + inter->dhcp_acklen) - return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); - - tagtype = *ptr++; - - /* Pad tag. */ - if (tagtype == 0) - continue; - - /* End tag. */ - if (tagtype == 0xff) - return grub_error (GRUB_ERR_IO, N_("no DHCP option %d found"), num); - - taglength = *ptr++; - - if (tagtype == num) - break; - ptr += taglength; - } + ptr = find_dhcp_option (inter->dhcp_ack, inter->dhcp_acklen, num, &taglength); + if (!ptr) + return grub_error (GRUB_ERR_IO, N_("no DHCP option %u found"), num); if (grub_strcmp (args[3], "string") == 0) { grub_err_t err = GRUB_ERR_NONE; - char *val = 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); @@ -409,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; @@ -441,8 +804,8 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), struct grub_net_network_level_interface *ifaces; grub_size_t ncards = 0; unsigned j = 0; - int interval; grub_err_t err; + unsigned i; FOR_NET_CARDS (card) { @@ -454,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; @@ -471,15 +834,15 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), card->num_ifaces++; if (!ifaces[j].name) { - unsigned i; for (i = 0; i < j; i++) grub_free (ifaces[i].name); grub_free (ifaces); return grub_errno; } ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV; - grub_memcpy (&ifaces[j].hwaddress, &card->default_address, + grub_memcpy (&ifaces[j].hwaddress, &card->default_address, sizeof (ifaces[j].hwaddress)); + ifaces[j].dhcp_tmo = ifaces[j].dhcp_tmo_left = 1; j++; } ifaces[ncards - 1].next = grub_net_network_level_interfaces; @@ -487,82 +850,52 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), grub_net_network_level_interfaces->prev = & ifaces[ncards - 1].next; grub_net_network_level_interfaces = &ifaces[0]; ifaces[0].prev = &grub_net_network_level_interfaces; - for (interval = 200; interval < 10000; interval *= 2) + + /* + * Running DHCP restransmission timer is kept per interface in dhcp_tmo_left. + * When it runs off, dhcp_tmo is increased exponentionally and dhcp_tmo_left + * initialized to it. Max value is 32 which gives approximately 12s total per + * packet timeout assuming 200ms poll tick. Timeout is reset when DHCP OFFER + * is received, so total timeout is 25s in the worst case. + * + * DHCP NAK also resets timer and transaction starts again. + * + * Total wait time is limited to ~25s to prevent endless loop in case of + * permanent NAK + */ + for (i = 0; i < GRUB_DHCP_MAX_PACKET_TIMEOUT * 4; i++) { - int done = 0; + int need_poll = 0; for (j = 0; j < ncards; j++) { - struct grub_net_bootp_packet *pack; - struct grub_datetime date; - grub_int32_t t = 0; - struct grub_net_buff *nb; - struct udphdr *udph; - grub_net_network_level_address_t target; - grub_net_link_level_address_t ll_target; - - if (!ifaces[j].prev) + if (!ifaces[j].prev || + ifaces[j].dhcp_tmo > GRUB_DHCP_MAX_PACKET_TIMEOUT) continue; - nb = grub_netbuff_alloc (sizeof (*pack) + 64 + 128); - if (!nb) + + if (--ifaces[j].dhcp_tmo_left) { - grub_netbuff_free (nb); - return grub_errno; + need_poll = 1; + continue; } - err = grub_netbuff_reserve (nb, sizeof (*pack) + 64 + 128); + + ifaces[j].dhcp_tmo *= 2; + if (ifaces[j].dhcp_tmo > GRUB_DHCP_MAX_PACKET_TIMEOUT) + continue; + + err = send_dhcp_packet (&ifaces[j]); if (err) { - grub_netbuff_free (nb); - return err; + grub_print_error (); + /* To ignore it during next poll */ + ifaces[j].dhcp_tmo = GRUB_DHCP_MAX_PACKET_TIMEOUT + 1; + continue; } - err = grub_netbuff_push (nb, sizeof (*pack) + 64); - if (err) - { - grub_netbuff_free (nb); - return err; - } - pack = (void *) nb->data; - done = 1; - grub_memset (pack, 0, sizeof (*pack) + 64); - pack->opcode = 1; - pack->hw_type = 1; - pack->hw_len = 6; - err = grub_get_datetime (&date); - if (err || !grub_datetime2unixtime (&date, &t)) - { - grub_errno = GRUB_ERR_NONE; - t = 0; - } - pack->ident = grub_cpu_to_be32 (t); - pack->seconds = grub_cpu_to_be16 (t); - - grub_memcpy (&pack->mac_addr, &ifaces[j].hwaddress.mac, 6); - - grub_netbuff_push (nb, sizeof (*udph)); - - udph = (struct udphdr *) nb->data; - udph->src = grub_cpu_to_be16_compile_time (68); - udph->dst = grub_cpu_to_be16_compile_time (67); - udph->chksum = 0; - udph->len = grub_cpu_to_be16 (nb->tail - nb->data); - target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - target.ipv4 = 0xffffffff; - err = grub_net_link_layer_resolve (&ifaces[j], &target, &ll_target); - if (err) - return err; - - udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, - &ifaces[j].address, - &target); - - err = grub_net_send_ip_packet (&ifaces[j], &target, &ll_target, nb, - GRUB_NET_IP_UDP); - grub_netbuff_free (nb); - if (err) - return err; + ifaces[j].dhcp_tmo_left = ifaces[j].dhcp_tmo; + need_poll = 1; } - if (!done) + if (!need_poll) break; - grub_net_poll_cards (interval, 0); + grub_net_poll_cards (200, 0); } err = GRUB_ERR_NONE; @@ -582,7 +915,7 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), return err; } -static grub_command_t cmd_getdhcp, cmd_bootp; +static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp; void grub_bootp_init (void) @@ -590,6 +923,9 @@ grub_bootp_init (void) cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp, N_("[CARD]"), N_("perform a bootp autoconfiguration")); + cmd_dhcp = grub_register_command ("net_dhcp", grub_cmd_bootp, + N_("[CARD]"), + N_("perform a DHCP autoconfiguration")); cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, N_("VAR INTERFACE NUMBER DESCRIPTION"), N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); @@ -600,4 +936,5 @@ grub_bootp_fini (void) { grub_unregister_command (cmd_getdhcp); grub_unregister_command (cmd_bootp); + grub_unregister_command (cmd_dhcp); } diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c 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 a78d164db..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); @@ -153,11 +150,11 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, char *comma_char = 0; char *equal_char = 0; grub_size_t field_counter = 0; - - grub_net_network_level_address_t client_addr, gateway_addr, subnet_mask; - grub_net_link_level_address_t hw_addr; + grub_net_network_level_address_t client_addr = {0, {0}, 0}, gateway_addr = {0, {0}, 0}, subnet_mask = {0, {0}, 0}; + grub_net_link_level_address_t hw_addr = {0, {{0, 0, 0, 0, 0, 0}}}; grub_net_interface_flags_t flags = 0; struct grub_net_network_level_interface *inter = NULL; + grub_uint16_t vlantag = 0; hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; @@ -175,6 +172,11 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, *equal_char = 0; grub_env_set_net_property ((*card)->name, args, equal_char + 1, grub_strlen(equal_char + 1)); + + if ((grub_strcmp (args, "vtag") == 0) && + (grub_strlen (equal_char + 1) == 8)) + vlantag = grub_strtoul (equal_char + 1 + 4, 0, 16); + *equal_char = '='; } else @@ -213,8 +215,9 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, hw_addr.mac, sizeof(hw_addr.mac), 0); inter = grub_net_add_addr ((*card)->name, *card, &client_addr, &hw_addr, flags); + inter->vlantag = vlantag; grub_net_add_ipv4_local (inter, - __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4))); + __builtin_clz (~grub_be_to_cpu32 (subnet_mask.ipv4))); } if (gateway_addr.ipv4 != 0) @@ -314,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"; @@ -347,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; @@ -397,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; @@ -454,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 (); @@ -551,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 c397b1b34..707bbb12c 100644 --- a/grub-core/net/ethernet.c +++ b/grub-core/net/ethernet.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -44,7 +45,7 @@ struct llchdr struct snaphdr { - grub_uint8_t oui[3]; + grub_uint8_t oui[3]; grub_uint16_t type; } GRUB_PACKED; @@ -56,10 +57,17 @@ 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 = grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER); - COMPILE_TIME_ASSERT (sizeof (*eth) < GRUB_NET_MAX_LINK_HEADER_SIZE); + etherhdr_size = sizeof (*eth); + COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); - err = grub_netbuff_push (nb, sizeof (*eth)); + /* Increase ethernet header in case of vlantag */ + if (inf->vlantag != 0) + etherhdr_size += 4; + + err = grub_netbuff_push (nb, etherhdr_size); if (err) return err; eth = (struct etherhdr *) nb->data; @@ -76,6 +84,20 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, return err; inf->card->opened = 1; } + + /* Check and add a vlan-tag if needed. */ + if (inf->vlantag != 0) + { + /* Move eth type to the right */ + grub_memcpy ((char *) nb->data + etherhdr_size - 2, + (char *) nb->data + etherhdr_size - 6, 2); + + /* Add the tag in the middle */ + grub_uint16_t vlan = grub_cpu_to_be16 (inf->vlantag); + grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); + grub_memcpy ((char *) nb->data + etherhdr_size - 4, &vlan, 2); + } + return inf->card->driver->send (inf->card, nb); } @@ -90,10 +112,25 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, grub_net_link_level_address_t hwaddress; grub_net_link_level_address_t src_hwaddress; grub_err_t err; + grub_uint8_t etherhdr_size = sizeof (*eth); + grub_uint16_t vlantag = 0; + + + /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ + /* longer than the original one. The vlantag id is extracted and the header */ + /* is reseted to the original size. */ + if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == grub_cpu_to_be16_compile_time (VLANTAG_IDENTIFIER)) + { + vlantag = grub_be_to_cpu16 (grub_get_unaligned16 (nb->data + etherhdr_size)); + etherhdr_size += 4; + /* Move eth type to the original position */ + grub_memcpy((char *) nb->data + etherhdr_size - 6, + (char *) nb->data + etherhdr_size - 2, 2); + } eth = (struct etherhdr *) nb->data; type = grub_be_to_cpu16 (eth->type); - err = grub_netbuff_pull (nb, sizeof (*eth)); + err = grub_netbuff_pull (nb, etherhdr_size); if (err) return err; @@ -121,13 +158,14 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, { /* ARP packet. */ case GRUB_NET_ETHERTYPE_ARP: - grub_net_arp_receive (nb, card); + grub_net_arp_receive (nb, card, &vlantag); grub_netbuff_free (nb); return GRUB_ERR_NONE; /* IP packet. */ case GRUB_NET_ETHERTYPE_IP: case GRUB_NET_ETHERTYPE_IP6: - return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress); + return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress, + &vlantag); } grub_netbuff_free (nb); return GRUB_ERR_NONE; diff --git a/grub-core/net/http.c b/grub-core/net/http.c 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 aba4f8908..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; @@ -228,12 +229,13 @@ handle_dgram (struct grub_net_buff *nb, grub_net_ip_protocol_t proto, const grub_net_network_level_address_t *source, const grub_net_network_level_address_t *dest, + grub_uint16_t *vlantag, grub_uint8_t ttl) { struct grub_net_network_level_interface *inf = NULL; grub_err_t err; int multicast = 0; - + /* DHCP needs special treatment since we don't know IP yet. */ { struct udphdr *udph; @@ -253,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); @@ -270,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 @@ -278,7 +280,7 @@ handle_dgram (struct grub_net_buff *nb, && grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, sizeof (inf->hwaddress.mac)) == 0) { - grub_net_process_dhcp (nb, inf->card); + grub_net_process_dhcp (nb, inf); grub_netbuff_free (nb); return GRUB_ERR_NONE; } @@ -293,6 +295,15 @@ handle_dgram (struct grub_net_buff *nb, && grub_net_addr_cmp (&inf->address, dest) == 0 && grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0) break; + + /* Verify vlantag id */ + if (inf->card == card && inf->vlantag != *vlantag) + { + grub_dprintf ("net", "invalid vlantag! %x != %x\n", + inf->vlantag, *vlantag); + break; + } + /* Solicited node multicast. */ if (inf->card == card && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6 @@ -304,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) @@ -315,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) @@ -383,7 +394,8 @@ static grub_err_t grub_net_recv_ip4_packets (struct grub_net_buff *nb, struct grub_net_card *card, const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress) + const grub_net_link_level_address_t *src_hwaddress, + grub_uint16_t *vlantag) { struct iphdr *iph = (struct iphdr *) nb->data; grub_err_t err; @@ -428,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); @@ -458,7 +470,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, dest.ipv4 = iph->dest; return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol, - &source, &dest, iph->ttl); + &source, &dest, vlantag, iph->ttl); } for (prev = &reassembles, rsm = *prev; rsm; prev = &rsm->next, rsm = *prev) @@ -501,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) { @@ -594,7 +613,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, dest.ipv4 = dst; return handle_dgram (ret, card, src_hwaddress, - hwaddress, proto, &source, &dest, + hwaddress, proto, &source, &dest, vlantag, ttl); } } @@ -652,7 +671,8 @@ static grub_err_t grub_net_recv_ip6_packets (struct grub_net_buff *nb, struct grub_net_card *card, const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress) + const grub_net_link_level_address_t *src_hwaddress, + grub_uint16_t *vlantag) { struct ip6hdr *iph = (struct ip6hdr *) nb->data; grub_err_t err; @@ -689,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); @@ -703,21 +723,24 @@ grub_net_recv_ip6_packets (struct grub_net_buff *nb, grub_memcpy (dest.ipv6, &iph->dest, sizeof (dest.ipv6)); return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol, - &source, &dest, iph->ttl); + &source, &dest, vlantag, iph->ttl); } grub_err_t grub_net_recv_ip_packets (struct grub_net_buff *nb, struct grub_net_card *card, const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress) + const grub_net_link_level_address_t *src_hwaddress, + grub_uint16_t *vlantag) { struct iphdr *iph = (struct iphdr *) nb->data; if ((iph->verhdrlen >> 4) == 4) - return grub_net_recv_ip4_packets (nb, card, hwaddress, src_hwaddress); + return grub_net_recv_ip4_packets (nb, card, hwaddress, src_hwaddress, + vlantag); if ((iph->verhdrlen >> 4) == 6) - return grub_net_recv_ip6_packets (nb, card, hwaddress, src_hwaddress); + return grub_net_recv_ip6_packets (nb, card, hwaddress, src_hwaddress, + vlantag); grub_dprintf ("net", "Bad IP version: %d\n", (iph->verhdrlen >> 4)); grub_netbuff_free (nb); return GRUB_ERR_NONE; diff --git a/grub-core/net/net.c b/grub-core/net/net.c index 10773fc34..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; @@ -1706,21 +1911,21 @@ grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) static struct grub_fs grub_net_fs = { .name = "netfs", - .dir = grub_net_fs_dir, - .open = grub_net_fs_open, - .read = grub_net_fs_read, - .close = grub_net_fs_close, - .label = NULL, - .uuid = NULL, - .mtime = NULL, + .fs_dir = grub_net_fs_dir, + .fs_open = grub_net_fs_open, + .fs_read = grub_net_fs_read, + .fs_close = grub_net_fs_close, + .fs_label = NULL, + .fs_uuid = NULL, + .fs_mtime = NULL, }; static grub_err_t grub_net_fini_hw (int noreturn __attribute__ ((unused))) { struct grub_net_card *card; - FOR_NET_CARDS (card) - if (card->opened) + 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 7338f8245..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,17 +166,17 @@ grub_username_get (char buf[], unsigned buf_size) while (1) { - key = grub_getkey (); + key = grub_getkey (); if (key == '\n' || key == '\r') break; - if (key == '\e') + if (key == GRUB_TERM_ESC) { cur_len = 0; break; } - if (key == '\b') + if (key == GRUB_TERM_BACKSPACE) { if (cur_len) { @@ -197,7 +201,33 @@ grub_username_get (char buf[], unsigned buf_size) grub_xputs ("\n"); grub_refresh (); - return (key != '\e'); + 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 @@ -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/autofs.c b/grub-core/normal/autofs.c index 721b9c325..7a7cf2b0f 100644 --- a/grub-core/normal/autofs.c +++ b/grub-core/normal/autofs.c @@ -33,12 +33,6 @@ autoload_fs_module (void) { grub_named_list_t p; int ret = 0; - grub_file_filter_t grub_file_filters_was[GRUB_FILE_FILTER_MAX]; - - grub_memcpy (grub_file_filters_was, grub_file_filters_enabled, - sizeof (grub_file_filters_enabled)); - grub_memcpy (grub_file_filters_enabled, grub_file_filters_all, - sizeof (grub_file_filters_enabled)); while ((p = fs_module_list) != NULL) { @@ -56,9 +50,6 @@ autoload_fs_module (void) grub_free (p); } - grub_memcpy (grub_file_filters_enabled, grub_file_filters_was, - sizeof (grub_file_filters_enabled)); - return ret; } @@ -82,7 +73,7 @@ read_fs_list (const char *prefix) tmp_autoload_hook = grub_fs_autoload_hook; grub_fs_autoload_hook = NULL; - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST); if (file) { /* Override previous fs.lst. */ 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 a36180d75..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 (); @@ -626,12 +641,12 @@ grub_cmdline_get (const char *prompt_translated) cl_insert (cl_terms, nterms, &lpos, &llen, &max_len, &buf, kill_buf); break; - case '\e': + case GRUB_TERM_ESC: grub_free (cl_terms); grub_free (buf); return 0; - case '\b': + case GRUB_TERM_BACKSPACE: if (lpos > 0) { lpos--; diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c index 2c9b9e931..18cadfa85 100644 --- a/grub-core/normal/completion.c +++ b/grub-core/normal/completion.c @@ -284,10 +284,11 @@ complete_file (void) /* Cut away the filename part. */ dirfile = grub_strrchr (dir, '/'); - dirfile[1] = '\0'; + if (dirfile) + dirfile[1] = '\0'; /* Iterate the directory. */ - (fs->dir) (dev, dir, iterate_dir, NULL); + (fs->fs_dir) (dev, dir, iterate_dir, NULL); grub_free (dir); @@ -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 2bfd67c8e..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) @@ -94,7 +94,7 @@ read_crypto_list (const char *prefix) return; } - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST); grub_free (filename); if (!file) { @@ -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,19 +142,19 @@ read_crypto_list (const char *prefix) grub_free (cur); continue; } - + cur->modname = grub_strdup (p); if (! cur->modname) { grub_errno = GRUB_ERR_NONE; - grub_free (cur); grub_free (cur->name); + grub_free (cur); continue; } cur->next = crypto_specs; crypto_specs = cur; } - + grub_file_close (file); grub_errno = GRUB_ERR_NONE; diff --git a/grub-core/normal/dyncmd.c b/grub-core/normal/dyncmd.c index 169c126f5..719ebf477 100644 --- a/grub-core/normal/dyncmd.c +++ b/grub-core/normal/dyncmd.c @@ -106,7 +106,7 @@ read_command_list (const char *prefix) { grub_file_t file; - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST); if (file) { char *buf = NULL; diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 78a70a8bf..96abfda2f 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -123,7 +124,7 @@ read_config_file (const char *config) } /* Try to open the config file. */ - rawfile = grub_file_open (config); + rawfile = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); if (! rawfile) return 0; @@ -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 719e2fb1c..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; } @@ -698,7 +701,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) c = grub_getkey_noblock (); - if (c != GRUB_TERM_NO_KEY) + /* Negative values are returned on error. */ + if ((c != GRUB_TERM_NO_KEY) && (c > 0)) { if (timeout >= 0) { @@ -748,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; @@ -763,7 +765,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) *auto_boot = 0; return current_entry; - case '\e': + case GRUB_TERM_ESC: if (nested) { menu_fini (); @@ -785,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; @@ -807,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 @@ -860,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; @@ -869,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 eeeee5580..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 (); @@ -1403,7 +1416,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) goto fail; break; - case '\e': + case GRUB_TERM_ESC: destroy_screen (screen); return; 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 38f91b9b9..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 * @@ -119,10 +119,10 @@ grub_normal_print_device_info (const char *name) if (grub_strcmp (fsname, "ext2") == 0) fsname = "ext*"; grub_printf_ (N_("Filesystem type %s"), fsname); - if (fs->label) + if (fs->fs_label) { char *label; - (fs->label) (dev, &label); + (fs->fs_label) (dev, &label); if (grub_errno == GRUB_ERR_NONE) { if (label && grub_strlen (label)) @@ -134,11 +134,11 @@ grub_normal_print_device_info (const char *name) } grub_errno = GRUB_ERR_NONE; } - if (fs->mtime) + if (fs->fs_mtime) { - grub_int32_t tm; + grub_int64_t tm; struct grub_datetime datetime; - (fs->mtime) (dev, &tm); + (fs->fs_mtime) (dev, &tm); if (grub_errno == GRUB_ERR_NONE) { grub_unixtime2datetime (tm, &datetime); @@ -154,10 +154,10 @@ grub_normal_print_device_info (const char *name) } grub_errno = GRUB_ERR_NONE; } - if (fs->uuid) + if (fs->fs_uuid) { char *uuid; - (fs->uuid) (dev, &uuid); + (fs->fs_uuid) (dev, &uuid); if (grub_errno == GRUB_ERR_NONE) { if (uuid && grub_strlen (uuid)) @@ -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 ac5d69f0f..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) @@ -331,7 +331,7 @@ read_terminal_list (const char *prefix) return; } - file = grub_file_open (filename); + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE_LIST); grub_free (filename); if (!file) { @@ -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 7d99b54b8..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); } @@ -439,36 +437,44 @@ grub_util_get_fd_size (grub_util_fd_t fd, return -1; } -void +int grub_util_fd_close (grub_util_fd_t fd) { switch (fd->type) { case GRUB_UTIL_FD_FILE: - close (fd->fd); - return; + return close (fd->fd); case GRUB_UTIL_FD_DISK: CloseDevice ((struct IORequest *) fd->ioreq); DeleteIORequest((struct IORequest *) fd->ioreq); DeleteMsgPort (fd->mp); - return; + return 0; } + return 0; } static int allow_fd_syncs = 1; -static void +static int grub_util_fd_sync_volume (grub_util_fd_t fd) { + LONG err; + fd->ioreq->iotd_Req.io_Command = CMD_UPDATE; fd->ioreq->iotd_Req.io_Length = 0; fd->ioreq->iotd_Req.io_Data = 0; fd->ioreq->iotd_Req.io_Offset = 0; fd->ioreq->iotd_Req.io_Actual = 0; - DoIO ((struct IORequest *) fd->ioreq); + err = DoIO ((struct IORequest *) fd->ioreq); + if (err) + { + grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ()); + return -1; + } + return 0; } -void +int grub_util_fd_sync (grub_util_fd_t fd) { if (allow_fd_syncs) @@ -476,22 +482,22 @@ grub_util_fd_sync (grub_util_fd_t fd) switch (fd->type) { case GRUB_UTIL_FD_FILE: - fsync (fd->fd); - return; + return fsync (fd->fd); case GRUB_UTIL_FD_DISK: - grub_util_fd_sync_volume (fd); - return; + return grub_util_fd_sync_volume (fd); } } + return 0; } -void +int grub_util_file_sync (FILE *f) { - fflush (f); + if (fflush (f) != 0) + return -1; if (!allow_fd_syncs) - return; - fsync (fileno (f)); + return 0; + return fsync (fileno (f)); } void @@ -564,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 4b5502aeb..68813de9a 100644 --- a/grub-core/osdep/basic/platform.c +++ b/grub-core/osdep/basic/platform.c @@ -18,9 +18,15 @@ #include +const char * +grub_install_get_default_arm_platform (void) +{ + return "arm-uboot"; +} + const char * grub_install_get_default_x86_platform (void) -{ +{ return "i386-pc"; } diff --git a/grub-core/osdep/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 ccc1d7028..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) @@ -338,8 +338,8 @@ grub_util_follow_gpart_up (const char *name, grub_disk_addr_t *off_out, char **n grub_util_follow_gpart_up (name_tmp, &off, name_out); free (name_tmp); LIST_FOREACH (config, &provider->lg_config, lg_config) - if (strcasecmp (config->lg_name, "start") == 0) - off += strtoull (config->lg_val, 0, 10); + if (strcasecmp (config->lg_name, "offset") == 0) + off += strtoull (config->lg_val, 0, 10) / provider->lg_sectorsize; if (off_out) *off_out = off; return; 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 74024fd06..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,8 +83,7 @@ grub_install_get_blocklist (grub_device_t root_dev, grub_disk_cache_invalidate_all (); - grub_file_filter_disable_compression (); - file = grub_file_open (core_path_dev); + 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) @@ -117,13 +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. */ - grub_file_filter_disable_compression (); - file = grub_file_open (core_path_dev); + 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 06179fca7..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. */ @@ -374,7 +336,8 @@ grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int f char dev[PATH_MAX]; grub_disk_addr_t part_start = 0; - part_start = grub_partition_get_start (disk->partition); + part_start = grub_partition_get_start (disk->partition) + >> (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); strncpy (dev, grub_util_biosdisk_get_osdev (disk), sizeof (dev) - 1); dev[sizeof(dev) - 1] = '\0'; @@ -382,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/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c index a79682a5e..a6153d359 100644 --- a/grub-core/osdep/linux/ofpath.c +++ b/grub-core/osdep/linux/ofpath.c @@ -38,6 +38,46 @@ #include #include +#ifdef __sparc__ +typedef enum + { + GRUB_OFPATH_SPARC_WWN_ADDR = 1, + GRUB_OFPATH_SPARC_TGT_LUN, + } ofpath_sparc_addressing; + +struct ofpath_sparc_hba +{ + grub_uint32_t device_id; + ofpath_sparc_addressing addressing; +}; + +static struct ofpath_sparc_hba sparc_lsi_hba[] = { + /* Rhea, Jasper 320, LSI53C1020/1030. */ + {0x30, GRUB_OFPATH_SPARC_TGT_LUN}, + /* SAS-1068E. */ + {0x50, GRUB_OFPATH_SPARC_TGT_LUN}, + /* SAS-1064E. */ + {0x56, GRUB_OFPATH_SPARC_TGT_LUN}, + /* Pandora SAS-1068E. */ + {0x58, GRUB_OFPATH_SPARC_TGT_LUN}, + /* Aspen, Invader, LSI SAS-3108. */ + {0x5d, GRUB_OFPATH_SPARC_TGT_LUN}, + /* Niwot, SAS 2108. */ + {0x79, GRUB_OFPATH_SPARC_TGT_LUN}, + /* Erie, Falcon, LSI SAS 2008. */ + {0x72, GRUB_OFPATH_SPARC_WWN_ADDR}, + /* LSI WarpDrive 6203. */ + {0x7e, GRUB_OFPATH_SPARC_WWN_ADDR}, + /* LSI SAS 2308. */ + {0x87, GRUB_OFPATH_SPARC_WWN_ADDR}, + /* LSI SAS 3008. */ + {0x97, GRUB_OFPATH_SPARC_WWN_ADDR}, + {0, 0} +}; + +static const int LSI_VENDOR_ID = 0x1000; +#endif + #ifdef OFPATH_STANDALONE #define xmalloc malloc void @@ -120,6 +160,8 @@ find_obppath (const char *sysfs_path_orig) #endif fd = open(path, O_RDONLY); + +#ifndef __sparc__ if (fd < 0 || fstat (fd, &st) < 0) { if (fd >= 0) @@ -127,6 +169,7 @@ find_obppath (const char *sysfs_path_orig) snprintf(path, path_size, "%s/devspec", sysfs_path); fd = open(path, O_RDONLY); } +#endif if (fd < 0 || fstat (fd, &st) < 0) { @@ -307,6 +350,55 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi return ret; } +#ifdef __sparc__ +static char * +of_path_of_nvme(const char *sys_devname __attribute__((unused)), + const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) +{ + char *sysfs_path, *of_path, disk[MAX_DISK_CAT]; + const char *digit_string, *part_end; + + digit_string = trailing_digits (device); + part_end = devicenode + strlen (devicenode) - 1; + + if ((*digit_string != '\0') && (*part_end == 'p')) + { + /* We have a partition number, strip it off. */ + int part; + char *nvmedev, *end; + + nvmedev = strdup (devicenode); + + if (!nvmedev) + return NULL; + + end = nvmedev + strlen (nvmedev) - 1; + /* Remove the p. */ + *end = '\0'; + sscanf (digit_string, "%d", &part); + snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); + sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); + free (nvmedev); + } + else + { + /* We do not have the parition. */ + snprintf (disk, sizeof (disk), "/disk@1"); + sysfs_path = block_device_get_sysfs_path_and_link (device); + } + + of_path = find_obppath (sysfs_path); + + if (of_path) + strcat (of_path, disk); + + free (sysfs_path); + return of_path; +} +#endif + static int vendor_is_ATA(const char *path) { @@ -335,6 +427,64 @@ vendor_is_ATA(const char *path) return (memcmp(bufcont, "ATA", 3) == 0); } +#ifdef __sparc__ +static void +check_hba_identifiers (const char *sysfs_path, int *vendor, int *device_id) +{ + char *ed = strstr (sysfs_path, "host"); + size_t path_size; + char *p, *path; + char buf[8]; + int fd; + + if (!ed) + return; + + p = xstrdup (sysfs_path); + ed = strstr (p, "host"); + + *ed = '\0'; + + path_size = (strlen (p) + sizeof ("vendor")); + path = xmalloc (path_size); + + if (!path) + goto out; + + snprintf (path, path_size, "%svendor", p); + fd = open (path, O_RDONLY); + + if (fd < 0) + goto out; + + memset (buf, 0, sizeof (buf)); + + if (read (fd, buf, sizeof (buf) - 1) < 0) + goto out; + + close (fd); + sscanf (buf, "%x", vendor); + + snprintf (path, path_size, "%sdevice", p); + fd = open (path, O_RDONLY); + + if (fd < 0) + goto out; + + memset (buf, 0, sizeof (buf)); + + if (read (fd, buf, sizeof (buf) - 1) < 0) + goto out; + + close (fd); + sscanf (buf, "%x", device_id); + + out: + free (path); + free (p); +} +#endif + static void check_sas (const char *sysfs_path, int *tgt, unsigned long int *sas_address) { @@ -396,7 +546,7 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev { const char *p, *digit_string, *disk_name; int host, bus, tgt, lun; - unsigned long int sas_address; + unsigned long int sas_address = 0; char *sysfs_path, disk[MAX_DISK_CAT - sizeof ("/fp@0,0")]; char *of_path; @@ -413,9 +563,8 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev } of_path = find_obppath(sysfs_path); - free (sysfs_path); if (!of_path) - return NULL; + goto out; if (strstr (of_path, "qlc")) strcat (of_path, "/fp@0,0"); @@ -444,6 +593,46 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev } else { +#ifdef __sparc__ + ofpath_sparc_addressing addressing = GRUB_OFPATH_SPARC_TGT_LUN; + int vendor = 0, device_id = 0; + char *optr = disk; + + check_hba_identifiers (sysfs_path, &vendor, &device_id); + + if (vendor == LSI_VENDOR_ID) + { + struct ofpath_sparc_hba *lsi_hba; + + /* + * Over time different OF addressing schemes have been supported. + * There is no generic addressing scheme that works across + * every HBA. + */ + for (lsi_hba = sparc_lsi_hba; lsi_hba->device_id; lsi_hba++) + if (lsi_hba->device_id == device_id) + { + addressing = lsi_hba->addressing; + break; + } + } + + if (addressing == GRUB_OFPATH_SPARC_WWN_ADDR) + optr += snprintf (disk, sizeof (disk), "/%s@w%lx,%x", disk_name, + sas_address, lun); + else + optr += snprintf (disk, sizeof (disk), "/%s@%x,%x", disk_name, tgt, + lun); + + if (*digit_string != '\0') + { + int part; + + sscanf (digit_string, "%d", &part); + snprintf (optr, sizeof (disk) - (optr - disk - 1), ":%c", 'a' + + (part - 1)); + } +#else if (lun == 0) { int sas_id = 0; @@ -491,8 +680,12 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev } free (lunstr); } +#endif } strcat(of_path, disk); + + out: + free (sysfs_path); return of_path; } @@ -537,6 +730,11 @@ grub_util_devname_to_ofpath (const char *sys_devname) /* All the models I've seen have a devalias "floppy". New models have no floppy at all. */ ofpath = xstrdup ("floppy"); +#ifdef __sparc__ + else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm' + && device[3] == 'e') + ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode); +#endif else { grub_util_warn (_("unknown device type %s"), device); diff --git a/grub-core/osdep/linux/platform.c b/grub-core/osdep/linux/platform.c index 775b6c031..e28a79dab 100644 --- a/grub-core/osdep/linux/platform.c +++ b/grub-core/osdep/linux/platform.c @@ -97,15 +97,16 @@ read_platform_size (void) return ret; } -const char * -grub_install_get_default_x86_platform (void) -{ +/* Are we running on an EFI-based system? */ +static int +is_efi_system (void) +{ /* - On Linux, we need the efivars kernel modules. - If no EFI is available this module just does nothing - besides a small hello and if we detect efi we'll load it - anyway later. So it should be safe to - try to load it here. + * Linux uses efivarfs (mounted on /sys/firmware/efi/efivars) to access the + * EFI variable store. Some legacy systems may still use the deprecated + * efivars interface (accessed through /sys/firmware/efi/vars). Where both + * are present, libefivar will use the former in preference, so attempting + * to load efivars will not interfere with later operations. */ grub_util_exec_redirect_all ((const char * []){ "modprobe", "efivars", NULL }, NULL, NULL, "/dev/null"); @@ -114,13 +115,36 @@ grub_install_get_default_x86_platform (void) if (is_not_empty_directory ("/sys/firmware/efi")) { grub_util_info ("...found"); + return 1; + } + else + { + grub_util_info ("... not found"); + return 0; + } +} + +const char * +grub_install_get_default_arm_platform (void) +{ + if (is_efi_system()) + return "arm-efi"; + else + return "arm-uboot"; +} + +const char * +grub_install_get_default_x86_platform (void) +{ + if (is_efi_system()) + { if (read_platform_size() == 64) return "x86_64-efi"; else return "i386-efi"; } - grub_util_info ("... not found. Looking for /proc/device-tree .."); + grub_util_info ("Looking for /proc/device-tree .."); if (is_not_empty_directory ("/proc/device-tree")) { grub_util_info ("...found"); 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 935ff120e..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 (); @@ -99,7 +99,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, { fd = open (stdin_file, O_RDONLY); if (fd < 0) - exit (127); + _exit (127); dup2 (fd, STDIN_FILENO); close (fd); } @@ -108,7 +108,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, { fd = open (stdout_file, O_WRONLY | O_CREAT, 0700); if (fd < 0) - exit (127); + _exit (127); dup2 (fd, STDOUT_FILENO); close (fd); } @@ -117,7 +117,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, { fd = open (stderr_file, O_WRONLY | O_CREAT, 0700); if (fd < 0) - exit (127); + _exit (127); dup2 (fd, STDERR_FILENO); close (fd); } @@ -126,7 +126,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, setenv ("LC_ALL", "C", 1); execvp ((char *) argv[0], (char **) argv); - exit (127); + _exit (127); } waitpid (pid, &status, 0); if (!WIFEXITED (status)) @@ -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 4bf37b027..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 @@ -34,6 +34,7 @@ #ifdef HAVE_LIMITS_H #include #endif + #include #include @@ -50,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 @@ -113,6 +109,8 @@ #include #endif +#include "save-cwd.h" + #if !defined (__GNU__) static void strip_extra_slashes (char *dir) @@ -160,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; @@ -176,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; @@ -231,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) @@ -259,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) @@ -307,7 +306,7 @@ grub_util_find_root_devices_from_poolname (char *poolname) } break; } - + free (line); } @@ -352,7 +351,7 @@ char * grub_find_device (const char *dir, dev_t dev) { DIR *dp; - char *saved_cwd; + struct saved_cwd saved_cwd; struct dirent *ent; if (! dir) @@ -362,12 +361,17 @@ grub_find_device (const char *dir, dev_t dev) if (! dp) return 0; - saved_cwd = xgetcwd (); + if (save_cwd (&saved_cwd) < 0) + { + grub_util_error ("%s", _("cannot save the original directory")); + closedir (dp); + return 0; + } grub_util_info ("changing current directory to %s", dir); if (chdir (dir) < 0) { - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return 0; } @@ -410,11 +414,11 @@ grub_find_device (const char *dir, dev_t dev) if (res) { - if (chdir (saved_cwd) < 0) + if (restore_cwd (&saved_cwd) < 0) grub_util_error ("%s", _("cannot restore the original directory")); - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return res; } @@ -428,8 +432,11 @@ grub_find_device (const char *dir, dev_t dev) { #ifdef __linux__ /* Skip device names like /dev/dm-0, which are short-hand aliases - to more descriptive device names, e.g. those under /dev/mapper */ - if (ent->d_name[0] == 'd' && + to more descriptive device names, e.g. those under /dev/mapper. + Also, don't skip devices which names start with dm-[0-9] in + directories below /dev, e.g. /dev/mapper/dm-0-luks. */ + if (strcmp (dir, "/dev") == 0 && + ent->d_name[0] == 'd' && ent->d_name[1] == 'm' && ent->d_name[2] == '-' && ent->d_name[3] >= '0' && @@ -443,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", @@ -465,19 +472,19 @@ grub_find_device (const char *dir, dev_t dev) continue; } - if (chdir (saved_cwd) < 0) + if (restore_cwd (&saved_cwd) < 0) grub_util_error ("%s", _("cannot restore the original directory")); - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return res; } } - if (chdir (saved_cwd) < 0) + if (restore_cwd (&saved_cwd) < 0) grub_util_error ("%s", _("cannot restore the original directory")); - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return 0; } @@ -533,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 2a8c5882e..3a00d7451 100644 --- a/grub-core/osdep/unix/hostdisk.c +++ b/grub-core/osdep/unix/hostdisk.c @@ -77,11 +77,19 @@ grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsiz int grub_util_fd_seek (grub_util_fd_t fd, grub_uint64_t off) { +#if SIZEOF_OFF_T == 8 off_t offset = (off_t) off; if (lseek (fd, offset, SEEK_SET) != offset) return -1; +#elif SIZEOF_OFF64_T == 8 + off64_t offset = (off64_t) off; + if (lseek64 (fd, offset, SEEK_SET) != offset) + return -1; +#else +#error "No large file support" +#endif return 0; } @@ -156,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); } @@ -169,20 +180,22 @@ grub_util_fd_strerror (void) static int allow_fd_syncs = 1; -void +int grub_util_fd_sync (grub_util_fd_t fd) { if (allow_fd_syncs) - fsync (fd); + return fsync (fd); + return 0; } -void +int grub_util_file_sync (FILE *f) { - fflush (f); + if (fflush (f) != 0) + return -1; if (!allow_fd_syncs) - return; - fsync (fileno (f)); + return 0; + return fsync (fileno (f)); } void @@ -191,10 +204,10 @@ grub_util_disable_fd_syncs (void) allow_fd_syncs = 0; } -void +int grub_util_fd_close (grub_util_fd_t fd) { - close (fd); + return close (fd); } char * diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c index a3fcfcaca..de712211c 100644 --- a/grub-core/osdep/unix/platform.c +++ b/grub-core/osdep/unix/platform.c @@ -78,19 +78,20 @@ get_ofpathname (const char *dev) dev); } -static void +static int grub_install_remove_efi_entries_by_distributor (const char *efi_distributor) { int fd; pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd); char *line = NULL; size_t len = 0; + int rc = 0; if (!pid) { grub_util_warn (_("Unable to open stream from %s: %s"), "efibootmgr", strerror (errno)); - return; + return errno; } FILE *fp = fdopen (fd, "r"); @@ -98,7 +99,7 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor) { grub_util_warn (_("Unable to open stream from %s: %s"), "efibootmgr", strerror (errno)); - return; + return errno; } line = xmalloc (80); @@ -119,23 +120,25 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor) bootnum = line + sizeof ("Boot") - 1; bootnum[4] = '\0'; if (!verbosity) - grub_util_exec ((const char * []){ "efibootmgr", "-q", + rc = grub_util_exec ((const char * []){ "efibootmgr", "-q", "-b", bootnum, "-B", NULL }); else - grub_util_exec ((const char * []){ "efibootmgr", + rc = grub_util_exec ((const char * []){ "efibootmgr", "-b", bootnum, "-B", NULL }); } free (line); + return rc; } -void +int grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, const char *efi_distributor) { const char * efidir_disk; int efidir_part; + int ret; efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk); efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1; @@ -151,23 +154,26 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL }); #endif /* Delete old entries from the same distributor. */ - grub_install_remove_efi_entries_by_distributor (efi_distributor); + ret = grub_install_remove_efi_entries_by_distributor (efi_distributor); + if (ret) + return ret; char *efidir_part_str = xasprintf ("%d", efidir_part); if (!verbosity) - grub_util_exec ((const char * []){ "efibootmgr", "-q", + 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 - grub_util_exec ((const char * []){ "efibootmgr", + 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; } void @@ -229,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 85507af88..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 { @@ -275,11 +273,18 @@ grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len) static int allow_fd_syncs = 1; -void +int grub_util_fd_sync (grub_util_fd_t fd) { if (allow_fd_syncs) - FlushFileBuffers (fd); + { + if (!FlushFileBuffers (fd)) + { + grub_util_info ("flush err %x", (int) GetLastError ()); + return -1; + } + } + return 0; } void @@ -288,10 +293,15 @@ grub_util_disable_fd_syncs (void) allow_fd_syncs = 0; } -void +int grub_util_fd_close (grub_util_fd_t fd) { - CloseHandle (fd); + if (!CloseHandle (fd)) + { + grub_util_info ("close err %x", (int) GetLastError ()); + return -1; + } + return 0; } const char * @@ -339,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; } @@ -347,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); @@ -387,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] = '*'; @@ -510,7 +520,7 @@ get_temp_name (void) *ptr++ = '0' + r; else *ptr++ = 'a' + (r - 10); - } + } *ptr = '\0'; return grub_util_tchar_to_utf8 (rt); @@ -594,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); } @@ -620,16 +630,25 @@ grub_util_fopen (const char *path, const char *mode) return ret; } -void +int grub_util_file_sync (FILE *f) { HANDLE hnd; - fflush (f); + if (fflush (f) != 0) + { + grub_util_info ("fflush err %x", (int) GetLastError ()); + return -1; + } if (!allow_fd_syncs) - return; + return 0; hnd = (HANDLE) _get_osfhandle (fileno (f)); - FlushFileBuffers (hnd); + if (!FlushFileBuffers (hnd)) + { + grub_util_info ("flush err %x", (int) GetLastError ()); + return -1; + } + return 0; } int 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 912269191..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 (); @@ -201,7 +201,7 @@ set_efi_variable_bootn (grub_uint16_t n, void *in, grub_size_t len) set_efi_variable (varname, in, len); } -void +int grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, const char *efi_distributor) @@ -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); @@ -363,7 +363,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, grub_util_error ("%s", grub_errmsg); efidir_grub_dev->disk->partition = p; grub_memcpy (hddp->partition_signature, - gptdata.guid, 16); + &gptdata.guid, 16); hddp->partmap_type = 2; hddp->signature_type = 2; @@ -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]; @@ -407,6 +417,8 @@ grub_install_register_efi (grub_device_t efidir_grub_dev, set_efi_variable_bootn (order_num, entry, (grub_uint8_t *) pathptr - entry); set_efi_variable (L"BootOrder", new_boot_order, new_boot_order_len * sizeof (grub_uint16_t)); + + return 0; } void 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 83bcba779..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_type_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_type_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 6d4b455a1..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") }; @@ -175,9 +175,9 @@ grub_partition_msdos_iterate (grub_disk_t disk, e = mbr.entries + p.index; p.start = p.offset - + (grub_le_to_cpu32 (e->start) + + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)) - delta; - p.len = grub_le_to_cpu32 (e->length) + p.len = (grub_uint64_t)grub_le_to_cpu32 (e->length) << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); p.msdostype = e->type; @@ -210,7 +210,7 @@ grub_partition_msdos_iterate (grub_disk_t disk, if (grub_msdos_partition_is_extended (e->type)) { p.offset = ext_offset - + (grub_le_to_cpu32 (e->start) + + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); if (! ext_offset) ext_offset = p.offset; @@ -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; @@ -294,9 +295,9 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, if (!grub_msdos_partition_is_empty (e->type) && end > offset - + (grub_le_to_cpu32 (e->start) + + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS))) - end = offset + (grub_le_to_cpu32 (e->start) + end = offset + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); /* If this is a GPT partition, this MBR is just a dummy. */ @@ -311,8 +312,8 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, if (grub_msdos_partition_is_extended (e->type)) { - offset = ext_offset - + (grub_le_to_cpu32 (e->start) + offset = ext_offset + + ((grub_disk_addr_t)grub_le_to_cpu32 (e->start) << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); if (! ext_offset) ext_offset = offset; @@ -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 a8502d907..da99dfa05 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -27,15 +27,24 @@ #include #include #include +#include /* Max digits for a char is 3 (0xFF is 255), similarly for an int it is sizeof (int) * 3, and one extra for a possible -ve sign. */ #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) +/* + * A limit on recursion, to avoid colliding with the heap. UEFI defines a baseline + * stack size of 128 KiB. So, assuming at most 1-2 KiB per iteration this should + * keep us safe. + */ +#define MAX_RECURSION_DEPTH 64 + static unsigned long is_continue; static unsigned long active_loops; static unsigned long active_breaks; static unsigned long function_return; +static unsigned long recursion_depth; #define GRUB_SCRIPT_SCOPE_MALLOCED 1 #define GRUB_SCRIPT_SCOPE_ARGS_MALLOCED 2 @@ -121,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) @@ -153,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) @@ -214,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) @@ -484,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); @@ -552,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; @@ -623,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)) @@ -748,6 +760,9 @@ cleanup: } } + if (result.args == NULL || result.argc == 0) + goto fail; + if (! result.args[result.argc - 1]) result.argc--; @@ -784,7 +799,7 @@ cleanup: grub_free (expansions[j]); } grub_free (expansions); - + if (failed) { grub_script_argv_free (&unexpanded); @@ -812,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); @@ -837,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; @@ -891,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); } @@ -929,16 +955,37 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_err_t ret = 0; grub_script_function_t func = 0; char errnobuf[18]; - char *cmdname; - int argc; + char *cmdname, *cmdstring; + int argc, offset = 0, cmdlen = 0; + unsigned int i; char **args; int invert; struct grub_script_argv argv = { 0, 0, 0 }; /* Lookup the command. */ - if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[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++) + { + cmdlen += grub_strlen (argv.args[i]) + 1; + } + + cmdstring = grub_malloc (cmdlen); + if (!cmdstring) + { + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + N_("cannot allocate command buffer")); + } + + for (i = 0; i < argv.argc; i++) + { + offset += grub_snprintf (cmdstring + offset, cmdlen - offset, "%s ", + argv.args[i]); + } + cmdstring[cmdlen - 1] = '\0'; + grub_verify_string (cmdstring, GRUB_VERIFY_COMMAND); + grub_free (cmdstring); invert = 0; argc = argv.argc - 1; args = argv.args + 1; @@ -1163,4 +1210,3 @@ grub_script_execute (struct grub_script *script) return grub_script_execute_cmd (script->cmd); } - 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 95b219170..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) \ @@ -91,7 +91,7 @@ typedef size_t yy_size_t; #define stdin 0 #define stdout 0 -#define fprintf(...) 0 +#define fprintf(...) (void)0 #define exit(...) grub_fatal("fatal error in lexer") #endif 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 new file mode 100644 index 000000000..a17e49c32 --- /dev/null +++ b/grub-core/term/arm/cros.c @@ -0,0 +1,125 @@ +/* + * GRUB -- GRand Unified Bootloader + * + * Copyright (C) 2012 Google Inc. + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * This is based on depthcharge code. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct grub_ps2_state ps2_state; + +struct grub_cros_ec_keyscan old_scan; + +static const struct grub_fdtbus_dev *cros_ec; + +static grub_uint8_t map_code[GRUB_CROS_EC_KEYSCAN_COLS][GRUB_CROS_EC_KEYSCAN_ROWS]; + +static grub_uint8_t e0_translate[16] = + { + 0x1c, 0x1d, 0x35, 0x00, + 0x38, 0x00, 0x47, 0x48, + 0x49, 0x4b, 0x4d, 0x4f, + 0x50, 0x51, 0x52, 0x53, + }; + +/* If there is a character pending, return it; + otherwise return GRUB_TERM_NO_KEY. */ +static int +grub_cros_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) +{ + struct grub_cros_ec_keyscan scan; + int i, j; + if (grub_cros_ec_scan_keyboard (cros_ec, &scan) < 0) + return GRUB_TERM_NO_KEY; + for (i = 0; i < GRUB_CROS_EC_KEYSCAN_COLS; i++) + if (scan.data[i] ^ old_scan.data[i]) + for (j = 0; j < GRUB_CROS_EC_KEYSCAN_ROWS; j++) + if ((scan.data[i] ^ old_scan.data[i]) & (1 << j)) + { + grub_uint8_t code = map_code[i][j]; + int ret; + grub_uint8_t brk = 0; + if (!(scan.data[i] & (1 << j))) + brk = 0x80; + grub_dprintf ("cros_keyboard", "key <%d, %d> code %x\n", i, j, code); + if (code < 0x60) + ret = grub_ps2_process_incoming_byte (&ps2_state, code | brk); + else if (code >= 0x60 && code < 0x70 && e0_translate[code - 0x60]) + { + grub_ps2_process_incoming_byte (&ps2_state, 0xe0); + ret = grub_ps2_process_incoming_byte (&ps2_state, e0_translate[code - 0x60] | brk); + } + else + ret = GRUB_TERM_NO_KEY; + old_scan.data[i] ^= (1 << j); + if (ret != GRUB_TERM_NO_KEY) + return ret; + } + return GRUB_TERM_NO_KEY; +} + +static struct grub_term_input grub_cros_keyboard_term = + { + .name = "cros_keyboard", + .getkey = grub_cros_keyboard_getkey + }; + +static grub_err_t +cros_attach (const struct grub_fdtbus_dev *dev) +{ + grub_size_t keymap_size, i; + const grub_uint8_t *keymap = grub_fdtbus_get_prop (dev, "linux,keymap", &keymap_size); + + if (!dev->parent || !grub_cros_ec_validate (dev->parent)) + return GRUB_ERR_IO; + + if (keymap) + { + for (i = 0; i + 3 < keymap_size; i += 4) + if (keymap[i+1] < GRUB_CROS_EC_KEYSCAN_COLS && keymap[i] < GRUB_CROS_EC_KEYSCAN_ROWS + && keymap[i+2] == 0 && keymap[i+3] < 0x80) + map_code[keymap[i+1]][keymap[i]] = keymap[i+3]; + } + + cros_ec = dev->parent; + ps2_state.current_set = 1; + ps2_state.at_keyboard_status = 0; + grub_term_register_input ("cros_keyboard", &grub_cros_keyboard_term); + return GRUB_ERR_NONE; +} + +static struct grub_fdtbus_driver cros = +{ + .compatible = "google,cros-ec-keyb", + .attach = cros_attach +}; + +void +grub_cros_init (void) +{ + grub_fdtbus_register (&cros); +} diff --git a/grub-core/term/arm/cros_ec.c b/grub-core/term/arm/cros_ec.c new file mode 100644 index 000000000..f4144818b --- /dev/null +++ b/grub-core/term/arm/cros_ec.c @@ -0,0 +1,238 @@ +/* + * GRUB -- GRand Unified Bootloader + * + * Copyright (C) 2012 Google Inc. + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * This is based on depthcharge code. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static const grub_uint64_t FRAMING_TIMEOUT_MS = 300; + +static const grub_uint8_t EC_FRAMING_BYTE = 0xec; + +#define EC_CMD_MKBP_STATE 0x60 +#define EC_CMD_VERSION0 0xdc + +static grub_uint64_t last_transfer; + +static void +stop_bus (const struct grub_fdtbus_dev *spi) +{ + spi->driver->stop (spi); + last_transfer = grub_get_time_ms (); +} + +static int +wait_for_frame (const struct grub_fdtbus_dev *spi) +{ + grub_uint64_t start = grub_get_time_ms (); + grub_uint8_t byte; + do + { + if (spi->driver->receive (spi, &byte, 1)) + return -1; + if (byte != EC_FRAMING_BYTE && + grub_get_time_ms () - start > FRAMING_TIMEOUT_MS) + { + grub_dprintf ("cros", "Timeout waiting for framing byte.\n"); + return -1; + } + } + while (byte != EC_FRAMING_BYTE); + return 0; +} + +/* + * Calculate a simple 8-bit checksum of a data block + * + * @param data Data block to checksum + * @param size Size of data block in bytes + * @return checksum value (0 to 255) + */ +static grub_uint8_t +cros_ec_calc_checksum (const void *data, int size) +{ + grub_uint8_t csum; + const grub_uint8_t *bytes = data; + int i; + + for (i = csum = 0; i < size; i++) + csum += bytes[i]; + return csum & 0xff; +} + +enum +{ + /* response, arglen */ + CROS_EC_SPI_IN_HDR_SIZE = 2, + /* version, cmd, arglen */ + CROS_EC_SPI_OUT_HDR_SIZE = 3 +}; + +static grub_uint8_t busbuf[256]; +#define MSG_BYTES ((int)sizeof (busbuf)) + +static int +ec_command (const struct grub_fdtbus_dev *dev, int cmd, int cmd_version, + const void *dout, int dout_len, void *din, int din_len) +{ + const struct grub_fdtbus_dev *spi = dev->parent; + grub_uint8_t *bytes; + + /* Header + data + checksum. */ + grub_uint32_t out_bytes = CROS_EC_SPI_OUT_HDR_SIZE + dout_len + 1; + grub_uint32_t in_bytes = CROS_EC_SPI_IN_HDR_SIZE + din_len + 1; + + /* + * Sanity-check I/O sizes given transaction overhead in internal + * buffers. + */ + if (out_bytes > MSG_BYTES) + { + grub_dprintf ("cros", "Cannot send %d bytes\n", dout_len); + return -1; + } + if (in_bytes > MSG_BYTES) + { + grub_dprintf ("cros", "Cannot receive %d bytes\n", din_len); + return -1; + } + + /* Prepare the output. */ + bytes = busbuf; + *bytes++ = EC_CMD_VERSION0 + cmd_version; + *bytes++ = cmd; + *bytes++ = dout_len; + grub_memcpy (bytes, dout, dout_len); + bytes += dout_len; + + *bytes++ = cros_ec_calc_checksum (busbuf, + CROS_EC_SPI_OUT_HDR_SIZE + dout_len); + + /* Depthcharge uses 200 us here but GRUB timer resolution is only 1ms, + decrease this when we increase timer resolution. */ + while (grub_get_time_ms () - last_transfer < 1) + ; + + if (spi->driver->start (spi)) + return -1; + + /* Allow EC to ramp up clock after being awoken. */ + /* Depthcharge only waits 100 us here but GRUB timer resolution is only 1ms, + decrease this when we increase timer resolution. */ + grub_millisleep (1); + + if (spi->driver->send (spi, busbuf, out_bytes)) + { + stop_bus (spi); + return -1; + } + + /* Wait until the EC is ready. */ + if (wait_for_frame (spi)) + { + stop_bus (spi); + return -1; + } + + /* Read the response code and the data length. */ + bytes = busbuf; + if (spi->driver->receive (spi, bytes, 2)) + { + stop_bus (spi); + return -1; + } + grub_uint8_t result = *bytes++; + grub_uint8_t length = *bytes++; + + /* Make sure there's enough room for the data. */ + if (CROS_EC_SPI_IN_HDR_SIZE + length + 1 > MSG_BYTES) + { + grub_dprintf ("cros", "Received length %#02x too large\n", length); + stop_bus (spi); + return -1; + } + + /* Read the data and the checksum, and finish up. */ + if (spi->driver->receive (spi, bytes, length + 1)) + { + stop_bus (spi); + return -1; + } + bytes += length; + int expected = *bytes++; + stop_bus (spi); + + /* Check the integrity of the response. */ + if (result != 0) + { + grub_dprintf ("cros", "Received bad result code %d\n", result); + return -result; + } + + int csum = cros_ec_calc_checksum (busbuf, + CROS_EC_SPI_IN_HDR_SIZE + length); + + if (csum != expected) + { + grub_dprintf ("cros", "Invalid checksum rx %#02x, calced %#02x\n", + expected, csum); + return -1; + } + + /* If the caller wants the response, copy it out for them. */ + if (length < din_len) + din_len = length; + if (din) + { + grub_memcpy (din, (grub_uint8_t *) busbuf + CROS_EC_SPI_IN_HDR_SIZE, din_len); + } + + return din_len; +} + +int +grub_cros_ec_scan_keyboard (const struct grub_fdtbus_dev *dev, struct grub_cros_ec_keyscan *scan) +{ + if (ec_command (dev, EC_CMD_MKBP_STATE, 0, NULL, 0, scan, + sizeof (*scan)) < (int) sizeof (*scan)) + return -1; + + return 0; +} + +int +grub_cros_ec_validate (const struct grub_fdtbus_dev *dev) +{ + if (!grub_fdtbus_is_compatible("google,cros-ec-spi", dev)) + return 0; + if (!dev->parent) + return 0; + if (!dev->parent->driver) + return 0; + if (!dev->parent->driver->send + || !dev->parent->driver->receive) + return 0; + return 1; +} + diff --git a/grub-core/term/arm/pl050.c b/grub-core/term/arm/pl050.c new file mode 100644 index 000000000..b082243b0 --- /dev/null +++ b/grub-core/term/arm/pl050.c @@ -0,0 +1,189 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile grub_uint32_t *pl050_regs; + +static struct grub_ps2_state ps2_state; + +static void +keyboard_controller_wait_until_ready (void) +{ + while (! (pl050_regs[1] & 0x40)); +} + +static grub_uint8_t +wait_ack (void) +{ + grub_uint64_t endtime; + grub_uint8_t ack; + + endtime = grub_get_time_ms () + 20; + do + ack = pl050_regs[2]; + while (ack != GRUB_AT_ACK && ack != GRUB_AT_NACK + && grub_get_time_ms () < endtime); + return ack; +} + + +static int +write_mode (int mode) +{ + unsigned i; + for (i = 0; i < GRUB_AT_TRIES; i++) + { + grub_uint8_t ack; + keyboard_controller_wait_until_ready (); + pl050_regs[2] = 0xf0; + keyboard_controller_wait_until_ready (); + pl050_regs[2] = mode; + keyboard_controller_wait_until_ready (); + ack = wait_ack (); + if (ack == GRUB_AT_NACK) + continue; + if (ack == GRUB_AT_ACK) + break; + return 0; + } + + return (i != GRUB_AT_TRIES); +} + +static int +query_mode (void) +{ + grub_uint8_t ret; + int e; + + e = write_mode (0); + if (!e) + return 0; + + keyboard_controller_wait_until_ready (); + + do + ret = pl050_regs[2]; + while (ret == GRUB_AT_ACK); + + /* QEMU translates the set even in no-translate mode. */ + if (ret == 0x43 || ret == 1) + return 1; + if (ret == 0x41 || ret == 2) + return 2; + if (ret == 0x3f || ret == 3) + return 3; + return 0; +} + +static void +set_scancodes (void) +{ + write_mode (2); + ps2_state.current_set = query_mode (); + grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); + if (ps2_state.current_set == 2) + return; + + write_mode (1); + ps2_state.current_set = query_mode (); + grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); + if (ps2_state.current_set == 1) + return; + grub_dprintf ("atkeyb", "no supported scancode set found\n"); +} + +static void +keyboard_controller_led (grub_uint8_t leds) +{ + keyboard_controller_wait_until_ready (); + pl050_regs[2] = 0xed; + keyboard_controller_wait_until_ready (); + pl050_regs[2] = leds & 0x7; +} + +/* If there is a character pending, return it; + otherwise return GRUB_TERM_NO_KEY. */ +static int +grub_pl050_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) +{ + grub_uint8_t at_key; + int ret; + grub_uint8_t old_led; + + if (!(pl050_regs[1] & 0x10)) + return -1; + at_key = pl050_regs[2]; + old_led = ps2_state.led_status; + + ret = grub_ps2_process_incoming_byte (&ps2_state, at_key); + if (old_led != ps2_state.led_status) + keyboard_controller_led (ps2_state.led_status); + return ret; +} + +static struct grub_term_input grub_pl050_keyboard_term = + { + .name = "pl050_keyboard", + .getkey = grub_pl050_keyboard_getkey + }; + +static grub_err_t +pl050_attach(const struct grub_fdtbus_dev *dev) +{ + const grub_uint32_t *reg; + reg = grub_fdtbus_get_prop (dev, "reg", 0); + + /* Mouse. Nothing to do. */ + if (grub_be_to_cpu32 (*reg) == 0x7000) + return 0; + + pl050_regs = grub_fdtbus_map_reg (dev, 0, 0); + + if (!grub_fdtbus_is_mapping_valid (pl050_regs)) + return grub_error (GRUB_ERR_IO, "could not map pl050"); + + ps2_state.at_keyboard_status = 0; + set_scancodes (); + keyboard_controller_led (ps2_state.led_status); + + grub_term_register_input ("pl050_keyboard", &grub_pl050_keyboard_term); + return GRUB_ERR_NONE; +} + +struct grub_fdtbus_driver pl050 = +{ + .compatible = "arm,pl050", + .attach = pl050_attach +}; + +void +grub_pl050_init (void) +{ + grub_fdtbus_register (&pl050); +} diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index b4ea9ff7e..f8a129eb7 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -22,216 +22,37 @@ #include #include #include -#include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); -static short at_keyboard_status = 0; -static int e0_received = 0; -static int f0_received = 0; - -static grub_uint8_t led_status; - -#define KEYBOARD_LED_SCROLL (1 << 0) -#define KEYBOARD_LED_NUM (1 << 1) -#define KEYBOARD_LED_CAPS (1 << 2) - static grub_uint8_t grub_keyboard_controller_orig; static grub_uint8_t grub_keyboard_orig_set; -static grub_uint8_t current_set; - -static void -grub_keyboard_controller_init (void); - -static const grub_uint8_t set1_mapping[128] = - { - /* 0x00 */ 0 /* Unused */, GRUB_KEYBOARD_KEY_ESCAPE, - /* 0x02 */ GRUB_KEYBOARD_KEY_1, GRUB_KEYBOARD_KEY_2, - /* 0x04 */ GRUB_KEYBOARD_KEY_3, GRUB_KEYBOARD_KEY_4, - /* 0x06 */ GRUB_KEYBOARD_KEY_5, GRUB_KEYBOARD_KEY_6, - /* 0x08 */ GRUB_KEYBOARD_KEY_7, GRUB_KEYBOARD_KEY_8, - /* 0x0a */ GRUB_KEYBOARD_KEY_9, GRUB_KEYBOARD_KEY_0, - /* 0x0c */ GRUB_KEYBOARD_KEY_DASH, GRUB_KEYBOARD_KEY_EQUAL, - /* 0x0e */ GRUB_KEYBOARD_KEY_BACKSPACE, GRUB_KEYBOARD_KEY_TAB, - /* 0x10 */ GRUB_KEYBOARD_KEY_Q, GRUB_KEYBOARD_KEY_W, - /* 0x12 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_R, - /* 0x14 */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_Y, - /* 0x16 */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_I, - /* 0x18 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_P, - /* 0x1a */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_RBRACKET, - /* 0x1c */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_LEFT_CTRL, - /* 0x1e */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_S, - /* 0x20 */ GRUB_KEYBOARD_KEY_D, GRUB_KEYBOARD_KEY_F, - /* 0x22 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_H, - /* 0x24 */ GRUB_KEYBOARD_KEY_J, GRUB_KEYBOARD_KEY_K, - /* 0x26 */ GRUB_KEYBOARD_KEY_L, GRUB_KEYBOARD_KEY_SEMICOLON, - /* 0x28 */ GRUB_KEYBOARD_KEY_DQUOTE, GRUB_KEYBOARD_KEY_RQUOTE, - /* 0x2a */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, GRUB_KEYBOARD_KEY_BACKSLASH, - /* 0x2c */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_X, - /* 0x2e */ GRUB_KEYBOARD_KEY_C, GRUB_KEYBOARD_KEY_V, - /* 0x30 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_N, - /* 0x32 */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_COMMA, - /* 0x34 */ GRUB_KEYBOARD_KEY_DOT, GRUB_KEYBOARD_KEY_SLASH, - /* 0x36 */ GRUB_KEYBOARD_KEY_RIGHT_SHIFT, GRUB_KEYBOARD_KEY_NUMMUL, - /* 0x38 */ GRUB_KEYBOARD_KEY_LEFT_ALT, GRUB_KEYBOARD_KEY_SPACE, - /* 0x3a */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_F1, - /* 0x3c */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F3, - /* 0x3e */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_F5, - /* 0x40 */ GRUB_KEYBOARD_KEY_F6, GRUB_KEYBOARD_KEY_F7, - /* 0x42 */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F9, - /* 0x44 */ GRUB_KEYBOARD_KEY_F10, GRUB_KEYBOARD_KEY_NUM_LOCK, - /* 0x46 */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, GRUB_KEYBOARD_KEY_NUM7, - /* 0x48 */ GRUB_KEYBOARD_KEY_NUM8, GRUB_KEYBOARD_KEY_NUM9, - /* 0x4a */ GRUB_KEYBOARD_KEY_NUMMINUS, GRUB_KEYBOARD_KEY_NUM4, - /* 0x4c */ GRUB_KEYBOARD_KEY_NUM5, GRUB_KEYBOARD_KEY_NUM6, - /* 0x4e */ GRUB_KEYBOARD_KEY_NUMPLUS, GRUB_KEYBOARD_KEY_NUM1, - /* 0x50 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM3, - /* 0x52 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT, - /* 0x54 */ 0, 0, - /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, - /* 0x58 */ GRUB_KEYBOARD_KEY_F12, 0, - /* 0x5a */ 0, 0, - /* 0x5c */ 0, 0, - /* 0x5e */ 0, 0, - /* 0x60 */ 0, 0, - /* 0x62 */ 0, 0, - /* OLPC keys. Just mapped to normal keys. */ - /* 0x64 */ 0, GRUB_KEYBOARD_KEY_UP, - /* 0x66 */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_LEFT, - /* 0x68 */ GRUB_KEYBOARD_KEY_RIGHT, 0, - /* 0x6a */ 0, 0, - /* 0x6c */ 0, 0, - /* 0x6e */ 0, 0, - /* 0x70 */ 0, 0, - /* 0x72 */ 0, GRUB_KEYBOARD_KEY_JP_RO, - /* 0x74 */ 0, 0, - /* 0x76 */ 0, 0, - /* 0x78 */ 0, 0, - /* 0x7a */ 0, 0, - /* 0x7c */ 0, GRUB_KEYBOARD_KEY_JP_YEN, - /* 0x7e */ GRUB_KEYBOARD_KEY_KPCOMMA - }; - -static const struct -{ - grub_uint8_t from, to; -} set1_e0_mapping[] = - { - {0x1c, GRUB_KEYBOARD_KEY_NUMENTER}, - {0x1d, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, - {0x35, GRUB_KEYBOARD_KEY_NUMSLASH }, - {0x38, GRUB_KEYBOARD_KEY_RIGHT_ALT}, - {0x47, GRUB_KEYBOARD_KEY_HOME}, - {0x48, GRUB_KEYBOARD_KEY_UP}, - {0x49, GRUB_KEYBOARD_KEY_PPAGE}, - {0x4b, GRUB_KEYBOARD_KEY_LEFT}, - {0x4d, GRUB_KEYBOARD_KEY_RIGHT}, - {0x4f, GRUB_KEYBOARD_KEY_END}, - {0x50, GRUB_KEYBOARD_KEY_DOWN}, - {0x51, GRUB_KEYBOARD_KEY_NPAGE}, - {0x52, GRUB_KEYBOARD_KEY_INSERT}, - {0x53, GRUB_KEYBOARD_KEY_DELETE}, - }; - -static const grub_uint8_t set2_mapping[256] = - { - /* 0x00 */ 0, GRUB_KEYBOARD_KEY_F9, - /* 0x02 */ 0, GRUB_KEYBOARD_KEY_F5, - /* 0x04 */ GRUB_KEYBOARD_KEY_F3, GRUB_KEYBOARD_KEY_F1, - /* 0x06 */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F12, - /* 0x08 */ 0, GRUB_KEYBOARD_KEY_F10, - /* 0x0a */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F6, - /* 0x0c */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_TAB, - /* 0x0e */ GRUB_KEYBOARD_KEY_RQUOTE, 0, - /* 0x10 */ 0, GRUB_KEYBOARD_KEY_LEFT_ALT, - /* 0x12 */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, 0, - /* 0x14 */ GRUB_KEYBOARD_KEY_LEFT_CTRL, GRUB_KEYBOARD_KEY_Q, - /* 0x16 */ GRUB_KEYBOARD_KEY_1, 0, - /* 0x18 */ 0, 0, - /* 0x1a */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_S, - /* 0x1c */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_W, - /* 0x1e */ GRUB_KEYBOARD_KEY_2, 0, - /* 0x20 */ 0, GRUB_KEYBOARD_KEY_C, - /* 0x22 */ GRUB_KEYBOARD_KEY_X, GRUB_KEYBOARD_KEY_D, - /* 0x24 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_4, - /* 0x26 */ GRUB_KEYBOARD_KEY_3, 0, - /* 0x28 */ 0, GRUB_KEYBOARD_KEY_SPACE, - /* 0x2a */ GRUB_KEYBOARD_KEY_V, GRUB_KEYBOARD_KEY_F, - /* 0x2c */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_R, - /* 0x2e */ GRUB_KEYBOARD_KEY_5, 0, - /* 0x30 */ 0, GRUB_KEYBOARD_KEY_N, - /* 0x32 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_H, - /* 0x34 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_Y, - /* 0x36 */ GRUB_KEYBOARD_KEY_6, 0, - /* 0x38 */ 0, 0, - /* 0x3a */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_J, - /* 0x3c */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_7, - /* 0x3e */ GRUB_KEYBOARD_KEY_8, 0, - /* 0x40 */ 0, GRUB_KEYBOARD_KEY_COMMA, - /* 0x42 */ GRUB_KEYBOARD_KEY_K, GRUB_KEYBOARD_KEY_I, - /* 0x44 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_0, - /* 0x46 */ GRUB_KEYBOARD_KEY_9, 0, - /* 0x48 */ 0, GRUB_KEYBOARD_KEY_DOT, - /* 0x4a */ GRUB_KEYBOARD_KEY_SLASH, GRUB_KEYBOARD_KEY_L, - /* 0x4c */ GRUB_KEYBOARD_KEY_SEMICOLON, GRUB_KEYBOARD_KEY_P, - /* 0x4e */ GRUB_KEYBOARD_KEY_DASH, 0, - /* 0x50 */ 0, GRUB_KEYBOARD_KEY_JP_RO, - /* 0x52 */ GRUB_KEYBOARD_KEY_DQUOTE, 0, - /* 0x54 */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_EQUAL, - /* 0x56 */ 0, 0, - /* 0x58 */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_RIGHT_SHIFT, - /* 0x5a */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_RBRACKET, - /* 0x5c */ 0, GRUB_KEYBOARD_KEY_BACKSLASH, - /* 0x5e */ 0, 0, - /* 0x60 */ 0, GRUB_KEYBOARD_KEY_102ND, - /* 0x62 */ 0, 0, - /* 0x64 */ 0, 0, - /* 0x66 */ GRUB_KEYBOARD_KEY_BACKSPACE, 0, - /* 0x68 */ 0, GRUB_KEYBOARD_KEY_NUM1, - /* 0x6a */ GRUB_KEYBOARD_KEY_JP_YEN, GRUB_KEYBOARD_KEY_NUM4, - /* 0x6c */ GRUB_KEYBOARD_KEY_NUM7, GRUB_KEYBOARD_KEY_KPCOMMA, - /* 0x6e */ 0, 0, - /* 0x70 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT, - /* 0x72 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM5, - /* 0x74 */ GRUB_KEYBOARD_KEY_NUM6, GRUB_KEYBOARD_KEY_NUM8, - /* 0x76 */ GRUB_KEYBOARD_KEY_ESCAPE, GRUB_KEYBOARD_KEY_NUM_LOCK, - /* 0x78 */ GRUB_KEYBOARD_KEY_F11, GRUB_KEYBOARD_KEY_NUMPLUS, - /* 0x7a */ GRUB_KEYBOARD_KEY_NUM3, GRUB_KEYBOARD_KEY_NUMMINUS, - /* 0x7c */ GRUB_KEYBOARD_KEY_NUMMUL, GRUB_KEYBOARD_KEY_NUM9, - /* 0x7e */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, 0, - /* 0x80 */ 0, 0, - /* 0x82 */ 0, GRUB_KEYBOARD_KEY_F7, - }; - -static const struct -{ - grub_uint8_t from, to; -} set2_e0_mapping[] = - { - {0x11, GRUB_KEYBOARD_KEY_RIGHT_ALT}, - {0x14, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, - {0x4a, GRUB_KEYBOARD_KEY_NUMSLASH}, - {0x5a, GRUB_KEYBOARD_KEY_NUMENTER}, - {0x69, GRUB_KEYBOARD_KEY_END}, - {0x6b, GRUB_KEYBOARD_KEY_LEFT}, - {0x6c, GRUB_KEYBOARD_KEY_HOME}, - {0x70, GRUB_KEYBOARD_KEY_INSERT}, - {0x71, GRUB_KEYBOARD_KEY_DELETE}, - {0x72, GRUB_KEYBOARD_KEY_DOWN}, - {0x74, GRUB_KEYBOARD_KEY_RIGHT}, - {0x75, GRUB_KEYBOARD_KEY_UP}, - {0x7a, GRUB_KEYBOARD_KEY_NPAGE}, - {0x7d, GRUB_KEYBOARD_KEY_PPAGE}, - }; +struct grub_ps2_state ps2_state; static int ping_sent; +static void +grub_keyboard_controller_init (void); + static void keyboard_controller_wait_until_ready (void) { - while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))); + unsigned int i = 200; + + /* 50 us would be enough but our current time resolution is 1ms. */ + grub_millisleep (1); + + while (!KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) + { + grub_millisleep (1); + + /* Timeout. */ + if (!i--) + break; + } } static grub_uint8_t @@ -241,10 +62,11 @@ wait_ack (void) grub_uint8_t ack; endtime = grub_get_time_ms () + 20; - do + do { + keyboard_controller_wait_until_ready (); ack = grub_inb (KEYBOARD_REG_DATA); - while (ack != GRUB_AT_ACK && ack != GRUB_AT_NACK - && grub_get_time_ms () < endtime); + } while (ack != GRUB_AT_ACK && ack != GRUB_AT_NACK + && grub_get_time_ms () < endtime); return ack; } @@ -326,12 +148,10 @@ query_mode (void) if (!e) return 0; - keyboard_controller_wait_until_ready (); - - do + do { + keyboard_controller_wait_until_ready (); ret = grub_inb (KEYBOARD_REG_DATA); - while (ret == GRUB_AT_ACK); - + } while (ret == GRUB_AT_ACK); /* QEMU translates the set even in no-translate mode. */ if (ret == 0x43 || ret == 1) return 1; @@ -350,28 +170,32 @@ set_scancodes (void) if (!grub_keyboard_orig_set) { grub_dprintf ("atkeyb", "No sets support assumed\n"); - current_set = 1; + ps2_state.current_set = 1; return; } #if !USE_SCANCODE_SET - current_set = 1; + ps2_state.current_set = 1; return; #else grub_keyboard_controller_write (grub_keyboard_controller_orig - & ~KEYBOARD_AT_TRANSLATE); + & ~KEYBOARD_AT_TRANSLATE + & ~KEYBOARD_AT_DISABLE); + + keyboard_controller_wait_until_ready (); + grub_outb (KEYBOARD_COMMAND_ENABLE, KEYBOARD_REG_DATA); write_mode (2); - current_set = query_mode (); - grub_dprintf ("atkeyb", "returned set %d\n", current_set); - if (current_set == 2) + ps2_state.current_set = query_mode (); + grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); + if (ps2_state.current_set == 2) return; write_mode (1); - current_set = query_mode (); - grub_dprintf ("atkeyb", "returned set %d\n", current_set); - if (current_set == 1) + ps2_state.current_set = query_mode (); + grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set); + if (ps2_state.current_set == 1) return; grub_dprintf ("atkeyb", "no supported scancode set found\n"); #endif @@ -386,164 +210,10 @@ keyboard_controller_led (grub_uint8_t leds) grub_outb (leds & 0x7, KEYBOARD_REG_DATA); } -static int -fetch_key (int *is_break) -{ - int was_ext = 0; - grub_uint8_t at_key; - int ret = 0; - - if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - return -1; - at_key = grub_inb (KEYBOARD_REG_DATA); - /* May happen if no keyboard is connected. Just ignore this. */ - if (at_key == 0xff) - return -1; - if (at_key == 0xe0) - { - e0_received = 1; - return -1; - } - - if ((current_set == 2 || current_set == 3) && at_key == 0xf0) - { - f0_received = 1; - return -1; - } - - /* Setting LEDs may generate ACKs. */ - if (at_key == GRUB_AT_ACK) - return -1; - - was_ext = e0_received; - e0_received = 0; - - switch (current_set) - { - case 1: - *is_break = !!(at_key & 0x80); - if (!was_ext) - ret = set1_mapping[at_key & 0x7f]; - else - { - unsigned i; - for (i = 0; i < ARRAY_SIZE (set1_e0_mapping); i++) - if (set1_e0_mapping[i].from == (at_key & 0x7f)) - { - ret = set1_e0_mapping[i].to; - break; - } - } - break; - case 2: - *is_break = f0_received; - f0_received = 0; - if (!was_ext) - ret = set2_mapping[at_key]; - else - { - unsigned i; - for (i = 0; i < ARRAY_SIZE (set2_e0_mapping); i++) - if (set2_e0_mapping[i].from == at_key) - { - ret = set2_e0_mapping[i].to; - break; - } - } - break; - default: - return -1; - } - if (!ret) - { - if (was_ext) - grub_dprintf ("atkeyb", "Unknown key 0xe0+0x%02x from set %d\n", - at_key, current_set); - else - grub_dprintf ("atkeyb", "Unknown key 0x%02x from set %d\n", - at_key, current_set); - return -1; - } - return ret; -} - -/* FIXME: This should become an interrupt service routine. For now - it's just used to catch events from control keys. */ -static int -grub_keyboard_isr (grub_keyboard_key_t key, int is_break) -{ - if (!is_break) - switch (key) - { - case GRUB_KEYBOARD_KEY_LEFT_SHIFT: - at_keyboard_status |= GRUB_TERM_STATUS_LSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: - at_keyboard_status |= GRUB_TERM_STATUS_RSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_CTRL: - at_keyboard_status |= GRUB_TERM_STATUS_LCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_CTRL: - at_keyboard_status |= GRUB_TERM_STATUS_RCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_ALT: - at_keyboard_status |= GRUB_TERM_STATUS_RALT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_ALT: - at_keyboard_status |= GRUB_TERM_STATUS_LALT; - return 1; - default: - return 0; - } - else - switch (key) - { - case GRUB_KEYBOARD_KEY_LEFT_SHIFT: - at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: - at_keyboard_status &= ~GRUB_TERM_STATUS_RSHIFT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_CTRL: - at_keyboard_status &= ~GRUB_TERM_STATUS_LCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_CTRL: - at_keyboard_status &= ~GRUB_TERM_STATUS_RCTRL; - return 1; - case GRUB_KEYBOARD_KEY_RIGHT_ALT: - at_keyboard_status &= ~GRUB_TERM_STATUS_RALT; - return 1; - case GRUB_KEYBOARD_KEY_LEFT_ALT: - at_keyboard_status &= ~GRUB_TERM_STATUS_LALT; - return 1; - default: - return 0; - } -} - -/* If there is a raw key pending, return it; otherwise return -1. */ -static int -grub_keyboard_getkey (void) -{ - int key; - int is_break = 0; - - key = fetch_key (&is_break); - if (key == -1) - return -1; - - if (grub_keyboard_isr (key, is_break)) - return -1; - if (is_break) - return -1; - return key; -} - int grub_at_keyboard_is_alive (void) { - if (current_set != 0) + if (ps2_state.current_set != 0) return 1; if (ping_sent && KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)) @@ -566,51 +236,28 @@ grub_at_keyboard_is_alive (void) static int grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) { - int code; + grub_uint8_t at_key; + int ret; + grub_uint8_t old_led; if (!grub_at_keyboard_is_alive ()) return GRUB_TERM_NO_KEY; - code = grub_keyboard_getkey (); - if (code == -1) + if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) return GRUB_TERM_NO_KEY; -#ifdef DEBUG_AT_KEYBOARD - grub_dprintf ("atkeyb", "Detected key 0x%x\n", code); -#endif - switch (code) - { - case GRUB_KEYBOARD_KEY_CAPS_LOCK: - at_keyboard_status ^= GRUB_TERM_STATUS_CAPS; - led_status ^= KEYBOARD_LED_CAPS; - keyboard_controller_led (led_status); + at_key = grub_inb (KEYBOARD_REG_DATA); + old_led = ps2_state.led_status; -#ifdef DEBUG_AT_KEYBOARD - grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & GRUB_KEYBOARD_STATUS_CAPS_LOCK)); -#endif - return GRUB_TERM_NO_KEY; - case GRUB_KEYBOARD_KEY_NUM_LOCK: - at_keyboard_status ^= GRUB_TERM_STATUS_NUM; - led_status ^= KEYBOARD_LED_NUM; - keyboard_controller_led (led_status); - -#ifdef DEBUG_AT_KEYBOARD - grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & GRUB_KEYBOARD_STATUS_NUM_LOCK)); -#endif - return GRUB_TERM_NO_KEY; - case GRUB_KEYBOARD_KEY_SCROLL_LOCK: - at_keyboard_status ^= GRUB_TERM_STATUS_SCROLL; - led_status ^= KEYBOARD_LED_SCROLL; - keyboard_controller_led (led_status); - return GRUB_TERM_NO_KEY; - default: - return grub_term_map_key (code, at_keyboard_status); - } + ret = grub_ps2_process_incoming_byte (&ps2_state, at_key); + if (old_led != ps2_state.led_status) + keyboard_controller_led (ps2_state.led_status); + return ret; } static void grub_keyboard_controller_init (void) { - at_keyboard_status = 0; + ps2_state.at_keyboard_status = 0; /* Drain input buffer. */ while (1) { @@ -632,13 +279,13 @@ grub_keyboard_controller_init (void) grub_keyboard_orig_set = query_mode (); #endif set_scancodes (); - keyboard_controller_led (led_status); + keyboard_controller_led (ps2_state.led_status); } static grub_err_t grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) { - if (current_set == 0) + if (ps2_state.current_set == 0) return GRUB_ERR_NONE; if (grub_keyboard_orig_set) write_mode (grub_keyboard_orig_set); @@ -655,7 +302,7 @@ grub_at_fini_hw (int noreturn __attribute__ ((unused))) static grub_err_t grub_at_restore_hw (void) { - if (current_set == 0) + if (ps2_state.current_set == 0) return GRUB_ERR_NONE; /* Drain input buffer. */ @@ -668,7 +315,7 @@ grub_at_restore_hw (void) grub_inb (KEYBOARD_REG_DATA); } set_scancodes (); - keyboard_controller_led (led_status); + keyboard_controller_led (ps2_state.led_status); return GRUB_ERR_NONE; } diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index 7d31095b1..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[] = @@ -104,7 +201,7 @@ const unsigned efi_codes[] = GRUB_TERM_KEY_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, - GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, '\e' + GRUB_TERM_KEY_F10, GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, GRUB_TERM_ESC }; static int @@ -122,6 +219,9 @@ grub_efi_translate_key (grub_efi_input_key_t key) else return key.unicode_char; } + /* Some devices send enter with scan_code 0x0d (F3) and unicode_char 0x0d. */ + else if (key.scan_code == '\r' && key.unicode_char == '\r') + return key.unicode_char; else if (key.scan_code < ARRAY_SIZE (efi_codes)) return efi_codes[key.scan_code]; @@ -141,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; @@ -149,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 @@ -186,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) @@ -220,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; @@ -242,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; @@ -250,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 @@ -268,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; } @@ -339,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, @@ -361,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/coreboot/cbmemc.c b/grub-core/term/i386/coreboot/cbmemc.c index 25e64a05c..cea9b8431 100644 --- a/grub-core/term/i386/coreboot/cbmemc.c +++ b/grub-core/term/i386/coreboot/cbmemc.c @@ -23,17 +23,20 @@ #include #include #include -#include +#include #include #include GRUB_MOD_LICENSE ("GPLv3+"); +#define CURSOR_MASK ((1 << 28) - 1) +#define OVERFLOW (1 << 31) + struct grub_linuxbios_cbmemc { grub_uint32_t size; - grub_uint32_t pointer; - char data[0]; + grub_uint32_t cursor; + char body[0]; }; static struct grub_linuxbios_cbmemc *cbmemc; @@ -41,11 +44,20 @@ static struct grub_linuxbios_cbmemc *cbmemc; static void put (struct grub_term_output *term __attribute__ ((unused)), const int c) { + grub_uint32_t flags, cursor; if (!cbmemc) return; - if (cbmemc->pointer < cbmemc->size) - cbmemc->data[cbmemc->pointer] = c; - cbmemc->pointer++; + flags = cbmemc->cursor & ~CURSOR_MASK; + cursor = cbmemc->cursor & CURSOR_MASK; + if (cursor >= cbmemc->size) + return; + cbmemc->body[cursor++] = c; + if (cursor >= cbmemc->size) + { + cursor = 0; + flags |= OVERFLOW; + } + cbmemc->cursor = flags | cursor; } struct grub_terminfo_output_state grub_cbmemc_terminfo_output = @@ -87,21 +99,29 @@ grub_cmd_cbmemc (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { - grub_size_t len; - char *str; - struct grub_linuxbios_cbmemc *cbmemc_saved; + grub_size_t size, cursor; + struct grub_linuxbios_cbmemc *real_cbmemc; if (!cbmemc) return grub_error (GRUB_ERR_IO, "no CBMEM console found"); - len = cbmemc->pointer; - if (len > cbmemc->size) - len = cbmemc->size; - str = cbmemc->data; - cbmemc_saved = cbmemc; + real_cbmemc = cbmemc; cbmemc = 0; - grub_xnputs (str, len); - cbmemc = cbmemc_saved; + cursor = real_cbmemc->cursor & CURSOR_MASK; + if (!(real_cbmemc->cursor & OVERFLOW) && cursor < real_cbmemc->size) + size = cursor; + else + size = real_cbmemc->size; + if (real_cbmemc->cursor & OVERFLOW) + { + if (cursor > size) + cursor = 0; + grub_xnputs(real_cbmemc->body + cursor, size - cursor); + grub_xnputs(real_cbmemc->body, cursor); + } + else + grub_xnputs(real_cbmemc->body, size); + cbmemc = real_cbmemc; return 0; } diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c index 28de46b57..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); } @@ -204,7 +204,7 @@ static int grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) { const grub_uint16_t bypass_table[] = { - 0x0100 | '\e', 0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r', 0x1c00 | '\n' + 0x0100 | GRUB_TERM_ESC, 0x0f00 | GRUB_TERM_TAB, 0x0e00 | GRUB_TERM_BACKSPACE, 0x1c00 | '\r', 0x1c00 | '\n' }; struct grub_bios_int_registers regs; unsigned i; @@ -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 new file mode 100644 index 000000000..c7a09a821 --- /dev/null +++ b/grub-core/term/ps2.c @@ -0,0 +1,387 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#define KEYBOARD_LED_SCROLL (1 << 0) +#define KEYBOARD_LED_NUM (1 << 1) +#define KEYBOARD_LED_CAPS (1 << 2) + +static const grub_uint8_t set1_mapping[128] = + { + /* 0x00 */ 0 /* Unused */, GRUB_KEYBOARD_KEY_ESCAPE, + /* 0x02 */ GRUB_KEYBOARD_KEY_1, GRUB_KEYBOARD_KEY_2, + /* 0x04 */ GRUB_KEYBOARD_KEY_3, GRUB_KEYBOARD_KEY_4, + /* 0x06 */ GRUB_KEYBOARD_KEY_5, GRUB_KEYBOARD_KEY_6, + /* 0x08 */ GRUB_KEYBOARD_KEY_7, GRUB_KEYBOARD_KEY_8, + /* 0x0a */ GRUB_KEYBOARD_KEY_9, GRUB_KEYBOARD_KEY_0, + /* 0x0c */ GRUB_KEYBOARD_KEY_DASH, GRUB_KEYBOARD_KEY_EQUAL, + /* 0x0e */ GRUB_KEYBOARD_KEY_BACKSPACE, GRUB_KEYBOARD_KEY_TAB, + /* 0x10 */ GRUB_KEYBOARD_KEY_Q, GRUB_KEYBOARD_KEY_W, + /* 0x12 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_R, + /* 0x14 */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_Y, + /* 0x16 */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_I, + /* 0x18 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_P, + /* 0x1a */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_RBRACKET, + /* 0x1c */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_LEFT_CTRL, + /* 0x1e */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_S, + /* 0x20 */ GRUB_KEYBOARD_KEY_D, GRUB_KEYBOARD_KEY_F, + /* 0x22 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_H, + /* 0x24 */ GRUB_KEYBOARD_KEY_J, GRUB_KEYBOARD_KEY_K, + /* 0x26 */ GRUB_KEYBOARD_KEY_L, GRUB_KEYBOARD_KEY_SEMICOLON, + /* 0x28 */ GRUB_KEYBOARD_KEY_DQUOTE, GRUB_KEYBOARD_KEY_RQUOTE, + /* 0x2a */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, GRUB_KEYBOARD_KEY_BACKSLASH, + /* 0x2c */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_X, + /* 0x2e */ GRUB_KEYBOARD_KEY_C, GRUB_KEYBOARD_KEY_V, + /* 0x30 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_N, + /* 0x32 */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_COMMA, + /* 0x34 */ GRUB_KEYBOARD_KEY_DOT, GRUB_KEYBOARD_KEY_SLASH, + /* 0x36 */ GRUB_KEYBOARD_KEY_RIGHT_SHIFT, GRUB_KEYBOARD_KEY_NUMMUL, + /* 0x38 */ GRUB_KEYBOARD_KEY_LEFT_ALT, GRUB_KEYBOARD_KEY_SPACE, + /* 0x3a */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_F1, + /* 0x3c */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F3, + /* 0x3e */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_F5, + /* 0x40 */ GRUB_KEYBOARD_KEY_F6, GRUB_KEYBOARD_KEY_F7, + /* 0x42 */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F9, + /* 0x44 */ GRUB_KEYBOARD_KEY_F10, GRUB_KEYBOARD_KEY_NUM_LOCK, + /* 0x46 */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, GRUB_KEYBOARD_KEY_NUM7, + /* 0x48 */ GRUB_KEYBOARD_KEY_NUM8, GRUB_KEYBOARD_KEY_NUM9, + /* 0x4a */ GRUB_KEYBOARD_KEY_NUMMINUS, GRUB_KEYBOARD_KEY_NUM4, + /* 0x4c */ GRUB_KEYBOARD_KEY_NUM5, GRUB_KEYBOARD_KEY_NUM6, + /* 0x4e */ GRUB_KEYBOARD_KEY_NUMPLUS, GRUB_KEYBOARD_KEY_NUM1, + /* 0x50 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM3, + /* 0x52 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT, + /* 0x54 */ 0, 0, + /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, + /* 0x58 */ GRUB_KEYBOARD_KEY_F12, 0, + /* 0x5a */ 0, 0, + /* 0x5c */ 0, 0, + /* 0x5e */ 0, 0, + /* 0x60 */ 0, 0, + /* 0x62 */ 0, 0, + /* OLPC keys. Just mapped to normal keys. */ + /* 0x64 */ 0, GRUB_KEYBOARD_KEY_UP, + /* 0x66 */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_LEFT, + /* 0x68 */ GRUB_KEYBOARD_KEY_RIGHT, 0, + /* 0x6a */ 0, 0, + /* 0x6c */ 0, 0, + /* 0x6e */ 0, 0, + /* 0x70 */ 0, 0, + /* 0x72 */ 0, GRUB_KEYBOARD_KEY_JP_RO, + /* 0x74 */ 0, 0, + /* 0x76 */ 0, 0, + /* 0x78 */ 0, 0, + /* 0x7a */ 0, 0, + /* 0x7c */ 0, GRUB_KEYBOARD_KEY_JP_YEN, + /* 0x7e */ GRUB_KEYBOARD_KEY_KPCOMMA + }; + +static const struct +{ + grub_uint8_t from, to; +} set1_e0_mapping[] = + { + {0x1c, GRUB_KEYBOARD_KEY_NUMENTER}, + {0x1d, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, + {0x35, GRUB_KEYBOARD_KEY_NUMSLASH }, + {0x38, GRUB_KEYBOARD_KEY_RIGHT_ALT}, + {0x47, GRUB_KEYBOARD_KEY_HOME}, + {0x48, GRUB_KEYBOARD_KEY_UP}, + {0x49, GRUB_KEYBOARD_KEY_PPAGE}, + {0x4b, GRUB_KEYBOARD_KEY_LEFT}, + {0x4d, GRUB_KEYBOARD_KEY_RIGHT}, + {0x4f, GRUB_KEYBOARD_KEY_END}, + {0x50, GRUB_KEYBOARD_KEY_DOWN}, + {0x51, GRUB_KEYBOARD_KEY_NPAGE}, + {0x52, GRUB_KEYBOARD_KEY_INSERT}, + {0x53, GRUB_KEYBOARD_KEY_DELETE}, + }; + +static const grub_uint8_t set2_mapping[256] = + { + /* 0x00 */ 0, GRUB_KEYBOARD_KEY_F9, + /* 0x02 */ 0, GRUB_KEYBOARD_KEY_F5, + /* 0x04 */ GRUB_KEYBOARD_KEY_F3, GRUB_KEYBOARD_KEY_F1, + /* 0x06 */ GRUB_KEYBOARD_KEY_F2, GRUB_KEYBOARD_KEY_F12, + /* 0x08 */ 0, GRUB_KEYBOARD_KEY_F10, + /* 0x0a */ GRUB_KEYBOARD_KEY_F8, GRUB_KEYBOARD_KEY_F6, + /* 0x0c */ GRUB_KEYBOARD_KEY_F4, GRUB_KEYBOARD_KEY_TAB, + /* 0x0e */ GRUB_KEYBOARD_KEY_RQUOTE, 0, + /* 0x10 */ 0, GRUB_KEYBOARD_KEY_LEFT_ALT, + /* 0x12 */ GRUB_KEYBOARD_KEY_LEFT_SHIFT, 0, + /* 0x14 */ GRUB_KEYBOARD_KEY_LEFT_CTRL, GRUB_KEYBOARD_KEY_Q, + /* 0x16 */ GRUB_KEYBOARD_KEY_1, 0, + /* 0x18 */ 0, 0, + /* 0x1a */ GRUB_KEYBOARD_KEY_Z, GRUB_KEYBOARD_KEY_S, + /* 0x1c */ GRUB_KEYBOARD_KEY_A, GRUB_KEYBOARD_KEY_W, + /* 0x1e */ GRUB_KEYBOARD_KEY_2, 0, + /* 0x20 */ 0, GRUB_KEYBOARD_KEY_C, + /* 0x22 */ GRUB_KEYBOARD_KEY_X, GRUB_KEYBOARD_KEY_D, + /* 0x24 */ GRUB_KEYBOARD_KEY_E, GRUB_KEYBOARD_KEY_4, + /* 0x26 */ GRUB_KEYBOARD_KEY_3, 0, + /* 0x28 */ 0, GRUB_KEYBOARD_KEY_SPACE, + /* 0x2a */ GRUB_KEYBOARD_KEY_V, GRUB_KEYBOARD_KEY_F, + /* 0x2c */ GRUB_KEYBOARD_KEY_T, GRUB_KEYBOARD_KEY_R, + /* 0x2e */ GRUB_KEYBOARD_KEY_5, 0, + /* 0x30 */ 0, GRUB_KEYBOARD_KEY_N, + /* 0x32 */ GRUB_KEYBOARD_KEY_B, GRUB_KEYBOARD_KEY_H, + /* 0x34 */ GRUB_KEYBOARD_KEY_G, GRUB_KEYBOARD_KEY_Y, + /* 0x36 */ GRUB_KEYBOARD_KEY_6, 0, + /* 0x38 */ 0, 0, + /* 0x3a */ GRUB_KEYBOARD_KEY_M, GRUB_KEYBOARD_KEY_J, + /* 0x3c */ GRUB_KEYBOARD_KEY_U, GRUB_KEYBOARD_KEY_7, + /* 0x3e */ GRUB_KEYBOARD_KEY_8, 0, + /* 0x40 */ 0, GRUB_KEYBOARD_KEY_COMMA, + /* 0x42 */ GRUB_KEYBOARD_KEY_K, GRUB_KEYBOARD_KEY_I, + /* 0x44 */ GRUB_KEYBOARD_KEY_O, GRUB_KEYBOARD_KEY_0, + /* 0x46 */ GRUB_KEYBOARD_KEY_9, 0, + /* 0x48 */ 0, GRUB_KEYBOARD_KEY_DOT, + /* 0x4a */ GRUB_KEYBOARD_KEY_SLASH, GRUB_KEYBOARD_KEY_L, + /* 0x4c */ GRUB_KEYBOARD_KEY_SEMICOLON, GRUB_KEYBOARD_KEY_P, + /* 0x4e */ GRUB_KEYBOARD_KEY_DASH, 0, + /* 0x50 */ 0, GRUB_KEYBOARD_KEY_JP_RO, + /* 0x52 */ GRUB_KEYBOARD_KEY_DQUOTE, 0, + /* 0x54 */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_EQUAL, + /* 0x56 */ 0, 0, + /* 0x58 */ GRUB_KEYBOARD_KEY_CAPS_LOCK, GRUB_KEYBOARD_KEY_RIGHT_SHIFT, + /* 0x5a */ GRUB_KEYBOARD_KEY_ENTER, GRUB_KEYBOARD_KEY_RBRACKET, + /* 0x5c */ 0, GRUB_KEYBOARD_KEY_BACKSLASH, + /* 0x5e */ 0, 0, + /* 0x60 */ 0, GRUB_KEYBOARD_KEY_102ND, + /* 0x62 */ 0, 0, + /* 0x64 */ 0, 0, + /* 0x66 */ GRUB_KEYBOARD_KEY_BACKSPACE, 0, + /* 0x68 */ 0, GRUB_KEYBOARD_KEY_NUM1, + /* 0x6a */ GRUB_KEYBOARD_KEY_JP_YEN, GRUB_KEYBOARD_KEY_NUM4, + /* 0x6c */ GRUB_KEYBOARD_KEY_NUM7, GRUB_KEYBOARD_KEY_KPCOMMA, + /* 0x6e */ 0, 0, + /* 0x70 */ GRUB_KEYBOARD_KEY_NUM0, GRUB_KEYBOARD_KEY_NUMDOT, + /* 0x72 */ GRUB_KEYBOARD_KEY_NUM2, GRUB_KEYBOARD_KEY_NUM5, + /* 0x74 */ GRUB_KEYBOARD_KEY_NUM6, GRUB_KEYBOARD_KEY_NUM8, + /* 0x76 */ GRUB_KEYBOARD_KEY_ESCAPE, GRUB_KEYBOARD_KEY_NUM_LOCK, + /* 0x78 */ GRUB_KEYBOARD_KEY_F11, GRUB_KEYBOARD_KEY_NUMPLUS, + /* 0x7a */ GRUB_KEYBOARD_KEY_NUM3, GRUB_KEYBOARD_KEY_NUMMINUS, + /* 0x7c */ GRUB_KEYBOARD_KEY_NUMMUL, GRUB_KEYBOARD_KEY_NUM9, + /* 0x7e */ GRUB_KEYBOARD_KEY_SCROLL_LOCK, 0, + /* 0x80 */ 0, 0, + /* 0x82 */ 0, GRUB_KEYBOARD_KEY_F7, + }; + +static const struct +{ + grub_uint8_t from, to; +} set2_e0_mapping[] = + { + {0x11, GRUB_KEYBOARD_KEY_RIGHT_ALT}, + {0x14, GRUB_KEYBOARD_KEY_RIGHT_CTRL}, + {0x4a, GRUB_KEYBOARD_KEY_NUMSLASH}, + {0x5a, GRUB_KEYBOARD_KEY_NUMENTER}, + {0x69, GRUB_KEYBOARD_KEY_END}, + {0x6b, GRUB_KEYBOARD_KEY_LEFT}, + {0x6c, GRUB_KEYBOARD_KEY_HOME}, + {0x70, GRUB_KEYBOARD_KEY_INSERT}, + {0x71, GRUB_KEYBOARD_KEY_DELETE}, + {0x72, GRUB_KEYBOARD_KEY_DOWN}, + {0x74, GRUB_KEYBOARD_KEY_RIGHT}, + {0x75, GRUB_KEYBOARD_KEY_UP}, + {0x7a, GRUB_KEYBOARD_KEY_NPAGE}, + {0x7d, GRUB_KEYBOARD_KEY_PPAGE}, + }; + +static int +fetch_key (struct grub_ps2_state *ps2_state, grub_uint8_t at_key, int *is_break) +{ + int was_ext = 0; + int ret = 0; + + /* May happen if no keyboard is connected. Just ignore this. */ + if (at_key == 0xff) + return -1; + if (at_key == 0xe0) + { + ps2_state->e0_received = 1; + return -1; + } + + if ((ps2_state->current_set == 2 || ps2_state->current_set == 3) && at_key == 0xf0) + { + ps2_state->f0_received = 1; + return -1; + } + + /* Setting LEDs may generate ACKs. */ + if (at_key == GRUB_AT_ACK) + return -1; + + was_ext = ps2_state->e0_received; + ps2_state->e0_received = 0; + + switch (ps2_state->current_set) + { + case 1: + *is_break = !!(at_key & 0x80); + if (!was_ext) + ret = set1_mapping[at_key & 0x7f]; + else + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (set1_e0_mapping); i++) + if (set1_e0_mapping[i].from == (at_key & 0x7f)) + { + ret = set1_e0_mapping[i].to; + break; + } + } + break; + case 2: + *is_break = ps2_state->f0_received; + ps2_state->f0_received = 0; + if (!was_ext) + ret = set2_mapping[at_key]; + else + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (set2_e0_mapping); i++) + if (set2_e0_mapping[i].from == at_key) + { + ret = set2_e0_mapping[i].to; + break; + } + } + break; + default: + return -1; + } + if (!ret) + { + if (was_ext) + grub_dprintf ("atkeyb", "Unknown key 0xe0+0x%02x from set %d\n", + at_key, ps2_state->current_set); + else + grub_dprintf ("atkeyb", "Unknown key 0x%02x from set %d\n", + at_key, ps2_state->current_set); + return -1; + } + return ret; +} + +/* FIXME: This should become an interrupt service routine. For now + it's just used to catch events from control keys. */ +static int +grub_keyboard_isr (struct grub_ps2_state *ps2_state, + grub_keyboard_key_t key, int is_break) +{ + if (!is_break) + switch (key) + { + case GRUB_KEYBOARD_KEY_LEFT_SHIFT: + ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_LSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: + ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_RSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_CTRL: + ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_LCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_CTRL: + ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_RCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_ALT: + ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_RALT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_ALT: + ps2_state->at_keyboard_status |= GRUB_TERM_STATUS_LALT; + return 1; + default: + return 0; + } + else + switch (key) + { + case GRUB_KEYBOARD_KEY_LEFT_SHIFT: + ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_SHIFT: + ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_RSHIFT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_CTRL: + ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_LCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_CTRL: + ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_RCTRL; + return 1; + case GRUB_KEYBOARD_KEY_RIGHT_ALT: + ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_RALT; + return 1; + case GRUB_KEYBOARD_KEY_LEFT_ALT: + ps2_state->at_keyboard_status &= ~GRUB_TERM_STATUS_LALT; + return 1; + default: + return 0; + } +} + +/* If there is a key pending, return it; otherwise return GRUB_TERM_NO_KEY. */ +int +grub_ps2_process_incoming_byte (struct grub_ps2_state *ps2_state, + grub_uint8_t at_key) +{ + int code; + int is_break = 0; + + code = fetch_key (ps2_state, at_key, &is_break); + if (code == -1) + return GRUB_TERM_NO_KEY; + + if (grub_keyboard_isr (ps2_state, code, is_break)) + return GRUB_TERM_NO_KEY; + if (is_break) + return GRUB_TERM_NO_KEY; +#ifdef DEBUG_AT_KEYBOARD + grub_dprintf ("atkeyb", "Detected key 0x%x\n", code); +#endif + switch (code) + { + case GRUB_KEYBOARD_KEY_CAPS_LOCK: + ps2_state->at_keyboard_status ^= GRUB_TERM_STATUS_CAPS; + ps2_state->led_status ^= KEYBOARD_LED_CAPS; + +#ifdef DEBUG_AT_KEYBOARD + grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(ps2_state->at_keyboard_status & GRUB_KEYBOARD_STATUS_CAPS_LOCK)); +#endif + return GRUB_TERM_NO_KEY; + case GRUB_KEYBOARD_KEY_NUM_LOCK: + ps2_state->at_keyboard_status ^= GRUB_TERM_STATUS_NUM; + ps2_state->led_status ^= KEYBOARD_LED_NUM; + +#ifdef DEBUG_AT_KEYBOARD + grub_dprintf ("atkeyb", "num_lock = %d\n", !!(ps2_state->at_keyboard_status & GRUB_KEYBOARD_STATUS_NUM_LOCK)); +#endif + return GRUB_TERM_NO_KEY; + case GRUB_KEYBOARD_KEY_SCROLL_LOCK: + ps2_state->at_keyboard_status ^= GRUB_TERM_STATUS_SCROLL; + ps2_state->led_status ^= KEYBOARD_LED_SCROLL; + return GRUB_TERM_NO_KEY; + default: + return grub_term_map_key (code, ps2_state->at_keyboard_status); + } +} diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c 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 f0d3e3deb..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)++; \ } @@ -426,12 +429,12 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, } *len = 1; keys[0] = c; - if (c != ANSI_CSI && c != '\e') + if (c != ANSI_CSI && c != GRUB_TERM_ESC) { /* Backspace: Ctrl-h. */ if (c == 0x7f) - c = '\b'; - if (c < 0x20 && c != '\t' && c!= '\b' && c != '\n' && c != '\r') + c = GRUB_TERM_BACKSPACE; + if (c < 0x20 && c != GRUB_TERM_TAB && c!= GRUB_TERM_BACKSPACE && c != '\n' && c != '\r') c = GRUB_TERM_CTRL | (c - 1 + 'a'); *len = 1; keys[0] = c; @@ -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, @@ -487,7 +490,7 @@ grub_terminfo_readkey (struct grub_term_input *term, int *keys, int *len, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_END }; unsigned i; - if (c == '\e') + if (c == GRUB_TERM_ESC) { CONTINUE_READ; @@ -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,11 +605,11 @@ 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] == '\e' + if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC && grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT) && grub_get_time_ms () - data->last_key_time < 1000 && (data->last_key & GRUB_TERM_EXTENDED)) @@ -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/checksums.h b/grub-core/tests/checksums.h index efa1adb3f..8273bd105 100644 --- a/grub-core/tests/checksums.h +++ b/grub-core/tests/checksums.h @@ -1,129 +1,129 @@ - { "cmdline_cat", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x64d48e11, 0x64d48e11, 0x4330a1f4, 0x4330a1f4, 0x601e4c0e, 0x601e4c0e, 0x82696fe9, 0x82696fe9, 0x41073bc1, 0x41073bc1, 0xc26fdc51, 0xc26fdc51, 0xb44ab310, 0xb44ab310, 0x7eea73d0, 0x7eea73d0, 0x51990cc9, 0x51990cc9, 0xba84146a, 0xba84146a, 0x81f97e51, 0x81f97e51, 0x3f03537, 0x3f03537, 0xfc05e3b5, 0xfc05e3b5, 0x3b7cdb50, 0x3b7cdb50, 0x6c348a56, 0x6c348a56, 0xc01c7fa1, 0xc01c7fa1, 0x61d25f00, 0x61d25f00, 0x55e18a76, 0x55e18a76, 0x6420218b, 0x6420218b, 0xf123faa7, 0xf123faa7, 0x696c7eda, 0xcceb9bb0, 0x9263f602, 0x9263f602, }, 45 }, - { "cmdline_cat", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xe6e8acc3, 0xe6e8acc3, 0x826fcefc, 0x826fcefc, 0x604df2bf, 0x604df2bf, 0xc4b080b4, 0xc4b080b4, 0x926dc345, 0x926dc345, 0x8c5bdf8b, 0x8c5bdf8b, 0x2e2c4b47, 0x2e2c4b47, 0x5a40ab79, 0x5a40ab79, 0x30273200, 0x30273200, 0xc9baee33, 0xc9baee33, 0xe5bcf997, 0xe5bcf997, 0xe89072ad, 0xe89072ad, 0xa37a82bf, 0xa37a82bf, 0x94820281, 0x94820281, 0xf12d471, 0xf12d471, 0x24066d71, 0x24066d71, 0xc9ccad48, 0xc9ccad48, 0xef4da67a, 0xef4da67a, 0x9b941cce, 0x9b941cce, 0xfc657f55, 0xfc657f55, 0x361b98a5, 0x16a28824, 0x1fb9fe37, 0x1fb9fe37, }, 45 }, - { "cmdline_cat", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x9f1b6349, 0x9f1b6349, 0x4d602d62, 0x4d602d62, 0xacb261fd, 0xacb261fd, 0x216f238b, 0x216f238b, 0x692ce8e8, 0x692ce8e8, 0xd5728c94, 0xd5728c94, 0xa52a2994, 0xa52a2994, 0x5db1a6cf, 0x5db1a6cf, 0xaba6ebeb, 0xaba6ebeb, 0x52b7b1b2, 0x52b7b1b2, 0x7552f41b, 0x7552f41b, 0xb2c2a7ce, 0xb2c2a7ce, 0x1b7b534e, 0x1b7b534e, 0x76112f0c, 0x76112f0c, 0xaf522ac, 0xaf522ac, 0x27da0578, 0x27da0578, 0x3e09bc10, 0x3e09bc10, 0x5e80fbb9, 0x5e80fbb9, 0x9e6bf207, 0x9e6bf207, 0xcf02355f, 0xcf02355f, 0x1eb1112f, 0xf2a4c25e, 0x63e655c4, 0x63e655c4, }, 45 }, - { "cmdline_cat", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xfb375a6d, 0xfb375a6d, 0xe84b0b99, 0xe84b0b99, 0x47425305, 0x47425305, 0xae2951a0, 0xae2951a0, 0x9c166a1e, 0x9c166a1e, 0xccae4822, 0xccae4822, 0x6ff31033, 0x6ff31033, 0x3ea842c4, 0x3ea842c4, 0x53a0f741, 0x53a0f741, 0x565a8328, 0x565a8328, 0x698498b4, 0x698498b4, 0x956c542b, 0x956c542b, 0x1d90d193, 0x1d90d193, 0x93a302cd, 0x93a302cd, 0x2de75bd, 0x2de75bd, 0x6c6a8682, 0x6c6a8682, 0xcc3eb620, 0xcc3eb620, 0x6a63564b, 0x6a63564b, 0x62934959, 0x62934959, 0xef320100, 0xef320100, 0x94cc54bf, 0x9473a69c, 0x632eb358, 0x632eb358, }, 45 }, - { "cmdline_cat", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xc24f56a4, 0xc24f56a4, 0x3294d372, 0x3294d372, 0x27cc0a5f, 0x27cc0a5f, 0x2ef60b42, 0x2ef60b42, 0xd0985c3d, 0xd0985c3d, 0x8628c70d, 0x8628c70d, 0xfd4baba8, 0xfd4baba8, 0xaad76619, 0xaad76619, 0xcea8ebd6, 0xcea8ebd6, 0x6c20bcf1, 0x6c20bcf1, 0xeeba475, 0xeeba475, 0x149ff274, 0x149ff274, 0xcebe6493, 0xcebe6493, 0x1e505f4b, 0x1e505f4b, 0x7c12f45a, 0x7c12f45a, 0x41703c44, 0x41703c44, 0x346ba166, 0x346ba166, 0x941fe02f, 0x941fe02f, 0xf5be5bb3, 0xf5be5bb3, 0x3d52a9a2, 0x3d52a9a2, 0x33af135a, 0xd4ee3b2, 0x8e3f61b0, 0x8e3f61b0, }, 45 }, - { "cmdline_cat", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xb96e28e9, 0xb96e28e9, 0x11da3359, 0x11da3359, 0xc36007c7, 0xc36007c7, 0x77a353a1, 0x77a353a1, 0xeb88539b, 0xeb88539b, 0x1e00cd2e, 0x1e00cd2e, 0xcc58d945, 0xcc58d945, 0x967f9311, 0x967f9311, 0x1b4aee63, 0x1b4aee63, 0x93da5a6a, 0x93da5a6a, 0x66934cb7, 0x66934cb7, 0xbbcefdce, 0xbbcefdce, 0x78f492b1, 0x78f492b1, 0x924f313b, 0x924f313b, 0x83d7a122, 0x83d7a122, 0x330676e1, 0x330676e1, 0x4223f775, 0x4223f775, 0xd023d9f8, 0xd023d9f8, 0x4fdf440, 0x4fdf440, 0x308b0685, 0x308b0685, 0xdc63a02b, 0x9502eb7f, 0x8a3a85e2, 0x8a3a85e2, }, 45 }, - { "cmdline_cat", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x53572ec9, 0x53572ec9, 0xeceb44e4, 0xeceb44e4, 0x5278dfd2, 0x5278dfd2, 0x2ed7d0d4, 0x2ed7d0d4, 0xa3440592, 0xa3440592, 0x92ffa5c6, 0x92ffa5c6, 0xaff2ad3e, 0xaff2ad3e, 0x2a31cab3, 0x2a31cab3, 0x299ef74e, 0x299ef74e, 0x76e54e80, 0x76e54e80, 0xb964e0f3, 0xb964e0f3, 0x2106b636, 0x2106b636, 0x1ee23596, 0x1ee23596, 0xeb3c9e13, 0xeb3c9e13, 0x1aa29e04, 0x1aa29e04, 0x7a262f24, 0x7a262f24, 0x467ad56a, 0x467ad56a, 0xd985c883, 0xd985c883, 0x7e57edbf, 0x7e57edbf, 0xf9d8e719, 0xf9d8e719, 0x1df01339, 0xf04bbace, 0x2a481eef, 0x2a481eef, }, 45 }, - { "gfxterm_menu", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xa9354fc3, 0xcffaa340, 0xa9354fc3, 0xeac38284, 0x59c36f00, 0x59c36f00, 0x935c7fca, 0x935c7fca, 0x935c7fca, 0xeddc12ac, 0xeddc12ac, 0xeddc12ac, 0x8f2a077e, 0x8f2a077e, 0x8f2a077e, 0x59c36f00, 0xeac38284, 0xeac38284, 0x59c36f00, }, 20 }, - { "gfxterm_menu", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xe1081bb8, 0x45229c00, 0xe1081bb8, 0xcf0d9ec7, 0xaa4593fe, 0xaa4593fe, 0x4b2baf4c, 0x4b2baf4c, 0x4b2baf4c, 0xeddea22b, 0xeddea22b, 0xeddea22b, 0xc0e60953, 0xc0e60953, 0xc0e60953, 0xaa4593fe, 0xcf0d9ec7, 0xcf0d9ec7, 0xaa4593fe, }, 20 }, - { "gfxterm_menu", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x75bf9d41, 0xcf33c299, 0x75bf9d41, 0x28a8f0c5, 0xc9cbf769, 0xc9cbf769, 0xf426354c, 0xf426354c, 0xf426354c, 0xafef480, 0xafef480, 0xafef480, 0xe3b44b88, 0xe3b44b88, 0xe3b44b88, 0xc9cbf769, 0x28a8f0c5, 0x28a8f0c5, 0xc9cbf769, }, 20 }, - { "gfxterm_menu", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xc611f412, 0x75b1fd25, 0xc611f412, 0x6847bdca, 0x9813a416, 0x9813a416, 0xac296590, 0xac296590, 0xac296590, 0x3df2e3a3, 0x3df2e3a3, 0x3df2e3a3, 0x2448de73, 0x2448de73, 0x2448de73, 0x9813a416, 0x6847bdca, 0x6847bdca, 0x9813a416, }, 20 }, - { "gfxterm_menu", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xf8d2d04, 0x1f7b3665, 0xf8d2d04, 0x792b18b7, 0x5fcf013d, 0x5fcf013d, 0xc05e35aa, 0xc05e35aa, 0xc05e35aa, 0x124e2ddc, 0x124e2ddc, 0x124e2ddc, 0x43d1243, 0x43d1243, 0x43d1243, 0x5fcf013d, 0x792b18b7, 0x792b18b7, 0x5fcf013d, }, 20 }, - { "gfxterm_menu", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xcec57923, 0x9abdddfd, 0xcec57923, 0xd5c0a324, 0xdd28f52b, 0xdd28f52b, 0x73523a9b, 0x73523a9b, 0x73523a9b, 0x526ec37f, 0x526ec37f, 0x526ec37f, 0x2fd608f3, 0x2fd608f3, 0x2fd608f3, 0xdd28f52b, 0xd5c0a324, 0xd5c0a324, 0xdd28f52b, }, 20 }, - { "gfxterm_menu", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xf5d1bb8f, 0x5e406c32, 0xf5d1bb8f, 0xa6ea00f, 0x43d1f34, 0x43d1f34, 0x4064c649, 0x4064c649, 0x4064c649, 0x3f6e6fe1, 0x3f6e6fe1, 0x3f6e6fe1, 0xa63f6a67, 0xa63f6a67, 0xa63f6a67, 0x43d1f34, 0xa6ea00f, 0xa6ea00f, 0x43d1f34, }, 20 }, - { "gfxmenu", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x1027210c, 0x64e51c81, 0x1027210c, 0x45ca4a8a, 0x9a2e0d26, 0xa90b01bc, 0xa90b01bc, 0xa90b01bc, 0xf5d3f77c, 0xf5d3f77c, 0xf5d3f77c, 0xdc4b39ee, 0xdc4b39ee, 0xdc4b39ee, 0x59c36f00, 0x45ca4a8a, 0x45ca4a8a, }, 18 }, - { "gfxmenu", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x8d12f697, 0xc5b32248, 0x8d12f697, 0x56720aa4, 0xa9d58ccd, 0x11c82fe4, 0x11c82fe4, 0x11c82fe4, 0x449785ee, 0x449785ee, 0x449785ee, 0x2da44da7, 0x2da44da7, 0x2da44da7, 0xaa4593fe, 0x56720aa4, 0x56720aa4, }, 18 }, - { "gfxmenu", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xa5ec9f45, 0xdb7085d8, 0xa5ec9f45, 0x9caf1d3f, 0x5411be8b, 0xc52df491, 0xc52df491, 0xc52df491, 0xba935205, 0xba935205, 0xba935205, 0xf8e7327d, 0xf8e7327d, 0xf8e7327d, 0xc9cbf769, 0x9caf1d3f, 0x9caf1d3f, }, 18 }, - { "gfxmenu", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x1c3742c9, 0xce8e83bf, 0xeb96c838, 0xce8e83bf, 0x73cb3bc1, 0x740d78cf, 0x6a50b915, 0x6a50b915, 0x6a50b915, 0x81f55369, 0x81f55369, 0x81f55369, 0x87be5399, 0x87be5399, 0x87be5399, 0x1c3742c9, 0x73cb3bc1, 0x73cb3bc1, }, 18 }, - { "gfxmenu", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0xcc5a7bed, 0x56a03e51, 0xee7d8d4b, 0x56a03e51, 0x5bdf9413, 0xbcda144c, 0xf841f7f, 0xf841f7f, 0xf841f7f, 0x60cdc36e, 0x60cdc36e, 0x60cdc36e, 0x6d3b5d6d, 0x6d3b5d6d, 0x6d3b5d6d, 0xcc5a7bed, 0x5bdf9413, 0x5bdf9413, }, 18 }, - { "gfxmenu", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xef4a3312, 0xea8a9cf0, 0x8929e522, 0xea8a9cf0, 0x78f3dfbc, 0x5d55a141, 0x5b2ee37, 0x5b2ee37, 0x5b2ee37, 0xc300aa29, 0xc300aa29, 0xc300aa29, 0xd7657a96, 0xd7657a96, 0xd7657a96, 0xef4a3312, 0x78f3dfbc, 0x78f3dfbc, }, 18 }, - { "gfxmenu", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x54e48d80, 0x6dcf1d57, 0x925a4c8f, 0x6dcf1d57, 0x69005b38, 0x6d6bb4bc, 0x8001ca17, 0x8001ca17, 0x8001ca17, 0x1f23cc6, 0x1f23cc6, 0x1f23cc6, 0x975685a9, 0x975685a9, 0x975685a9, 0x54e48d80, 0x69005b38, 0x69005b38, }, 18 }, - { "gfxterm_ar", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x82d8a3c, 0x6cd37a4, 0x82d8a3c, 0x4bdb477b, 0x59c36f00, 0x59c36f00, 0x46da1ede, 0x46da1ede, 0x46da1ede, 0x385a73b8, 0x385a73b8, 0x385a73b8, 0x5aac666a, 0x5aac666a, 0x5aac666a, 0x59c36f00, 0x4bdb477b, 0x4bdb477b, 0x59c36f00, }, 20 }, - { "gfxterm_ar", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x78e61710, 0x8cfbe03c, 0x78e61710, 0x56e3926f, 0xaa4593fe, 0xaa4593fe, 0x8e893728, 0x8e893728, 0x8e893728, 0x287c3a4f, 0x287c3a4f, 0x287c3a4f, 0x5449137, 0x5449137, 0x5449137, 0xaa4593fe, 0x56e3926f, 0x56e3926f, 0xaa4593fe, }, 20 }, - { "gfxterm_ar", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x8616c425, 0x949a7fa8, 0x8616c425, 0xdb01a9a1, 0xc9cbf769, 0xc9cbf769, 0xea2a5113, 0xea2a5113, 0xea2a5113, 0x14f290df, 0x14f290df, 0x14f290df, 0xfdb82fd7, 0xfdb82fd7, 0xfdb82fd7, 0xc9cbf769, 0xdb01a9a1, 0xdb01a9a1, 0xc9cbf769, }, 20 }, - { "gfxterm_ar", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x7b96f2e, 0x1a88dd6f, 0x7b96f2e, 0xa9ef26f6, 0x9813a416, 0x9813a416, 0xc6bba65a, 0xc6bba65a, 0xc6bba65a, 0x57602069, 0x57602069, 0x57602069, 0x4eda1db9, 0x4eda1db9, 0x4eda1db9, 0x9813a416, 0xa9ef26f6, 0xa9ef26f6, 0x9813a416, }, 20 }, - { "gfxterm_ar", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x95679383, 0x54029d22, 0x95679383, 0xe3c1a630, 0x5fcf013d, 0x5fcf013d, 0x7cccc38f, 0x7cccc38f, 0x7cccc38f, 0xaedcdbf9, 0xaedcdbf9, 0xaedcdbf9, 0xb8afe466, 0xb8afe466, 0xb8afe466, 0x5fcf013d, 0xe3c1a630, 0xe3c1a630, 0x5fcf013d, }, 20 }, - { "gfxterm_ar", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xdc1ff783, 0x13e0969e, 0xdc1ff783, 0xc71a2d84, 0xdd28f52b, 0xdd28f52b, 0x9227d7c1, 0x9227d7c1, 0x9227d7c1, 0xb31b2e25, 0xb31b2e25, 0xb31b2e25, 0xcea3e5a9, 0xcea3e5a9, 0xcea3e5a9, 0xdd28f52b, 0xc71a2d84, 0xc71a2d84, 0xdd28f52b, }, 20 }, - { "gfxterm_ar", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x23cfa079, 0x52702665, 0x23cfa079, 0xdc70bbf9, 0x43d1f34, 0x43d1f34, 0x733dddc9, 0x733dddc9, 0x733dddc9, 0xc377461, 0xc377461, 0xc377461, 0x956671e7, 0x956671e7, 0x956671e7, 0x43d1f34, 0xdc70bbf9, 0xdc70bbf9, 0x43d1f34, }, 20 }, - { "gfxterm_cyr", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x4582c049, 0x3db332af, 0x4582c049, 0x6740d0e, 0x59c36f00, 0x59c36f00, 0x1e6dfa2, 0x1e6dfa2, 0x1e6dfa2, 0x7f66b2c4, 0x7f66b2c4, 0x7f66b2c4, 0x1d90a716, 0x1d90a716, 0x1d90a716, 0x59c36f00, 0x6740d0e, 0x6740d0e, 0x59c36f00, }, 20 }, - { "gfxterm_cyr", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xdc8ccbe5, 0x7f38bbe9, 0xdc8ccbe5, 0xf2894e9a, 0xaa4593fe, 0xaa4593fe, 0xb1e9401e, 0xb1e9401e, 0xb1e9401e, 0x171c4d79, 0x171c4d79, 0x171c4d79, 0x3a24e601, 0x3a24e601, 0x3a24e601, 0xaa4593fe, 0xf2894e9a, 0xf2894e9a, 0xaa4593fe, }, 20 }, - { "gfxterm_cyr", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x2ab2ff2f, 0x88773992, 0x2ab2ff2f, 0x77a592ab, 0xc9cbf769, 0xc9cbf769, 0x261a2f75, 0x261a2f75, 0x261a2f75, 0xd8c2eeb9, 0xd8c2eeb9, 0xd8c2eeb9, 0x318851b1, 0x318851b1, 0x318851b1, 0xc9cbf769, 0x77a592ab, 0x77a592ab, 0xc9cbf769, }, 20 }, - { "gfxterm_cyr", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x4937982a, 0x671b7841, 0x4937982a, 0xe761d1f2, 0x9813a416, 0x9813a416, 0x87d79e45, 0x87d79e45, 0x87d79e45, 0x160c1876, 0x160c1876, 0x160c1876, 0xfb625a6, 0xfb625a6, 0xfb625a6, 0x9813a416, 0xe761d1f2, 0xe761d1f2, 0x9813a416, }, 20 }, - { "gfxterm_cyr", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x617eae5c, 0xfad61931, 0x617eae5c, 0x17d89bef, 0x5fcf013d, 0x5fcf013d, 0xde0c1058, 0xde0c1058, 0xde0c1058, 0xc1c082e, 0xc1c082e, 0xc1c082e, 0x1a6f37b1, 0x1a6f37b1, 0x1a6f37b1, 0x5fcf013d, 0x17d89bef, 0x17d89bef, 0x5fcf013d, }, 20 }, - { "gfxterm_cyr", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xfa1ba2c2, 0x640c9857, 0xfa1ba2c2, 0xe11e78c5, 0xdd28f52b, 0xdd28f52b, 0x63b59689, 0x63b59689, 0x63b59689, 0x42896f6d, 0x42896f6d, 0x42896f6d, 0x3f31a4e1, 0x3f31a4e1, 0x3f31a4e1, 0xdd28f52b, 0xe11e78c5, 0xe11e78c5, 0xdd28f52b, }, 20 }, - { "gfxterm_cyr", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x8e48efc2, 0xcc38fe16, 0x8e48efc2, 0x71f7f442, 0x43d1f34, 0x43d1f34, 0xebe57216, 0xebe57216, 0xebe57216, 0x94efdbbe, 0x94efdbbe, 0x94efdbbe, 0xdbede38, 0xdbede38, 0xdbede38, 0x43d1f34, 0x71f7f442, 0x71f7f442, 0x43d1f34, }, 20 }, - { "gfxterm_heb", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x266da594, 0x24b82ab5, 0x266da594, 0x659b68d3, 0x59c36f00, 0x59c36f00, 0xdb8dd8c4, 0xdb8dd8c4, 0xdb8dd8c4, 0xa50db5a2, 0xa50db5a2, 0xa50db5a2, 0xc7fba070, 0xc7fba070, 0xc7fba070, 0x59c36f00, 0x659b68d3, 0x659b68d3, 0x59c36f00, }, 20 }, - { "gfxterm_heb", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xba8fe08d, 0x9d9bc2e, 0xba8fe08d, 0x948a65f2, 0xaa4593fe, 0xaa4593fe, 0xaa152d8e, 0xaa152d8e, 0xaa152d8e, 0xce020e9, 0xce020e9, 0xce020e9, 0x21d88b91, 0x21d88b91, 0x21d88b91, 0xaa4593fe, 0x948a65f2, 0x948a65f2, 0xaa4593fe, }, 20 }, - { "gfxterm_heb", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x9a003828, 0x2ba49253, 0x9a003828, 0xc71755ac, 0xc9cbf769, 0xc9cbf769, 0xaa0a5e12, 0xaa0a5e12, 0xaa0a5e12, 0x54d29fde, 0x54d29fde, 0x54d29fde, 0xbd9820d6, 0xbd9820d6, 0xbd9820d6, 0xc9cbf769, 0xc71755ac, 0xc71755ac, 0xc9cbf769, }, 20 }, - { "gfxterm_heb", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x8187ce81, 0x75269aaa, 0x8187ce81, 0x2fd18759, 0x9813a416, 0x9813a416, 0x12e905c0, 0x12e905c0, 0x12e905c0, 0x833283f3, 0x833283f3, 0x833283f3, 0x9a88be23, 0x9a88be23, 0x9a88be23, 0x9813a416, 0x2fd18759, 0x2fd18759, 0x9813a416, }, 20 }, - { "gfxterm_heb", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x500d0c44, 0x70d2d942, 0x500d0c44, 0x26ab39f7, 0x5fcf013d, 0x5fcf013d, 0x5bde93cf, 0x5bde93cf, 0x5bde93cf, 0x89ce8bb9, 0x89ce8bb9, 0x89ce8bb9, 0x9fbdb426, 0x9fbdb426, 0x9fbdb426, 0x5fcf013d, 0x26ab39f7, 0x26ab39f7, 0x5fcf013d, }, 20 }, - { "gfxterm_heb", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x16591b36, 0x21c0f059, 0x16591b36, 0xd5cc131, 0xdd28f52b, 0xdd28f52b, 0x2010760f, 0x2010760f, 0x2010760f, 0x12c8feb, 0x12c8feb, 0x12c8feb, 0x7c944467, 0x7c944467, 0x7c944467, 0xdd28f52b, 0xd5cc131, 0xd5cc131, 0xdd28f52b, }, 20 }, - { "gfxterm_heb", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xddbfde17, 0xfb121565, 0xddbfde17, 0x2200c597, 0x43d1f34, 0x43d1f34, 0xb6333f22, 0xb6333f22, 0xb6333f22, 0xc939968a, 0xc939968a, 0xc939968a, 0x5068930c, 0x5068930c, 0x5068930c, 0x43d1f34, 0x2200c597, 0x2200c597, 0x43d1f34, }, 20 }, - { "gfxterm_gre", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xde6eb23f, 0x622ba005, 0xde6eb23f, 0x9d987f78, 0x59c36f00, 0x59c36f00, 0xfaf9dd19, 0xfaf9dd19, 0xfaf9dd19, 0x8479b07f, 0x8479b07f, 0x8479b07f, 0xe68fa5ad, 0xe68fa5ad, 0xe68fa5ad, 0x59c36f00, 0x9d987f78, 0x9d987f78, 0x59c36f00, }, 20 }, - { "gfxterm_gre", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x920dc865, 0x643d1348, 0x920dc865, 0xbc084d1a, 0xaa4593fe, 0xaa4593fe, 0xb332a002, 0xb332a002, 0xb332a002, 0x15c7ad65, 0x15c7ad65, 0x15c7ad65, 0x38ff061d, 0x38ff061d, 0x38ff061d, 0xaa4593fe, 0xbc084d1a, 0xbc084d1a, 0xaa4593fe, }, 20 }, - { "gfxterm_gre", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xae96dbc6, 0x1d9c4918, 0xae96dbc6, 0xf381b642, 0xc9cbf769, 0xc9cbf769, 0x9bd7a35, 0x9bd7a35, 0x9bd7a35, 0xf765bbf9, 0xf765bbf9, 0xf765bbf9, 0x1e2f04f1, 0x1e2f04f1, 0x1e2f04f1, 0xc9cbf769, 0xf381b642, 0xf381b642, 0xc9cbf769, }, 20 }, - { "gfxterm_gre", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x68ab5a83, 0x1dedd3f0, 0x68ab5a83, 0xc6fd135b, 0x9813a416, 0x9813a416, 0xfe9f04ad, 0xfe9f04ad, 0xfe9f04ad, 0x6f44829e, 0x6f44829e, 0x6f44829e, 0x76febf4e, 0x76febf4e, 0x76febf4e, 0x9813a416, 0xc6fd135b, 0xc6fd135b, 0x9813a416, }, 20 }, - { "gfxterm_gre", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xa113e90c, 0xc3b993d8, 0xa113e90c, 0xd7b5dcbf, 0x5fcf013d, 0x5fcf013d, 0xd4453517, 0xd4453517, 0xd4453517, 0x6552d61, 0x6552d61, 0x6552d61, 0x102612fe, 0x102612fe, 0x102612fe, 0x5fcf013d, 0xd7b5dcbf, 0xd7b5dcbf, 0x5fcf013d, }, 20 }, - { "gfxterm_gre", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xd74db26e, 0xfee01078, 0xd74db26e, 0xcc486869, 0xdd28f52b, 0xdd28f52b, 0x5b477f04, 0x5b477f04, 0x5b477f04, 0x7a7b86e0, 0x7a7b86e0, 0x7a7b86e0, 0x7c34d6c, 0x7c34d6c, 0x7c34d6c, 0xdd28f52b, 0xcc486869, 0xcc486869, 0xdd28f52b, }, 20 }, - { "gfxterm_gre", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xa80953f6, 0x13208dce, 0xa80953f6, 0x57b64876, 0x43d1f34, 0x43d1f34, 0x15662f13, 0x15662f13, 0x15662f13, 0x6a6c86bb, 0x6a6c86bb, 0x6a6c86bb, 0xf33d833d, 0xf33d833d, 0xf33d833d, 0x43d1f34, 0x57b64876, 0x57b64876, 0x43d1f34, }, 20 }, - { "gfxterm_ru", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x28730c5a, 0x10c504c1, 0x28730c5a, 0x6b85c11d, 0x59c36f00, 0x59c36f00, 0xe2713dc2, 0xe2713dc2, 0xe2713dc2, 0x9cf150a4, 0x9cf150a4, 0x9cf150a4, 0xfe074576, 0xfe074576, 0xfe074576, 0x59c36f00, 0x6b85c11d, 0x6b85c11d, 0x59c36f00, }, 20 }, - { "gfxterm_ru", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xa6720cda, 0x79326293, 0xa6720cda, 0x887789a5, 0xaa4593fe, 0xaa4593fe, 0xf5a98049, 0xf5a98049, 0xf5a98049, 0x535c8d2e, 0x535c8d2e, 0x535c8d2e, 0x7e642656, 0x7e642656, 0x7e642656, 0xaa4593fe, 0x887789a5, 0x887789a5, 0xaa4593fe, }, 20 }, - { "gfxterm_ru", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xefc130b0, 0xc15c12f3, 0xefc130b0, 0xb2d65d34, 0xc9cbf769, 0xc9cbf769, 0xb80d0c51, 0xb80d0c51, 0xb80d0c51, 0x46d5cd9d, 0x46d5cd9d, 0x46d5cd9d, 0xaf9f7295, 0xaf9f7295, 0xaf9f7295, 0xc9cbf769, 0xb2d65d34, 0xb2d65d34, 0xc9cbf769, }, 20 }, - { "gfxterm_ru", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xd363ab7, 0x7fdff86a, 0xd363ab7, 0xa360736f, 0x9813a416, 0x9813a416, 0xf0212278, 0xf0212278, 0xf0212278, 0x61faa44b, 0x61faa44b, 0x61faa44b, 0x7840999b, 0x7840999b, 0x7840999b, 0x9813a416, 0xa360736f, 0xa360736f, 0x9813a416, }, 20 }, - { "gfxterm_ru", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xdd4249ff, 0xf4a0d4a3, 0xdd4249ff, 0xabe47c4c, 0x5fcf013d, 0x5fcf013d, 0x4170c1bb, 0x4170c1bb, 0x4170c1bb, 0x9360d9cd, 0x9360d9cd, 0x9360d9cd, 0x8513e652, 0x8513e652, 0x8513e652, 0x5fcf013d, 0xabe47c4c, 0xabe47c4c, 0x5fcf013d, }, 20 }, - { "gfxterm_ru", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xdf2ffd30, 0x53da6bb9, 0xdf2ffd30, 0xc42a2737, 0xdd28f52b, 0xdd28f52b, 0x8077de4, 0x8077de4, 0x8077de4, 0x293b8400, 0x293b8400, 0x293b8400, 0x54834f8c, 0x54834f8c, 0x54834f8c, 0xdd28f52b, 0xc42a2737, 0xc42a2737, 0xdd28f52b, }, 20 }, - { "gfxterm_ru", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xbfb4210a, 0x7a4373, 0xbfb4210a, 0x400b3a8a, 0x43d1f34, 0x43d1f34, 0xd0b7fd4b, 0xd0b7fd4b, 0xd0b7fd4b, 0xafbd54e3, 0xafbd54e3, 0xafbd54e3, 0x36ec5165, 0x36ec5165, 0x36ec5165, 0x43d1f34, 0x400b3a8a, 0x400b3a8a, 0x43d1f34, }, 20 }, - { "gfxterm_fr", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xd6e69c19, 0xfd01b92b, 0xd6e69c19, 0x9510515e, 0x59c36f00, 0x59c36f00, 0xd41a73d2, 0xd41a73d2, 0xd41a73d2, 0xaa9a1eb4, 0xaa9a1eb4, 0xaa9a1eb4, 0xc86c0b66, 0xc86c0b66, 0xc86c0b66, 0x59c36f00, 0x9510515e, 0x9510515e, 0x59c36f00, }, 20 }, - { "gfxterm_fr", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x770e32e, 0xf0e77497, 0x770e32e, 0x29756651, 0xaa4593fe, 0xaa4593fe, 0x9e257fc7, 0x9e257fc7, 0x9e257fc7, 0x38d072a0, 0x38d072a0, 0x38d072a0, 0x15e8d9d8, 0x15e8d9d8, 0x15e8d9d8, 0xaa4593fe, 0x29756651, 0x29756651, 0xaa4593fe, }, 20 }, - { "gfxterm_fr", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xa2fe1c87, 0x3e7869d8, 0xa2fe1c87, 0xffe97103, 0xc9cbf769, 0xc9cbf769, 0xc5920970, 0xc5920970, 0xc5920970, 0x3b4ac8bc, 0x3b4ac8bc, 0x3b4ac8bc, 0xd20077b4, 0xd20077b4, 0xd20077b4, 0xc9cbf769, 0xffe97103, 0xffe97103, 0xc9cbf769, }, 20 }, - { "gfxterm_fr", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x551e28a2, 0x117eec93, 0x551e28a2, 0xfb48617a, 0x9813a416, 0x9813a416, 0x9bd613bc, 0x9bd613bc, 0x9bd613bc, 0xa0d958f, 0xa0d958f, 0xa0d958f, 0x13b7a85f, 0x13b7a85f, 0x13b7a85f, 0x9813a416, 0xfb48617a, 0xfb48617a, 0x9813a416, }, 20 }, - { "gfxterm_fr", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xb371f66c, 0x6f3a4cc9, 0xb371f66c, 0xc5d7c3df, 0x5fcf013d, 0x5fcf013d, 0x1cfef603, 0x1cfef603, 0x1cfef603, 0xceeeee75, 0xceeeee75, 0xceeeee75, 0xd89dd1ea, 0xd89dd1ea, 0xd89dd1ea, 0x5fcf013d, 0xc5d7c3df, 0xc5d7c3df, 0x5fcf013d, }, 20 }, - { "gfxterm_fr", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xc6b72d49, 0xedbe4dae, 0xc6b72d49, 0xddb2f74e, 0xdd28f52b, 0xdd28f52b, 0x86b465e5, 0x86b465e5, 0x86b465e5, 0xa7889c01, 0xa7889c01, 0xa7889c01, 0xda30578d, 0xda30578d, 0xda30578d, 0xdd28f52b, 0xddb2f74e, 0xddb2f74e, 0xdd28f52b, }, 20 }, - { "gfxterm_fr", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x5e2e17e4, 0x9bf82c1b, 0x5e2e17e4, 0xa1910c64, 0x43d1f34, 0x43d1f34, 0x823d979, 0x823d979, 0x823d979, 0x772970d1, 0x772970d1, 0x772970d1, 0xee787557, 0xee787557, 0xee787557, 0x43d1f34, 0xa1910c64, 0xa1910c64, 0x43d1f34, }, 20 }, - { "gfxterm_quot", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x15d42b6c, 0x731bc7ef, 0x15d42b6c, 0x5622e62b, 0x59c36f00, 0x59c36f00, 0x935c7fca, 0x935c7fca, 0x935c7fca, 0xeddc12ac, 0xeddc12ac, 0xeddc12ac, 0x8f2a077e, 0x8f2a077e, 0x8f2a077e, 0x59c36f00, 0x5622e62b, 0x5622e62b, 0x59c36f00, }, 20 }, - { "gfxterm_quot", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x58683e3c, 0xfc42b984, 0x58683e3c, 0x766dbb43, 0xaa4593fe, 0xaa4593fe, 0x4b2baf4c, 0x4b2baf4c, 0x4b2baf4c, 0xeddea22b, 0xeddea22b, 0xeddea22b, 0xc0e60953, 0xc0e60953, 0xc0e60953, 0xaa4593fe, 0x766dbb43, 0x766dbb43, 0xaa4593fe, }, 20 }, - { "gfxterm_quot", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xf5d76d17, 0x4f5b32cf, 0xf5d76d17, 0xa8c00093, 0xc9cbf769, 0xc9cbf769, 0xf426354c, 0xf426354c, 0xf426354c, 0xafef480, 0xafef480, 0xafef480, 0xe3b44b88, 0xe3b44b88, 0xe3b44b88, 0xc9cbf769, 0xa8c00093, 0xa8c00093, 0xc9cbf769, }, 20 }, - { "gfxterm_quot", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x73304730, 0xc0904e07, 0x73304730, 0xdd660ee8, 0x9813a416, 0x9813a416, 0xac296590, 0xac296590, 0xac296590, 0x3df2e3a3, 0x3df2e3a3, 0x3df2e3a3, 0x2448de73, 0x2448de73, 0x2448de73, 0x9813a416, 0xdd660ee8, 0xdd660ee8, 0x9813a416, }, 20 }, - { "gfxterm_quot", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x4daec3fc, 0x5d58d89d, 0x4daec3fc, 0x3b08f64f, 0x5fcf013d, 0x5fcf013d, 0xc05e35aa, 0xc05e35aa, 0xc05e35aa, 0x124e2ddc, 0x124e2ddc, 0x124e2ddc, 0x43d1243, 0x43d1243, 0x43d1243, 0x5fcf013d, 0x3b08f64f, 0x3b08f64f, 0x5fcf013d, }, 20 }, - { "gfxterm_quot", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x5af5f85c, 0xe8d5c82, 0x5af5f85c, 0x41f0225b, 0xdd28f52b, 0xdd28f52b, 0x73523a9b, 0x73523a9b, 0x73523a9b, 0x526ec37f, 0x526ec37f, 0x526ec37f, 0x2fd608f3, 0x2fd608f3, 0x2fd608f3, 0xdd28f52b, 0x41f0225b, 0x41f0225b, 0xdd28f52b, }, 20 }, - { "gfxterm_quot", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xb819f982, 0x13882e3f, 0xb819f982, 0x47a6e202, 0x43d1f34, 0x43d1f34, 0x4064c649, 0x4064c649, 0x4064c649, 0x3f6e6fe1, 0x3f6e6fe1, 0x3f6e6fe1, 0xa63f6a67, 0xa63f6a67, 0xa63f6a67, 0x43d1f34, 0x47a6e202, 0x47a6e202, 0x43d1f34, }, 20 }, - { "gfxterm_piglatin", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x4e09ed16, 0x1b959f2, 0x4e09ed16, 0xdff2051, 0x59c36f00, 0x59c36f00, 0x9d5feea7, 0x9d5feea7, 0x9d5feea7, 0xe3df83c1, 0xe3df83c1, 0xe3df83c1, 0x81299613, 0x81299613, 0x81299613, 0x59c36f00, 0xdff2051, 0xdff2051, 0x59c36f00, }, 20 }, - { "gfxterm_piglatin", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xb4fe3633, 0xbd9a0250, 0xb4fe3633, 0x9afbb34c, 0xaa4593fe, 0xaa4593fe, 0x8d224121, 0x8d224121, 0x8d224121, 0x2bd74c46, 0x2bd74c46, 0x2bd74c46, 0x6efe73e, 0x6efe73e, 0x6efe73e, 0xaa4593fe, 0x9afbb34c, 0x9afbb34c, 0xaa4593fe, }, 20 }, - { "gfxterm_piglatin", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x19cdf337, 0xd89c052a, 0x19cdf337, 0x44da9eb3, 0xc9cbf769, 0xc9cbf769, 0x203fc41b, 0x203fc41b, 0x203fc41b, 0xdee705d7, 0xdee705d7, 0xdee705d7, 0x37adbadf, 0x37adbadf, 0x37adbadf, 0xc9cbf769, 0x44da9eb3, 0x44da9eb3, 0xc9cbf769, }, 20 }, - { "gfxterm_piglatin", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x5bd9226d, 0x73b88c1, 0x5bd9226d, 0xf58f6bb5, 0x9813a416, 0x9813a416, 0x60c7ae6c, 0x60c7ae6c, 0x60c7ae6c, 0xf11c285f, 0xf11c285f, 0xf11c285f, 0xe8a6158f, 0xe8a6158f, 0xe8a6158f, 0x9813a416, 0xf58f6bb5, 0xf58f6bb5, 0x9813a416, }, 20 }, - { "gfxterm_piglatin", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x5bee0c71, 0x22fee848, 0x5bee0c71, 0x2d4839c2, 0x5fcf013d, 0x5fcf013d, 0x56213219, 0x56213219, 0x56213219, 0x84312a6f, 0x84312a6f, 0x84312a6f, 0x924215f0, 0x924215f0, 0x924215f0, 0x5fcf013d, 0x2d4839c2, 0x2d4839c2, 0x5fcf013d, }, 20 }, - { "gfxterm_piglatin", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x56e6fad4, 0x3c9e4aea, 0x56e6fad4, 0x4de320d3, 0xdd28f52b, 0xdd28f52b, 0x83d6662d, 0x83d6662d, 0x83d6662d, 0xa2ea9fc9, 0xa2ea9fc9, 0xa2ea9fc9, 0xdf525445, 0xdf525445, 0xdf525445, 0xdd28f52b, 0x4de320d3, 0x4de320d3, 0xdd28f52b, }, 20 }, - { "gfxterm_piglatin", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xfde17453, 0xe772a7a, 0xfde17453, 0x25e6fd3, 0x43d1f34, 0x43d1f34, 0xad2497d2, 0xad2497d2, 0xad2497d2, 0xd22e3e7a, 0xd22e3e7a, 0xd22e3e7a, 0x4b7f3bfc, 0x4b7f3bfc, 0x4b7f3bfc, 0x43d1f34, 0x25e6fd3, 0x25e6fd3, 0x43d1f34, }, 20 }, - { "gfxterm_ch", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x5112a279, 0x63608f0d, 0x5112a279, 0x12e46f3e, 0x59c36f00, 0x59c36f00, 0x64cc7367, 0x64cc7367, 0x64cc7367, 0x1a4c1e01, 0x1a4c1e01, 0x1a4c1e01, 0x78ba0bd3, 0x78ba0bd3, 0x78ba0bd3, 0x59c36f00, 0x12e46f3e, 0x12e46f3e, 0x59c36f00, }, 20 }, - { "gfxterm_ch", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x428dd311, 0x6168e994, 0x428dd311, 0x6c88566e, 0xaa4593fe, 0xaa4593fe, 0x9a464f37, 0x9a464f37, 0x9a464f37, 0x3cb34250, 0x3cb34250, 0x3cb34250, 0x118be928, 0x118be928, 0x118be928, 0xaa4593fe, 0x6c88566e, 0x6c88566e, 0xaa4593fe, }, 20 }, - { "gfxterm_ch", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xc71c50d3, 0xf111a91c, 0xc71c50d3, 0x9a0b3d57, 0xc9cbf769, 0xc9cbf769, 0x9bc1473d, 0x9bc1473d, 0x9bc1473d, 0x651986f1, 0x651986f1, 0x651986f1, 0x8c5339f9, 0x8c5339f9, 0x8c5339f9, 0xc9cbf769, 0x9a0b3d57, 0x9a0b3d57, 0xc9cbf769, }, 20 }, - { "gfxterm_ch", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x61d6a73a, 0xf4179296, 0x61d6a73a, 0xcf80eee2, 0x9813a416, 0x9813a416, 0x841b9482, 0x841b9482, 0x841b9482, 0x15c012b1, 0x15c012b1, 0x15c012b1, 0xc7a2f61, 0xc7a2f61, 0xc7a2f61, 0x9813a416, 0xcf80eee2, 0xcf80eee2, 0x9813a416, }, 20 }, - { "gfxterm_ch", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x9b88583d, 0x4c7bf28e, 0x9b88583d, 0xed2e6d8e, 0x5fcf013d, 0x5fcf013d, 0x31e3f856, 0x31e3f856, 0x31e3f856, 0xe3f3e020, 0xe3f3e020, 0xe3f3e020, 0xf580dfbf, 0xf580dfbf, 0xf580dfbf, 0x5fcf013d, 0xed2e6d8e, 0xed2e6d8e, 0x5fcf013d, }, 20 }, - { "gfxterm_ch", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x77b18e2f, 0xe8e63830, 0x77b18e2f, 0x6cb45428, 0xdd28f52b, 0xdd28f52b, 0x8c504561, 0x8c504561, 0x8c504561, 0xad6cbc85, 0xad6cbc85, 0xad6cbc85, 0xd0d47709, 0xd0d47709, 0xd0d47709, 0xdd28f52b, 0x6cb45428, 0x6cb45428, 0xdd28f52b, }, 20 }, - { "gfxterm_ch", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xc7bba485, 0x9b3a97f6, 0xc7bba485, 0x3804bf05, 0x43d1f34, 0x43d1f34, 0xb57a04a9, 0xb57a04a9, 0xb57a04a9, 0xca70ad01, 0xca70ad01, 0xca70ad01, 0x5321a887, 0x5321a887, 0x5321a887, 0x43d1f34, 0x3804bf05, 0x3804bf05, 0x43d1f34, }, 20 }, - { "gfxterm_red", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x1d498e, 0x66d2a50d, 0x1d498e, 0x5730f750, 0x59c36f00, 0x59c36f00, 0xfafd31bc, 0xfafd31bc, 0xfafd31bc, 0x847d5cda, 0x847d5cda, 0x847d5cda, 0xe68b4908, 0xe68b4908, 0xe68b4908, 0x59c36f00, 0x5730f750, 0x5730f750, 0x59c36f00, }, 20 }, - { "gfxterm_red", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xf23a914f, 0x561016f7, 0xf23a914f, 0x429d4b19, 0xaa4593fe, 0xaa4593fe, 0xc03115b6, 0xc03115b6, 0xc03115b6, 0x66c418d1, 0x66c418d1, 0x66c418d1, 0x4bfcb3a9, 0x4bfcb3a9, 0x4bfcb3a9, 0xaa4593fe, 0x429d4b19, 0x429d4b19, 0xaa4593fe, }, 20 }, - { "gfxterm_red", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x731ebcf1, 0xc992e329, 0x731ebcf1, 0x633ba25f, 0xc9cbf769, 0xc9cbf769, 0x600022fb, 0x600022fb, 0x600022fb, 0x9ed8e337, 0x9ed8e337, 0x9ed8e337, 0x77925c3f, 0x77925c3f, 0x77925c3f, 0xc9cbf769, 0x633ba25f, 0x633ba25f, 0xc9cbf769, }, 20 }, - { "gfxterm_red", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x4a87e91c, 0xf927e02b, 0x4a87e91c, 0x7af61533, 0x9813a416, 0x9813a416, 0x58a063c0, 0x58a063c0, 0x58a063c0, 0xc97be5f3, 0xc97be5f3, 0xc97be5f3, 0xd0c1d823, 0xd0c1d823, 0xd0c1d823, 0x9813a416, 0x7af61533, 0x7af61533, 0x9813a416, }, 20 }, - { "gfxterm_red", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xb4820844, 0xa4741325, 0xb4820844, 0x1a85e7b1, 0x5fcf013d, 0x5fcf013d, 0x19cab3ea, 0x19cab3ea, 0x19cab3ea, 0xcbdaab9c, 0xcbdaab9c, 0xcbdaab9c, 0xdda99403, 0xdda99403, 0xdda99403, 0x5fcf013d, 0x1a85e7b1, 0x1a85e7b1, 0x5fcf013d, }, 20 }, - { "gfxterm_red", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x52a9ee36, 0x6d14ae8, 0x52a9ee36, 0xdccd25ec, 0xdd28f52b, 0xdd28f52b, 0xb6275f8e, 0xb6275f8e, 0xb6275f8e, 0x971ba66a, 0x971ba66a, 0x971ba66a, 0xeaa36de6, 0xeaa36de6, 0xeaa36de6, 0xdd28f52b, 0xdccd25ec, 0xdccd25ec, 0xdd28f52b, }, 20 }, - { "gfxterm_red", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x6d47d8, 0xabfc9065, 0x6d47d8, 0x9735c178, 0x43d1f34, 0x43d1f34, 0xa8a2bd89, 0xa8a2bd89, 0xa8a2bd89, 0xd7a81421, 0xd7a81421, 0xd7a81421, 0x4ef911a7, 0x4ef911a7, 0x4ef911a7, 0x43d1f34, 0x9735c178, 0x9735c178, 0x43d1f34, }, 20 }, - { "gfxterm_high", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x3a3fb187, 0x5cf05d04, 0x3a3fb187, 0x82751e4d, 0x59c36f00, 0x59c36f00, 0x935c7fca, 0x935c7fca, 0x935c7fca, 0xeddc12ac, 0xeddc12ac, 0xeddc12ac, 0x8f2a077e, 0x8f2a077e, 0x8f2a077e, 0x59c36f00, 0x82751e4d, 0x82751e4d, 0x59c36f00, }, 20 }, - { "gfxterm_high", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x9086a313, 0x34ac24ab, 0x9086a313, 0x53006b9c, 0xaa4593fe, 0xaa4593fe, 0x4b2baf4c, 0x4b2baf4c, 0x4b2baf4c, 0xeddea22b, 0xeddea22b, 0xeddea22b, 0xc0e60953, 0xc0e60953, 0xc0e60953, 0xaa4593fe, 0x53006b9c, 0x53006b9c, 0xaa4593fe, }, 20 }, - { "gfxterm_high", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xb1b455e8, 0xb380a30, 0xb1b455e8, 0xf3d1a9d5, 0xc9cbf769, 0xc9cbf769, 0xf426354c, 0xf426354c, 0xf426354c, 0xafef480, 0xafef480, 0xafef480, 0xe3b44b88, 0xe3b44b88, 0xe3b44b88, 0xc9cbf769, 0xf3d1a9d5, 0xf3d1a9d5, 0xc9cbf769, }, 20 }, - { "gfxterm_high", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x3d86952b, 0x8e269c1c, 0x3d86952b, 0x73953762, 0x9813a416, 0x9813a416, 0xac296590, 0xac296590, 0xac296590, 0x3df2e3a3, 0x3df2e3a3, 0x3df2e3a3, 0x2448de73, 0x2448de73, 0x2448de73, 0x9813a416, 0x73953762, 0x73953762, 0x9813a416, }, 20 }, - { "gfxterm_high", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xcd662d92, 0xdd9036f3, 0xcd662d92, 0x5e0022a5, 0x5fcf013d, 0x5fcf013d, 0xc05e35aa, 0xc05e35aa, 0xc05e35aa, 0x124e2ddc, 0x124e2ddc, 0x124e2ddc, 0x43d1243, 0x43d1243, 0x43d1243, 0x5fcf013d, 0x5e0022a5, 0x5e0022a5, 0x5fcf013d, }, 20 }, - { "gfxterm_high", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x4f4e340f, 0x1b3690d1, 0x4f4e340f, 0xa8c8f051, 0xdd28f52b, 0xdd28f52b, 0x73523a9b, 0x73523a9b, 0x73523a9b, 0x526ec37f, 0x526ec37f, 0x526ec37f, 0x2fd608f3, 0x2fd608f3, 0x2fd608f3, 0xdd28f52b, 0xa8c8f051, 0xa8c8f051, 0xdd28f52b, }, 20 }, - { "gfxterm_high", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xad11478c, 0x6809031, 0xad11478c, 0xd5991923, 0x43d1f34, 0x43d1f34, 0x4064c649, 0x4064c649, 0x4064c649, 0x3f6e6fe1, 0x3f6e6fe1, 0x3f6e6fe1, 0xa63f6a67, 0xa63f6a67, 0xa63f6a67, 0x43d1f34, 0xd5991923, 0xd5991923, 0x43d1f34, }, 20 }, - { "videotest", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x1368a483, 0x1368a483, 0x1368a483, 0x1368a483, 0x1368a483, }, 5 }, - { "videotest", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0x7033079c, 0x7033079c, 0x7033079c, 0x7033079c, 0x7033079c, }, 5 }, - { "videotest", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xff583fbf, 0xff583fbf, 0xff583fbf, 0xff583fbf, 0xff583fbf, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x4c2cef83, 0x1b215a88, 0xe2378595, 0xb53a309e, 0x15f64d5e, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x758f388c, 0xd4442397, 0x33f5784b, 0x923e6350, 0xf97bb902, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xb9f6f52a, 0x4e24e8b7, 0x53beb8e1, 0xa46ca57c, 0x688a184d, }, 5 }, - { "videotest", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x5bd98ce3, 0x15df7962, 0xc7d467e1, 0x89d29260, 0x662e2c16, }, 5 }, - { "videotest", 640, 480, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi256 */, (grub_uint32_t []) { 0xf9847b65, 0xf9847b65, 0xf9847b65, 0xf9847b65, 0xf9847b65, }, 5 }, - { "videotest", 800, 600, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi256 */, (grub_uint32_t []) { 0xc421716d, 0xc421716d, 0xc421716d, 0xc421716d, 0xc421716d, }, 5 }, - { "videotest", 1024, 768, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi256 */, (grub_uint32_t []) { 0x5d46f2a8, 0x5d46f2a8, 0x5d46f2a8, 0x5d46f2a8, 0x5d46f2a8, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 640x480xrgba5550 */, (grub_uint32_t []) { 0x25690db2, 0x25690db2, 0x25690db2, 0x25690db2, 0x25690db2, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 800x600xrgba5550 */, (grub_uint32_t []) { 0x7333f220, 0x7333f220, 0x7333f220, 0x7333f220, 0x7333f220, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 1024x768xrgba5550 */, (grub_uint32_t []) { 0xac52d537, 0xac52d537, 0xac52d537, 0xac52d537, 0xac52d537, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 640x480xrgba5650 */, (grub_uint32_t []) { 0xd4cbcd66, 0xd4cbcd66, 0xd4cbcd66, 0xd4cbcd66, 0xd4cbcd66, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 800x600xrgba5650 */, (grub_uint32_t []) { 0x9d23f9d1, 0x9d23f9d1, 0x9d23f9d1, 0x9d23f9d1, 0x9d23f9d1, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 1024x768xrgba5650 */, (grub_uint32_t []) { 0x89acbf88, 0x89acbf88, 0x89acbf88, 0x89acbf88, 0x89acbf88, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 640x480xrgba8880 */, (grub_uint32_t []) { 0x335fadcb, 0x1f517b5c, 0x6b4200e5, 0x474cd672, 0x8364f797, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 800x600xrgba8880 */, (grub_uint32_t []) { 0xcf9985f8, 0x1d92c7fc, 0x6e637701, 0xbc683505, 0x898016fb, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 1024x768xrgba8880 */, (grub_uint32_t []) { 0xdb824190, 0x378d05dc, 0x670bff9, 0xea7ffbb5, 0x658bcbb3, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 640x480xbgra5550 */, (grub_uint32_t []) { 0x18ed532e, 0x18ed532e, 0x18ed532e, 0x18ed532e, 0x18ed532e, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 800x600xbgra5550 */, (grub_uint32_t []) { 0x2b35b09f, 0x2b35b09f, 0x2b35b09f, 0x2b35b09f, 0x2b35b09f, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 1024x768xbgra5550 */, (grub_uint32_t []) { 0xa24c4d98, 0xa24c4d98, 0xa24c4d98, 0xa24c4d98, 0xa24c4d98, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 640x480xbgra5650 */, (grub_uint32_t []) { 0xc07dde33, 0xc07dde33, 0xc07dde33, 0xc07dde33, 0xc07dde33, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 800x600xbgra5650 */, (grub_uint32_t []) { 0x7e6ed757, 0x7e6ed757, 0x7e6ed757, 0x7e6ed757, 0x7e6ed757, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 1024x768xbgra5650 */, (grub_uint32_t []) { 0x700255dd, 0x700255dd, 0x700255dd, 0x700255dd, 0x700255dd, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 640x480xbgra8880 */, (grub_uint32_t []) { 0x157232bd, 0x5e6bdacd, 0x8341e25d, 0xc8580a2d, 0x3cf9e58c, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 800x600xbgra8880 */, (grub_uint32_t []) { 0xbfafd7cd, 0x51650951, 0x67d61c04, 0x891cc298, 0xab036ae, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 1024x768xbgra8880 */, (grub_uint32_t []) { 0x760580c9, 0xdc6d8205, 0x2739f3a0, 0x8d51f16c, 0xd47d661b, }, 5 }, - { "videotest", 640, 480, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 640x480xbgra8888 */, (grub_uint32_t []) { 0xada3b5f, 0x24cd61a6, 0x56f48ead, 0x78e3d454, 0xb28750bb, }, 5 }, - { "videotest", 800, 600, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 800x600xbgra8888 */, (grub_uint32_t []) { 0x827694e2, 0x9d97c3dd, 0xbdb43a9c, 0xa2556da3, 0xfdf3c81e, }, 5 }, - { "videotest", 1024, 768, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 1024x768xbgra8888 */, (grub_uint32_t []) { 0x664534a5, 0xcd0979a0, 0x3531d85e, 0x9e7d955b, 0xc0aced53, }, 5 }, + { "cmdline_cat", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xc69be699, 0xc69be699, 0xe17fc97c, 0xe17fc97c, 0xc2512486, 0xc2512486, 0x20260761, 0x20260761, 0xe3485349, 0xe3485349, 0x6020b4d9, 0x6020b4d9, 0x1605db98, 0x1605db98, 0xdca51b58, 0xdca51b58, 0xf3d66441, 0xf3d66441, 0x18cb7ce2, 0x18cb7ce2, 0x23b616d9, 0x23b616d9, 0xa1bf5dbf, 0xa1bf5dbf, 0x5e4a8b3d, 0x5e4a8b3d, 0x9933b3d8, 0x9933b3d8, 0xce7be2de, 0xce7be2de, 0x62531729, 0x62531729, 0xc39d3788, 0xc39d3788, 0xf7aee2fe, 0xf7aee2fe, 0xc66f4903, 0xc66f4903, 0x536c922f, 0x536c922f, 0xcb231652, 0x4ae07b67, 0x146816d5, 0x146816d5, }, 45 }, + { "cmdline_cat", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x29d0cfb7, 0x29d0cfb7, 0x4d57ad88, 0x4d57ad88, 0xaf7591cb, 0xaf7591cb, 0xb88e3c0, 0xb88e3c0, 0x5d55a031, 0x5d55a031, 0x4363bcff, 0x4363bcff, 0xe1142833, 0xe1142833, 0x9578c80d, 0x9578c80d, 0xff1f5174, 0xff1f5174, 0x6828d47, 0x6828d47, 0x2a849ae3, 0x2a849ae3, 0x27a811d9, 0x27a811d9, 0x6c42e1cb, 0x6c42e1cb, 0x5bba61f5, 0x5bba61f5, 0xc02ab705, 0xc02ab705, 0xeb3e0e05, 0xeb3e0e05, 0x6f4ce3c, 0x6f4ce3c, 0x2075c50e, 0x2075c50e, 0x54ac7fba, 0x54ac7fba, 0x335d1c21, 0x335d1c21, 0xf923fbd1, 0x1b489d4d, 0x1253eb5e, 0x1253eb5e, }, 45 }, + { "cmdline_cat", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x6ff92a98, 0x6ff92a98, 0xbd8264b3, 0xbd8264b3, 0x5c50282c, 0x5c50282c, 0xd18d6a5a, 0xd18d6a5a, 0x99cea139, 0x99cea139, 0x2590c545, 0x2590c545, 0x55c86045, 0x55c86045, 0xad53ef1e, 0xad53ef1e, 0x5b44a23a, 0x5b44a23a, 0xa255f863, 0xa255f863, 0x85b0bdca, 0x85b0bdca, 0x4220ee1f, 0x4220ee1f, 0xeb991a9f, 0xeb991a9f, 0x86f366dd, 0x86f366dd, 0xfa176b7d, 0xfa176b7d, 0xd7384ca9, 0xd7384ca9, 0xceebf5c1, 0xceebf5c1, 0xae62b268, 0xae62b268, 0x6e89bbd6, 0x6e89bbd6, 0x3fe07c8e, 0x3fe07c8e, 0xee5358fe, 0x162d1a8a, 0x876f8d10, 0x876f8d10, }, 45 }, + { "cmdline_cat", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xb96afaea, 0xb96afaea, 0xaa16ab1e, 0xaa16ab1e, 0x51ff382, 0x51ff382, 0xec74f127, 0xec74f127, 0xde4bca99, 0xde4bca99, 0x8ef3e8a5, 0x8ef3e8a5, 0x2daeb0b4, 0x2daeb0b4, 0x7cf5e243, 0x7cf5e243, 0x11fd57c6, 0x11fd57c6, 0x140723af, 0x140723af, 0x2bd93833, 0x2bd93833, 0xd731f4ac, 0xd731f4ac, 0x5fcd7114, 0x5fcd7114, 0xd1fea24a, 0xd1fea24a, 0x4083d53a, 0x4083d53a, 0x2e372605, 0x2e372605, 0x8e6316a7, 0x8e6316a7, 0x283ef6cc, 0x283ef6cc, 0x20cee9de, 0x20cee9de, 0xad6fa187, 0xad6fa187, 0xd691f438, 0xf3257e63, 0x4786ba7, 0x4786ba7, }, 45 }, + { "cmdline_cat", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x48acf1bf, 0x48acf1bf, 0xb8777469, 0xb8777469, 0xad2fad44, 0xad2fad44, 0xa415ac59, 0xa415ac59, 0x5a7bfb26, 0x5a7bfb26, 0xccb6016, 0xccb6016, 0x77a80cb3, 0x77a80cb3, 0x2034c102, 0x2034c102, 0x444b4ccd, 0x444b4ccd, 0xe6c31bea, 0xe6c31bea, 0x8408036e, 0x8408036e, 0x9e7c556f, 0x9e7c556f, 0x445dc388, 0x445dc388, 0x94b3f850, 0x94b3f850, 0xf6f15341, 0xf6f15341, 0xcb939b5f, 0xcb939b5f, 0xbe88067d, 0xbe88067d, 0x1efc4734, 0x1efc4734, 0x7f5dfca8, 0x7f5dfca8, 0xb7b10eb9, 0xb7b10eb9, 0xb94cb441, 0x9571329, 0x8a26912b, 0x8a26912b, }, 45 }, + { "cmdline_cat", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xc508d04e, 0xc508d04e, 0x6dbccbfe, 0x6dbccbfe, 0xbf06ff60, 0xbf06ff60, 0xbc5ab06, 0xbc5ab06, 0x97eeab3c, 0x97eeab3c, 0x62663589, 0x62663589, 0xb03e21e2, 0xb03e21e2, 0xea196bb6, 0xea196bb6, 0x672c16c4, 0x672c16c4, 0xefbca2cd, 0xefbca2cd, 0x1af5b410, 0x1af5b410, 0xc7a80569, 0xc7a80569, 0x4926a16, 0x4926a16, 0xee29c99c, 0xee29c99c, 0xffb15985, 0xffb15985, 0x4f608e46, 0x4f608e46, 0x3e450fd2, 0x3e450fd2, 0xac45215f, 0xac45215f, 0x789b0ce7, 0x789b0ce7, 0x4cedfe22, 0x4cedfe22, 0xa005588c, 0x701da05c, 0x6f25cec1, 0x6f25cec1, }, 45 }, + { "cmdline_cat", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x29e7a7f, 0x29e7a7f, 0xbd221052, 0xbd221052, 0x3b18b64, 0x3b18b64, 0x7f1e8462, 0x7f1e8462, 0xf28d5124, 0xf28d5124, 0xc336f170, 0xc336f170, 0xfe3bf988, 0xfe3bf988, 0x7bf89e05, 0x7bf89e05, 0x7857a3f8, 0x7857a3f8, 0x272c1a36, 0x272c1a36, 0xe8adb445, 0xe8adb445, 0x70cfe280, 0x70cfe280, 0x4f2b6120, 0x4f2b6120, 0xbaf5caa5, 0xbaf5caa5, 0x4b6bcab2, 0x4b6bcab2, 0x2bef7b92, 0x2bef7b92, 0x17b381dc, 0x17b381dc, 0x884c9c35, 0x884c9c35, 0x2f9eb909, 0x2f9eb909, 0xa811b3af, 0xa811b3af, 0x4c39478f, 0x5a72c3ab, 0x8071678a, 0x8071678a, }, 45 }, + { "gfxterm_menu", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xd9f04953, 0xbf3fa5d0, 0xd9f04953, 0x9a068414, 0x59c36f00, 0x59c36f00, 0x620c0067, 0x620c0067, 0x620c0067, 0x1c8c6d01, 0x1c8c6d01, 0x1c8c6d01, 0xc3269013, 0xc3269013, 0xc3269013, 0x59c36f00, 0x9a068414, 0x9a068414, 0x59c36f00, }, 20 }, + { "gfxterm_menu", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x9254157f, 0x367e92c7, 0x9254157f, 0xbc519000, 0xaa4593fe, 0xaa4593fe, 0xa8a596c8, 0xa8a596c8, 0xa8a596c8, 0xe509baf, 0xe509baf, 0xe509baf, 0x16f0dc06, 0x16f0dc06, 0x16f0dc06, 0xaa4593fe, 0xbc519000, 0xbc519000, 0xaa4593fe, }, 20 }, + { "gfxterm_menu", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x354b1976, 0x8fc746ae, 0x354b1976, 0x685c74f2, 0xc9cbf769, 0xc9cbf769, 0x3ce35e1d, 0x3ce35e1d, 0x3ce35e1d, 0xc23b9fd1, 0xc23b9fd1, 0xc23b9fd1, 0x5b18528e, 0x5b18528e, 0x5b18528e, 0xc9cbf769, 0x685c74f2, 0x685c74f2, 0xc9cbf769, }, 20 }, + { "gfxterm_menu", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x1c9ec014, 0xaf3ec923, 0x1c9ec014, 0x43f5296, 0x9813a416, 0x9813a416, 0x43fda3fa, 0x43fda3fa, 0x43fda3fa, 0xd22625c9, 0xd22625c9, 0xd22625c9, 0x76a62c0a, 0x76a62c0a, 0x76a62c0a, 0x9813a416, 0x43f5296, 0x43f5296, 0x9813a416, }, 20 }, + { "gfxterm_menu", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xa704f7ea, 0xb7f2ec8b, 0xa704f7ea, 0xb279bf59, 0x5fcf013d, 0x5fcf013d, 0xf3582c48, 0xf3582c48, 0xf3582c48, 0x2148343e, 0x2148343e, 0x2148343e, 0x9c719024, 0x9c719024, 0x9c719024, 0x5fcf013d, 0xb279bf59, 0xb279bf59, 0x5fcf013d, }, 20 }, + { "gfxterm_menu", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xf293ce36, 0xa6eb6ae8, 0xf293ce36, 0xcd87647e, 0xdd28f52b, 0xdd28f52b, 0xb3c7ef80, 0xb3c7ef80, 0xb3c7ef80, 0x92fb1664, 0x92fb1664, 0x92fb1664, 0xd15b5e2e, 0xd15b5e2e, 0xd15b5e2e, 0xdd28f52b, 0xcd87647e, 0xcd87647e, 0xdd28f52b, }, 20 }, + { "gfxterm_menu", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x31e75bd7, 0x9a768c6a, 0x31e75bd7, 0xa8fc31a6, 0x43d1f34, 0x43d1f34, 0xa0717008, 0xa0717008, 0xa0717008, 0xdf7bd9a0, 0xdf7bd9a0, 0xdf7bd9a0, 0x8e5a9312, 0x8e5a9312, 0x8e5a9312, 0x43d1f34, 0xa8fc31a6, 0xa8fc31a6, 0x43d1f34, }, 20 }, + { "gfxmenu", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x1ce7bd78, 0x682580f5, 0x1ce7bd78, 0x490ad6fe, 0x9a2e0d26, 0x64eb71ba, 0x64eb71ba, 0x64eb71ba, 0x3833877a, 0x3833877a, 0x3833877a, 0xcfc14f0a, 0xcfc14f0a, 0xcfc14f0a, 0x59c36f00, 0x490ad6fe, 0x490ad6fe, }, 18 }, + { "gfxmenu", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x2b6ff87d, 0x63ce2ca2, 0x2b6ff87d, 0xf00f044e, 0xa9d58ccd, 0xe2c46577, 0xe2c46577, 0xe2c46577, 0xb79bcf7d, 0xb79bcf7d, 0xb79bcf7d, 0xbc30ed71, 0xbc30ed71, 0xbc30ed71, 0xaa4593fe, 0xf00f044e, 0xf00f044e, }, 18 }, + { "gfxmenu", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xe61cadba, 0x9880b727, 0xe61cadba, 0xdf5f2fc0, 0x5411be8b, 0x4449774e, 0x4449774e, 0x4449774e, 0x3bf7d1da, 0x3bf7d1da, 0x3bf7d1da, 0xd2ddee01, 0xd2ddee01, 0xd2ddee01, 0xc9cbf769, 0xdf5f2fc0, 0xdf5f2fc0, }, 18 }, + { "gfxmenu", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x1c3742c9, 0xbe54acf7, 0x9b4ce770, 0xbe54acf7, 0x3111489, 0x740d78cf, 0x314c4c59, 0x314c4c59, 0x314c4c59, 0xdae9a625, 0xdae9a625, 0xdae9a625, 0xcbf8af57, 0xcbf8af57, 0xcbf8af57, 0x1c3742c9, 0x3111489, 0x3111489, }, 18 }, + { "gfxmenu", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0xcc5a7bed, 0xee571de5, 0x568aaeff, 0xee571de5, 0xe328b7a7, 0xbcda144c, 0xf56e1b60, 0xf56e1b60, 0xf56e1b60, 0x9a27c771, 0x9a27c771, 0x9a27c771, 0xd6d05397, 0xd6d05397, 0xd6d05397, 0xcc5a7bed, 0xe328b7a7, 0xe328b7a7, }, 18 }, + { "gfxmenu", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xef4a3312, 0x1db9877c, 0x7e1afeae, 0x1db9877c, 0x8fc0c430, 0x5d55a141, 0x96f335c6, 0x96f335c6, 0x96f335c6, 0x504171d8, 0x504171d8, 0x504171d8, 0x69f71c0, 0x69f71c0, 0x69f71c0, 0xef4a3312, 0x8fc0c430, 0x8fc0c430, }, 18 }, + { "gfxmenu", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x54e48d80, 0x151819bd, 0xea8d4865, 0x151819bd, 0x11d75fd2, 0x6d6bb4bc, 0x650ccd09, 0x650ccd09, 0x650ccd09, 0xe4ff3bd8, 0xe4ff3bd8, 0xe4ff3bd8, 0xc5308b73, 0xc5308b73, 0xc5308b73, 0x54e48d80, 0x11d75fd2, 0x11d75fd2, }, 18 }, + { "gfxterm_ar", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xd0b06c3d, 0xde50d1a5, 0xd0b06c3d, 0x9346a17a, 0x59c36f00, 0x59c36f00, 0xacff5d47, 0xacff5d47, 0xacff5d47, 0xd27f3021, 0xd27f3021, 0xd27f3021, 0xdd5cd33, 0xdd5cd33, 0xdd5cd33, 0x59c36f00, 0x9346a17a, 0x9346a17a, 0x59c36f00, }, 20 }, + { "gfxterm_ar", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xf32d50c1, 0x730a7ed, 0xf32d50c1, 0xdd28d5be, 0xaa4593fe, 0xaa4593fe, 0xba8a2d4c, 0xba8a2d4c, 0xba8a2d4c, 0x1c7f202b, 0x1c7f202b, 0x1c7f202b, 0x4df6782, 0x4df6782, 0x4df6782, 0xaa4593fe, 0xdd28d5be, 0xdd28d5be, 0xaa4593fe, }, 20 }, + { "gfxterm_ar", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x711a4ac1, 0x6396f14c, 0x711a4ac1, 0x2c0d2745, 0xc9cbf769, 0xc9cbf769, 0x6b6ccbb0, 0x6b6ccbb0, 0x6b6ccbb0, 0x95b40a7c, 0x95b40a7c, 0x95b40a7c, 0xc97c723, 0xc97c723, 0xc97c723, 0xc9cbf769, 0x2c0d2745, 0x2c0d2745, 0xc9cbf769, }, 20 }, + { "gfxterm_ar", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x29baad6a, 0x348b1f2b, 0x29baad6a, 0x311b3fe8, 0x9813a416, 0x9813a416, 0xe8e982cc, 0xe8e982cc, 0xe8e982cc, 0x793204ff, 0x793204ff, 0x793204ff, 0xddb20d3c, 0xddb20d3c, 0xddb20d3c, 0x9813a416, 0x311b3fe8, 0x311b3fe8, 0x9813a416, }, 20 }, + { "gfxterm_ar", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xf834b3bb, 0x3951bd1a, 0xf834b3bb, 0xed49fb08, 0x5fcf013d, 0x5fcf013d, 0x5aefa2a7, 0x5aefa2a7, 0x5aefa2a7, 0x88ffbad1, 0x88ffbad1, 0x88ffbad1, 0x35c61ecb, 0x35c61ecb, 0x35c61ecb, 0x5fcf013d, 0xed49fb08, 0xed49fb08, 0x5fcf013d, }, 20 }, + { "gfxterm_ar", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x7e9a7a47, 0xb1651b5a, 0x7e9a7a47, 0x418ed00f, 0xdd28f52b, 0xdd28f52b, 0x83f9db69, 0x83f9db69, 0x83f9db69, 0xa2c5228d, 0xa2c5228d, 0xa2c5228d, 0xe1656ac7, 0xe1656ac7, 0xe1656ac7, 0xdd28f52b, 0x418ed00f, 0x418ed00f, 0xdd28f52b, }, 20 }, + { "gfxterm_ar", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xc6a0340, 0x7dd5855c, 0xc6a0340, 0x95716931, 0x43d1f34, 0x43d1f34, 0x5f1c24c0, 0x5f1c24c0, 0x5f1c24c0, 0x20168d68, 0x20168d68, 0x20168d68, 0x7137c7da, 0x7137c7da, 0x7137c7da, 0x43d1f34, 0x95716931, 0x95716931, 0x43d1f34, }, 20 }, + { "gfxterm_cyr", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xd3798aaa, 0xab48784c, 0xd3798aaa, 0x908f47ed, 0x59c36f00, 0x59c36f00, 0x1688ec7c, 0x1688ec7c, 0x1688ec7c, 0x6808811a, 0x6808811a, 0x6808811a, 0xb7a27c08, 0xb7a27c08, 0xb7a27c08, 0x59c36f00, 0x908f47ed, 0x908f47ed, 0x59c36f00, }, 20 }, + { "gfxterm_cyr", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xc30d9d2a, 0x60b9ed26, 0xc30d9d2a, 0xed081855, 0xaa4593fe, 0xaa4593fe, 0x3eba2192, 0x3eba2192, 0x3eba2192, 0x984f2cf5, 0x984f2cf5, 0x984f2cf5, 0x80ef6b5c, 0x80ef6b5c, 0x80ef6b5c, 0xaa4593fe, 0xed081855, 0xed081855, 0xaa4593fe, }, 20 }, + { "gfxterm_cyr", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xe469e6af, 0x46ac2012, 0xe469e6af, 0xb97e8b2b, 0xc9cbf769, 0xc9cbf769, 0x60f0d993, 0x60f0d993, 0x60f0d993, 0x9e28185f, 0x9e28185f, 0x9e28185f, 0x70bd500, 0x70bd500, 0x70bd500, 0xc9cbf769, 0xb97e8b2b, 0xb97e8b2b, 0xc9cbf769, }, 20 }, + { "gfxterm_cyr", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x8538d2ef, 0xab143284, 0x8538d2ef, 0x9d99406d, 0x9813a416, 0x9813a416, 0x7e8326ec, 0x7e8326ec, 0x7e8326ec, 0xef58a0df, 0xef58a0df, 0xef58a0df, 0x4bd8a91c, 0x4bd8a91c, 0x4bd8a91c, 0x9813a416, 0x9d99406d, 0x9d99406d, 0x9813a416, }, 20 }, + { "gfxterm_cyr", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x8115198c, 0x1abdaee1, 0x8115198c, 0x9468513f, 0x5fcf013d, 0x5fcf013d, 0xa5e86484, 0xa5e86484, 0xa5e86484, 0x77f87cf2, 0x77f87cf2, 0x77f87cf2, 0xcac1d8e8, 0xcac1d8e8, 0xcac1d8e8, 0x5fcf013d, 0x9468513f, 0x9468513f, 0x5fcf013d, }, 20 }, + { "gfxterm_cyr", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xea03b805, 0x74148290, 0xea03b805, 0xd517124d, 0xdd28f52b, 0xdd28f52b, 0x8f6eee40, 0x8f6eee40, 0x8f6eee40, 0xae5217a4, 0xae5217a4, 0xae5217a4, 0xedf25fee, 0xedf25fee, 0xedf25fee, 0xdd28f52b, 0xd517124d, 0xd517124d, 0xdd28f52b, }, 20 }, + { "gfxterm_cyr", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xa044490f, 0xe23458db, 0xa044490f, 0x395f237e, 0x43d1f34, 0x43d1f34, 0xe1ca82c2, 0xe1ca82c2, 0xe1ca82c2, 0x9ec02b6a, 0x9ec02b6a, 0x9ec02b6a, 0xcfe161d8, 0xcfe161d8, 0xcfe161d8, 0x43d1f34, 0x395f237e, 0x395f237e, 0x43d1f34, }, 20 }, + { "gfxterm_heb", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xf3259b30, 0xf1f01411, 0xf3259b30, 0xb0d35677, 0x59c36f00, 0x59c36f00, 0x97895f8e, 0x97895f8e, 0x97895f8e, 0xe90932e8, 0xe90932e8, 0xe90932e8, 0x36a3cffa, 0x36a3cffa, 0x36a3cffa, 0x59c36f00, 0xb0d35677, 0xb0d35677, 0x59c36f00, }, 20 }, + { "gfxterm_heb", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x53a43759, 0xe0f26bfa, 0x53a43759, 0x7da1b226, 0xaa4593fe, 0xaa4593fe, 0xbf482a4e, 0xbf482a4e, 0xbf482a4e, 0x19bd2729, 0x19bd2729, 0x19bd2729, 0x11d6080, 0x11d6080, 0x11d6080, 0xaa4593fe, 0x7da1b226, 0x7da1b226, 0xaa4593fe, }, 20 }, + { "gfxterm_heb", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xd7ff8d53, 0x665b2728, 0xd7ff8d53, 0x8ae8e0d7, 0xc9cbf769, 0xc9cbf769, 0x5a693e73, 0x5a693e73, 0x5a693e73, 0xa4b1ffbf, 0xa4b1ffbf, 0xa4b1ffbf, 0x3d9232e0, 0x3d9232e0, 0x3d9232e0, 0xc9cbf769, 0x8ae8e0d7, 0x8ae8e0d7, 0xc9cbf769, }, 20 }, + { "gfxterm_heb", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x99fddcbe, 0x6d5c8895, 0x99fddcbe, 0x815c4e3c, 0x9813a416, 0x9813a416, 0x9bcf9821, 0x9bcf9821, 0x9bcf9821, 0xa141e12, 0xa141e12, 0xa141e12, 0xae9417d1, 0xae9417d1, 0xae9417d1, 0x9813a416, 0x815c4e3c, 0x815c4e3c, 0x9813a416, }, 20 }, + { "gfxterm_heb", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x5797846, 0x25a6ad40, 0x5797846, 0x100430f5, 0x5fcf013d, 0x5fcf013d, 0xddc86daf, 0xddc86daf, 0xddc86daf, 0xfd875d9, 0xfd875d9, 0xfd875d9, 0xb2e1d1c3, 0xb2e1d1c3, 0xb2e1d1c3, 0x5fcf013d, 0x100430f5, 0x100430f5, 0x5fcf013d, }, 20 }, + { "gfxterm_heb", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x30653ae8, 0x7fcd187, 0x30653ae8, 0xf7190a0, 0xdd28f52b, 0xdd28f52b, 0x24c3d325, 0x24c3d325, 0x24c3d325, 0x5ff2ac1, 0x5ff2ac1, 0x5ff2ac1, 0x465f628b, 0x465f628b, 0x465f628b, 0xdd28f52b, 0xf7190a0, 0xf7190a0, 0xdd28f52b, }, 20 }, + { "gfxterm_heb", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x3bd91638, 0x1d74dd4a, 0x3bd91638, 0xa2c27c49, 0x43d1f34, 0x43d1f34, 0x53d1ad3d, 0x53d1ad3d, 0x53d1ad3d, 0x2cdb0495, 0x2cdb0495, 0x2cdb0495, 0x7dfa4e27, 0x7dfa4e27, 0x7dfa4e27, 0x43d1f34, 0xa2c27c49, 0xa2c27c49, 0x43d1f34, }, 20 }, + { "gfxterm_gre", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xbe2c351a, 0x2692720, 0xbe2c351a, 0xfddaf85d, 0x59c36f00, 0x59c36f00, 0x1b2e2301, 0x1b2e2301, 0x1b2e2301, 0x65ae4e67, 0x65ae4e67, 0x65ae4e67, 0xba04b375, 0xba04b375, 0xba04b375, 0x59c36f00, 0xfddaf85d, 0xfddaf85d, 0x59c36f00, }, 20 }, + { "gfxterm_gre", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x1eca82e1, 0xe8fa59cc, 0x1eca82e1, 0x30cf079e, 0xaa4593fe, 0xaa4593fe, 0xaf27ddc5, 0xaf27ddc5, 0xaf27ddc5, 0x9d2d0a2, 0x9d2d0a2, 0x9d2d0a2, 0x1172970b, 0x1172970b, 0x1172970b, 0xaa4593fe, 0x30cf079e, 0x30cf079e, 0xaa4593fe, }, 20 }, + { "gfxterm_gre", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xa9ccd435, 0x1ac646eb, 0xa9ccd435, 0xf4dbb9b1, 0xc9cbf769, 0xc9cbf769, 0x86d69aa0, 0x86d69aa0, 0x86d69aa0, 0x780e5b6c, 0x780e5b6c, 0x780e5b6c, 0xe12d9633, 0xe12d9633, 0xe12d9633, 0xc9cbf769, 0xf4dbb9b1, 0xf4dbb9b1, 0xc9cbf769, }, 20 }, + { "gfxterm_gre", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xf96d568, 0x7ad05c1b, 0xf96d568, 0x173747ea, 0x9813a416, 0x9813a416, 0xacf9792a, 0xacf9792a, 0xacf9792a, 0x3d22ff19, 0x3d22ff19, 0x3d22ff19, 0x99a2f6da, 0x99a2f6da, 0x99a2f6da, 0x9813a416, 0x173747ea, 0x173747ea, 0x9813a416, }, 20 }, + { "gfxterm_gre", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xa0dc6b9c, 0xc2761148, 0xa0dc6b9c, 0xb5a1232f, 0x5fcf013d, 0x5fcf013d, 0x4e05748b, 0x4e05748b, 0x4e05748b, 0x9c156cfd, 0x9c156cfd, 0x9c156cfd, 0x212cc8e7, 0x212cc8e7, 0x212cc8e7, 0x5fcf013d, 0xb5a1232f, 0xb5a1232f, 0x5fcf013d, }, 20 }, + { "gfxterm_gre", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xcd722f7d, 0xe4df8d6b, 0xcd722f7d, 0xf2668535, 0xdd28f52b, 0xdd28f52b, 0xbdbb8019, 0xbdbb8019, 0xbdbb8019, 0x9c8779fd, 0x9c8779fd, 0x9c8779fd, 0xdf2731b7, 0xdf2731b7, 0xdf2731b7, 0xdd28f52b, 0xf2668535, 0xf2668535, 0xdd28f52b, }, 20 }, + { "gfxterm_gre", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xa6c99d2f, 0x1de04317, 0xa6c99d2f, 0x3fd2f75e, 0x43d1f34, 0x43d1f34, 0x3f85b7d3, 0x3f85b7d3, 0x3f85b7d3, 0x408f1e7b, 0x408f1e7b, 0x408f1e7b, 0x11ae54c9, 0x11ae54c9, 0x11ae54c9, 0x43d1f34, 0x3fd2f75e, 0x3fd2f75e, 0x43d1f34, }, 20 }, + { "gfxterm_ru", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x1e35b709, 0x2683bf92, 0x1e35b709, 0x5dc37a4e, 0x59c36f00, 0x59c36f00, 0xd697967f, 0xd697967f, 0xd697967f, 0xa817fb19, 0xa817fb19, 0xa817fb19, 0x77bd060b, 0x77bd060b, 0x77bd060b, 0x59c36f00, 0x5dc37a4e, 0x5dc37a4e, 0x59c36f00, }, 20 }, + { "gfxterm_ru", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x53ff7735, 0x8cbf197c, 0x53ff7735, 0x7dfaf24a, 0xaa4593fe, 0xaa4593fe, 0x389a922, 0x389a922, 0x389a922, 0xa57ca445, 0xa57ca445, 0xa57ca445, 0xbddce3ec, 0xbddce3ec, 0xbddce3ec, 0xaa4593fe, 0x7dfaf24a, 0x7dfaf24a, 0xaa4593fe, }, 20 }, + { "gfxterm_ru", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x5217c47d, 0x7c8ae63e, 0x5217c47d, 0xf00a9f9, 0xc9cbf769, 0xc9cbf769, 0x3995409, 0x3995409, 0x3995409, 0xfd4195c5, 0xfd4195c5, 0xfd4195c5, 0x6462589a, 0x6462589a, 0x6462589a, 0xc9cbf769, 0xf00a9f9, 0xf00a9f9, 0xc9cbf769, }, 20 }, + { "gfxterm_ru", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x45b67706, 0x375fb5db, 0x45b67706, 0x5d17e584, 0x9813a416, 0x9813a416, 0x8195719b, 0x8195719b, 0x8195719b, 0x104ef7a8, 0x104ef7a8, 0x104ef7a8, 0xb4cefe6b, 0xb4cefe6b, 0xb4cefe6b, 0x9813a416, 0x5d17e584, 0x5d17e584, 0x9813a416, }, 20 }, + { "gfxterm_ru", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xfc209a25, 0xd5c20779, 0xfc209a25, 0xe95dd296, 0x5fcf013d, 0x5fcf013d, 0xe5699efe, 0xe5699efe, 0xe5699efe, 0x37798688, 0x37798688, 0x37798688, 0x8a402292, 0x8a402292, 0x8a402292, 0x5fcf013d, 0xe95dd296, 0xe95dd296, 0x5fcf013d, }, 20 }, + { "gfxterm_ru", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x77f956f0, 0xfb0cc079, 0x77f956f0, 0x48edfcb8, 0xdd28f52b, 0xdd28f52b, 0xd51b1dc9, 0xd51b1dc9, 0xd51b1dc9, 0xf427e42d, 0xf427e42d, 0xf427e42d, 0xb787ac67, 0xb787ac67, 0xb787ac67, 0xdd28f52b, 0x48edfcb8, 0x48edfcb8, 0xdd28f52b, }, 20 }, + { "gfxterm_ru", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x1d9ac82a, 0xa254aa53, 0x1d9ac82a, 0x8481a25b, 0x43d1f34, 0x43d1f34, 0xc304df68, 0xc304df68, 0xc304df68, 0xbc0e76c0, 0xbc0e76c0, 0xbc0e76c0, 0xed2f3c72, 0xed2f3c72, 0xed2f3c72, 0x43d1f34, 0x8481a25b, 0x8481a25b, 0x43d1f34, }, 20 }, + { "gfxterm_fr", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xa6239a89, 0x8dc4bfbb, 0xa6239a89, 0xe5d557ce, 0x59c36f00, 0x59c36f00, 0x244cf807, 0x244cf807, 0x244cf807, 0x5acc9561, 0x5acc9561, 0x5acc9561, 0x85666873, 0x85666873, 0x85666873, 0x59c36f00, 0xe5d557ce, 0xe5d557ce, 0x59c36f00, }, 20 }, + { "gfxterm_fr", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x742cede9, 0x83bb7a50, 0x742cede9, 0x5a296896, 0xaa4593fe, 0xaa4593fe, 0xd83f8aeb, 0xd83f8aeb, 0xd83f8aeb, 0x7eca878c, 0x7eca878c, 0x7eca878c, 0x666ac025, 0x666ac025, 0x666ac025, 0xaa4593fe, 0x5a296896, 0x5a296896, 0xaa4593fe, }, 20 }, + { "gfxterm_fr", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xe20a98b0, 0x7e8cedef, 0xe20a98b0, 0xbf1df534, 0xc9cbf769, 0xc9cbf769, 0x2748b88c, 0x2748b88c, 0x2748b88c, 0xd9907940, 0xd9907940, 0xd9907940, 0x40b3b41f, 0x40b3b41f, 0x40b3b41f, 0xc9cbf769, 0xbf1df534, 0xbf1df534, 0xc9cbf769, }, 20 }, + { "gfxterm_fr", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x8f911ca4, 0xcbf1d895, 0x8f911ca4, 0x97308e26, 0x9813a416, 0x9813a416, 0x5b359bf4, 0x5b359bf4, 0x5b359bf4, 0xcaee1dc7, 0xcaee1dc7, 0xcaee1dc7, 0x6e6e1404, 0x6e6e1404, 0x6e6e1404, 0x9813a416, 0x97308e26, 0x97308e26, 0x9813a416, }, 20 }, + { "gfxterm_fr", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x1bf82c82, 0xc7b39627, 0x1bf82c82, 0xe856431, 0x5fcf013d, 0x5fcf013d, 0xa9dbae99, 0xa9dbae99, 0xa9dbae99, 0x7bcbb6ef, 0x7bcbb6ef, 0x7bcbb6ef, 0xc6f212f5, 0xc6f212f5, 0xc6f212f5, 0x5fcf013d, 0xe856431, 0xe856431, 0x5fcf013d, }, 20 }, + { "gfxterm_fr", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xfae19a5c, 0xd1e8fabb, 0xfae19a5c, 0xc5f53014, 0xdd28f52b, 0xdd28f52b, 0xfa2c5565, 0xfa2c5565, 0xfa2c5565, 0xdb10ac81, 0xdb10ac81, 0xdb10ac81, 0x98b0e4cb, 0x98b0e4cb, 0x98b0e4cb, 0xdd28f52b, 0xc5f53014, 0xc5f53014, 0xdd28f52b, }, 20 }, + { "gfxterm_fr", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x9a18f7bc, 0x5fcecc43, 0x9a18f7bc, 0x3039dcd, 0x43d1f34, 0x43d1f34, 0x287a2b96, 0x287a2b96, 0x287a2b96, 0x5770823e, 0x5770823e, 0x5770823e, 0x651c88c, 0x651c88c, 0x651c88c, 0x43d1f34, 0x3039dcd, 0x3039dcd, 0x43d1f34, }, 20 }, + { "gfxterm_quot", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x65112dfc, 0x3dec17f, 0x65112dfc, 0x26e7e0bb, 0x59c36f00, 0x59c36f00, 0x620c0067, 0x620c0067, 0x620c0067, 0x1c8c6d01, 0x1c8c6d01, 0x1c8c6d01, 0xc3269013, 0xc3269013, 0xc3269013, 0x59c36f00, 0x26e7e0bb, 0x26e7e0bb, 0x59c36f00, }, 20 }, + { "gfxterm_quot", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x2b3430fb, 0x8f1eb743, 0x2b3430fb, 0x531b584, 0xaa4593fe, 0xaa4593fe, 0xa8a596c8, 0xa8a596c8, 0xa8a596c8, 0xe509baf, 0xe509baf, 0xe509baf, 0x16f0dc06, 0x16f0dc06, 0x16f0dc06, 0xaa4593fe, 0x531b584, 0x531b584, 0xaa4593fe, }, 20 }, + { "gfxterm_quot", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xb523e920, 0xfafb6f8, 0xb523e920, 0xe83484a4, 0xc9cbf769, 0xc9cbf769, 0x3ce35e1d, 0x3ce35e1d, 0x3ce35e1d, 0xc23b9fd1, 0xc23b9fd1, 0xc23b9fd1, 0x5b18528e, 0x5b18528e, 0x5b18528e, 0xc9cbf769, 0xe83484a4, 0xe83484a4, 0xc9cbf769, }, 20 }, + { "gfxterm_quot", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xa9bf7336, 0x1a1f7a01, 0xa9bf7336, 0xb11ee1b4, 0x9813a416, 0x9813a416, 0x43fda3fa, 0x43fda3fa, 0x43fda3fa, 0xd22625c9, 0xd22625c9, 0xd22625c9, 0x76a62c0a, 0x76a62c0a, 0x76a62c0a, 0x9813a416, 0xb11ee1b4, 0xb11ee1b4, 0x9813a416, }, 20 }, + { "gfxterm_quot", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xe5271912, 0xf5d10273, 0xe5271912, 0xf05a51a1, 0x5fcf013d, 0x5fcf013d, 0xf3582c48, 0xf3582c48, 0xf3582c48, 0x2148343e, 0x2148343e, 0x2148343e, 0x9c719024, 0x9c719024, 0x9c719024, 0x5fcf013d, 0xf05a51a1, 0xf05a51a1, 0x5fcf013d, }, 20 }, + { "gfxterm_quot", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x66a34f49, 0x32dbeb97, 0x66a34f49, 0x59b7e501, 0xdd28f52b, 0xdd28f52b, 0xb3c7ef80, 0xb3c7ef80, 0xb3c7ef80, 0x92fb1664, 0x92fb1664, 0x92fb1664, 0xd15b5e2e, 0xd15b5e2e, 0xd15b5e2e, 0xdd28f52b, 0x59b7e501, 0x59b7e501, 0xdd28f52b, }, 20 }, + { "gfxterm_quot", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x7c2f19da, 0xd7bece67, 0x7c2f19da, 0xe53473ab, 0x43d1f34, 0x43d1f34, 0xa0717008, 0xa0717008, 0xa0717008, 0xdf7bd9a0, 0xdf7bd9a0, 0xdf7bd9a0, 0x8e5a9312, 0x8e5a9312, 0x8e5a9312, 0x43d1f34, 0xe53473ab, 0xe53473ab, 0x43d1f34, }, 20 }, + { "gfxterm_piglatin", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x37943894, 0x78248c70, 0x37943894, 0x7462f5d3, 0x59c36f00, 0x59c36f00, 0xf4be229a, 0xf4be229a, 0xf4be229a, 0x8a3e4ffc, 0x8a3e4ffc, 0x8a3e4ffc, 0x5594b2ee, 0x5594b2ee, 0x5594b2ee, 0x59c36f00, 0x7462f5d3, 0x7462f5d3, 0x59c36f00, }, 20 }, + { "gfxterm_piglatin", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xd5158e6c, 0xdc71ba0f, 0xd5158e6c, 0xfb100b13, 0xaa4593fe, 0xaa4593fe, 0xd3ed72a3, 0xd3ed72a3, 0xd3ed72a3, 0x75187fc4, 0x75187fc4, 0x75187fc4, 0x6db8386d, 0x6db8386d, 0x6db8386d, 0xaa4593fe, 0xfb100b13, 0xfb100b13, 0xaa4593fe, }, 20 }, + { "gfxterm_piglatin", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0x6277a9e6, 0xa3265ffb, 0x6277a9e6, 0x3f60c462, 0xc9cbf769, 0xc9cbf769, 0x2dcf8a8d, 0x2dcf8a8d, 0x2dcf8a8d, 0xd3174b41, 0xd3174b41, 0xd3174b41, 0x4a34861e, 0x4a34861e, 0x4a34861e, 0xc9cbf769, 0x3f60c462, 0x3f60c462, 0xc9cbf769, }, 20 }, + { "gfxterm_piglatin", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0x81115dc4, 0xddf3f768, 0x81115dc4, 0x99b0cf46, 0x9813a416, 0x9813a416, 0x9b9d96df, 0x9b9d96df, 0x9b9d96df, 0xa4610ec, 0xa4610ec, 0xa4610ec, 0xaec6192f, 0xaec6192f, 0xaec6192f, 0x9813a416, 0x99b0cf46, 0x99b0cf46, 0x9813a416, }, 20 }, + { "gfxterm_piglatin", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x5e96a904, 0x27864d3d, 0x5e96a904, 0x4bebe1b7, 0x5fcf013d, 0x5fcf013d, 0x18cae7f4, 0x18cae7f4, 0x18cae7f4, 0xcadaff82, 0xcadaff82, 0xcadaff82, 0x77e35b98, 0x77e35b98, 0x77e35b98, 0x5fcf013d, 0x4bebe1b7, 0x4bebe1b7, 0x5fcf013d, }, 20 }, + { "gfxterm_piglatin", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0xd00b19f8, 0xba73a9c6, 0xd00b19f8, 0xef1fb3b0, 0xdd28f52b, 0xdd28f52b, 0xb660046d, 0xb660046d, 0xb660046d, 0x975cfd89, 0x975cfd89, 0x975cfd89, 0xd4fcb5c3, 0xd4fcb5c3, 0xd4fcb5c3, 0xdd28f52b, 0xef1fb3b0, 0xef1fb3b0, 0xdd28f52b, }, 20 }, + { "gfxterm_piglatin", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x8b4b98cd, 0x78ddc6e4, 0x8b4b98cd, 0x1250f2bc, 0x43d1f34, 0x43d1f34, 0x4889d3fd, 0x4889d3fd, 0x4889d3fd, 0x37837a55, 0x37837a55, 0x37837a55, 0x66a230e7, 0x66a230e7, 0x66a230e7, 0x43d1f34, 0x1250f2bc, 0x1250f2bc, 0x43d1f34, }, 20 }, + { "gfxterm_ch", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0xfecb570e, 0xccb97a7a, 0xfecb570e, 0xbd3d9a49, 0x59c36f00, 0x59c36f00, 0x40281258, 0x40281258, 0x40281258, 0x3ea87f3e, 0x3ea87f3e, 0x3ea87f3e, 0xe102822c, 0xe102822c, 0xe102822c, 0x59c36f00, 0xbd3d9a49, 0xbd3d9a49, 0x59c36f00, }, 20 }, + { "gfxterm_ch", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0x897d1fac, 0xaa982529, 0x897d1fac, 0xa7789ad3, 0xaa4593fe, 0xaa4593fe, 0xa482510, 0xa482510, 0xa482510, 0xacbd2877, 0xacbd2877, 0xacbd2877, 0xb41d6fde, 0xb41d6fde, 0xb41d6fde, 0xaa4593fe, 0xa7789ad3, 0xa7789ad3, 0xaa4593fe, }, 20 }, + { "gfxterm_ch", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xd02a5297, 0xe627ab58, 0xd02a5297, 0x8d3d3f13, 0xc9cbf769, 0xc9cbf769, 0xbf0a8b7f, 0xbf0a8b7f, 0xbf0a8b7f, 0x41d24ab3, 0x41d24ab3, 0x41d24ab3, 0xd8f187ec, 0xd8f187ec, 0xd8f187ec, 0xc9cbf769, 0x8d3d3f13, 0x8d3d3f13, 0xc9cbf769, }, 20 }, + { "gfxterm_ch", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xa653dcda, 0x3392e976, 0xa653dcda, 0xbef24e58, 0x9813a416, 0x9813a416, 0x4f2bc106, 0x4f2bc106, 0x4f2bc106, 0xdef04735, 0xdef04735, 0xdef04735, 0x7a704ef6, 0x7a704ef6, 0x7a704ef6, 0x9813a416, 0xbef24e58, 0xbef24e58, 0x9813a416, }, 20 }, + { "gfxterm_ch", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xe2d7b585, 0x35241f36, 0xe2d7b585, 0xf7aafd36, 0x5fcf013d, 0x5fcf013d, 0xf2bd04db, 0xf2bd04db, 0xf2bd04db, 0x20ad1cad, 0x20ad1cad, 0x20ad1cad, 0x9d94b8b7, 0x9d94b8b7, 0x9d94b8b7, 0x5fcf013d, 0xf7aafd36, 0xf7aafd36, 0x5fcf013d, }, 20 }, + { "gfxterm_ch", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x72ff749c, 0xeda8c283, 0x72ff749c, 0x4debded4, 0xdd28f52b, 0xdd28f52b, 0xb8c9cc22, 0xb8c9cc22, 0xb8c9cc22, 0x99f535c6, 0x99f535c6, 0x99f535c6, 0xda557d8c, 0xda557d8c, 0xda557d8c, 0xdd28f52b, 0x4debded4, 0x4debded4, 0xdd28f52b, }, 20 }, + { "gfxterm_ch", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0xb7cac764, 0xeb4bf417, 0xb7cac764, 0x2ed1ad15, 0x43d1f34, 0x43d1f34, 0xce718801, 0xce718801, 0xce718801, 0xb17b21a9, 0xb17b21a9, 0xb17b21a9, 0xe05a6b1b, 0xe05a6b1b, 0xe05a6b1b, 0x43d1f34, 0x2ed1ad15, 0x2ed1ad15, 0x43d1f34, }, 20 }, + { "gfxterm_red", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x930e8e13, 0xf5c16290, 0x930e8e13, 0x27f5f1c0, 0x59c36f00, 0x59c36f00, 0xbad4e11, 0xbad4e11, 0xbad4e11, 0x752d2377, 0x752d2377, 0x752d2377, 0xaa87de65, 0xaa87de65, 0xaa87de65, 0x59c36f00, 0x27f5f1c0, 0x27f5f1c0, 0x59c36f00, }, 20 }, + { "gfxterm_red", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xff9301f2, 0x5bb9864a, 0xff9301f2, 0x31c145de, 0xaa4593fe, 0xaa4593fe, 0x23bf2c32, 0x23bf2c32, 0x23bf2c32, 0x854a2155, 0x854a2155, 0x854a2155, 0x9dea66fc, 0x9dea66fc, 0x9dea66fc, 0xaa4593fe, 0x31c145de, 0x31c145de, 0xaa4593fe, }, 20 }, + { "gfxterm_red", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xfc5938ef, 0x46d56737, 0xfc5938ef, 0x23cf2668, 0xc9cbf769, 0xc9cbf769, 0xa8c549aa, 0xa8c549aa, 0xa8c549aa, 0x561d8866, 0x561d8866, 0x561d8866, 0xcf3e4539, 0xcf3e4539, 0xcf3e4539, 0xc9cbf769, 0x23cf2668, 0x23cf2668, 0xc9cbf769, }, 20 }, + { "gfxterm_red", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xe7160822, 0x54b60115, 0xe7160822, 0x168efa6f, 0x9813a416, 0x9813a416, 0xb774a5aa, 0xb774a5aa, 0xb774a5aa, 0x26af2399, 0x26af2399, 0x26af2399, 0x822f2a5a, 0x822f2a5a, 0x822f2a5a, 0x9813a416, 0x168efa6f, 0x168efa6f, 0x9813a416, }, 20 }, + { "gfxterm_red", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0xf655f9b2, 0xe6a3e2d3, 0xf655f9b2, 0xd1d7405f, 0x5fcf013d, 0x5fcf013d, 0x2accaa08, 0x2accaa08, 0x2accaa08, 0xf8dcb27e, 0xf8dcb27e, 0xf8dcb27e, 0x45e51664, 0x45e51664, 0x45e51664, 0x5fcf013d, 0xd1d7405f, 0xd1d7405f, 0x5fcf013d, }, 20 }, + { "gfxterm_red", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x2d85ebdc, 0x79fd4f02, 0x2d85ebdc, 0xc48ae2b6, 0xdd28f52b, 0xdd28f52b, 0x76b28a95, 0x76b28a95, 0x76b28a95, 0x578e7371, 0x578e7371, 0x578e7371, 0x142e3b3b, 0x142e3b3b, 0x142e3b3b, 0xdd28f52b, 0xc48ae2b6, 0xc48ae2b6, 0xdd28f52b, }, 20 }, + { "gfxterm_red", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x29c00f98, 0x8251d825, 0x29c00f98, 0x35a750d1, 0x43d1f34, 0x43d1f34, 0x48b70bc8, 0x48b70bc8, 0x48b70bc8, 0x37bda260, 0x37bda260, 0x37bda260, 0x669ce8d2, 0x669ce8d2, 0x669ce8d2, 0x43d1f34, 0x35a750d1, 0x35a750d1, 0x43d1f34, }, 20 }, + { "gfxterm_high", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x59c36f00, 0x4afab717, 0x2c355b94, 0x4afab717, 0x1166d9d0, 0x59c36f00, 0x59c36f00, 0x620c0067, 0x620c0067, 0x620c0067, 0x1c8c6d01, 0x1c8c6d01, 0x1c8c6d01, 0xc3269013, 0xc3269013, 0xc3269013, 0x59c36f00, 0x1166d9d0, 0x1166d9d0, 0x59c36f00, }, 20 }, + { "gfxterm_high", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xaa4593fe, 0xe3daadd4, 0x47f02a6c, 0xe3daadd4, 0x5ea9fb21, 0xaa4593fe, 0xaa4593fe, 0xa8a596c8, 0xa8a596c8, 0xa8a596c8, 0xe509baf, 0xe509baf, 0xe509baf, 0x16f0dc06, 0x16f0dc06, 0x16f0dc06, 0xaa4593fe, 0x5ea9fb21, 0x5ea9fb21, 0xaa4593fe, }, 20 }, + { "gfxterm_high", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xc9cbf769, 0xf140d1df, 0x4bcc8e07, 0xf140d1df, 0x7c962dcb, 0xc9cbf769, 0xc9cbf769, 0x3ce35e1d, 0x3ce35e1d, 0x3ce35e1d, 0xc23b9fd1, 0xc23b9fd1, 0xc23b9fd1, 0x5b18528e, 0x5b18528e, 0x5b18528e, 0xc9cbf769, 0x7c962dcb, 0x7c962dcb, 0xc9cbf769, }, 20 }, + { "gfxterm_high", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x9813a416, 0xe709a12d, 0x54a9a81a, 0xe709a12d, 0xde04d65c, 0x9813a416, 0x9813a416, 0x43fda3fa, 0x43fda3fa, 0x43fda3fa, 0xd22625c9, 0xd22625c9, 0xd22625c9, 0x76a62c0a, 0x76a62c0a, 0x76a62c0a, 0x9813a416, 0xde04d65c, 0xde04d65c, 0x9813a416, }, 20 }, + { "gfxterm_high", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0x5fcf013d, 0x65eff77c, 0x7519ec1d, 0x65eff77c, 0x1cd7d353, 0x5fcf013d, 0x5fcf013d, 0xf3582c48, 0xf3582c48, 0xf3582c48, 0x2148343e, 0x2148343e, 0x2148343e, 0x9c719024, 0x9c719024, 0x9c719024, 0x5fcf013d, 0x1cd7d353, 0x1cd7d353, 0x5fcf013d, }, 20 }, + { "gfxterm_high", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0xdd28f52b, 0x7318831a, 0x276027c4, 0x7318831a, 0xd7e4f5bb, 0xdd28f52b, 0xdd28f52b, 0xb3c7ef80, 0xb3c7ef80, 0xb3c7ef80, 0x92fb1664, 0x92fb1664, 0x92fb1664, 0xd15b5e2e, 0xd15b5e2e, 0xd15b5e2e, 0xdd28f52b, 0xd7e4f5bb, 0xd7e4f5bb, 0xdd28f52b, }, 20 }, + { "gfxterm_high", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x43d1f34, 0x6927a7d4, 0xc2b67069, 0x6927a7d4, 0xfc345163, 0x43d1f34, 0x43d1f34, 0xa0717008, 0xa0717008, 0xa0717008, 0xdf7bd9a0, 0xdf7bd9a0, 0xdf7bd9a0, 0x8e5a9312, 0x8e5a9312, 0x8e5a9312, 0x43d1f34, 0xfc345163, 0xfc345163, 0x43d1f34, }, 20 }, + { "videotest", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0xe6012f70, 0xe6012f70, 0xe6012f70, 0xe6012f70, 0xe6012f70, }, 5 }, + { "videotest", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xfb6be77b, 0xfb6be77b, 0xfb6be77b, 0xfb6be77b, 0xfb6be77b, }, 5 }, + { "videotest", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0x67c0629f, 0x67c0629f, 0x67c0629f, 0x67c0629f, 0x67c0629f, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 640x480xrgba8888 */, (grub_uint32_t []) { 0x8f20afbb, 0xd8f7abc, 0x8f937344, 0xd3ca643, 0x8e471645, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 800x600xrgba8888 */, (grub_uint32_t []) { 0xdca764da, 0x9f76da9a, 0x5b04185a, 0x18d5a61a, 0xd60deb2b, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 1024x768xrgba8888 */, (grub_uint32_t []) { 0x7b87af36, 0x7cb96093, 0x75fa307c, 0x72c4ffd9, 0x677c91a2, }, 5 }, + { "videotest", 2560, 1440, 0x1, 256, 32, 4, 16, 8, 8, 8, 0, 8, 24, 8 /* 2560x1440xrgba8888 */, (grub_uint32_t []) { 0x72981c65, 0x50120635, 0x378c28c5, 0x15063295, 0xf8b07525, }, 5 }, + { "videotest", 640, 480, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi256 */, (grub_uint32_t []) { 0xc8f64b58, 0xc8f64b58, 0xc8f64b58, 0xc8f64b58, 0xc8f64b58, }, 5 }, + { "videotest", 800, 600, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi256 */, (grub_uint32_t []) { 0x2b499dfa, 0x2b499dfa, 0x2b499dfa, 0x2b499dfa, 0x2b499dfa, }, 5 }, + { "videotest", 1024, 768, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi256 */, (grub_uint32_t []) { 0x6156b420, 0x6156b420, 0x6156b420, 0x6156b420, 0x6156b420, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 640x480xrgba5550 */, (grub_uint32_t []) { 0x363285ca, 0x363285ca, 0x363285ca, 0x363285ca, 0x363285ca, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 800x600xrgba5550 */, (grub_uint32_t []) { 0x25bb37f4, 0x25bb37f4, 0x25bb37f4, 0x25bb37f4, 0x25bb37f4, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 1024x768xrgba5550 */, (grub_uint32_t []) { 0xeeab9e91, 0xeeab9e91, 0xeeab9e91, 0xeeab9e91, 0xeeab9e91, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 640x480xrgba5650 */, (grub_uint32_t []) { 0x26a9a50b, 0x26a9a50b, 0x26a9a50b, 0x26a9a50b, 0x26a9a50b, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 800x600xrgba5650 */, (grub_uint32_t []) { 0x2c0f4fe7, 0x2c0f4fe7, 0x2c0f4fe7, 0x2c0f4fe7, 0x2c0f4fe7, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 16, 2, 11, 5, 5, 6, 0, 5, 0, 0 /* 1024x768xrgba5650 */, (grub_uint32_t []) { 0x46c11052, 0x46c11052, 0x46c11052, 0x46c11052, 0x46c11052, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 640x480xrgba8880 */, (grub_uint32_t []) { 0xe56cf615, 0xcd2be572, 0xb5e2d0db, 0x9da5c3bc, 0x4470bb89, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 800x600xrgba8880 */, (grub_uint32_t []) { 0x2a25b871, 0x4bf85361, 0xe99e6e51, 0x88438541, 0xa8be62c0, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 24, 3, 16, 8, 8, 8, 0, 8, 0, 0 /* 1024x768xrgba8880 */, (grub_uint32_t []) { 0x81523037, 0xd8c0bfd3, 0x32772fff, 0x6be5a01b, 0xe2f47956, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 640x480xbgra5550 */, (grub_uint32_t []) { 0x1833bb41, 0x1833bb41, 0x1833bb41, 0x1833bb41, 0x1833bb41, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 800x600xbgra5550 */, (grub_uint32_t []) { 0x2c39a0e8, 0x2c39a0e8, 0x2c39a0e8, 0x2c39a0e8, 0x2c39a0e8, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 15, 2, 0, 5, 5, 5, 10, 5, 0, 0 /* 1024x768xbgra5550 */, (grub_uint32_t []) { 0xf0d4c23, 0xf0d4c23, 0xf0d4c23, 0xf0d4c23, 0xf0d4c23, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 640x480xbgra5650 */, (grub_uint32_t []) { 0x456d063c, 0x456d063c, 0x456d063c, 0x456d063c, 0x456d063c, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 800x600xbgra5650 */, (grub_uint32_t []) { 0x47e15a2e, 0x47e15a2e, 0x47e15a2e, 0x47e15a2e, 0x47e15a2e, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 16, 2, 0, 5, 5, 6, 11, 5, 0, 0 /* 1024x768xbgra5650 */, (grub_uint32_t []) { 0x54d7300d, 0x54d7300d, 0x54d7300d, 0x54d7300d, 0x54d7300d, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 640x480xbgra8880 */, (grub_uint32_t []) { 0x770da211, 0x8ef2528e, 0x811e35de, 0x78e1c541, 0x9ec6fb7e, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 800x600xbgra8880 */, (grub_uint32_t []) { 0xeb181fbc, 0xae648cc1, 0x61e13946, 0x249daa3b, 0xfb0624b9, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 24, 3, 0, 8, 8, 8, 16, 8, 0, 0 /* 1024x768xbgra8880 */, (grub_uint32_t []) { 0x2b6f64dc, 0xc25f8431, 0xfce2d3f7, 0x15d2331a, 0x81987c7b, }, 5 }, + { "videotest", 640, 480, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 640x480xbgra8888 */, (grub_uint32_t []) { 0xa260f7dd, 0x3e2f4980, 0x9f13fd96, 0x35c43cb, 0xd886e34b, }, 5 }, + { "videotest", 800, 600, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 800x600xbgra8888 */, (grub_uint32_t []) { 0x41a9bff8, 0xa0d3f7c3, 0x86b1597f, 0x67cb1144, 0xca740407, }, 5 }, + { "videotest", 1024, 768, 0x1, 256, 32, 4, 0, 8, 8, 8, 16, 8, 24, 8 /* 1024x768xbgra8888 */, (grub_uint32_t []) { 0x8f7a3b6d, 0xcb84c6e3, 0x687c071, 0x42793dff, 0x996dbba4, }, 5 }, diff --git a/grub-core/tests/cmdline_cat_test.c b/grub-core/tests/cmdline_cat_test.c index f1e21439e..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,19 +91,19 @@ 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', GRUB_TERM_NO_KEY, - GRUB_TERM_NO_KEY, '\e'}, + GRUB_TERM_NO_KEY, GRUB_TERM_ESC}, 23); grub_video_checksum ("cmdline_cat"); 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 8f63dc27a..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++) { @@ -146,7 +146,7 @@ gfxterm_menu (void) return; } grub_terminal_input_fake_sequence ((int []) { -1, -1, -1, GRUB_TERM_KEY_DOWN, -1, 'e', - -1, GRUB_TERM_KEY_RIGHT, -1, 'x', -1, '\e', -1, '\e' }, 14); + -1, GRUB_TERM_KEY_RIGHT, -1, 'x', -1, GRUB_TERM_ESC, -1, GRUB_TERM_ESC }, 14); grub_video_checksum (tests[j].name); diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c index d4822a124..38e981f2c 100644 --- a/grub-core/tests/lib/functional_test.c +++ b/grub-core/tests/lib/functional_test.c @@ -26,14 +26,23 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_err_t grub_functional_test (grub_extcmd_context_t ctxt __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) + int argc, + char **args) { grub_test_t test; int ok = 1; + int i; FOR_LIST_ELEMENTS (test, grub_test_list) { + if (argc != 0) + { + for (i = 0; i < argc; i++) + if (grub_strcmp(args[i], test->name) == 0) + break; + if (i == argc) + continue; + } grub_errno = 0; ok = ok && !grub_test_run (test); grub_errno = 0; @@ -70,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/setjmp_test.c b/grub-core/tests/setjmp_test.c index 390cb26eb..604a6ce8f 100644 --- a/grub-core/tests/setjmp_test.c +++ b/grub-core/tests/setjmp_test.c @@ -25,7 +25,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_jmp_buf jmp_point; static int expected, ctr; -#pragma GCC diagnostic ignored "-Wmissing-noreturn" +/* This fixes GCC7 "unintentional fallthrough" warning */ +static void jmp0 (void) __attribute__ ((noreturn)); +static void jmp1 (void) __attribute__ ((noreturn)); +static void jmp2 (void) __attribute__ ((noreturn)); static void jmp0 (void) 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/i386/coreboot/cbfb.c b/grub-core/video/coreboot/cbfb.c similarity index 99% rename from grub-core/video/i386/coreboot/cbfb.c rename to grub-core/video/coreboot/cbfb.c index dede0c37e..986003c51 100644 --- a/grub-core/video/i386/coreboot/cbfb.c +++ b/grub-core/video/coreboot/cbfb.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; @@ -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 464ede874..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; }; @@ -94,14 +94,23 @@ static int find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) { struct find_framebuf_ctx *ctx = data; - grub_pci_address_t addr; + grub_pci_address_t addr, rcaddr; + grub_uint32_t subclass; addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - if (grub_pci_read (addr) >> 24 == 0x3) + subclass = (grub_pci_read (addr) >> 16) & 0xffff; + + if (subclass != GRUB_PCI_CLASS_DISPLAY_VGA) + return 0; + + /* Enable MEM address spaces */ + rcaddr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); + grub_pci_write_word (rcaddr, grub_pci_read_word (rcaddr) | GRUB_PCI_COMMAND_MEM_ENABLED); + { 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; @@ -120,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; @@ -129,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)) { @@ -140,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; - } } } @@ -153,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, @@ -176,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); @@ -226,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 0b150ec24..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; @@ -181,6 +180,7 @@ grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev, case 32: out->reserved_mask_size = 8; out->reserved_field_pos = 24; + /* FALLTHROUGH */ case 24: out->red_mask_size = 8; @@ -233,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) { @@ -260,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 c3e0df240..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; @@ -736,6 +844,7 @@ grub_jpeg_decode_jpeg (struct grub_jpeg_data *data) case JPEG_MARKER_SOS: /* Start Of Scan. */ if (grub_jpeg_decode_sos (data)) break; + /* FALLTHROUGH */ case JPEG_MARKER_RST0: /* Restart. */ case JPEG_MARKER_RST1: case JPEG_MARKER_RST2: @@ -771,7 +880,7 @@ grub_video_reader_jpeg (struct grub_video_bitmap **bitmap, grub_file_t file; struct grub_jpeg_data *data; - file = grub_buffile_open (filename, 0); + file = grub_buffile_open (filename, GRUB_FILE_TYPE_PIXMAP, 0); if (!file) return grub_errno; diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c index e1a01e99f..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) @@ -1086,7 +1081,7 @@ grub_video_reader_png (struct grub_video_bitmap **bitmap, grub_file_t file; struct grub_png_data *data; - file = grub_buffile_open (filename, 0); + file = grub_buffile_open (filename, GRUB_FILE_TYPE_PIXMAP, 0); if (!file) return grub_errno; diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c index c7a16fa9c..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; @@ -297,7 +297,7 @@ grub_video_reader_tga (struct grub_video_bitmap **bitmap, grub_memset (&data, 0, sizeof (data)); - data.file = grub_buffile_open (filename, 0); + data.file = grub_buffile_open (filename, GRUB_FILE_TYPE_PIXMAP, 0); if (! data.file) 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 f252663c1..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); @@ -663,6 +663,8 @@ grub_video_set_mode (const char *modestring, return GRUB_ERR_NONE; } + else + continue; } err = parse_modespec (current_mode, &width, &height, &depth); diff --git a/include/grub/acpi.h b/include/grub/acpi.h index 66148f684..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; @@ -93,7 +94,7 @@ struct grub_acpi_madt grub_uint32_t lapic_addr; grub_uint32_t flags; struct grub_acpi_madt_entry_header entries[0]; -}; +} GRUB_PACKED; enum { @@ -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/aout.h b/include/grub/aout.h index 10d7dde61..c8c1d94ec 100644 --- a/include/grub/aout.h +++ b/include/grub/aout.h @@ -52,6 +52,7 @@ #define GRUB_AOUT_HEADER 1 #include +#include struct grub_aout32_header { diff --git a/include/grub/arc/arc.h b/include/grub/arc/arc.h index 7615a49a9..6d14b9748 100644 --- a/include/grub/arc/arc.h +++ b/include/grub/arc/arc.h @@ -53,7 +53,7 @@ enum grub_arc_memory_type #ifndef GRUB_CPU_WORDS_BIGENDIAN GRUB_ARC_MEMORY_FREE_CONTIGUOUS, #endif - } grub_arc_memory_type_t; + }; struct grub_arc_timeinfo { @@ -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/coreboot/console.h b/include/grub/arm/coreboot/console.h new file mode 100644 index 000000000..13a14b783 --- /dev/null +++ b/include/grub/arm/coreboot/console.h @@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_CONSOLE_HEADER +#define GRUB_MACHINE_CONSOLE_HEADER 1 + +void grub_video_coreboot_fb_init (void); +void grub_video_coreboot_fb_early_init (void); +void grub_video_coreboot_fb_late_init (void); +void grub_video_coreboot_fb_fini (void); + +extern struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; + +#endif /* ! GRUB_MACHINE_CONSOLE_HEADER */ diff --git a/include/grub/arm/coreboot/kernel.h b/include/grub/arm/coreboot/kernel.h new file mode 100644 index 000000000..269505342 --- /dev/null +++ b/include/grub/arm/coreboot/kernel.h @@ -0,0 +1,44 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#ifndef ASM_FILE + +#include +#include + +struct grub_fdt_board +{ + const char *vendor, *part; + const grub_uint8_t *dtb; + grub_size_t dtb_size; +}; + +extern struct grub_fdt_board grub_fdt_boards[]; +void grub_machine_timer_init (void); +void grub_pl050_init (void); +void grub_cros_init (void); +void grub_rk3288_spi_init (void); +extern grub_addr_t EXPORT_VAR (start_of_ram); +#endif /* ! ASM_FILE */ + +#define GRUB_KERNEL_MACHINE_STACK_SIZE GRUB_KERNEL_ARM_STACK_SIZE + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/arm/cros_ec.h b/include/grub/arm/cros_ec.h new file mode 100644 index 000000000..45a372572 --- /dev/null +++ b/include/grub/arm/cros_ec.h @@ -0,0 +1,21 @@ +#ifndef GRUB_ARM_CROS_EC_H +#define GRUB_ARM_CROS_EC_H 1 + +#include +#include + +#define GRUB_CROS_EC_KEYSCAN_COLS 13 +#define GRUB_CROS_EC_KEYSCAN_ROWS 8 + +struct grub_cros_ec_keyscan { + grub_uint8_t data[GRUB_CROS_EC_KEYSCAN_COLS]; +}; + +int +grub_cros_ec_scan_keyboard (const struct grub_fdtbus_dev *dev, + struct grub_cros_ec_keyscan *scan); + +int +grub_cros_ec_validate (const struct grub_fdtbus_dev *dev); + +#endif diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h index a66caad13..5b8fb14e0 100644 --- a/include/grub/arm/linux.h +++ b/include/grub/arm/linux.h @@ -17,30 +17,31 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_LINUX_CPU_HEADER -#define GRUB_LINUX_CPU_HEADER 1 - -#define LINUX_ZIMAGE_OFFSET 0x24 -#define LINUX_ZIMAGE_MAGIC 0x016f2818 +#ifndef GRUB_ARM_LINUX_HEADER +#define GRUB_ARM_LINUX_HEADER 1 #include "system.h" +#include + #if defined GRUB_MACHINE_UBOOT # include # define LINUX_ADDRESS (start_of_ram + 0x8000) -# define LINUX_INITRD_ADDRESS (start_of_ram + 0x02000000) +# define LINUX_INITRD_ADDRESS (start_of_ram + 0x03000000) # define LINUX_FDT_ADDRESS (LINUX_INITRD_ADDRESS - 0x10000) # define grub_arm_firmware_get_boot_data grub_uboot_get_boot_data # define grub_arm_firmware_get_machine_type grub_uboot_get_machine_type -#elif defined GRUB_MACHINE_EFI -# include -# include -/* On UEFI platforms - load the images at the lowest available address not - less than *_PHYS_OFFSET from the first available memory location. */ -# define LINUX_PHYS_OFFSET (0x00008000) -# define LINUX_INITRD_PHYS_OFFSET (LINUX_PHYS_OFFSET + 0x02000000) -# define LINUX_FDT_PHYS_OFFSET (LINUX_INITRD_PHYS_OFFSET - 0x10000) -# define grub_arm_firmware_get_boot_data (grub_addr_t)grub_efi_get_firmware_fdt +#elif defined (GRUB_MACHINE_COREBOOT) +#include +#include +# define LINUX_ADDRESS (start_of_ram + 0x8000) +# define LINUX_INITRD_ADDRESS (start_of_ram + 0x03000000) +# define LINUX_FDT_ADDRESS (LINUX_INITRD_ADDRESS - 0x10000) +static inline const void * +grub_arm_firmware_get_boot_data (void) +{ + return grub_fdtbus_get_fdt (); +} static inline grub_uint32_t grub_arm_firmware_get_machine_type (void) { @@ -48,6 +49,4 @@ grub_arm_firmware_get_machine_type (void) } #endif -#define FDT_ADDITIONAL_ENTRIES_SIZE 0x300 - -#endif /* ! GRUB_LINUX_CPU_HEADER */ +#endif /* ! GRUB_ARM_LINUX_HEADER */ diff --git a/include/grub/arm/startup.h b/include/grub/arm/startup.h new file mode 100644 index 000000000..9afb6c57c --- /dev/null +++ b/include/grub/arm/startup.h @@ -0,0 +1,16 @@ +#ifndef GRUB_STARTUP_CPU_HEADER +#define GRUB_STARTUP_CPU_HEADER + +struct grub_arm_startup_registers +{ + /* registers 0-11 */ + /* for U-boot r[1] is machine type */ + /* for U-boot r[2] is boot data */ + grub_uint32_t r[12]; + grub_uint32_t sp; + grub_uint32_t lr; +}; + +extern struct grub_arm_startup_registers grub_arm_saved_registers; + +#endif diff --git a/include/grub/arm/system.h b/include/grub/arm/system.h 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/arm/time.h b/include/grub/arm/time.h index 4128506cb..c5a685225 100644 --- a/include/grub/arm/time.h +++ b/include/grub/arm/time.h @@ -23,7 +23,7 @@ static __inline void grub_cpu_idle (void) { /* FIXME: this can't work until we handle interrupts. */ -/* __asm__ __volatile__ ("wfi"); */ +/* asm volatile ("wfi"); */ } #endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h deleted file mode 100644 index 1ea23696e..000000000 --- a/include/grub/arm64/linux.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_LINUX_CPU_HEADER -#define GRUB_LINUX_CPU_HEADER 1 - -#include - -#define GRUB_ARM64_LINUX_MAGIC 0x644d5241 /* 'ARM\x64' */ - -#define GRUB_EFI_PE_MAGIC 0x5A4D - -/* From linux/Documentation/arm64/booting.txt */ -struct grub_arm64_linux_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 */ -}; - -grub_err_t grub_arm64_uefi_check_image (struct grub_arm64_linux_kernel_header - *lh); -grub_err_t grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, - char *args); - -#endif /* ! GRUB_LINUX_CPU_HEADER */ diff --git a/include/grub/arm64/time.h b/include/grub/arm64/time.h index 4128506cb..c5a685225 100644 --- a/include/grub/arm64/time.h +++ b/include/grub/arm64/time.h @@ -23,7 +23,7 @@ static __inline void grub_cpu_idle (void) { /* FIXME: this can't work until we handle interrupts. */ -/* __asm__ __volatile__ ("wfi"); */ +/* asm volatile ("wfi"); */ } #endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index b4f8ff0a0..bcb4d9ba7 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -23,13 +23,11 @@ #define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) #define KEYBOARD_COMMAND_READ 0x20 #define KEYBOARD_COMMAND_WRITE 0x60 +#define KEYBOARD_COMMAND_ENABLE 0xf4 #define KEYBOARD_COMMAND_REBOOT 0xfe #define KEYBOARD_AT_TRANSLATE 0x40 - -#define GRUB_AT_ACK 0xfa -#define GRUB_AT_NACK 0xfe -#define GRUB_AT_TRIES 5 +#define KEYBOARD_AT_DISABLE 0x10 #define KEYBOARD_ISMAKE(x) !((x) & 0x80) #define KEYBOARD_ISREADY(x) ((x) & 0x01) 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/autoefi.h b/include/grub/autoefi.h index b75591176..b7a252e07 100644 --- a/include/grub/autoefi.h +++ b/include/grub/autoefi.h @@ -55,7 +55,7 @@ static inline grub_err_t grub_autoefi_prepare (void) # define SYSTEM_TABLE_PTR GRUB_EFIEMU_SYSTEM_TABLE_PTR # define SIZEOF_OF_UINTN GRUB_EFIEMU_SIZEOF_OF_UINTN # define SYSTEM_TABLE GRUB_EFIEMU_SYSTEM_TABLE -# define grub_efi_allocate_pages(x,y) (x) +# define grub_efi_allocate_fixed(x,y) (x) # define grub_efi_free_pages(x,y) GRUB_EFI_SUCCESS # define grub_autoefi_finish_boot_services grub_efiemu_finish_boot_services # define EFI_PRESENT 1 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/bufio.h b/include/grub/bufio.h index acdd0c882..0ff72d103 100644 --- a/include/grub/bufio.h +++ b/include/grub/bufio.h @@ -22,7 +22,9 @@ #include -grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, int size); -grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, int size); +grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, grub_size_t size); +grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, + enum grub_file_type type, + grub_size_t size); #endif /* ! GRUB_BUFIO_H */ diff --git a/include/grub/cache.h b/include/grub/cache.h index fc669dfd1..7aa8d7933 100644 --- a/include/grub/cache.h +++ b/include/grub/cache.h @@ -34,15 +34,17 @@ void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); #endif #ifndef GRUB_MACHINE_EMU -#ifdef _mips -void EXPORT_FUNC(grub_arch_sync_dma_caches) (volatile void *address, - grub_size_t len); -#else +#if defined (__aarch64__) || defined (__ia64__) || defined (__powerpc__) || \ + defined (__sparc__) + +#elif defined (__i386__) || defined (__x86_64__) static inline void grub_arch_sync_dma_caches (volatile void *address __attribute__ ((unused)), grub_size_t len __attribute__ ((unused))) { } +#else +void EXPORT_FUNC(grub_arch_sync_dma_caches) (volatile void *address, grub_size_t len); #endif #endif 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 dc73649a5..17828b322 100644 --- a/include/grub/compiler-rt.h +++ b/include/grub/compiler-rt.h @@ -53,13 +53,15 @@ EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b); #endif -#if defined (__sparc__) || defined (__powerpc__) || defined (__mips__) || defined (__arm__) +#if defined (__sparc__) || defined (__powerpc__) || defined (__mips__) || \ + defined (__arm__) || defined(__riscv) unsigned EXPORT_FUNC (__ctzdi2) (grub_uint64_t x); #define NEED_CTZDI2 1 #endif -#if defined (__mips__) || defined (__arm__) +#if defined (__mips__) || defined (__arm__) || \ + (defined(__riscv) && (__riscv_xlen == 32)) unsigned EXPORT_FUNC (__ctzsi2) (grub_uint32_t x); #define NEED_CTZSI2 1 @@ -108,6 +110,15 @@ EXPORT_FUNC (__aeabi_llsr) (grub_uint64_t u, int b); #endif +#if defined(__mips__) || defined(__riscv) || defined(__sparc__) +int +EXPORT_FUNC (__clzsi2) (grub_uint32_t val); +#endif + +#if defined(__mips__) || defined(__riscv) || defined(__sparc__) +int +EXPORT_FUNC (__clzdi2) (grub_uint64_t val); +#endif #if defined (__powerpc__) @@ -150,7 +161,8 @@ void EXPORT_FUNC (_savegpr_31) (void); #endif -#if defined (__powerpc__) || defined(__mips__) || defined (__arm__) +#if defined (__powerpc__) || defined(__mips__) || defined (__arm__) || \ + (defined(__riscv) && (__riscv_xlen == 32)) int EXPORT_FUNC(__ucmpdi2) (grub_uint64_t a, grub_uint64_t b); @@ -165,7 +177,8 @@ grub_uint64_t EXPORT_FUNC (__lshrdi3) (grub_uint64_t u, int b); #endif -#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || defined (__arm__) +#if defined (__powerpc__) || defined(__mips__) || defined(__sparc__) || \ + defined (__arm__) || defined(__riscv) grub_uint32_t EXPORT_FUNC(__bswapsi2) (grub_uint32_t u); 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/i386/coreboot/lbio.h b/include/grub/coreboot/lbio.h similarity index 93% rename from include/grub/i386/coreboot/lbio.h rename to include/grub/coreboot/lbio.h index 1c3fa6f19..5076d36c7 100644 --- a/include/grub/i386/coreboot/lbio.h +++ b/include/grub/coreboot/lbio.h @@ -20,6 +20,9 @@ #ifndef _GRUB_MACHINE_LBIO_HEADER #define _GRUB_MACHINE_LBIO_HEADER 1 +#include +#include + struct grub_linuxbios_table_header { grub_uint8_t signature[4]; @@ -102,4 +105,10 @@ EXPORT_FUNC(grub_linuxbios_table_iterate) (int (*hook) (grub_linuxbios_table_ite void *), void *hook_data); +grub_linuxbios_table_header_t +grub_linuxbios_get_tables (void); + +int +grub_linuxbios_check_signature (grub_linuxbios_table_header_t tbl_header); + #endif diff --git a/include/grub/crypto.h b/include/grub/crypto.h index 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 b385af826..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. */ @@ -49,6 +51,7 @@ enum grub_disk_dev_id GRUB_DISK_DEVICE_CBFSDISK_ID, GRUB_DISK_DEVICE_UBOOTDISK_ID, GRUB_DISK_DEVICE_XEN, + GRUB_DISK_DEVICE_OBDISK_ID, }; struct grub_disk; @@ -57,7 +60,7 @@ struct grub_disk_memberlist; #endif typedef enum - { + { GRUB_DISK_PULL_NONE, GRUB_DISK_PULL_REMOVABLE, GRUB_DISK_PULL_RESCAN, @@ -76,26 +79,26 @@ struct grub_disk_dev enum grub_disk_dev_id id; /* Call HOOK with each device name, until HOOK returns non-zero. */ - int (*iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data, + int (*disk_iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data, grub_disk_pull_t pull); /* Open the device named NAME, and set up DISK. */ - grub_err_t (*open) (const char *name, struct grub_disk *disk); + grub_err_t (*disk_open) (const char *name, struct grub_disk *disk); /* Close the disk DISK. */ - void (*close) (struct grub_disk *disk); + void (*disk_close) (struct grub_disk *disk); /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF. */ - grub_err_t (*read) (struct grub_disk *disk, grub_disk_addr_t sector, + grub_err_t (*disk_read) (struct grub_disk *disk, grub_disk_addr_t sector, grub_size_t size, char *buf); /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK. */ - grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector, + grub_err_t (*disk_write) (struct grub_disk *disk, grub_disk_addr_t sector, grub_size_t size, const char *buf); #ifdef GRUB_UTIL - struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk); - const char * (*raidname) (struct grub_disk *disk); + struct grub_disk_memberlist *(*disk_memberlist) (struct grub_disk *disk); + const char * (*disk_raidname) (struct grub_disk *disk); #endif /* The next disk device. */ @@ -107,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 @@ -160,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 @@ -170,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); @@ -186,7 +242,7 @@ grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data) for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) for (p = grub_disk_dev_list; p; p = p->next) - if (p->iterate && (p->iterate) (hook, hook_data, pull)) + if (p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull)) return 1; return 0; @@ -211,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 d89273c1b..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; @@ -189,6 +189,15 @@ typedef grub_err_t (*grub_raid6_recover_func_t) (struct grub_diskfilter_segment extern grub_raid5_recover_func_t grub_raid5_recover_func; extern grub_raid6_recover_func_t grub_raid6_recover_func; +typedef grub_err_t (* raid_recover_read_t)(void *data, int disk_nr, + grub_uint64_t addr, void *dest, + grub_size_t size); + +extern grub_err_t +grub_raid6_recover_gen (void *data, grub_uint64_t nstripes, int disknr, int p, + char *buf, grub_uint64_t sector, grub_size_t size, + int layout, raid_recover_read_t read_func); + grub_err_t grub_diskfilter_vg_register (struct grub_diskfilter_vg *vg); grub_err_t diff --git a/include/grub/dl.h b/include/grub/dl.h index 2bca56ce0..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,8 @@ 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; Elf_Sym *symtab; @@ -202,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 @@ -240,6 +242,18 @@ grub_dl_get (const char *name) return 0; } +static inline void +grub_dl_set_persistent (grub_dl_t mod) +{ + mod->persistent = 1; +} + +static inline int +grub_dl_is_persistent (grub_dl_t mod) +{ + return mod->persistent; +} + #endif grub_err_t grub_dl_register_symbol (const char *name, void *addr, @@ -279,12 +293,15 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #endif -#if defined (__powerpc__) || defined (__mips__) || defined (__arm__) +#if defined (__powerpc__) || defined (__mips__) || defined (__arm__) || \ + (defined(__riscv) && (__riscv_xlen == 32)) #define GRUB_ARCH_DL_TRAMP_ALIGN 4 #define GRUB_ARCH_DL_GOT_ALIGN 4 #endif -#if defined (__aarch64__) || defined (__sparc__) +#if defined (__aarch64__) || defined (__sparc__) || \ + defined (__loongarch_lp64) || \ + (defined(__riscv) && (__riscv_xlen == 64)) #define GRUB_ARCH_DL_TRAMP_ALIGN 8 #define GRUB_ARCH_DL_GOT_ALIGN 8 #endif diff --git a/include/grub/dma.h b/include/grub/dma.h new file mode 100644 index 000000000..19992ebc1 --- /dev/null +++ b/include/grub/dma.h @@ -0,0 +1,44 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_DMA_H +#define GRUB_DMA_H 1 + +struct grub_pci_dma_chunk; + +struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, + grub_size_t size); +void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); +volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); +grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); + +static inline void * +grub_dma_phys2virt (grub_uint32_t phys, struct grub_pci_dma_chunk *chunk) +{ + return ((grub_uint8_t *) grub_dma_get_virt (chunk) + + (phys - grub_dma_get_phys (chunk))); +} + +static inline grub_uint32_t +grub_dma_virt2phys (volatile void *virt, struct grub_pci_dma_chunk *chunk) +{ + return (((grub_uint8_t *) virt - (grub_uint8_t *) grub_dma_get_virt (chunk)) + + grub_dma_get_phys (chunk)); +} + +#endif diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index c7c9f0e1d..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,92 +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__) +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 e9c601f34..a5cd99e5a 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -23,31 +23,54 @@ #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 * -EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, +EXPORT_FUNC(grub_efi_allocate_pages_real) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages, + grub_efi_allocate_type_t alloctype, + grub_efi_memory_type_t memtype); +void * +EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); +void * +EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); +grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); int EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size, grub_efi_memory_descriptor_t *memory_map, grub_efi_uintn_t *map_key, grub_efi_uintn_t *descriptor_size, grub_efi_uint32_t *descriptor_version); +void grub_efi_memory_fini (void); grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); @@ -65,27 +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__) -void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); -#endif +void * +EXPORT_FUNC (grub_efi_find_configuration_table) (const grub_guid_t *target_guid); -grub_addr_t grub_efi_modules_addr (void); +#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__) +void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); +grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); +#endif +#include +grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file, + struct linux_arch_kernel_header *lh); +grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, + char *args); + +grub_addr_t grub_efi_section_addr (const char *section); void grub_efi_mm_init (void); void grub_efi_mm_fini (void); diff --git a/include/grub/arm64/fdtload.h b/include/grub/efi/fdtload.h similarity index 89% rename from include/grub/arm64/fdtload.h rename to include/grub/efi/fdtload.h index 7b9ddba91..713c9424d 100644 --- a/include/grub/arm64/fdtload.h +++ b/include/grub/efi/fdtload.h @@ -29,7 +29,4 @@ grub_fdt_unload (void); grub_err_t grub_fdt_install (void); -#define GRUB_EFI_PAGE_SHIFT 12 -#define GRUB_EFI_BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) - #endif 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/memory.h b/include/grub/efi/memory.h index 20526b146..08fe62277 100644 --- a/include/grub/efi/memory.h +++ b/include/grub/efi/memory.h @@ -22,6 +22,13 @@ #include #include +/* The term "page" in UEFI refers only to a 4 KiB-aligned 4 KiB size region of + memory. It is not concerned with underlying translation management concepts, + but only used as the granule for memory allocations. */ +#define GRUB_EFI_PAGE_SHIFT 12 +#define GRUB_EFI_PAGE_SIZE (1 << GRUB_EFI_PAGE_SHIFT) +#define GRUB_EFI_BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> GRUB_EFI_PAGE_SHIFT) + #define GRUB_MMAP_REGISTER_BY_FIRMWARE 1 grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size, diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index f79c36c02..9887e14b2 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -20,6 +20,7 @@ #define GRUB_EFI_PE32_HEADER 1 #include +#include /* The MSDOS compatibility stub. This was copied from the output of objcopy, and it is not necessary to care about what this means. */ @@ -45,11 +46,30 @@ #define GRUB_PE32_MSDOS_STUB_SIZE 0x80 +#define GRUB_PE32_MAGIC 0x5a4d + +struct grub_msdos_image_header +{ + /* This is always 'MZ'. (GRUB_PE32_MAGIC) */ + grub_uint16_t msdos_magic; + + grub_uint16_t reserved[29]; + + /* The file offset of the PE image header. */ + grub_uint32_t pe_image_header_offset; +}; + /* According to the spec, the minimal alignment is 512 bytes... But some examples (such as EFI drivers in the Intel Sample Implementation) use 32 bytes (0x20) instead, and it seems - to be working. For now, GRUB uses 512 bytes for safety. */ -#define GRUB_PE32_SECTION_ALIGNMENT 0x200 + to be working. + + However, there is firmware showing up in the field now with + page alignment constraints to guarantee that page protection + bits take effect. Because currently existing GRUB code can not + properly distinguish between in-memory and in-file layout, let's + bump all alignment to GRUB_EFI_PAGE_SIZE. */ +#define GRUB_PE32_SECTION_ALIGNMENT GRUB_EFI_PAGE_SIZE #define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT struct grub_pe32_coff_header @@ -68,6 +88,10 @@ 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 #define GRUB_PE32_RELOCS_STRIPPED 0x0001 #define GRUB_PE32_EXECUTABLE_IMAGE 0x0002 @@ -207,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 @@ -243,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]; @@ -272,19 +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_SECTION 6 -#define GRUB_PE32_REL_BASED_REL 7 -#define GRUB_PE32_REL_BASED_ARM_MOV32T 7 -#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 new file mode 100644 index 000000000..6c6802ee5 --- /dev/null +++ b/include/grub/efi/tpm.h @@ -0,0 +1,195 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_EFI_TPM_HEADER +#define GRUB_EFI_TPM_HEADER 1 + +#define EFI_TPM_GUID {0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd }}; +#define EFI_TPM2_GUID {0x607f766c, 0x7455, 0x42be, {0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }}; + +#define TCG_ALG_SHA 0x00000004 + +/* These structs are as defined in the TCG EFI Protocol Specification, family 2.0. */ + +struct __TCG_VERSION +{ + grub_efi_uint8_t Major; + grub_efi_uint8_t Minor; + grub_efi_uint8_t RevMajor; + grub_efi_uint8_t RevMinor; +}; +typedef struct __TCG_VERSION TCG_VERSION; + +struct __TCG_EFI_BOOT_SERVICE_CAPABILITY +{ + /* Size of this structure. */ + grub_efi_uint8_t Size; + TCG_VERSION StructureVersion; + TCG_VERSION ProtocolSpecVersion; + /* Hash algorithms supported by this TPM. */ + grub_efi_uint8_t HashAlgorithmBitmap; + /* 1 if TPM present. */ + char TPMPresentFlag; + /* 1 if TPM deactivated. */ + char TPMDeactivatedFlag; +}; +typedef struct __TCG_EFI_BOOT_SERVICE_CAPABILITY TCG_EFI_BOOT_SERVICE_CAPABILITY; + +struct tdTCG_PCR_EVENT +{ + grub_efi_uint32_t PCRIndex; + grub_efi_uint32_t EventType; + grub_efi_uint8_t digest[20]; + grub_efi_uint32_t EventSize; + grub_efi_uint8_t Event[1]; +}; +typedef struct tdTCG_PCR_EVENT TCG_PCR_EVENT; + +struct grub_efi_tpm_protocol +{ + grub_efi_status_t + (__grub_efi_api *status_check) (struct grub_efi_tpm_protocol *this, + TCG_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability, + grub_efi_uint32_t *TCGFeatureFlags, + grub_efi_physical_address_t *EventLogLocation, + grub_efi_physical_address_t *EventLogLastEntry); + + grub_efi_status_t + (__grub_efi_api *hash_all) (struct grub_efi_tpm_protocol *this, + grub_efi_uint8_t *HashData, + grub_efi_uint64_t HashLen, + grub_efi_uint32_t AlgorithmId, + grub_efi_uint64_t *HashedDataLen, + grub_efi_uint8_t **HashedDataResult); + + grub_efi_status_t + (__grub_efi_api *log_event) (struct grub_efi_tpm_protocol *this, + TCG_PCR_EVENT *TCGLogData, + grub_efi_uint32_t *EventNumber, + grub_efi_uint32_t Flags); + + grub_efi_status_t + (__grub_efi_api *pass_through_to_tpm) (struct grub_efi_tpm_protocol *this, + grub_efi_uint32_t TpmInputParameterBlockSize, + grub_efi_uint8_t *TpmInputParameterBlock, + grub_efi_uint32_t TpmOutputParameterBlockSize, + grub_efi_uint8_t *TpmOutputParameterBlock); + + grub_efi_status_t + (__grub_efi_api *log_extend_event) (struct grub_efi_tpm_protocol *this, + grub_efi_physical_address_t HashData, + grub_efi_uint64_t HashDataLen, + grub_efi_uint32_t AlgorithmId, + TCG_PCR_EVENT *TCGLogData, + grub_efi_uint32_t *EventNumber, + grub_efi_physical_address_t *EventLogLastEntry); +}; + +typedef struct grub_efi_tpm_protocol grub_efi_tpm_protocol_t; + +typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_BITMAP; +typedef grub_efi_uint32_t EFI_TCG2_EVENT_LOG_FORMAT; +typedef grub_efi_uint32_t EFI_TCG2_EVENT_ALGORITHM_BITMAP; + +struct tdEFI_TCG2_VERSION +{ + grub_efi_uint8_t Major; + grub_efi_uint8_t Minor; +} GRUB_PACKED; +typedef struct tdEFI_TCG2_VERSION EFI_TCG2_VERSION; + +struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY +{ + grub_efi_uint8_t Size; + EFI_TCG2_VERSION StructureVersion; + EFI_TCG2_VERSION ProtocolVersion; + EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap; + EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs; + grub_efi_boolean_t TPMPresentFlag; + grub_efi_uint16_t MaxCommandSize; + grub_efi_uint16_t MaxResponseSize; + grub_efi_uint32_t ManufacturerID; + grub_efi_uint32_t NumberOfPcrBanks; + EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks; +}; +typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY EFI_TCG2_BOOT_SERVICE_CAPABILITY; + +typedef grub_efi_uint32_t TCG_PCRINDEX; +typedef grub_efi_uint32_t TCG_EVENTTYPE; + +struct tdEFI_TCG2_EVENT_HEADER +{ + grub_efi_uint32_t HeaderSize; + grub_efi_uint16_t HeaderVersion; + TCG_PCRINDEX PCRIndex; + TCG_EVENTTYPE EventType; +} GRUB_PACKED; +typedef struct tdEFI_TCG2_EVENT_HEADER EFI_TCG2_EVENT_HEADER; + +struct tdEFI_TCG2_EVENT +{ + grub_efi_uint32_t Size; + EFI_TCG2_EVENT_HEADER Header; + grub_efi_uint8_t Event[1]; +} GRUB_PACKED; +typedef struct tdEFI_TCG2_EVENT EFI_TCG2_EVENT; + +struct grub_efi_tpm2_protocol +{ + grub_efi_status_t + (__grub_efi_api *get_capability) (struct grub_efi_tpm2_protocol *this, + EFI_TCG2_BOOT_SERVICE_CAPABILITY *ProtocolCapability); + + grub_efi_status_t + (__grub_efi_api *get_event_log) (struct grub_efi_tpm2_protocol *this, + EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat, + grub_efi_physical_address_t *EventLogLocation, + grub_efi_physical_address_t *EventLogLastEntry, + grub_efi_boolean_t *EventLogTruncated); + + grub_efi_status_t + (__grub_efi_api *hash_log_extend_event) (struct grub_efi_tpm2_protocol *this, + grub_efi_uint64_t Flags, + grub_efi_physical_address_t DataToHash, + grub_efi_uint64_t DataToHashLen, + EFI_TCG2_EVENT *EfiTcgEvent); + + grub_efi_status_t + (__grub_efi_api *submit_command) (struct grub_efi_tpm2_protocol *this, + grub_efi_uint32_t InputParameterBlockSize, + grub_efi_uint8_t *InputParameterBlock, + grub_efi_uint32_t OutputParameterBlockSize, + grub_efi_uint8_t *OutputParameterBlock); + + grub_efi_status_t + (__grub_efi_api *get_active_pcr_banks) (struct grub_efi_tpm2_protocol *this, + grub_efi_uint32_t *ActivePcrBanks); + + grub_efi_status_t + (__grub_efi_api *set_active_pcr_banks) (struct grub_efi_tpm2_protocol *this, + grub_efi_uint32_t ActivePcrBanks); + + grub_efi_status_t + (__grub_efi_api *get_result_of_set_active_pcr_banks) (struct grub_efi_tpm2_protocol *this, + grub_efi_uint32_t *OperationPresent, + grub_efi_uint32_t *Response); +}; + +typedef struct grub_efi_tpm2_protocol grub_efi_tpm2_protocol_t; + +#endif diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h index 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 9b6b729f4..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_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 c8492f9dc..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. */ @@ -247,6 +251,8 @@ typedef struct #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_NUM 95 #define EM_AARCH64 183 /* ARM 64-bit architecture */ +#define EM_RISCV 243 /* RISC-V */ +#define EM_LOONGARCH 258 /* LoongArch */ /* If it is necessary to assign new unofficial EM_* values, please pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the @@ -565,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). */ @@ -2473,6 +2480,100 @@ typedef Elf32_Addr Elf32_Conflict; #define R_X86_64_NUM 24 +/* RISC-V relocations */ +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 + +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_GNU_VTINHERIT 41 +#define R_RISCV_GNU_VTENTRY 42 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 + +/* LoongArch relocations */ +#define R_LARCH_NONE 0 +#define R_LARCH_64 2 +#define R_LARCH_MARK_LA 20 +#define R_LARCH_SOP_PUSH_PCREL 22 +#define R_LARCH_SOP_PUSH_ABSOLUTE 23 +#define R_LARCH_SOP_PUSH_PLT_PCREL 29 +#define R_LARCH_SOP_SUB 32 +#define R_LARCH_SOP_SL 33 +#define R_LARCH_SOP_SR 34 +#define R_LARCH_SOP_ADD 35 +#define R_LARCH_SOP_AND 36 +#define R_LARCH_SOP_IF_ELSE 37 +#define R_LARCH_SOP_POP_32_S_10_5 38 +#define R_LARCH_SOP_POP_32_U_10_12 39 +#define R_LARCH_SOP_POP_32_S_10_12 40 +#define R_LARCH_SOP_POP_32_S_10_16 41 +#define R_LARCH_SOP_POP_32_S_10_16_S2 42 +#define R_LARCH_SOP_POP_32_S_5_20 43 +#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 +#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 +#define R_LARCH_B26 66 +#define R_LARCH_ABS_HI20 67 +#define R_LARCH_ABS_LO12 68 +#define R_LARCH_ABS64_LO20 69 +#define R_LARCH_ABS64_HI12 70 +#define R_LARCH_PCALA_HI20 71 +#define R_LARCH_PCALA_LO12 72 + +extern grub_err_t grub_elf32_get_shnum (Elf32_Ehdr *e, Elf32_Shnum *shnum); +extern grub_err_t grub_elf32_get_shstrndx (Elf32_Ehdr *e, Elf32_Word *shstrndx); +extern grub_err_t grub_elf32_get_phnum (Elf32_Ehdr *e, Elf32_Word *phnum); + +extern grub_err_t grub_elf64_get_shnum (Elf64_Ehdr *e, Elf64_Shnum *shnum); +extern grub_err_t grub_elf64_get_shstrndx (Elf64_Ehdr *e, Elf64_Word *shstrndx); +extern grub_err_t grub_elf64_get_phnum (Elf64_Ehdr *e, Elf64_Word *phnum); + #ifdef GRUB_TARGET_WORDSIZE #if GRUB_TARGET_WORDSIZE == 32 @@ -2490,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) @@ -2499,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; @@ -2515,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/elfload.h b/include/grub/elfload.h index 9a7ae4ebb..dbb609c9b 100644 --- a/include/grub/elfload.h +++ b/include/grub/elfload.h @@ -42,7 +42,7 @@ typedef int (*grub_elf32_phdr_iterate_hook_t) typedef int (*grub_elf64_phdr_iterate_hook_t) (grub_elf_t elf, Elf64_Phdr *phdr, void *arg); -grub_elf_t grub_elf_open (const char *); +grub_elf_t grub_elf_open (const char *, enum grub_file_type type); grub_elf_t grub_elf_file (grub_file_t file, const char *filename); grub_err_t grub_elf_close (grub_elf_t); 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 8e37d5acb..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, ...); @@ -47,11 +48,11 @@ grub_util_fd_t EXPORT_FUNC(grub_util_fd_open) (const char *os_dev, int flags); const char * EXPORT_FUNC(grub_util_fd_strerror) (void); -void +int grub_util_fd_sync (grub_util_fd_t fd); void grub_util_disable_fd_syncs (void); -void +int EXPORT_FUNC(grub_util_fd_close) (grub_util_fd_t fd); grub_uint64_t diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index df6085bcb..fefbec499 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -24,13 +24,14 @@ #include +#include #include #include #include #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); @@ -43,22 +44,21 @@ char *grub_make_system_path_relative_to_its_root (const char *path) int grub_util_device_is_mapped (const char *dev); -#ifdef __MINGW32__ -#define GRUB_HOST_PRIuLONG_LONG "I64u" -#define GRUB_HOST_PRIxLONG_LONG "I64x" -#else #define GRUB_HOST_PRIuLONG_LONG "llu" #define GRUB_HOST_PRIxLONG_LONG "llx" -#endif +void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT; void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT; void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT; char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT; -char * EXPORT_FUNC(xasprintf) (const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2))) WARN_UNUSED_RESULT; +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; -void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2))); -void EXPORT_FUNC(grub_util_info) (const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2))); -void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2), noreturn)); +void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); +void EXPORT_FUNC(grub_util_info) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); +void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2), noreturn)); + +void EXPORT_FUNC(grub_util_set_kexecute) (void); +int EXPORT_FUNC(grub_util_get_kexecute) (void) WARN_UNUSED_RESULT; grub_uint64_t EXPORT_FUNC (grub_util_get_cpu_time_ms) (void); @@ -73,6 +73,11 @@ FILE * grub_util_fopen (const char *path, const char *mode); #endif -void grub_util_file_sync (FILE *f); +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 1590c688e..202fa8a7a 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -21,6 +21,7 @@ #define GRUB_ERR_HEADER 1 #include +#include #define GRUB_MAX_ERRMSG 256 @@ -71,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; @@ -84,13 +88,14 @@ 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); void EXPORT_FUNC(grub_print_error) (void); extern int EXPORT_VAR(grub_err_printed_errors); int grub_err_printf (const char *fmt, ...) - __attribute__ ((format (__printf__, 1, 2))); + __attribute__ ((format (GNU_PRINTF, 1, 2))); #endif /* ! GRUB_ERR_HEADER */ 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/fat.h b/include/grub/fat.h index 4a5aab793..8d7e4a1e5 100644 --- a/include/grub/fat.h +++ b/include/grub/fat.h @@ -28,20 +28,15 @@ struct grub_fat_bpb grub_uint16_t bytes_per_sector; grub_uint8_t sectors_per_cluster; grub_uint16_t num_reserved_sectors; - grub_uint8_t num_fats; - /* 0x10 */ + grub_uint8_t num_fats; /* 0x10 */ grub_uint16_t num_root_entries; grub_uint16_t num_total_sectors_16; - grub_uint8_t media; - /*0 x15 */ + grub_uint8_t media; /* 0x15 */ grub_uint16_t sectors_per_fat_16; - grub_uint16_t sectors_per_track; - /*0 x19 */ - grub_uint16_t num_heads; - /*0 x1b */ - grub_uint32_t num_hidden_sectors; - /* 0x1f */ - grub_uint32_t num_total_sectors_32; + grub_uint16_t sectors_per_track; /* 0x18 */ + grub_uint16_t num_heads; /* 0x1A */ + grub_uint32_t num_hidden_sectors; /* 0x1C */ + grub_uint32_t num_total_sectors_32; /* 0x20 */ union { struct 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/fdt.h b/include/grub/fdt.h index fdfca75bf..e609c7e41 100644 --- a/include/grub/fdt.h +++ b/include/grub/fdt.h @@ -20,6 +20,10 @@ #define GRUB_FDT_HEADER 1 #include +#include + +/* Space required when preparing the /chosen node after boot has been called. */ +#define GRUB_EFI_LINUX_FDT_EXTRA_SPACE 0x400 #define FDT_MAGIC 0xD00DFEED @@ -49,6 +53,11 @@ struct grub_fdt_empty_tree { #define GRUB_FDT_EMPTY_TREE_SZ sizeof (struct grub_fdt_empty_tree) +/* Size needed by a property entry: 1 token (FDT_PROPERTY), plus len and nameoff + fields, plus the property value, plus padding if needed. */ +#define grub_fdt_prop_entry_size(prop_len) \ + (3 * sizeof(grub_uint32_t) + ALIGN_UP(prop_len, sizeof(grub_uint32_t))) + #define grub_fdt_get_header(fdt, field) \ grub_be_to_cpu32(((const grub_fdt_header_t *)(fdt))->field) #define grub_fdt_set_header(fdt, field, value) \ @@ -95,16 +104,22 @@ struct grub_fdt_empty_tree { #define grub_fdt_set_size_dt_struct(fdt, value) \ grub_fdt_set_header(fdt, size_dt_struct, value) -int grub_fdt_create_empty_tree (void *fdt, unsigned int size); -int grub_fdt_check_header (void *fdt, unsigned int size); -int grub_fdt_check_header_nosize (void *fdt); -int grub_fdt_find_subnode (const void *fdt, unsigned int parentoffset, - const char *name); -int grub_fdt_add_subnode (void *fdt, unsigned int parentoffset, +int EXPORT_FUNC(grub_fdt_create_empty_tree) (void *fdt, unsigned int size); +int EXPORT_FUNC(grub_fdt_check_header) (const void *fdt, unsigned int size); +int EXPORT_FUNC(grub_fdt_check_header_nosize) (const void *fdt); +int EXPORT_FUNC(grub_fdt_find_subnode) (const void *fdt, unsigned int parentoffset, + const char *name); +int EXPORT_FUNC(grub_fdt_first_node) (const void *fdt, unsigned int parentoffset); +int EXPORT_FUNC(grub_fdt_next_node) (const void *fdt, unsigned int currentoffset); +int EXPORT_FUNC(grub_fdt_add_subnode) (void *fdt, unsigned int parentoffset, const char *name); +const char * +EXPORT_FUNC(grub_fdt_get_nodename) (const void *fdt, unsigned int nodeoffset); +const void *EXPORT_FUNC(grub_fdt_get_prop) (const void *fdt, unsigned int nodeoffset, const char *name, + grub_uint32_t *len); -int grub_fdt_set_prop (void *fdt, unsigned int nodeoffset, const char *name, - const void *val, grub_uint32_t len); +int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, const char *name, + const void *val, grub_uint32_t len); #define grub_fdt_set_prop32(fdt, nodeoffset, name, val) \ ({ \ grub_uint32_t _val = grub_cpu_to_be32(val); \ diff --git a/include/grub/fdtbus.h b/include/grub/fdtbus.h new file mode 100644 index 000000000..f519c40ec --- /dev/null +++ b/include/grub/fdtbus.h @@ -0,0 +1,89 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FDTBUS_HEADER +#define GRUB_FDTBUS_HEADER 1 + +#include +#include + +struct grub_fdtbus_dev +{ + struct grub_fdtbus_dev *next; + struct grub_fdtbus_dev *parent; + int node; + struct grub_fdtbus_driver *driver; +}; + +struct grub_fdtbus_driver +{ + struct grub_fdtbus_driver *next; + struct grub_fdtbus_driver **prev; + + const char *compatible; + + grub_err_t (*attach) (const struct grub_fdtbus_dev *dev); + void (*detach) (const struct grub_fdtbus_dev *dev); + + /* Message bus operations. */ + grub_err_t (*send) (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz); + grub_err_t (*receive) (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz); + grub_err_t (*start) (const struct grub_fdtbus_dev *dev); + void (*stop) (const struct grub_fdtbus_dev *dev); +}; + +extern char EXPORT_VAR(grub_fdtbus_invalid_mapping)[1]; + +static inline int +grub_fdtbus_is_mapping_valid (volatile void *m) +{ + return m != grub_fdtbus_invalid_mapping; +} + +volatile void * +EXPORT_FUNC(grub_fdtbus_map_reg) (const struct grub_fdtbus_dev *dev, int reg, grub_size_t *size); + +const void * +EXPORT_FUNC(grub_fdtbus_get_fdt) (void); + +const char * +EXPORT_FUNC(grub_fdtbus_get_name) (const struct grub_fdtbus_dev *dev); + +const void * +EXPORT_FUNC(grub_fdtbus_get_prop) (const struct grub_fdtbus_dev *dev, + const char *name, + grub_uint32_t *len); + +void +EXPORT_FUNC(grub_fdtbus_register) (struct grub_fdtbus_driver *driver); + +void +EXPORT_FUNC(grub_fdtbus_unregister) (struct grub_fdtbus_driver *driver); + +int +EXPORT_FUNC(grub_fdtbus_is_compatible) (const char *compat_string, + const struct grub_fdtbus_dev *dev); + +/* Must be called before any register(). */ +/* dtb is assumed to be unfreeable and must remain + valid for lifetime of GRUB. + */ +void +grub_fdtbus_init (const void *dtb, grub_size_t size); + +#endif diff --git a/include/grub/file.h b/include/grub/file.h index 739488cbe..a5bf3a792 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -25,6 +25,120 @@ #include #include +enum grub_file_type + { + GRUB_FILE_TYPE_NONE = 0, + /* GRUB module to be loaded. */ + GRUB_FILE_TYPE_GRUB_MODULE, + /* Loopback file to be represented as disk. */ + GRUB_FILE_TYPE_LOOPBACK, + /* Linux kernel to be loaded. */ + GRUB_FILE_TYPE_LINUX_KERNEL, + /* Linux initrd. */ + GRUB_FILE_TYPE_LINUX_INITRD, + + /* Multiboot kernel. */ + GRUB_FILE_TYPE_MULTIBOOT_KERNEL, + /* Multiboot module. */ + GRUB_FILE_TYPE_MULTIBOOT_MODULE, + + /* Xen hypervisor - used on ARM only. */ + GRUB_FILE_TYPE_XEN_HYPERVISOR, + /* Xen module - used on ARM only. */ + GRUB_FILE_TYPE_XEN_MODULE, + + GRUB_FILE_TYPE_BSD_KERNEL, + GRUB_FILE_TYPE_FREEBSD_ENV, + GRUB_FILE_TYPE_FREEBSD_MODULE, + GRUB_FILE_TYPE_FREEBSD_MODULE_ELF, + GRUB_FILE_TYPE_NETBSD_MODULE, + GRUB_FILE_TYPE_OPENBSD_RAMDISK, + + GRUB_FILE_TYPE_XNU_INFO_PLIST, + GRUB_FILE_TYPE_XNU_MKEXT, + GRUB_FILE_TYPE_XNU_KEXT, + GRUB_FILE_TYPE_XNU_KERNEL, + GRUB_FILE_TYPE_XNU_RAMDISK, + GRUB_FILE_TYPE_XNU_HIBERNATE_IMAGE, + GRUB_FILE_XNU_DEVPROP, + + GRUB_FILE_TYPE_PLAN9_KERNEL, + + GRUB_FILE_TYPE_NTLDR, + GRUB_FILE_TYPE_TRUECRYPT, + GRUB_FILE_TYPE_FREEDOS, + GRUB_FILE_TYPE_PXECHAINLOADER, + GRUB_FILE_TYPE_PCCHAINLOADER, + + GRUB_FILE_TYPE_COREBOOT_CHAINLOADER, + + GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE, + + /* File holding signature. */ + GRUB_FILE_TYPE_SIGNATURE, + /* File holding public key to verify signature once. */ + GRUB_FILE_TYPE_PUBLIC_KEY, + /* File holding public key to add to trused keys. */ + GRUB_FILE_TYPE_PUBLIC_KEY_TRUST, + /* File of which we intend to print a blocklist to the user. */ + GRUB_FILE_TYPE_PRINT_BLOCKLIST, + /* File we intend to use for test loading or testing speed. */ + GRUB_FILE_TYPE_TESTLOAD, + /* File we open only to get its size. E.g. in ls output. */ + GRUB_FILE_TYPE_GET_SIZE, + /* Font file. */ + GRUB_FILE_TYPE_FONT, + /* File holding encryption key for encrypted ZFS. */ + GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY, + /* File holding the encryption key. */ + GRUB_FILE_TYPE_CRYPTODISK_ENCRYPTION_KEY, + /* File holding the encryption metadata header */ + GRUB_FILE_TYPE_CRYPTODISK_DETACHED_HEADER, + /* File we open n grub-fstest. */ + GRUB_FILE_TYPE_FSTEST, + /* File we open n grub-mount. */ + GRUB_FILE_TYPE_MOUNT, + /* File which we attempt to identify the type of. */ + GRUB_FILE_TYPE_FILE_ID, + /* File holding ACPI table. */ + GRUB_FILE_TYPE_ACPI_TABLE, + /* File holding Device Tree. */ + GRUB_FILE_TYPE_DEVICE_TREE_IMAGE, + /* File we intend show to user. */ + GRUB_FILE_TYPE_CAT, + GRUB_FILE_TYPE_HEXCAT, + /* One of pair of files we intend to compare. */ + GRUB_FILE_TYPE_CMP, + /* List of hashes for hashsum. */ + GRUB_FILE_TYPE_HASHLIST, + /* File hashed by hashsum. */ + GRUB_FILE_TYPE_TO_HASH, + /* Keyboard layout. */ + GRUB_FILE_TYPE_KEYBOARD_LAYOUT, + /* Picture file. */ + GRUB_FILE_TYPE_PIXMAP, + /* *.lst shipped by GRUB. */ + GRUB_FILE_TYPE_GRUB_MODULE_LIST, + /* config file. */ + GRUB_FILE_TYPE_CONFIG, + GRUB_FILE_TYPE_THEME, + GRUB_FILE_TYPE_GETTEXT_CATALOG, + GRUB_FILE_TYPE_FS_SEARCH, + GRUB_FILE_TYPE_AUDIO, + GRUB_FILE_TYPE_VBE_DUMP, + + GRUB_FILE_TYPE_LOADENV, + GRUB_FILE_TYPE_SAVEENV, + + GRUB_FILE_TYPE_VERIFY_SIGNATURE, + + GRUB_FILE_TYPE_MASK = 0xffff, + + /* --skip-sig is specified. */ + GRUB_FILE_TYPE_SKIP_SIGNATURE = 0x10000, + GRUB_FILE_TYPE_NO_DECOMPRESS = 0x20000 + }; + /* File description. */ struct grub_file { @@ -68,7 +182,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); /* Filters with lower ID are executed first. */ typedef enum grub_file_filter_id { - GRUB_FILE_FILTER_PUBKEY, + GRUB_FILE_FILTER_VERIFY, GRUB_FILE_FILTER_GZIO, GRUB_FILE_FILTER_XZIO, GRUB_FILE_FILTER_LZOPIO, @@ -77,61 +191,26 @@ typedef enum grub_file_filter_id GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, } grub_file_filter_id_t; -typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, const char *filename); +typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, enum grub_file_type type); -extern grub_file_filter_t EXPORT_VAR(grub_file_filters_all)[GRUB_FILE_FILTER_MAX]; -extern grub_file_filter_t EXPORT_VAR(grub_file_filters_enabled)[GRUB_FILE_FILTER_MAX]; +extern grub_file_filter_t EXPORT_VAR(grub_file_filters)[GRUB_FILE_FILTER_MAX]; static inline void grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter) { - grub_file_filters_all[id] = filter; - grub_file_filters_enabled[id] = filter; + grub_file_filters[id] = filter; } static inline void grub_file_filter_unregister (grub_file_filter_id_t id) { - grub_file_filters_all[id] = 0; - grub_file_filters_enabled[id] = 0; -} - -static inline void -grub_file_filter_disable (grub_file_filter_id_t id) -{ - grub_file_filters_enabled[id] = 0; -} - -static inline void -grub_file_filter_disable_compression (void) -{ - grub_file_filter_id_t id; - - for (id = GRUB_FILE_FILTER_COMPRESSION_FIRST; - id <= GRUB_FILE_FILTER_COMPRESSION_LAST; id++) - grub_file_filters_enabled[id] = 0; -} - -static inline void -grub_file_filter_disable_all (void) -{ - grub_file_filter_id_t id; - - for (id = 0; - id < GRUB_FILE_FILTER_MAX; id++) - grub_file_filters_enabled[id] = 0; -} - -static inline void -grub_file_filter_disable_pubkey (void) -{ - grub_file_filters_enabled[GRUB_FILE_FILTER_PUBKEY] = 0; + grub_file_filters[id] = 0; } /* Get a device name from NAME. */ char *EXPORT_FUNC(grub_file_get_device_name) (const char *name); -grub_file_t EXPORT_FUNC(grub_file_open) (const char *name); +grub_file_t EXPORT_FUNC(grub_file_open) (const char *name, enum grub_file_type type); grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, void *buf, grub_size_t len); grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset); @@ -159,8 +238,8 @@ grub_file_seekable (const grub_file_t file) } grub_file_t -grub_file_offset_open (grub_file_t parent, grub_off_t start, - grub_off_t size); +grub_file_offset_open (grub_file_t parent, enum grub_file_type type, + grub_off_t start, grub_off_t size); void grub_file_offset_close (grub_file_t file); diff --git a/include/grub/fs.h b/include/grub/fs.h index 5678c60c2..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,35 +58,38 @@ struct grub_fs /* My name. */ const char *name; + /* My module */ + grub_dl_t mod; + /* Call HOOK with each file under DIR. */ - grub_err_t (*dir) (grub_device_t device, const char *path, + grub_err_t (*fs_dir) (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, void *hook_data); /* Open a file named NAME and initialize FILE. */ - grub_err_t (*open) (struct grub_file *file, const char *name); + grub_err_t (*fs_open) (struct grub_file *file, const char *name); /* Read LEN bytes data from FILE into BUF. */ - grub_ssize_t (*read) (struct grub_file *file, char *buf, grub_size_t len); + grub_ssize_t (*fs_read) (struct grub_file *file, char *buf, grub_size_t len); /* Close the file FILE. */ - grub_err_t (*close) (struct grub_file *file); + grub_err_t (*fs_close) (struct grub_file *file); /* Return the label of the device DEVICE in LABEL. The label is returned in a grub_malloc'ed buffer and should be freed by the caller. */ - grub_err_t (*label) (grub_device_t device, char **label); + grub_err_t (*fs_label) (grub_device_t device, char **label); /* Return the uuid of the device DEVICE in UUID. The uuid is returned in a grub_malloc'ed buffer and should be freed by the caller. */ - grub_err_t (*uuid) (grub_device_t device, char **uuid); + grub_err_t (*fs_uuid) (grub_device_t device, char **uuid); /* Get writing time of filesystem. */ - grub_err_t (*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. */ - grub_err_t (*embed) (grub_device_t device, unsigned int *nsectors, + grub_err_t (*fs_embed) (grub_device_t device, unsigned int *nsectors, unsigned int max_nsectors, grub_embed_type_t embed_type, grub_disk_addr_t **sectors); 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 1b32f6725..292ea03f1 100644 --- a/include/grub/gpt_partition.h +++ b/include/grub/gpt_partition.h @@ -22,15 +22,6 @@ #include #include -struct grub_gpt_part_type -{ - grub_uint32_t data1; - grub_uint16_t data2; - grub_uint16_t data3; - grub_uint8_t data4[8]; -} __attribute__ ((aligned(8))); -typedef struct grub_gpt_part_type grub_gpt_part_type_t; - #define GRUB_GPT_PARTITION_TYPE_EMPTY \ { 0x0, 0x0, 0x0, \ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \ @@ -70,13 +61,13 @@ struct grub_gpt_header struct grub_gpt_partentry { - grub_gpt_part_type_t type; - grub_uint8_t guid[16]; + 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/hfs.h b/include/grub/hfs.h index d935f5005..e27993c42 100644 --- a/include/grub/hfs.h +++ b/include/grub/hfs.h @@ -29,7 +29,7 @@ struct grub_hfs_extent /* The first physical block. */ grub_uint16_t first_block; grub_uint16_t count; -}; +} GRUB_PACKED; /* HFS stores extents in groups of 3. */ typedef struct grub_hfs_extent grub_hfs_datarecord_t[3]; 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/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/i386/io.h b/include/grub/i386/io.h index ae12a3e3d..e9cd80957 100644 --- a/include/grub/i386/io.h +++ b/include/grub/i386/io.h @@ -28,7 +28,7 @@ grub_inb (unsigned short int port) { unsigned char _v; - __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port)); + asm volatile ("inb %w1,%0":"=a" (_v):"Nd" (port)); return _v; } @@ -37,7 +37,7 @@ grub_inw (unsigned short int port) { unsigned short _v; - __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port)); + asm volatile ("inw %w1,%0":"=a" (_v):"Nd" (port)); return _v; } @@ -46,27 +46,27 @@ grub_inl (unsigned short int port) { unsigned int _v; - __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port)); + asm volatile ("inl %w1,%0":"=a" (_v):"Nd" (port)); return _v; } static __inline void grub_outb (unsigned char value, unsigned short int port) { - __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port)); + asm volatile ("outb %b0,%w1": :"a" (value), "Nd" (port)); } static __inline void grub_outw (unsigned short int value, unsigned short int port) { - __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port)); + asm volatile ("outw %w0,%w1": :"a" (value), "Nd" (port)); } static __inline void grub_outl (unsigned int value, unsigned short int port) { - __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port)); + asm volatile ("outl %0,%w1": :"a" (value), "Nd" (port)); } #endif /* _SYS_IO_H */ diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index da0ca3b83..6e0a8e5be 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -16,10 +16,12 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_LINUX_MACHINE_HEADER -#define GRUB_LINUX_MACHINE_HEADER 1 +#ifndef GRUB_I386_LINUX_HEADER +#define GRUB_I386_LINUX_HEADER 1 -#define GRUB_LINUX_MAGIC_SIGNATURE 0x53726448 /* "HdrS" */ +#include + +#define GRUB_LINUX_I386_MAGIC_SIGNATURE 0x53726448 /* "HdrS" */ #define GRUB_LINUX_DEFAULT_SETUP_SECTS 4 #define GRUB_LINUX_INITRD_MAX_ADDRESS 0x37FFFFFF #define GRUB_LINUX_MAX_SETUP_SECTS 64 @@ -43,6 +45,15 @@ #define GRUB_LINUX_CL_MAGIC 0xA33F +#define VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0) +#define VIDEO_CAPABILITY_64BIT_BASE (1 << 1) /* Frame buffer base is 64-bit. */ + +/* Maximum number of MBR signatures to store. */ +#define EDD_MBR_SIG_MAX 16 + +/* Number of edd_info structs starting at EDDBUF. */ +#define EDDMAXNR 6 + #ifdef __x86_64__ #define GRUB_LINUX_EFI_SIGNATURE \ @@ -61,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 @@ -69,23 +90,274 @@ #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. */ -struct linux_kernel_header +/* For the Linux/i386 boot protocol version 2.10. */ +struct linux_i386_kernel_header { grub_uint8_t code1[0x0020]; grub_uint16_t cl_magic; /* Magic number 0xA33F */ @@ -126,11 +398,11 @@ struct linux_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; @@ -139,177 +411,97 @@ struct linux_kernel_header grub_uint64_t setup_data; grub_uint64_t pref_address; grub_uint32_t init_size; + 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_uint8_t padding3[0x40 - 0x3a]; - - grub_uint16_t apm_version; /* 40 */ - grub_uint16_t apm_code_segment; /* 42 */ - grub_uint32_t apm_entry; /* 44 */ - grub_uint16_t apm_16bit_code_segment; /* 48 */ - grub_uint16_t apm_data_segment; /* 4a */ - grub_uint16_t apm_flags; /* 4c */ - grub_uint32_t apm_code_len; /* 4e */ - grub_uint16_t apm_data_len; /* 52 */ - - grub_uint8_t padding4[0x60 - 0x54]; - - grub_uint32_t ist_signature; /* 60 */ - grub_uint32_t ist_command; /* 64 */ - grub_uint32_t ist_event; /* 68 */ - grub_uint32_t ist_perf_level; /* 6c */ - - grub_uint8_t padding5[0x80 - 0x70]; - - grub_uint8_t hd0_drive_info[0x10]; /* 80 */ - grub_uint8_t hd1_drive_info[0x10]; /* 90 */ - grub_uint16_t rom_config_len; /* a0 */ - - grub_uint8_t padding6[0xb0 - 0xa2]; - - grub_uint32_t ofw_signature; /* b0 */ - grub_uint32_t ofw_num_items; /* b4 */ - grub_uint32_t ofw_cif_handler; /* b8 */ - grub_uint32_t ofw_idt; /* bc */ - - grub_uint8_t padding7[0x1b8 - 0xc0]; + 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 alt_mem; /* 1e0 */ - - grub_uint8_t padding8[0x1e8 - 0x1e4]; - - grub_uint8_t mmap_size; /* 1e8 */ - - grub_uint8_t padding9[0x1f1 - 0x1e9]; - - grub_uint8_t setup_sects; /* The size of the setup in sectors */ - grub_uint16_t root_flags; /* If the root is mounted readonly */ - grub_uint16_t syssize; /* obsolete */ - grub_uint16_t swap_dev; /* obsolete */ - grub_uint16_t ram_size; /* obsolete */ - grub_uint16_t vid_mode; /* Video mode control */ - grub_uint16_t root_dev; /* Default root device number */ - - grub_uint8_t padding10; /* 1fe */ - grub_uint8_t ps_mouse; /* 1ff */ - - grub_uint16_t jump; /* Jump instruction */ - grub_uint32_t header; /* Magic signature "HdrS" */ - grub_uint16_t version; /* Boot protocol version supported */ - grub_uint32_t realmode_swtch; /* Boot loader hook */ - grub_uint16_t start_sys; /* The load-low segment (obsolete) */ - grub_uint16_t kernel_version; /* Points to kernel version string */ - grub_uint8_t type_of_loader; /* Boot loader identifier */ - grub_uint8_t loadflags; /* Boot protocol option flags */ - grub_uint16_t setup_move_size; /* Move to high memory size */ - grub_uint32_t code32_start; /* Boot loader hook */ - grub_uint32_t ramdisk_image; /* initrd load address */ - grub_uint32_t ramdisk_size; /* initrd size */ - grub_uint32_t bootsect_kludge; /* obsolete */ - grub_uint16_t heap_end_ptr; /* Free memory after setup end */ - grub_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_uint8_t pad2[120]; /* 258 */ - struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20]; /* 2d0 */ + { + 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_k; /* 1e0 */ + grub_uint32_t scratch; /* 1e4 */ + grub_uint8_t e820_entries; /* 1e8 */ + grub_uint8_t eddbuf_entries; /* 1e9 */ + grub_uint8_t edd_mbr_sig_buf_entries; /* 1ea */ + grub_uint8_t kbd_status; /* 1eb */ + grub_uint8_t secure_boot; /* 1ec */ + grub_uint8_t _pad5[2]; /* 1ed */ + grub_uint8_t sentinel; /* 1ef */ + grub_uint8_t _pad6[1]; /* 1f0 */ + struct grub_setup_header hdr; /* 1f1 */ + grub_uint8_t _pad7[0x290 - 0x1f1 - sizeof(struct grub_setup_header)]; + grub_uint32_t edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 290 */ + struct grub_boot_e820_entry e820_table[GRUB_E820_MAX_ENTRIES_ZEROPAGE]; /* 2d0 */ + grub_uint8_t _pad8[48]; /* cd0 */ + struct grub_edd_info eddbuf[EDDMAXNR]; /* d00 */ + grub_uint8_t _pad9[276]; /* eec */ } GRUB_PACKED; #endif /* ! ASM_FILE */ -#endif /* ! GRUB_LINUX_MACHINE_HEADER */ +#endif /* ! GRUB_I386_LINUX_HEADER */ diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h index 8bb6e1cbb..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 @@ -44,6 +45,13 @@ #include +struct grub_e820_mmap_entry +{ + grub_uint64_t addr; + grub_uint64_t len; + grub_uint32_t type; +} GRUB_PACKED; + grub_uint64_t grub_mmap_get_upper (void); grub_uint64_t grub_mmap_get_lower (void); grub_uint64_t grub_mmap_get_post64 (void); 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/multiboot.h b/include/grub/i386/multiboot.h index 807a1de27..0b596fc20 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -19,6 +19,13 @@ #ifndef GRUB_MULTIBOOT_CPU_HEADER #define GRUB_MULTIBOOT_CPU_HEADER 1 +#define MULTIBOOT2_INITIAL_STATE { .eax = MULTIBOOT2_BOOTLOADER_MAGIC, \ + .ecx = 0, \ + .edx = 0, \ + /* Set esp to some random location in low memory to avoid breaking */ \ + /* non-compliant kernels. */ \ + .esp = 0x7ff00 \ + } #define MULTIBOOT_INITIAL_STATE { .eax = MULTIBOOT_BOOTLOADER_MAGIC, \ .ecx = 0, \ .edx = 0, \ @@ -28,7 +35,7 @@ } #define MULTIBOOT_ENTRY_REGISTER eip #define MULTIBOOT_MBI_REGISTER ebx -#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_I386 +#define MULTIBOOT2_ARCHITECTURE_CURRENT MULTIBOOT2_ARCHITECTURE_I386 #ifdef GRUB_MACHINE_EFI #ifdef __x86_64__ @@ -36,6 +43,10 @@ .rcx = 0, \ .rdx = 0, \ } +#define MULTIBOOT2_EFI_INITIAL_STATE { .rax = MULTIBOOT2_BOOTLOADER_MAGIC, \ + .rcx = 0, \ + .rdx = 0, \ + } #define MULTIBOOT_EFI_ENTRY_REGISTER rip #define MULTIBOOT_EFI_MBI_REGISTER rbx #endif 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/int.h b/include/grub/i386/pc/int.h index 16a53e4fe..a60104001 100644 --- a/include/grub/i386/pc/int.h +++ b/include/grub/i386/pc/int.h @@ -20,45 +20,11 @@ #define GRUB_INTERRUPT_MACHINE_HEADER 1 #include -#include - -struct grub_bios_int_registers -{ - grub_uint32_t eax; - grub_uint16_t es; - grub_uint16_t ds; - grub_uint16_t flags; - grub_uint16_t dummy; - grub_uint32_t ebx; - grub_uint32_t ecx; - grub_uint32_t edi; - grub_uint32_t esi; - grub_uint32_t edx; -}; - -#define GRUB_CPU_INT_FLAGS_CARRY 0x1 -#define GRUB_CPU_INT_FLAGS_PARITY 0x4 -#define GRUB_CPU_INT_FLAGS_ADJUST 0x10 -#define GRUB_CPU_INT_FLAGS_ZERO 0x40 -#define GRUB_CPU_INT_FLAGS_SIGN 0x80 -#define GRUB_CPU_INT_FLAGS_TRAP 0x100 -#define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200 -#define GRUB_CPU_INT_FLAGS_DIRECTION 0x400 -#define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800 -#ifdef GRUB_MACHINE_PCBIOS -#define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT -#else -#define GRUB_CPU_INT_FLAGS_DEFAULT 0 -#endif +#include void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno, struct grub_bios_int_registers *regs) __attribute__ ((regparm(3))); -struct grub_i386_idt -{ - grub_uint16_t limit; - grub_uint32_t base; -} GRUB_PACKED; #ifdef GRUB_MACHINE_PCBIOS extern struct grub_i386_idt *EXPORT_VAR(grub_realidt); diff --git a/include/grub/i386/pc/int_types.h b/include/grub/i386/pc/int_types.h new file mode 100644 index 000000000..2c5a69b63 --- /dev/null +++ b/include/grub/i386/pc/int_types.h @@ -0,0 +1,59 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_INTERRUPT_TYPES_MACHINE_HEADER +#define GRUB_INTERRUPT_TYPES_MACHINE_HEADER 1 + +#include + +#define GRUB_CPU_INT_FLAGS_CARRY 0x1 +#define GRUB_CPU_INT_FLAGS_PARITY 0x4 +#define GRUB_CPU_INT_FLAGS_ADJUST 0x10 +#define GRUB_CPU_INT_FLAGS_ZERO 0x40 +#define GRUB_CPU_INT_FLAGS_SIGN 0x80 +#define GRUB_CPU_INT_FLAGS_TRAP 0x100 +#define GRUB_CPU_INT_FLAGS_INTERRUPT 0x200 +#define GRUB_CPU_INT_FLAGS_DIRECTION 0x400 +#define GRUB_CPU_INT_FLAGS_OVERFLOW 0x800 +#ifdef GRUB_MACHINE_PCBIOS +#define GRUB_CPU_INT_FLAGS_DEFAULT GRUB_CPU_INT_FLAGS_INTERRUPT +#else +#define GRUB_CPU_INT_FLAGS_DEFAULT 0 +#endif + +struct grub_bios_int_registers +{ + grub_uint32_t eax; + grub_uint16_t es; + grub_uint16_t ds; + grub_uint16_t flags; + grub_uint16_t dummy; + grub_uint32_t ebx; + grub_uint32_t ecx; + grub_uint32_t edi; + grub_uint32_t esi; + grub_uint32_t edx; +}; + +struct grub_i386_idt +{ + grub_uint16_t limit; + grub_uint32_t base; +} GRUB_PACKED; + +#endif diff --git a/include/grub/i386/pc/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/time.h b/include/grub/i386/time.h index 842882cf2..4da5ae93c 100644 --- a/include/grub/i386/time.h +++ b/include/grub/i386/time.h @@ -23,7 +23,7 @@ static __inline void grub_cpu_idle (void) { /* FIXME: this can't work until we handle interrupts. */ -/* __asm__ __volatile__ ("hlt"); */ +/* asm volatile ("hlt"); */ } #endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h index a0aa2c573..3c96d3e0b 100644 --- a/include/grub/i386/tsc.h +++ b/include/grub/i386/tsc.h @@ -46,7 +46,12 @@ grub_get_tsc (void) grub_cpuid (0,a,b,c,d); /* Read TSC value. We cannot use "=A", since this would use %rax on x86_64. */ - __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); + 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; } @@ -54,7 +59,7 @@ grub_get_tsc (void) static __inline int grub_cpu_is_tsc_supported (void) { -#ifndef GRUB_MACHINE_XEN +#if !defined(GRUB_MACHINE_XEN) && !defined(GRUB_MACHINE_XEN_PVH) grub_uint32_t a,b,c,d; if (! grub_cpu_is_cpuid_supported ()) return 0; diff --git a/include/grub/i386/xen/hypercall.h b/include/grub/i386/xen/hypercall.h index 198ee94af..4e4c12a49 100644 --- a/include/grub/i386/xen/hypercall.h +++ b/include/grub/i386/xen/hypercall.h @@ -26,7 +26,10 @@ EXPORT_FUNC (grub_xen_hypercall) (grub_uint32_t callno, grub_uint32_t a0, grub_uint32_t a1, grub_uint32_t a2, grub_uint32_t a3, grub_uint32_t a4, grub_uint32_t a5) -__attribute__ ((regparm (3), cdecl)); +#ifdef GRUB_MACHINE_XEN + __attribute__ ((regparm (3), cdecl)) +#endif + ; static inline int grub_xen_sched_op (int cmd, void *arg) diff --git a/include/grub/i386/xen/kernel.h b/include/grub/i386/xen/kernel.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/i386/xen_pvh/boot.h b/include/grub/i386/xen_pvh/boot.h new file mode 100644 index 000000000..6cd23aa83 --- /dev/null +++ b/include/grub/i386/xen_pvh/boot.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/xen_pvh/console.h b/include/grub/i386/xen_pvh/console.h new file mode 100644 index 000000000..305a46d8e --- /dev/null +++ b/include/grub/i386/xen_pvh/console.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/xen_pvh/int.h b/include/grub/i386/xen_pvh/int.h new file mode 100644 index 000000000..0f1f9ee62 --- /dev/null +++ b/include/grub/i386/xen_pvh/int.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/xen_pvh/kernel.h b/include/grub/i386/xen_pvh/kernel.h new file mode 100644 index 000000000..2b7b8a129 --- /dev/null +++ b/include/grub/i386/xen_pvh/kernel.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#ifndef ASM_FILE + +#define GRUB_KERNEL_USE_RSDP_ADDR 1 + +extern grub_uint64_t EXPORT_VAR(grub_rsdp_addr); + +#endif /* ! ASM_FILE */ + +#endif /* GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/xen_pvh/memory.h b/include/grub/i386/xen_pvh/memory.h new file mode 100644 index 000000000..8dd6f7c8c --- /dev/null +++ b/include/grub/i386/xen_pvh/memory.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/xen_pvh/time.h b/include/grub/i386/xen_pvh/time.h new file mode 100644 index 000000000..2298ee8f4 --- /dev/null +++ b/include/grub/i386/xen_pvh/time.h @@ -0,0 +1 @@ +#include 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 8e4251303..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. */ @@ -146,6 +130,22 @@ enum grub_ieee1275_flag GRUB_IEEE1275_FLAG_BROKEN_REPEAT, GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN, + + GRUB_IEEE1275_FLAG_RAW_DEVNAMES, + +#if defined(__powerpc__) + /* + * On PFW, the first time we boot a Linux partition, we may only get 256MB of + * real memory area, even if the partition has more memory. Set this flag if + * we think we're running under PFW. Then, if this flag is set, and the RMA is + * only 256MB in size, try asking for more with CAS. + */ + GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY, +#endif + + GRUB_IEEE1275_FLAG_POWER_VM, + + GRUB_IEEE1275_FLAG_POWER_KVM, }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); @@ -210,7 +210,25 @@ int EXPORT_FUNC(grub_ieee1275_set_property) (grub_ieee1275_phandle_t phandle, int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle, int index, int r, int g, int b); int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs); - +int EXPORT_FUNC(grub_ieee1275_set_address) (grub_ieee1275_ihandle_t ihandle, + grub_uint32_t target, + grub_uint32_t lun); +int EXPORT_FUNC(grub_ieee1275_no_data_command) (grub_ieee1275_ihandle_t ihandle, + const void *cmd_addr, + grub_ssize_t *result); +int EXPORT_FUNC(grub_ieee1275_decode_unit4) (grub_ieee1275_ihandle_t ihandle, + void *addr, grub_size_t size, + grub_uint32_t *phy_lo, + grub_uint32_t *phy_hi, + grub_uint32_t *lun_lo, + grub_uint32_t *lun_hi); +char *EXPORT_FUNC(grub_ieee1275_encode_uint4) (grub_ieee1275_ihandle_t ihandle, + grub_uint32_t phy_lo, + grub_uint32_t phy_hi, + grub_uint32_t lun_lo, + grub_uint32_t lun_hi, + grub_size_t *size); +int EXPORT_FUNC(grub_ieee1275_get_block_size) (grub_ieee1275_ihandle_t ihandle); grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); @@ -235,6 +253,8 @@ void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *al void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, struct grub_ieee1275_devalias *alias); +char *EXPORT_FUNC(grub_ieee1275_get_boot_dev) (void); + #define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));) #define FOR_IEEE1275_DEVCHILDREN(devpath, alias) for (grub_ieee1275_children_first ((devpath), &(alias)); \ diff --git a/include/grub/ieee1275/obdisk.h b/include/grub/ieee1275/obdisk.h new file mode 100644 index 000000000..5da51f812 --- /dev/null +++ b/include/grub/ieee1275/obdisk.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_OBDISK_HEADER +#define GRUB_OBDISK_HEADER 1 + +extern void grub_obdisk_init (void); +extern void grub_obdisk_fini (void); + +#endif diff --git a/include/grub/ieee1275/tpm.h b/include/grub/ieee1275/tpm.h 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 20ddf2da2..6121c1e66 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -28,7 +28,10 @@ enum OBJ_TYPE_MEMDISK, OBJ_TYPE_CONFIG, OBJ_TYPE_PREFIX, - OBJ_TYPE_PUBKEY + OBJ_TYPE_PUBKEY, + OBJ_TYPE_DTB, + OBJ_TYPE_DISABLE_SHIM_LOCK, + OBJ_TYPE_DISABLE_CLI }; /* The module header. */ @@ -78,7 +81,9 @@ struct grub_module_info64 #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \ || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \ || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \ - || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) + || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) \ + || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) \ + || defined(GRUB_MACHINE_XEN_PVH) /* FIXME: stack is between 2 heap regions. Move it. */ #define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1 #endif 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/lib/cmdline.h b/include/grub/lib/cmdline.h index 1fe8d0179..cdca09b7a 100644 --- a/include/grub/lib/cmdline.h +++ b/include/grub/lib/cmdline.h @@ -21,11 +21,12 @@ #define GRUB_CMDLINE_HEADER 1 #include +#include #define LINUX_IMAGE "BOOT_IMAGE=" unsigned int grub_loader_cmdline_size (int argc, char *argv[]); -int grub_create_loader_cmdline (int argc, char *argv[], char *buf, - grub_size_t size); +grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf, + grub_size_t size, enum grub_verify_string_type type); #endif /* ! GRUB_CMDLINE_HEADER */ diff --git a/include/grub/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 d170ff6da..21f4b4b44 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -35,11 +35,12 @@ void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void EXPORT_FUNC(grub_list_remove) (grub_list_t item); #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) +#define FOR_LIST_ELEMENTS_NEXT(var, list) for ((var) = (var)->next; (var); (var) = (var)->next) #define FOR_LIST_ELEMENTS_SAFE(var, nxt, list) for ((var) = (list), (nxt) = ((var) ? (var)->next : 0); (var); (var) = (nxt), ((nxt) = (var) ? (var)->next : 0)) 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/loongarch64/time.h b/include/grub/loongarch64/time.h new file mode 100644 index 000000000..eefcd2788 --- /dev/null +++ b/include/grub/loongarch64/time.h @@ -0,0 +1,28 @@ +/* + * 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 KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static inline void +grub_cpu_idle(void) +{ + asm volatile ("idle 0"); +} + +#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/machoload.h b/include/grub/machoload.h index 1eec118f1..f1157f410 100644 --- a/include/grub/machoload.h +++ b/include/grub/machoload.h @@ -49,7 +49,8 @@ struct grub_macho_file }; typedef struct grub_macho_file *grub_macho_t; -grub_macho_t grub_macho_open (const char *, int is_64bit); +grub_macho_t grub_macho_open (const char *, enum grub_file_type type, + int is_64bit); grub_macho_t grub_macho_file (grub_file_t file, const char *filename, int is_64bit); grub_err_t grub_macho_close (grub_macho_t); 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/multiboot.h b/include/grub/mips/multiboot.h index 4aebf29e7..cdfb41e31 100644 --- a/include/grub/mips/multiboot.h +++ b/include/grub/mips/multiboot.h @@ -19,11 +19,11 @@ #ifndef GRUB_MULTIBOOT_CPU_HEADER #define GRUB_MULTIBOOT_CPU_HEADER 1 -#define MULTIBOOT_INITIAL_STATE { .gpr[4] = MULTIBOOT_BOOTLOADER_MAGIC, \ +#define MULTIBOOT2_INITIAL_STATE { .gpr[4] = MULTIBOOT2_BOOTLOADER_MAGIC, \ .jumpreg = 1 } #define MULTIBOOT_ENTRY_REGISTER gpr[1] #define MULTIBOOT_MBI_REGISTER gpr[5] -#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_MIPS32 +#define MULTIBOOT2_ARCHITECTURE_CURRENT MULTIBOOT2_ARCHITECTURE_MIPS32 #define MULTIBOOT_ELF32_MACHINE EM_MIPS #define MULTIBOOT_ELF64_MACHINE EM_MIPS 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 2a9f87cc2..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,13 +423,20 @@ 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__)) +#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ + (defined(__riscv) && (__riscv_xlen == 32))) #define GRUB_DIVISION_IN_SOFTWARE 1 #else #define GRUB_DIVISION_IN_SOFTWARE 0 @@ -396,16 +492,13 @@ grub_abs (int x) } /* Reboot the machine. */ -#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) +#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) || \ + defined (GRUB_MACHINE_EFI) void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); #else void grub_reboot (void) __attribute__ ((noreturn)); #endif -#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. */ @@ -438,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 { @@ -461,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/module_verifier.h b/include/grub/module_verifier.h index f4870cb9c..ba21c75e2 100644 --- a/include/grub/module_verifier.h +++ b/include/grub/module_verifier.h @@ -16,5 +16,5 @@ struct grub_module_verifier_arch { const int *short_relocations; }; -void grub_module_verify64(void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty); -void grub_module_verify32(void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty); +void grub_module_verify64(const char * const filename, void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty); +void grub_module_verify32(const char * const filename, void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty); diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index c96492bb5..d8847f753 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -22,19 +22,11 @@ #include -#ifdef GRUB_USE_MULTIBOOT2 -#include -/* Same thing as far as our loader is concerned. */ -#define MULTIBOOT_BOOTLOADER_MAGIC MULTIBOOT2_BOOTLOADER_MAGIC -#define MULTIBOOT_HEADER_MAGIC MULTIBOOT2_HEADER_MAGIC -#else #include -#endif #include #include -#ifndef GRUB_USE_MULTIBOOT2 typedef enum { GRUB_MULTIBOOT_QUIRKS_NONE = 0, @@ -42,7 +34,6 @@ typedef enum GRUB_MULTIBOOT_QUIRK_MODULES_AFTER_KERNEL = 2 } grub_multiboot_quirks_t; extern grub_multiboot_quirks_t grub_multiboot_quirks; -#endif extern struct grub_relocator *grub_multiboot_relocator; @@ -60,7 +51,7 @@ void grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize, unsigned shndx, void *data); -grub_uint32_t grub_get_multiboot_mmap_count (void); +grub_uint32_t grub_multiboot_get_mmap_count (void); grub_err_t grub_multiboot_set_video_mode (void); /* FIXME: support coreboot as well. */ @@ -83,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 new file mode 100644 index 000000000..b90aa6989 --- /dev/null +++ b/include/grub/multiboot2.h @@ -0,0 +1,104 @@ +/* multiboot.h - multiboot header file with grub definitions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2008,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MULTIBOOT2_HEADER +#define GRUB_MULTIBOOT2_HEADER 1 + +#include + +#include + +#include +#include + +extern struct grub_relocator *grub_multiboot2_relocator; + +void grub_multiboot2 (int argc, char *argv[]); +void grub_module2 (int argc, char *argv[]); + +void grub_multiboot2_set_accepts_video (int val); +grub_err_t grub_multiboot2_make_mbi (grub_uint32_t *target); +void grub_multiboot2_free_mbi (void); +grub_err_t grub_multiboot2_init_mbi (int argc, char *argv[]); +grub_err_t grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, + int argc, char *argv[]); +void grub_multiboot2_set_bootdev (void); +void +grub_multiboot2_add_elfsyms (grub_size_t num, grub_size_t entsize, + unsigned shndx, void *data); + +grub_uint32_t grub_multiboot2_get_mmap_count (void); +grub_err_t grub_multiboot2_set_video_mode (void); + +/* FIXME: support coreboot as well. */ +#if defined (GRUB_MACHINE_PCBIOS) +#define GRUB_MACHINE_HAS_VBE 1 +#else +#define GRUB_MACHINE_HAS_VBE 0 +#endif + +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) +#define GRUB_MACHINE_HAS_VGA_TEXT 1 +#else +#define GRUB_MACHINE_HAS_VGA_TEXT 0 +#endif + +#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) +#define GRUB_MACHINE_HAS_ACPI 1 +#else +#define GRUB_MACHINE_HAS_ACPI 0 +#endif + +#define GRUB_MULTIBOOT2_CONSOLE_EGA_TEXT 1 +#define GRUB_MULTIBOOT2_CONSOLE_FRAMEBUFFER 2 + +grub_err_t +grub_multiboot2_set_console (int console_type, int accepted_consoles, + int width, int height, int depth, + int console_required); +grub_err_t +grub_multiboot2_load (grub_file_t file, const char *filename); + +struct mbi_load_data +{ + grub_file_t file; + const char *filename; + void *buffer; + unsigned int mbi_ver; + int relocatable; + grub_uint32_t min_addr; + grub_uint32_t max_addr; + grub_size_t align; + grub_uint32_t preference; + grub_uint32_t link_base_addr; + grub_uint32_t load_base_addr; + int avoid_efi_boot_services; +}; +typedef struct mbi_load_data mbi_load_data_t; + +/* Load ELF32 or ELF64. */ +grub_err_t +grub_multiboot2_load_elf (mbi_load_data_t *mld); + +extern grub_size_t grub_multiboot2_pure_size; +extern grub_size_t grub_multiboot2_alloc_mbi; +extern grub_uint32_t grub_multiboot2_payload_eip; + + +#endif /* ! GRUB_MULTIBOOT_HEADER */ diff --git a/include/grub/net.h b/include/grub/net.h index 2192fa186..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); @@ -291,6 +294,12 @@ struct grub_net_network_level_interface grub_net_interface_flags_t flags; struct grub_net_bootp_packet *dhcp_ack; grub_size_t dhcp_acklen; + grub_uint16_t vlantag; + grub_uint32_t xid; /* DHCPv4 transaction id */ + grub_uint32_t srv_id; /* DHCPv4 server_identifier */ + grub_uint32_t my_ip; /* DHCPv4 offered IP address */ + unsigned dhcp_tmo_left; /* DHCPv4 running retransmission timeout */ + unsigned dhcp_tmo; /* DHCPv4 current retransmission timeout */ void *data; }; @@ -448,15 +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_END = 0xff + GRUB_NET_BOOTP_PAD = 0, + GRUB_NET_BOOTP_NETMASK = 1, + GRUB_NET_BOOTP_ROUTER = 3, + GRUB_NET_BOOTP_DNS = 6, + GRUB_NET_BOOTP_HOSTNAME = 12, + GRUB_NET_BOOTP_DOMAIN = 15, + GRUB_NET_BOOTP_ROOT_PATH = 17, + GRUB_NET_BOOTP_EXTENSIONS_PATH = 18, + GRUB_NET_DHCP_REQUESTED_IP_ADDRESS = 50, + GRUB_NET_DHCP_OVERLOAD = 52, + GRUB_NET_DHCP_MESSAGE_TYPE = 53, + GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, + GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, + GRUB_NET_BOOTP_CLIENT_ID = 61, + GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, + GRUB_NET_DHCP_BOOTFILE_NAME = 67, + GRUB_NET_BOOTP_CLIENT_UUID = 97, + GRUB_NET_BOOTP_END = 255 }; struct grub_net_network_level_interface * @@ -473,7 +491,7 @@ grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, void grub_net_process_dhcp (struct grub_net_buff *nb, - struct grub_net_card *card); + struct grub_net_network_level_interface *iface); int grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, @@ -497,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); @@ -516,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); @@ -554,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; @@ -561,4 +578,6 @@ extern char *grub_net_default_server; #define GRUB_NET_INTERVAL 400 #define GRUB_NET_INTERVAL_ADDITION 20 +#define VLANTAG_IDENTIFIER 0x8100 + #endif /* ! GRUB_NET_HEADER */ diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h index bb1703622..8eb211ba8 100644 --- a/include/grub/net/arp.h +++ b/include/grub/net/arp.h @@ -22,10 +22,11 @@ #include extern grub_err_t grub_net_arp_receive (struct grub_net_buff *nb, - struct grub_net_card *card); + struct grub_net_card *card, + grub_uint16_t *vlantag); grub_err_t grub_net_arp_send_request (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr); + 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 dcceaa568..e21a5eebc 100644 --- a/include/grub/net/ip.h +++ b/include/grub/net/ip.h @@ -48,7 +48,8 @@ grub_err_t grub_net_recv_ip_packets (struct grub_net_buff *nb, struct grub_net_card *card, const grub_net_link_level_address_t *hwaddress, - const grub_net_link_level_address_t *src_hwaddress); + const grub_net_link_level_address_t *src_hwaddress, + grub_uint16_t *vlantag); grub_err_t grub_net_send_ip_packet (struct grub_net_network_level_interface *inf, @@ -57,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, @@ -94,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 c88c86d4d..442dc31de 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -36,9 +36,10 @@ #define GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE (0x9000-0x8200) /* The segment where the kernel is loaded. */ -#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 +#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 -#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000 +#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000 +#define GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR 0x100000 /* The upper memory area (starting at 640 kiB). */ #define GRUB_MEMORY_I386_PC_UPPER 0xa0000 @@ -50,7 +51,7 @@ /* The offset of GRUB_CORE_ENTRY_ADDR. */ #define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 -#define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 +#define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x9000 /* The offset of GRUB_TOTAL_MODULE_SIZE. */ #define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 @@ -91,7 +92,7 @@ #define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 -#define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 +#define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x9000 #define GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR 0x100000 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 @@ -101,27 +102,35 @@ #define GRUB_KERNEL_I386_MULTIBOOT_MOD_ALIGN GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN #define GRUB_KERNEL_X86_64_XEN_MOD_ALIGN 0x8 -#define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8 +#define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8 +#define GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN 0x8 /* Non-zero value is only needed for PowerMacs. */ -#define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0 -#define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0 -#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 -#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 -#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0 -#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0 +#define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_XEN_PVH_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 +#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0 +#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0 #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 #define GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN 3 #define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN (1 << GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN) -#define GRUB_KERNEL_MIPS_LOONGSON_MOD_ALIGN 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 +#define GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN 0x8 +#define GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE 0x4 + +#define GRUB_KERNEL_ARM_STACK_SIZE 0x40000 +#define GRUB_KERNEL_ARM_COREBOOT_MOD_GAP (GRUB_KERNEL_ARM_STACK_SIZE + 1024) + /* Minimal gap between _end and the start of the modules. It's a hack for PowerMac to prevent "CLAIM failed" error. The real fix is to rewrite grub-mkimage to generate valid ELF files. */ 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 70d9a0513..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 @@ -142,27 +147,7 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook, void *hook_data); -struct grub_pci_dma_chunk; - -struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, - grub_size_t size); -void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); -volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); -grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); - -static inline void * -grub_dma_phys2virt (grub_uint32_t phys, struct grub_pci_dma_chunk *chunk) -{ - return ((grub_uint8_t *) grub_dma_get_virt (chunk) - + (phys - grub_dma_get_phys (chunk))); -} - -static inline grub_uint32_t -grub_dma_virt2phys (volatile void *virt, struct grub_pci_dma_chunk *chunk) -{ - return (((grub_uint8_t *) virt - (grub_uint8_t *) grub_dma_get_virt (chunk)) - + grub_dma_get_phys (chunk)); -} +#include grub_uint8_t EXPORT_FUNC (grub_pci_find_capability) (grub_pci_device_t dev, grub_uint8_t cap); 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/ps2.h b/include/grub/ps2.h new file mode 100644 index 000000000..4f2e527e4 --- /dev/null +++ b/include/grub/ps2.h @@ -0,0 +1,43 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_PS2_HEADER +#define GRUB_PS2_HEADER 1 + +#include + +#define GRUB_AT_ACK 0xfa +#define GRUB_AT_NACK 0xfe +#define GRUB_AT_TRIES 5 + +/* Make sure it's zeroed-out and set current_set at init. */ +struct grub_ps2_state +{ + int e0_received; + int f0_received; + grub_uint8_t led_status; + short at_keyboard_status; + grub_uint8_t current_set; +}; + +/* If there is a key pending, return it; otherwise return GRUB_TERM_NO_KEY. */ +int +grub_ps2_process_incoming_byte (struct grub_ps2_state *ps2_state, + grub_uint8_t data); + +#endif diff --git a/include/grub/pubkey.h b/include/grub/pubkey.h index 4a9d04b43..fb8be9cbb 100644 --- a/include/grub/pubkey.h +++ b/include/grub/pubkey.h @@ -25,7 +25,7 @@ struct grub_public_key * grub_load_public_key (grub_file_t f); grub_err_t -grub_verify_signature (grub_file_t f, grub_file_t sig, +grub_verify_signature (grub_file_t f, const char *fsig, struct grub_public_key *pk); 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/efi/memory.h b/include/grub/riscv32/efi/memory.h new file mode 100644 index 000000000..e61c474ff --- /dev/null +++ b/include/grub/riscv32/efi/memory.h @@ -0,0 +1,6 @@ +#ifndef GRUB_MEMORY_CPU_HEADER +#include + +#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffUL + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/riscv32/setjmp.h b/include/grub/riscv32/setjmp.h new file mode 100644 index 000000000..5a2123846 --- /dev/null +++ b/include/grub/riscv32/setjmp.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef unsigned long long grub_jmp_buf[14]; + +int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/riscv32/time.h b/include/grub/riscv32/time.h new file mode 100644 index 000000000..20abd648b --- /dev/null +++ b/include/grub/riscv32/time.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* TODO */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/riscv32/types.h b/include/grub/riscv32/types.h new file mode 100644 index 000000000..fac57a752 --- /dev/null +++ b/include/grub/riscv32/types.h @@ -0,0 +1,34 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 4 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 4 + +/* currently only support little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + +/* Unaligned accesses can be very slow, so avoid them */ +#undef GRUB_HAVE_UNALIGNED_ACCESS + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h new file mode 100644 index 000000000..c6cb32417 --- /dev/null +++ b/include/grub/riscv64/efi/memory.h @@ -0,0 +1,6 @@ +#ifndef GRUB_MEMORY_CPU_HEADER +#include + +#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/riscv64/setjmp.h b/include/grub/riscv64/setjmp.h new file mode 100644 index 000000000..5a2123846 --- /dev/null +++ b/include/grub/riscv64/setjmp.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef unsigned long long grub_jmp_buf[14]; + +int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/include/grub/riscv64/time.h b/include/grub/riscv64/time.h new file mode 100644 index 000000000..20abd648b --- /dev/null +++ b/include/grub/riscv64/time.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +static __inline void +grub_cpu_idle (void) +{ + /* TODO */ +} + +#endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/riscv64/types.h b/include/grub/riscv64/types.h new file mode 100644 index 000000000..c6bcad470 --- /dev/null +++ b/include/grub/riscv64/types.h @@ -0,0 +1,34 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +/* currently only support little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + +/* Unaligned accesses can be very slow, so avoid them */ +#undef GRUB_HAVE_UNALIGNED_ACCESS + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/include/grub/safemath.h b/include/grub/safemath.h 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/boot.h b/include/grub/sparc64/ieee1275/boot.h index 02d53f28e..cc5a941e3 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -46,8 +46,7 @@ #define GRUB_BOOT_MACHINE_KERNEL_BYTE 0x80 -#define GRUB_BOOT_MACHINE_CODE_END \ - (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) +#define GRUB_BOOT_MACHINE_CODE_END 0x1fc #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h index 32c77f80f..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 */ @@ -42,6 +45,8 @@ extern int EXPORT_FUNC(grub_ieee1275_claim_vaddr) (grub_addr_t vaddr, extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr, grub_size_t size, grub_uint32_t align); +extern grub_uint64_t EXPORT_FUNC(grub_ieee1275_num_blocks) (grub_uint32_t ihandle); +extern grub_uint64_t EXPORT_FUNC(grub_ieee1275_num_blocks64) (grub_uint32_t ihandle); extern grub_addr_t EXPORT_VAR (grub_ieee1275_original_stack); 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 5ffb38f69..7f1a14c84 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -55,7 +55,8 @@ #define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 0x52) #define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 0x4c) -#define GRUB_TERM_ESC '\e' +/* Hex value is used for ESC, since '\e' is nonstandard */ +#define GRUB_TERM_ESC 0x1b #define GRUB_TERM_TAB '\t' #define GRUB_TERM_BACKSPACE '\b' @@ -74,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. */ @@ -326,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); @@ -361,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) @@ -373,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 new file mode 100644 index 000000000..d09783dac --- /dev/null +++ b/include/grub/tpm.h @@ -0,0 +1,49 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2018 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TPM_HEADER +#define GRUB_TPM_HEADER 1 + +#include + +#define GRUB_STRING_PCR 8 +#define GRUB_BINARY_PCR 9 + +#define SHA1_DIGEST_SIZE 20 + +#define TPM_BASE 0x0 +#define TPM_SUCCESS TPM_BASE +#define TPM_AUTHFAIL (TPM_BASE + 0x1) +#define TPM_BADINDEX (TPM_BASE + 0x2) + +#define TPM_TAG_RQU_COMMAND 0x00C1 +#define TPM_ORD_Extend 0x14 + +#define EV_IPL 0x0d + +grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, + grub_uint8_t pcr, const char *description); +int grub_tpm_present (void); + +static inline bool +grub_is_tpm_fail_fatal (void) +{ + return grub_env_get_bool ("tpm_fail_fatal", false); +} + +#endif diff --git a/include/grub/types.h b/include/grub/types.h index b93e48201..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" @@ -130,33 +149,46 @@ typedef grub_int32_t grub_ssize_t; # define PRIdGRUB_SSIZE "d" #endif +#define GRUB_SCHAR_MAX 127 +#define GRUB_SCHAR_MIN (-GRUB_SCHAR_MAX - 1) #define GRUB_UCHAR_MAX 0xFF #define GRUB_USHRT_MAX 65535 #define GRUB_SHRT_MAX 0x7fff +#define GRUB_SHRT_MIN (-GRUB_SHRT_MAX - 1) #define GRUB_UINT_MAX 4294967295U #define GRUB_INT_MAX 0x7fffffff -#define GRUB_INT32_MIN (-2147483647 - 1) +#define GRUB_INT_MIN (-GRUB_INT_MAX - 1) #define GRUB_INT32_MAX 2147483647 +#define GRUB_INT32_MIN (-GRUB_INT32_MAX - 1) #if GRUB_CPU_SIZEOF_LONG == 8 # define GRUB_ULONG_MAX 18446744073709551615UL # define GRUB_LONG_MAX 9223372036854775807L -# define GRUB_LONG_MIN (-9223372036854775807L - 1) #else # define GRUB_ULONG_MAX 4294967295UL # define GRUB_LONG_MAX 2147483647L -# define GRUB_LONG_MIN (-2147483647L - 1) #endif +# define GRUB_LONG_MIN (-GRUB_LONG_MAX - 1) + +/* + * Cast to unsigned long long so that the "return value" is always a consistent + * type and to ensure an unsigned value regardless of type parameter. + */ +#define GRUB_TYPE_U_MAX(type) ((unsigned long long)((typeof (type))(~0))) +#define GRUB_TYPE_U_MIN(type) 0ULL typedef grub_uint64_t grub_properly_aligned_t; #define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t name[((size) + sizeof (grub_properly_aligned_t) - 1) / sizeof (grub_properly_aligned_t)] /* 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) @@ -164,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); \ @@ -314,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/uboot/uboot.h b/include/grub/uboot/uboot.h index c122de6ab..194130345 100644 --- a/include/grub/uboot/uboot.h +++ b/include/grub/uboot/uboot.h @@ -72,7 +72,8 @@ int EXPORT_FUNC (grub_uboot_dev_enum) (void); struct device_info * EXPORT_FUNC (grub_uboot_dev_get) (int index); int EXPORT_FUNC (grub_uboot_dev_open) (struct device_info *dev); int EXPORT_FUNC (grub_uboot_dev_close) (struct device_info *dev); -int grub_uboot_dev_write (struct device_info *dev, void *buf, int *len); +int grub_uboot_dev_write (struct device_info *dev, const void *buf, + grub_size_t blocks, grub_uint32_t start); int grub_uboot_dev_read (struct device_info *dev, void *buf, grub_size_t blocks, grub_uint32_t start, grub_size_t * real_blocks); int EXPORT_FUNC (grub_uboot_dev_recv) (struct device_info *dev, void *buf, 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 11d96481f..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; @@ -321,5 +325,9 @@ grub_usb_err_t grub_usb_check_transfer (grub_usb_transfer_t trans, grub_size_t *actual); void grub_usb_cancel_transfer (grub_usb_transfer_t trans); +void +grub_ehci_init_device (volatile void *regs); +void +grub_ehci_pci_scan (void); #endif /* GRUB_USB_H */ diff --git a/include/grub/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 5ca4811cd..5c0a52ca2 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -29,6 +29,8 @@ #define GRUB_INSTALL_OPTIONS \ { "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \ 0, N_("pre-load specified modules MODULES"), 1 }, \ + { "dtb", GRUB_INSTALL_OPTIONS_DTB, N_("FILE"), \ + 0, N_("embed a specific DTB"), 1 }, \ { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \ N_("MODULES"), 0, \ N_("install only MODULES and their dependencies [default=all]"), 1 }, \ @@ -61,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 } @@ -98,7 +106,12 @@ enum grub_install_plat GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, GRUB_INSTALL_PLATFORM_I386_XEN, GRUB_INSTALL_PLATFORM_X86_64_XEN, + GRUB_INSTALL_PLATFORM_I386_XEN_PVH, GRUB_INSTALL_PLATFORM_ARM64_EFI, + GRUB_INSTALL_PLATFORM_ARM_COREBOOT, + GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, + GRUB_INSTALL_PLATFORM_RISCV32_EFI, + GRUB_INSTALL_PLATFORM_RISCV64_EFI, GRUB_INSTALL_PLATFORM_MAX }; @@ -115,7 +128,11 @@ enum grub_install_options { GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, - GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS + GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, + GRUB_INSTALL_OPTIONS_DTB, + GRUB_INSTALL_OPTIONS_SBAT, + GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, + GRUB_INSTALL_OPTIONS_DISABLE_CLI }; extern char *grub_install_source_directory; @@ -176,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); + 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); @@ -186,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); @@ -203,10 +222,13 @@ grub_util_get_target_dirname (const struct grub_install_image_target_desc *t); void grub_install_create_envblk_file (const char *name); +const char * +grub_install_get_default_arm_platform (void); + const char * grub_install_get_default_x86_platform (void); -void +int grub_install_register_efi (grub_device_t efidir_grub_dev, const char *efifile_path, const char *efi_distributor); @@ -219,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 @@ -255,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 1a18708a8..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,14 +51,14 @@ 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, - Elf32_Addr target_addr, grub_size_t align, - size_t kernel_size, size_t bss_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, - Elf64_Addr target_addr, grub_size_t align, - size_t kernel_size, size_t bss_size); + int note, char *sbat, char **core_img, size_t *core_size, + Elf64_Addr target_addr, + struct grub_mkimage_layout *layout); struct grub_install_image_target_desc { @@ -71,7 +72,8 @@ struct grub_install_image_target_desc IMAGE_I386_IEEE1275, IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, - IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO + IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO, + IMAGE_XEN_PVH } id; enum { diff --git a/include/grub/verify.h b/include/grub/verify.h new file mode 100644 index 000000000..672ae1692 --- /dev/null +++ b/include/grub/verify.h @@ -0,0 +1,88 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_VERIFY_HEADER +#define GRUB_VERIFY_HEADER 1 + +#include +#include + +enum grub_verify_flags + { + GRUB_VERIFY_FLAGS_NONE = 0, + GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1, + GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2, + /* Defer verification to another authority. */ + GRUB_VERIFY_FLAGS_DEFER_AUTH = 4 + }; + +enum grub_verify_string_type + { + GRUB_VERIFY_KERNEL_CMDLINE, + GRUB_VERIFY_MODULE_CMDLINE, + GRUB_VERIFY_COMMAND, + }; + +struct grub_file_verifier +{ + struct grub_file_verifier *next; + struct grub_file_verifier **prev; + + const char *name; + + /* + * Check if file needs to be verified and set up context. + * init/read/fini is structured in the same way as hash interface. + */ + grub_err_t (*init) (grub_file_t io, enum grub_file_type type, + void **context, enum grub_verify_flags *flags); + + /* + * Right now we pass the whole file in one call but it may + * change in the future. If you insist on single buffer you + * need to set GRUB_VERIFY_FLAGS_SINGLE_CHUNK in verify_flags. + */ + grub_err_t (*write) (void *context, void *buf, grub_size_t size); + + grub_err_t (*fini) (void *context); + void (*close) (void *context); + + grub_err_t (*verify_string) (char *str, enum grub_verify_string_type type); +}; + +extern struct grub_file_verifier *EXPORT_VAR (grub_file_verifiers); + +extern void +grub_verifiers_init (void); + +static inline void +grub_verifier_register (struct grub_file_verifier *ver) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_file_verifiers), GRUB_AS_LIST (ver)); +} + +static inline void +grub_verifier_unregister (struct grub_file_verifier *ver) +{ + grub_list_remove (GRUB_AS_LIST (ver)); +} + +extern grub_err_t +EXPORT_FUNC (grub_verify_string) (char *str, enum grub_verify_string_type type); + +#endif /* ! GRUB_VERIFY_HEADER */ diff --git a/include/grub/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/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/x86_64/time.h b/include/grub/x86_64/time.h index 842882cf2..4da5ae93c 100644 --- a/include/grub/x86_64/time.h +++ b/include/grub/x86_64/time.h @@ -23,7 +23,7 @@ static __inline void grub_cpu_idle (void) { /* FIXME: this can't work until we handle interrupts. */ -/* __asm__ __volatile__ ("hlt"); */ +/* asm volatile ("hlt"); */ } #endif /* ! KERNEL_CPU_TIME_HEADER */ diff --git a/include/grub/xen.h b/include/grub/xen.h index c31cc10c7..91cb7cf81 100644 --- a/include/grub/xen.h +++ b/include/grub/xen.h @@ -95,6 +95,11 @@ typedef grub_uint64_t grub_xen_mfn_t; typedef grub_uint32_t grub_xen_mfn_t; #endif typedef unsigned int grub_xen_evtchn_t; + +#ifdef GRUB_MACHINE_XEN_PVH +extern struct hvm_start_info *pvh_start_info; +void grub_xen_setup_pvh (void); +#endif #endif #endif diff --git a/include/grub/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 5a3db5a7c..a039aa043 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -75,8 +75,8 @@ #define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 #define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 -#define MULTIBOOT_ARCHITECTURE_I386 0 -#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT2_ARCHITECTURE_I386 0 +#define MULTIBOOT2_ARCHITECTURE_MIPS32 4 #define MULTIBOOT_HEADER_TAG_OPTIONAL 1 #define MULTIBOOT_LOAD_PREFERENCE_NONE 0 @@ -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 f35804b88..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 @@ -260,6 +260,13 @@ typedef struct arch_shared_info arch_shared_info_t; #define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" #endif +/* + * Debug console IO port, also called "port E9 hack". Each character written + * to this IO port will be printed on the hypervisor console, subject to log + * level restrictions. + */ +#define XEN_HVM_DEBUGCONS_IOPORT 0xe9 + #endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */ /* diff --git a/include/xen/hvm/hvm_op.h b/include/xen/hvm/hvm_op.h new file mode 100644 index 000000000..0bdafdf59 --- /dev/null +++ b/include/xen/hvm/hvm_op.h @@ -0,0 +1,296 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2007, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__ +#define __XEN_PUBLIC_HVM_HVM_OP_H__ + +#include "../xen.h" +#include "../trace.h" +#include "../event_channel.h" + +/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */ +#define HVMOP_set_param 0 +#define HVMOP_get_param 1 +struct xen_hvm_param { + domid_t domid; /* IN */ + uint32_t index; /* IN */ + uint64_t value; /* IN/OUT */ +}; +typedef struct xen_hvm_param xen_hvm_param_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t); + +#if __XEN_INTERFACE_VERSION__ < 0x00040900 + +/* Set the logical level of one of a domain's PCI INTx wires. */ +#define HVMOP_set_pci_intx_level 2 +struct xen_hvm_set_pci_intx_level { + /* Domain to be updated. */ + domid_t domid; + /* PCI INTx identification in PCI topology (domain:bus:device:intx). */ + uint8_t domain, bus, device, intx; + /* Assertion level (0 = unasserted, 1 = asserted). */ + uint8_t level; +}; +typedef struct xen_hvm_set_pci_intx_level xen_hvm_set_pci_intx_level_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_intx_level_t); + +/* Set the logical level of one of a domain's ISA IRQ wires. */ +#define HVMOP_set_isa_irq_level 3 +struct xen_hvm_set_isa_irq_level { + /* Domain to be updated. */ + domid_t domid; + /* ISA device identification, by ISA IRQ (0-15). */ + uint8_t isa_irq; + /* Assertion level (0 = unasserted, 1 = asserted). */ + uint8_t level; +}; +typedef struct xen_hvm_set_isa_irq_level xen_hvm_set_isa_irq_level_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_isa_irq_level_t); + +#define HVMOP_set_pci_link_route 4 +struct xen_hvm_set_pci_link_route { + /* Domain to be updated. */ + domid_t domid; + /* PCI link identifier (0-3). */ + uint8_t link; + /* ISA IRQ (1-15), or 0 (disable link). */ + uint8_t isa_irq; +}; +typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t); + +#endif /* __XEN_INTERFACE_VERSION__ < 0x00040900 */ + +/* Flushes all VCPU TLBs: @arg must be NULL. */ +#define HVMOP_flush_tlbs 5 + +typedef enum { + HVMMEM_ram_rw, /* Normal read/write guest RAM */ + HVMMEM_ram_ro, /* Read-only; writes are discarded */ + HVMMEM_mmio_dm, /* Reads and write go to the device model */ +#if __XEN_INTERFACE_VERSION__ < 0x00040700 + HVMMEM_mmio_write_dm, /* Read-only; writes go to the device model */ +#else + HVMMEM_unused, /* Placeholder; setting memory to this type + will fail for code after 4.7.0 */ +#endif + HVMMEM_ioreq_server /* Memory type claimed by an ioreq server; type + changes to this value are only allowed after + an ioreq server has claimed its ownership. + Only pages with HVMMEM_ram_rw are allowed to + change to this type; conversely, pages with + this type are only allowed to be changed back + to HVMMEM_ram_rw. */ +} hvmmem_type_t; + +/* Hint from PV drivers for pagetable destruction. */ +#define HVMOP_pagetable_dying 9 +struct xen_hvm_pagetable_dying { + /* Domain with a pagetable about to be destroyed. */ + domid_t domid; + uint16_t pad[3]; /* align next field on 8-byte boundary */ + /* guest physical address of the toplevel pagetable dying */ + uint64_t gpa; +}; +typedef struct xen_hvm_pagetable_dying xen_hvm_pagetable_dying_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_pagetable_dying_t); + +/* Get the current Xen time, in nanoseconds since system boot. */ +#define HVMOP_get_time 10 +struct xen_hvm_get_time { + uint64_t now; /* OUT */ +}; +typedef struct xen_hvm_get_time xen_hvm_get_time_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_time_t); + +#define HVMOP_xentrace 11 +struct xen_hvm_xentrace { + uint16_t event, extra_bytes; + uint8_t extra[TRACE_EXTRA_MAX * sizeof(uint32_t)]; +}; +typedef struct xen_hvm_xentrace xen_hvm_xentrace_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t); + +/* Following tools-only interfaces may change in future. */ +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +/* Deprecated by XENMEM_access_op_set_access */ +#define HVMOP_set_mem_access 12 + +/* Deprecated by XENMEM_access_op_get_access */ +#define HVMOP_get_mem_access 13 + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +#define HVMOP_get_mem_type 15 +/* Return hvmmem_type_t for the specified pfn. */ +struct xen_hvm_get_mem_type { + /* Domain to be queried. */ + domid_t domid; + /* OUT variable. */ + uint16_t mem_type; + uint16_t pad[2]; /* align next field on 8-byte boundary */ + /* IN variable. */ + uint64_t pfn; +}; +typedef struct xen_hvm_get_mem_type xen_hvm_get_mem_type_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t); + +/* Following tools-only interfaces may change in future. */ +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +/* + * Definitions relating to DMOP_create_ioreq_server. (Defined here for + * backwards compatibility). + */ + +#define HVM_IOREQSRV_BUFIOREQ_OFF 0 +#define HVM_IOREQSRV_BUFIOREQ_LEGACY 1 +/* + * Use this when read_pointer gets updated atomically and + * the pointer pair gets read atomically: + */ +#define HVM_IOREQSRV_BUFIOREQ_ATOMIC 2 + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +#if defined(__i386__) || defined(__x86_64__) + +/* + * HVMOP_set_evtchn_upcall_vector: Set a that should be used for event + * channel upcalls on the specified . If set, + * this vector will be used in preference to the + * domain global callback via (see + * HVM_PARAM_CALLBACK_IRQ). + */ +#define HVMOP_set_evtchn_upcall_vector 23 +struct xen_hvm_evtchn_upcall_vector { + uint32_t vcpu; + uint8_t vector; +}; +typedef struct xen_hvm_evtchn_upcall_vector xen_hvm_evtchn_upcall_vector_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t); + +#endif /* defined(__i386__) || defined(__x86_64__) */ + +#define HVMOP_guest_request_vm_event 24 + +/* HVMOP_altp2m: perform altp2m state operations */ +#define HVMOP_altp2m 25 + +#define HVMOP_ALTP2M_INTERFACE_VERSION 0x00000001 + +struct xen_hvm_altp2m_domain_state { + /* IN or OUT variable on/off */ + uint8_t state; +}; +typedef struct xen_hvm_altp2m_domain_state xen_hvm_altp2m_domain_state_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_domain_state_t); + +struct xen_hvm_altp2m_vcpu_enable_notify { + uint32_t vcpu_id; + uint32_t pad; + /* #VE info area gfn */ + uint64_t gfn; +}; +typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enable_notify_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); + +struct xen_hvm_altp2m_view { + /* IN/OUT variable */ + uint16_t view; + /* Create view only: default access type + * NOTE: currently ignored */ + uint16_t hvmmem_default_access; /* xenmem_access_t */ +}; +typedef struct xen_hvm_altp2m_view xen_hvm_altp2m_view_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_view_t); + +struct xen_hvm_altp2m_set_mem_access { + /* view */ + uint16_t view; + /* Memory type */ + uint16_t hvmmem_access; /* xenmem_access_t */ + uint32_t pad; + /* gfn */ + uint64_t gfn; +}; +typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t); + +struct xen_hvm_altp2m_change_gfn { + /* view */ + uint16_t view; + uint16_t pad1; + uint32_t pad2; + /* old gfn */ + uint64_t old_gfn; + /* new gfn, INVALID_GFN (~0UL) means revert */ + uint64_t new_gfn; +}; +typedef struct xen_hvm_altp2m_change_gfn xen_hvm_altp2m_change_gfn_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_change_gfn_t); + +struct xen_hvm_altp2m_op { + uint32_t version; /* HVMOP_ALTP2M_INTERFACE_VERSION */ + uint32_t cmd; +/* Get/set the altp2m state for a domain */ +#define HVMOP_altp2m_get_domain_state 1 +#define HVMOP_altp2m_set_domain_state 2 +/* Set the current VCPU to receive altp2m event notifications */ +#define HVMOP_altp2m_vcpu_enable_notify 3 +/* Create a new view */ +#define HVMOP_altp2m_create_p2m 4 +/* Destroy a view */ +#define HVMOP_altp2m_destroy_p2m 5 +/* Switch view for an entire domain */ +#define HVMOP_altp2m_switch_p2m 6 +/* Notify that a page of memory is to have specific access types */ +#define HVMOP_altp2m_set_mem_access 7 +/* Change a p2m entry to have a different gfn->mfn mapping */ +#define HVMOP_altp2m_change_gfn 8 + domid_t domain; + uint16_t pad1; + uint32_t pad2; + union { + struct xen_hvm_altp2m_domain_state domain_state; + struct xen_hvm_altp2m_vcpu_enable_notify enable_notify; + struct xen_hvm_altp2m_view view; + struct xen_hvm_altp2m_set_mem_access set_mem_access; + struct xen_hvm_altp2m_change_gfn change_gfn; + uint8_t pad[64]; + } u; +}; +typedef struct xen_hvm_altp2m_op xen_hvm_altp2m_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_op_t); + +#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/hvm/params.h b/include/xen/hvm/params.h new file mode 100644 index 000000000..2ec2e7c80 --- /dev/null +++ b/include/xen/hvm/params.h @@ -0,0 +1,284 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2007, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_HVM_PARAMS_H__ +#define __XEN_PUBLIC_HVM_PARAMS_H__ + +#include "hvm_op.h" + +/* + * Parameter space for HVMOP_{set,get}_param. + */ + +#define HVM_PARAM_CALLBACK_IRQ 0 +#define HVM_PARAM_CALLBACK_IRQ_TYPE_MASK xen_mk_ullong(0xFF00000000000000) +/* + * How should CPU0 event-channel notifications be delivered? + * + * If val == 0 then CPU0 event-channel notifications are not delivered. + * If val != 0, val[63:56] encodes the type, as follows: + */ + +#define HVM_PARAM_CALLBACK_TYPE_GSI 0 +/* + * val[55:0] is a delivery GSI. GSI 0 cannot be used, as it aliases val == 0, + * and disables all notifications. + */ + +#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1 +/* + * val[55:0] is a delivery PCI INTx line: + * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0] + */ + +#if defined(__i386__) || defined(__x86_64__) +#define HVM_PARAM_CALLBACK_TYPE_VECTOR 2 +/* + * val[7:0] is a vector number. Check for XENFEAT_hvm_callback_vector to know + * if this delivery method is available. + */ +#elif defined(__arm__) || defined(__aarch64__) +#define HVM_PARAM_CALLBACK_TYPE_PPI 2 +/* + * val[55:16] needs to be zero. + * val[15:8] is interrupt flag of the PPI used by event-channel: + * bit 8: the PPI is edge(1) or level(0) triggered + * bit 9: the PPI is active low(1) or high(0) + * val[7:0] is a PPI number used by event-channel. + * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to + * the notification is handled by the interrupt controller. + */ +#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_MASK 0xFF00 +#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_LOW_LEVEL 2 +#endif + +/* + * These are not used by Xen. They are here for convenience of HVM-guest + * xenbus implementations. + */ +#define HVM_PARAM_STORE_PFN 1 +#define HVM_PARAM_STORE_EVTCHN 2 + +#define HVM_PARAM_PAE_ENABLED 4 + +#define HVM_PARAM_IOREQ_PFN 5 + +#define HVM_PARAM_BUFIOREQ_PFN 6 +#define HVM_PARAM_BUFIOREQ_EVTCHN 26 + +#if defined(__i386__) || defined(__x86_64__) + +/* + * Viridian enlightenments + * + * (See http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.0.docx) + * + * To expose viridian enlightenments to the guest set this parameter + * to the desired feature mask. The base feature set must be present + * in any valid feature mask. + */ +#define HVM_PARAM_VIRIDIAN 9 + +/* Base+Freq viridian feature sets: + * + * - Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) + * - APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR) + * - Virtual Processor index MSR (HV_X64_MSR_VP_INDEX) + * - Timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and + * HV_X64_MSR_APIC_FREQUENCY) + */ +#define _HVMPV_base_freq 0 +#define HVMPV_base_freq (1 << _HVMPV_base_freq) + +/* Feature set modifications */ + +/* Disable timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and + * HV_X64_MSR_APIC_FREQUENCY). + * This modification restores the viridian feature set to the + * original 'base' set exposed in releases prior to Xen 4.4. + */ +#define _HVMPV_no_freq 1 +#define HVMPV_no_freq (1 << _HVMPV_no_freq) + +/* Enable Partition Time Reference Counter (HV_X64_MSR_TIME_REF_COUNT) */ +#define _HVMPV_time_ref_count 2 +#define HVMPV_time_ref_count (1 << _HVMPV_time_ref_count) + +/* Enable Reference TSC Page (HV_X64_MSR_REFERENCE_TSC) */ +#define _HVMPV_reference_tsc 3 +#define HVMPV_reference_tsc (1 << _HVMPV_reference_tsc) + +/* Use Hypercall for remote TLB flush */ +#define _HVMPV_hcall_remote_tlb_flush 4 +#define HVMPV_hcall_remote_tlb_flush (1 << _HVMPV_hcall_remote_tlb_flush) + +/* Use APIC assist */ +#define _HVMPV_apic_assist 5 +#define HVMPV_apic_assist (1 << _HVMPV_apic_assist) + +/* Enable crash MSRs */ +#define _HVMPV_crash_ctl 6 +#define HVMPV_crash_ctl (1 << _HVMPV_crash_ctl) + +#define HVMPV_feature_mask \ + (HVMPV_base_freq | \ + HVMPV_no_freq | \ + HVMPV_time_ref_count | \ + HVMPV_reference_tsc | \ + HVMPV_hcall_remote_tlb_flush | \ + HVMPV_apic_assist | \ + HVMPV_crash_ctl) + +#endif + +/* + * Set mode for virtual timers (currently x86 only): + * delay_for_missed_ticks (default): + * Do not advance a vcpu's time beyond the correct delivery time for + * interrupts that have been missed due to preemption. Deliver missed + * interrupts when the vcpu is rescheduled and advance the vcpu's virtual + * time stepwise for each one. + * no_delay_for_missed_ticks: + * As above, missed interrupts are delivered, but guest time always tracks + * wallclock (i.e., real) time while doing so. + * no_missed_ticks_pending: + * No missed interrupts are held pending. Instead, to ensure ticks are + * delivered at some non-zero rate, if we detect missed ticks then the + * internal tick alarm is not disabled if the VCPU is preempted during the + * next tick period. + * one_missed_tick_pending: + * Missed interrupts are collapsed together and delivered as one 'late tick'. + * Guest time always tracks wallclock (i.e., real) time. + */ +#define HVM_PARAM_TIMER_MODE 10 +#define HVMPTM_delay_for_missed_ticks 0 +#define HVMPTM_no_delay_for_missed_ticks 1 +#define HVMPTM_no_missed_ticks_pending 2 +#define HVMPTM_one_missed_tick_pending 3 + +/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ +#define HVM_PARAM_HPET_ENABLED 11 + +/* Identity-map page directory used by Intel EPT when CR0.PG=0. */ +#define HVM_PARAM_IDENT_PT 12 + +/* Device Model domain, defaults to 0. */ +#define HVM_PARAM_DM_DOMAIN 13 + +/* ACPI S state: currently support S0 and S3 on x86. */ +#define HVM_PARAM_ACPI_S_STATE 14 + +/* TSS used on Intel when CR0.PE=0. */ +#define HVM_PARAM_VM86_TSS 15 + +/* Boolean: Enable aligning all periodic vpts to reduce interrupts */ +#define HVM_PARAM_VPT_ALIGN 16 + +/* Console debug shared memory ring and event channel */ +#define HVM_PARAM_CONSOLE_PFN 17 +#define HVM_PARAM_CONSOLE_EVTCHN 18 + +/* + * Select location of ACPI PM1a and TMR control blocks. Currently two locations + * are supported, specified by version 0 or 1 in this parameter: + * - 0: default, use the old addresses + * PM1A_EVT == 0x1f40; PM1A_CNT == 0x1f44; PM_TMR == 0x1f48 + * - 1: use the new default qemu addresses + * PM1A_EVT == 0xb000; PM1A_CNT == 0xb004; PM_TMR == 0xb008 + * You can find these address definitions in + */ +#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19 + +/* Deprecated */ +#define HVM_PARAM_MEMORY_EVENT_CR0 20 +#define HVM_PARAM_MEMORY_EVENT_CR3 21 +#define HVM_PARAM_MEMORY_EVENT_CR4 22 +#define HVM_PARAM_MEMORY_EVENT_INT3 23 +#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25 +#define HVM_PARAM_MEMORY_EVENT_MSR 30 + +/* Boolean: Enable nestedhvm (hvm only) */ +#define HVM_PARAM_NESTEDHVM 24 + +/* Params for the mem event rings */ +#define HVM_PARAM_PAGING_RING_PFN 27 +#define HVM_PARAM_MONITOR_RING_PFN 28 +#define HVM_PARAM_SHARING_RING_PFN 29 + +/* SHUTDOWN_* action in case of a triple fault */ +#define HVM_PARAM_TRIPLE_FAULT_REASON 31 + +#define HVM_PARAM_IOREQ_SERVER_PFN 32 +#define HVM_PARAM_NR_IOREQ_SERVER_PAGES 33 + +/* Location of the VM Generation ID in guest physical address space. */ +#define HVM_PARAM_VM_GENERATION_ID_ADDR 34 + +/* + * Set mode for altp2m: + * disabled: don't activate altp2m (default) + * mixed: allow access to all altp2m ops for both in-guest and external tools + * external: allow access to external privileged tools only + * limited: guest only has limited access (ie. control VMFUNC and #VE) + */ +#define HVM_PARAM_ALTP2M 35 +#define XEN_ALTP2M_disabled 0 +#define XEN_ALTP2M_mixed 1 +#define XEN_ALTP2M_external 2 +#define XEN_ALTP2M_limited 3 + +/* + * Size of the x87 FPU FIP/FDP registers that the hypervisor needs to + * save/restore. This is a workaround for a hardware limitation that + * does not allow the full FIP/FDP and FCS/FDS to be restored. + * + * Valid values are: + * + * 8: save/restore 64-bit FIP/FDP and clear FCS/FDS (default if CPU + * has FPCSDS feature). + * + * 4: save/restore 32-bit FIP/FDP, FCS/FDS, and clear upper 32-bits of + * FIP/FDP. + * + * 0: allow hypervisor to choose based on the value of FIP/FDP + * (default if CPU does not have FPCSDS). + * + * If FPCSDS (bit 13 in CPUID leaf 0x7, subleaf 0x0) is set, the CPU + * never saves FCS/FDS and this parameter should be left at the + * default of 8. + */ +#define HVM_PARAM_X87_FIP_WIDTH 36 + +/* + * TSS (and its size) used on Intel when CR0.PE=0. The address occupies + * the low 32 bits, while the size is in the high 32 ones. + */ +#define HVM_PARAM_VM86_TSS_SIZED 37 + +/* Enable MCA capabilities. */ +#define HVM_PARAM_MCA_CAP 38 +#define XEN_HVM_MCA_CAP_LMCE (xen_mk_ullong(1) << 0) +#define XEN_HVM_MCA_CAP_MASK XEN_HVM_MCA_CAP_LMCE + +#define HVM_NR_PARAMS 39 + +#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/include/xen/hvm/start_info.h b/include/xen/hvm/start_info.h new file mode 100644 index 000000000..648415976 --- /dev/null +++ b/include/xen/hvm/start_info.h @@ -0,0 +1,98 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2016, Citrix Systems, Inc. + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ +#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ + +/* + * Start of day structure passed to PVH guests and to HVM guests in %ebx. + * + * NOTE: nothing will be loaded at physical address 0, so a 0 value in any + * of the address fields should be treated as not present. + * + * 0 +----------------+ + * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE + * | | ("xEn3" with the 0x80 bit of the "E" set). + * 4 +----------------+ + * | version | Version of this structure. Current version is 0. New + * | | versions are guaranteed to be backwards-compatible. + * 8 +----------------+ + * | flags | SIF_xxx flags. + * 12 +----------------+ + * | nr_modules | Number of modules passed to the kernel. + * 16 +----------------+ + * | modlist_paddr | Physical address of an array of modules + * | | (layout of the structure below). + * 24 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 32 +----------------+ + * | rsdp_paddr | Physical address of the RSDP ACPI data structure. + * 40 +----------------+ + * + * The layout of each entry in the module structure is the following: + * + * 0 +----------------+ + * | paddr | Physical address of the module. + * 8 +----------------+ + * | size | Size of the module in bytes. + * 16 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 24 +----------------+ + * | reserved | + * 32 +----------------+ + * + * The address and sizes are always a 64bit little endian unsigned integer. + * + * NB: Xen on x86 will always try to place all the data below the 4GiB + * boundary. + */ +#define XEN_HVM_START_MAGIC_VALUE 0x336ec578 + +/* + * C representation of the x86/HVM start info layout. + * + * The canonical definition of this layout is above, this is just a way to + * represent the layout described there using C types. + */ +struct hvm_start_info { + uint32_t magic; /* Contains the magic value 0x336ec578 */ + /* ("xEn3" with the 0x80 bit of the "E" set).*/ + uint32_t version; /* Version of this structure. */ + uint32_t flags; /* SIF_xxx flags. */ + uint32_t nr_modules; /* Number of modules passed to the kernel. */ + uint64_t modlist_paddr; /* Physical address of an array of */ + /* hvm_modlist_entry. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t rsdp_paddr; /* Physical address of the RSDP ACPI data */ + /* structure. */ +}; + +struct hvm_modlist_entry { + uint64_t paddr; /* Physical address of the module. */ + uint64_t size; /* Size of the module in bytes. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t reserved; +}; + +#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */ diff --git a/include/xen/io/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/memory.h b/include/xen/memory.h new file mode 100644 index 000000000..20deef5cb --- /dev/null +++ b/include/xen/memory.h @@ -0,0 +1,665 @@ +/****************************************************************************** + * memory.h + * + * Memory reservation and information. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2005, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_MEMORY_H__ +#define __XEN_PUBLIC_MEMORY_H__ + +#include "xen.h" +#include "physdev.h" + +/* + * Increase or decrease the specified domain's memory reservation. Returns the + * number of extents successfully allocated or freed. + * arg == addr of struct xen_memory_reservation. + */ +#define XENMEM_increase_reservation 0 +#define XENMEM_decrease_reservation 1 +#define XENMEM_populate_physmap 6 + +#if __XEN_INTERFACE_VERSION__ >= 0x00030209 +/* + * Maximum # bits addressable by the user of the allocated region (e.g., I/O + * devices often have a 32-bit limitation even in 64-bit systems). If zero + * then the user has no addressing restriction. This field is not used by + * XENMEM_decrease_reservation. + */ +#define XENMEMF_address_bits(x) (x) +#define XENMEMF_get_address_bits(x) ((x) & 0xffu) +/* NUMA node to allocate from. */ +#define XENMEMF_node(x) (((x) + 1) << 8) +#define XENMEMF_get_node(x) ((((x) >> 8) - 1) & 0xffu) +/* Flag to populate physmap with populate-on-demand entries */ +#define XENMEMF_populate_on_demand (1<<16) +/* Flag to request allocation only from the node specified */ +#define XENMEMF_exact_node_request (1<<17) +#define XENMEMF_exact_node(n) (XENMEMF_node(n) | XENMEMF_exact_node_request) +/* Flag to indicate the node specified is virtual node */ +#define XENMEMF_vnode (1<<18) +#endif + +struct xen_memory_reservation { + + /* + * XENMEM_increase_reservation: + * OUT: MFN (*not* GMFN) bases of extents that were allocated + * XENMEM_decrease_reservation: + * IN: GMFN bases of extents to free + * XENMEM_populate_physmap: + * IN: GPFN bases of extents to populate with memory + * OUT: GMFN bases of extents that were allocated + * (NB. This command also updates the mach_to_phys translation table) + * XENMEM_claim_pages: + * IN: must be zero + */ + XEN_GUEST_HANDLE(xen_pfn_t) extent_start; + + /* Number of extents, and size/alignment of each (2^extent_order pages). */ + xen_ulong_t nr_extents; + unsigned int extent_order; + +#if __XEN_INTERFACE_VERSION__ >= 0x00030209 + /* XENMEMF flags. */ + unsigned int mem_flags; +#else + unsigned int address_bits; +#endif + + /* + * Domain whose reservation is being changed. + * Unprivileged domains can specify only DOMID_SELF. + */ + domid_t domid; +}; +typedef struct xen_memory_reservation xen_memory_reservation_t; +DEFINE_XEN_GUEST_HANDLE(xen_memory_reservation_t); + +/* + * An atomic exchange of memory pages. If return code is zero then + * @out.extent_list provides GMFNs of the newly-allocated memory. + * Returns zero on complete success, otherwise a negative error code. + * On complete success then always @nr_exchanged == @in.nr_extents. + * On partial success @nr_exchanged indicates how much work was done. + * + * Note that only PV guests can use this operation. + */ +#define XENMEM_exchange 11 +struct xen_memory_exchange { + /* + * [IN] Details of memory extents to be exchanged (GMFN bases). + * Note that @in.address_bits is ignored and unused. + */ + struct xen_memory_reservation in; + + /* + * [IN/OUT] Details of new memory extents. + * We require that: + * 1. @in.domid == @out.domid + * 2. @in.nr_extents << @in.extent_order == + * @out.nr_extents << @out.extent_order + * 3. @in.extent_start and @out.extent_start lists must not overlap + * 4. @out.extent_start lists GPFN bases to be populated + * 5. @out.extent_start is overwritten with allocated GMFN bases + */ + struct xen_memory_reservation out; + + /* + * [OUT] Number of input extents that were successfully exchanged: + * 1. The first @nr_exchanged input extents were successfully + * deallocated. + * 2. The corresponding first entries in the output extent list correctly + * indicate the GMFNs that were successfully exchanged. + * 3. All other input and output extents are untouched. + * 4. If not all input exents are exchanged then the return code of this + * command will be non-zero. + * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER! + */ + xen_ulong_t nr_exchanged; +}; +typedef struct xen_memory_exchange xen_memory_exchange_t; +DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t); + +/* + * Returns the maximum machine frame number of mapped RAM in this system. + * This command always succeeds (it never returns an error code). + * arg == NULL. + */ +#define XENMEM_maximum_ram_page 2 + +/* + * Returns the current or maximum memory reservation, in pages, of the + * specified domain (may be DOMID_SELF). Returns -ve errcode on failure. + * arg == addr of domid_t. + */ +#define XENMEM_current_reservation 3 +#define XENMEM_maximum_reservation 4 + +/* + * Returns the maximum GPFN in use by the guest, or -ve errcode on failure. + */ +#define XENMEM_maximum_gpfn 14 + +/* + * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys + * mapping table. Architectures which do not have a m2p table do not implement + * this command. + * arg == addr of xen_machphys_mfn_list_t. + */ +#define XENMEM_machphys_mfn_list 5 +struct xen_machphys_mfn_list { + /* + * Size of the 'extent_start' array. Fewer entries will be filled if the + * machphys table is smaller than max_extents * 2MB. + */ + unsigned int max_extents; + + /* + * Pointer to buffer to fill with list of extent starts. If there are + * any large discontiguities in the machine address space, 2MB gaps in + * the machphys table will be represented by an MFN base of zero. + */ + XEN_GUEST_HANDLE(xen_pfn_t) extent_start; + + /* + * Number of extents written to the above array. This will be smaller + * than 'max_extents' if the machphys table is smaller than max_e * 2MB. + */ + unsigned int nr_extents; +}; +typedef struct xen_machphys_mfn_list xen_machphys_mfn_list_t; +DEFINE_XEN_GUEST_HANDLE(xen_machphys_mfn_list_t); + +/* + * For a compat caller, this is identical to XENMEM_machphys_mfn_list. + * + * For a non compat caller, this functions similarly to + * XENMEM_machphys_mfn_list, but returns the mfns making up the compatibility + * m2p table. + */ +#define XENMEM_machphys_compat_mfn_list 25 + +/* + * Returns the location in virtual address space of the machine_to_phys + * mapping table. Architectures which do not have a m2p table, or which do not + * map it by default into guest address space, do not implement this command. + * arg == addr of xen_machphys_mapping_t. + */ +#define XENMEM_machphys_mapping 12 +struct xen_machphys_mapping { + xen_ulong_t v_start, v_end; /* Start and end virtual addresses. */ + xen_ulong_t max_mfn; /* Maximum MFN that can be looked up. */ +}; +typedef struct xen_machphys_mapping xen_machphys_mapping_t; +DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); + +/* Source mapping space. */ +/* ` enum phys_map_space { */ +#define XENMAPSPACE_shared_info 0 /* shared info page */ +#define XENMAPSPACE_grant_table 1 /* grant table page */ +#define XENMAPSPACE_gmfn 2 /* GMFN */ +#define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */ +#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom, + * XENMEM_add_to_physmap_batch only. */ +#define XENMAPSPACE_dev_mmio 5 /* device mmio region + ARM only; the region is mapped in + Stage-2 using the Normal Memory + Inner/Outer Write-Back Cacheable + memory attribute. */ +/* ` } */ + +/* + * Sets the GPFN at which a particular page appears in the specified guest's + * pseudophysical address space. + * arg == addr of xen_add_to_physmap_t. + */ +#define XENMEM_add_to_physmap 7 +struct xen_add_to_physmap { + /* Which domain to change the mapping for. */ + domid_t domid; + + /* Number of pages to go through for gmfn_range */ + uint16_t size; + + unsigned int space; /* => enum phys_map_space */ + +#define XENMAPIDX_grant_table_status 0x80000000 + + /* Index into space being mapped. */ + xen_ulong_t idx; + + /* GPFN in domid where the source mapping page should appear. */ + xen_pfn_t gpfn; +}; +typedef struct xen_add_to_physmap xen_add_to_physmap_t; +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t); + +/* A batched version of add_to_physmap. */ +#define XENMEM_add_to_physmap_batch 23 +struct xen_add_to_physmap_batch { + /* IN */ + /* Which domain to change the mapping for. */ + domid_t domid; + uint16_t space; /* => enum phys_map_space */ + + /* Number of pages to go through */ + uint16_t size; + +#if __XEN_INTERFACE_VERSION__ < 0x00040700 + domid_t foreign_domid; /* IFF gmfn_foreign. Should be 0 for other spaces. */ +#else + union xen_add_to_physmap_batch_extra { + domid_t foreign_domid; /* gmfn_foreign */ + uint16_t res0; /* All the other spaces. Should be 0 */ + } u; +#endif + + /* Indexes into space being mapped. */ + XEN_GUEST_HANDLE(xen_ulong_t) idxs; + + /* GPFN in domid where the source mapping page should appear. */ + XEN_GUEST_HANDLE(xen_pfn_t) gpfns; + + /* OUT */ + + /* Per index error code. */ + XEN_GUEST_HANDLE(int) errs; +}; +typedef struct xen_add_to_physmap_batch xen_add_to_physmap_batch_t; +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_batch_t); + +#if __XEN_INTERFACE_VERSION__ < 0x00040400 +#define XENMEM_add_to_physmap_range XENMEM_add_to_physmap_batch +#define xen_add_to_physmap_range xen_add_to_physmap_batch +typedef struct xen_add_to_physmap_batch xen_add_to_physmap_range_t; +DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_range_t); +#endif + +/* + * Unmaps the page appearing at a particular GPFN from the specified guest's + * pseudophysical address space. + * arg == addr of xen_remove_from_physmap_t. + */ +#define XENMEM_remove_from_physmap 15 +struct xen_remove_from_physmap { + /* Which domain to change the mapping for. */ + domid_t domid; + + /* GPFN of the current mapping of the page. */ + xen_pfn_t gpfn; +}; +typedef struct xen_remove_from_physmap xen_remove_from_physmap_t; +DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t); + +/*** REMOVED ***/ +/*#define XENMEM_translate_gpfn_list 8*/ + +/* + * Returns the pseudo-physical memory map as it was when the domain + * was started (specified by XENMEM_set_memory_map). + * arg == addr of xen_memory_map_t. + */ +#define XENMEM_memory_map 9 +struct xen_memory_map { + /* + * On call the number of entries which can be stored in buffer. On + * return the number of entries which have been stored in + * buffer. + */ + unsigned int nr_entries; + + /* + * Entries in the buffer are in the same format as returned by the + * BIOS INT 0x15 EAX=0xE820 call. + */ + XEN_GUEST_HANDLE(void) buffer; +}; +typedef struct xen_memory_map xen_memory_map_t; +DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t); + +/* + * Returns the real physical memory map. Passes the same structure as + * XENMEM_memory_map. + * Specifying buffer as NULL will return the number of entries required + * to store the complete memory map. + * arg == addr of xen_memory_map_t. + */ +#define XENMEM_machine_memory_map 10 + +/* + * Set the pseudo-physical memory map of a domain, as returned by + * XENMEM_memory_map. + * arg == addr of xen_foreign_memory_map_t. + */ +#define XENMEM_set_memory_map 13 +struct xen_foreign_memory_map { + domid_t domid; + struct xen_memory_map map; +}; +typedef struct xen_foreign_memory_map xen_foreign_memory_map_t; +DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t); + +#define XENMEM_set_pod_target 16 +#define XENMEM_get_pod_target 17 +struct xen_pod_target { + /* IN */ + uint64_t target_pages; + /* OUT */ + uint64_t tot_pages; + uint64_t pod_cache_pages; + uint64_t pod_entries; + /* IN */ + domid_t domid; +}; +typedef struct xen_pod_target xen_pod_target_t; + +#if defined(__XEN__) || defined(__XEN_TOOLS__) + +#ifndef uint64_aligned_t +#define uint64_aligned_t uint64_t +#endif + +/* + * Get the number of MFNs saved through memory sharing. + * The call never fails. + */ +#define XENMEM_get_sharing_freed_pages 18 +#define XENMEM_get_sharing_shared_pages 19 + +#define XENMEM_paging_op 20 +#define XENMEM_paging_op_nominate 0 +#define XENMEM_paging_op_evict 1 +#define XENMEM_paging_op_prep 2 + +struct xen_mem_paging_op { + uint8_t op; /* XENMEM_paging_op_* */ + domid_t domain; + + /* PAGING_PREP IN: buffer to immediately fill page in */ + uint64_aligned_t buffer; + /* Other OPs */ + uint64_aligned_t gfn; /* IN: gfn of page being operated on */ +}; +typedef struct xen_mem_paging_op xen_mem_paging_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_paging_op_t); + +#define XENMEM_access_op 21 +#define XENMEM_access_op_set_access 0 +#define XENMEM_access_op_get_access 1 +/* + * XENMEM_access_op_enable_emulate and XENMEM_access_op_disable_emulate are + * currently unused, but since they have been in use please do not reuse them. + * + * #define XENMEM_access_op_enable_emulate 2 + * #define XENMEM_access_op_disable_emulate 3 + */ +#define XENMEM_access_op_set_access_multi 4 + +typedef enum { + XENMEM_access_n, + XENMEM_access_r, + XENMEM_access_w, + XENMEM_access_rw, + XENMEM_access_x, + XENMEM_access_rx, + XENMEM_access_wx, + XENMEM_access_rwx, + /* + * Page starts off as r-x, but automatically + * change to r-w on a write + */ + XENMEM_access_rx2rw, + /* + * Log access: starts off as n, automatically + * goes to rwx, generating an event without + * pausing the vcpu + */ + XENMEM_access_n2rwx, + /* Take the domain default */ + XENMEM_access_default +} xenmem_access_t; + +struct xen_mem_access_op { + /* XENMEM_access_op_* */ + uint8_t op; + /* xenmem_access_t */ + uint8_t access; + domid_t domid; + /* + * Number of pages for set op (or size of pfn_list for + * XENMEM_access_op_set_access_multi) + * Ignored on setting default access and other ops + */ + uint32_t nr; + /* + * First pfn for set op + * pfn for get op + * ~0ull is used to set and get the default access for pages + */ + uint64_aligned_t pfn; + /* + * List of pfns to set access for + * Used only with XENMEM_access_op_set_access_multi + */ + XEN_GUEST_HANDLE(const_uint64) pfn_list; + /* + * Corresponding list of access settings for pfn_list + * Used only with XENMEM_access_op_set_access_multi + */ + XEN_GUEST_HANDLE(const_uint8) access_list; +}; +typedef struct xen_mem_access_op xen_mem_access_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_access_op_t); + +#define XENMEM_sharing_op 22 +#define XENMEM_sharing_op_nominate_gfn 0 +#define XENMEM_sharing_op_nominate_gref 1 +#define XENMEM_sharing_op_share 2 +#define XENMEM_sharing_op_debug_gfn 3 +#define XENMEM_sharing_op_debug_mfn 4 +#define XENMEM_sharing_op_debug_gref 5 +#define XENMEM_sharing_op_add_physmap 6 +#define XENMEM_sharing_op_audit 7 +#define XENMEM_sharing_op_range_share 8 + +#define XENMEM_SHARING_OP_S_HANDLE_INVALID (-10) +#define XENMEM_SHARING_OP_C_HANDLE_INVALID (-9) + +/* The following allows sharing of grant refs. This is useful + * for sharing utilities sitting as "filters" in IO backends + * (e.g. memshr + blktap(2)). The IO backend is only exposed + * to grant references, and this allows sharing of the grefs */ +#define XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG (xen_mk_ullong(1) << 62) + +#define XENMEM_SHARING_OP_FIELD_MAKE_GREF(field, val) \ + (field) = (XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG | val) +#define XENMEM_SHARING_OP_FIELD_IS_GREF(field) \ + ((field) & XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG) +#define XENMEM_SHARING_OP_FIELD_GET_GREF(field) \ + ((field) & (~XENMEM_SHARING_OP_FIELD_IS_GREF_FLAG)) + +struct xen_mem_sharing_op { + uint8_t op; /* XENMEM_sharing_op_* */ + domid_t domain; + + union { + struct mem_sharing_op_nominate { /* OP_NOMINATE_xxx */ + union { + uint64_aligned_t gfn; /* IN: gfn to nominate */ + uint32_t grant_ref; /* IN: grant ref to nominate */ + } u; + uint64_aligned_t handle; /* OUT: the handle */ + } nominate; + struct mem_sharing_op_share { /* OP_SHARE/ADD_PHYSMAP */ + uint64_aligned_t source_gfn; /* IN: the gfn of the source page */ + uint64_aligned_t source_handle; /* IN: handle to the source page */ + uint64_aligned_t client_gfn; /* IN: the client gfn */ + uint64_aligned_t client_handle; /* IN: handle to the client page */ + domid_t client_domain; /* IN: the client domain id */ + } share; + struct mem_sharing_op_range { /* OP_RANGE_SHARE */ + uint64_aligned_t first_gfn; /* IN: the first gfn */ + uint64_aligned_t last_gfn; /* IN: the last gfn */ + uint64_aligned_t opaque; /* Must be set to 0 */ + domid_t client_domain; /* IN: the client domain id */ + uint16_t _pad[3]; /* Must be set to 0 */ + } range; + struct mem_sharing_op_debug { /* OP_DEBUG_xxx */ + union { + uint64_aligned_t gfn; /* IN: gfn to debug */ + uint64_aligned_t mfn; /* IN: mfn to debug */ + uint32_t gref; /* IN: gref to debug */ + } u; + } debug; + } u; +}; +typedef struct xen_mem_sharing_op xen_mem_sharing_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_mem_sharing_op_t); + +/* + * Attempt to stake a claim for a domain on a quantity of pages + * of system RAM, but _not_ assign specific pageframes. Only + * arithmetic is performed so the hypercall is very fast and need + * not be preemptible, thus sidestepping time-of-check-time-of-use + * races for memory allocation. Returns 0 if the hypervisor page + * allocator has atomically and successfully claimed the requested + * number of pages, else non-zero. + * + * Any domain may have only one active claim. When sufficient memory + * has been allocated to resolve the claim, the claim silently expires. + * Claiming zero pages effectively resets any outstanding claim and + * is always successful. + * + * Note that a valid claim may be staked even after memory has been + * allocated for a domain. In this case, the claim is not incremental, + * i.e. if the domain's tot_pages is 3, and a claim is staked for 10, + * only 7 additional pages are claimed. + * + * Caller must be privileged or the hypercall fails. + */ +#define XENMEM_claim_pages 24 + +/* + * XENMEM_claim_pages flags - the are no flags at this time. + * The zero value is appropriate. + */ + +/* + * With some legacy devices, certain guest-physical addresses cannot safely + * be used for other purposes, e.g. to map guest RAM. This hypercall + * enumerates those regions so the toolstack can avoid using them. + */ +#define XENMEM_reserved_device_memory_map 27 +struct xen_reserved_device_memory { + xen_pfn_t start_pfn; + xen_ulong_t nr_pages; +}; +typedef struct xen_reserved_device_memory xen_reserved_device_memory_t; +DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_t); + +struct xen_reserved_device_memory_map { +#define XENMEM_RDM_ALL 1 /* Request all regions (ignore dev union). */ + /* IN */ + uint32_t flags; + /* + * IN/OUT + * + * Gets set to the required number of entries when too low, + * signaled by error code -ERANGE. + */ + unsigned int nr_entries; + /* OUT */ + XEN_GUEST_HANDLE(xen_reserved_device_memory_t) buffer; + /* IN */ + union { + struct physdev_pci_device pci; + } dev; +}; +typedef struct xen_reserved_device_memory_map xen_reserved_device_memory_map_t; +DEFINE_XEN_GUEST_HANDLE(xen_reserved_device_memory_map_t); + +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ + +/* + * XENMEM_get_vnumainfo used by guest to get + * vNUMA topology from hypervisor. + */ +#define XENMEM_get_vnumainfo 26 + +/* vNUMA node memory ranges */ +struct xen_vmemrange { + uint64_t start, end; + unsigned int flags; + unsigned int nid; +}; +typedef struct xen_vmemrange xen_vmemrange_t; +DEFINE_XEN_GUEST_HANDLE(xen_vmemrange_t); + +/* + * vNUMA topology specifies vNUMA node number, distance table, + * memory ranges and vcpu mapping provided for guests. + * XENMEM_get_vnumainfo hypercall expects to see from guest + * nr_vnodes, nr_vmemranges and nr_vcpus to indicate available memory. + * After filling guests structures, nr_vnodes, nr_vmemranges and nr_vcpus + * copied back to guest. Domain returns expected values of nr_vnodes, + * nr_vmemranges and nr_vcpus to guest if the values where incorrect. + */ +struct xen_vnuma_topology_info { + /* IN */ + domid_t domid; + uint16_t pad; + /* IN/OUT */ + unsigned int nr_vnodes; + unsigned int nr_vcpus; + unsigned int nr_vmemranges; + /* OUT */ + union { + XEN_GUEST_HANDLE(uint) h; + uint64_t pad; + } vdistance; + union { + XEN_GUEST_HANDLE(uint) h; + uint64_t pad; + } vcpu_to_vnode; + union { + XEN_GUEST_HANDLE(xen_vmemrange_t) h; + uint64_t pad; + } vmemrange; +}; +typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; +DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); + +/* Next available subop number is 28 */ + +#endif /* __XEN_PUBLIC_MEMORY_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/physdev.h b/include/xen/physdev.h new file mode 100644 index 000000000..b6faf8350 --- /dev/null +++ b/include/xen/physdev.h @@ -0,0 +1,387 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006, Keir Fraser + */ + +#ifndef __XEN_PUBLIC_PHYSDEV_H__ +#define __XEN_PUBLIC_PHYSDEV_H__ + +#include "xen.h" + +/* + * Prototype for this hypercall is: + * int physdev_op(int cmd, void *args) + * @cmd == PHYSDEVOP_??? (physdev operation). + * @args == Operation-specific extra arguments (NULL if none). + */ + +/* + * Notify end-of-interrupt (EOI) for the specified IRQ. + * @arg == pointer to physdev_eoi structure. + */ +#define PHYSDEVOP_eoi 12 +struct physdev_eoi { + /* IN */ + uint32_t irq; +}; +typedef struct physdev_eoi physdev_eoi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_eoi_t); + +/* + * Register a shared page for the hypervisor to indicate whether the guest + * must issue PHYSDEVOP_eoi. The semantics of PHYSDEVOP_eoi change slightly + * once the guest used this function in that the associated event channel + * will automatically get unmasked. The page registered is used as a bit + * array indexed by Xen's PIRQ value. + */ +#define PHYSDEVOP_pirq_eoi_gmfn_v1 17 +/* + * Register a shared page for the hypervisor to indicate whether the + * guest must issue PHYSDEVOP_eoi. This hypercall is very similar to + * PHYSDEVOP_pirq_eoi_gmfn_v1 but it doesn't change the semantics of + * PHYSDEVOP_eoi. The page registered is used as a bit array indexed by + * Xen's PIRQ value. + */ +#define PHYSDEVOP_pirq_eoi_gmfn_v2 28 +struct physdev_pirq_eoi_gmfn { + /* IN */ + xen_pfn_t gmfn; +}; +typedef struct physdev_pirq_eoi_gmfn physdev_pirq_eoi_gmfn_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pirq_eoi_gmfn_t); + +/* + * Query the status of an IRQ line. + * @arg == pointer to physdev_irq_status_query structure. + */ +#define PHYSDEVOP_irq_status_query 5 +struct physdev_irq_status_query { + /* IN */ + uint32_t irq; + /* OUT */ + uint32_t flags; /* XENIRQSTAT_* */ +}; +typedef struct physdev_irq_status_query physdev_irq_status_query_t; +DEFINE_XEN_GUEST_HANDLE(physdev_irq_status_query_t); + +/* Need to call PHYSDEVOP_eoi when the IRQ has been serviced? */ +#define _XENIRQSTAT_needs_eoi (0) +#define XENIRQSTAT_needs_eoi (1U<<_XENIRQSTAT_needs_eoi) + +/* IRQ shared by multiple guests? */ +#define _XENIRQSTAT_shared (1) +#define XENIRQSTAT_shared (1U<<_XENIRQSTAT_shared) + +/* + * Set the current VCPU's I/O privilege level. + * @arg == pointer to physdev_set_iopl structure. + */ +#define PHYSDEVOP_set_iopl 6 +struct physdev_set_iopl { + /* IN */ + uint32_t iopl; +}; +typedef struct physdev_set_iopl physdev_set_iopl_t; +DEFINE_XEN_GUEST_HANDLE(physdev_set_iopl_t); + +/* + * Set the current VCPU's I/O-port permissions bitmap. + * @arg == pointer to physdev_set_iobitmap structure. + */ +#define PHYSDEVOP_set_iobitmap 7 +struct physdev_set_iobitmap { + /* IN */ +#if __XEN_INTERFACE_VERSION__ >= 0x00030205 + XEN_GUEST_HANDLE(uint8) bitmap; +#else + uint8_t *bitmap; +#endif + uint32_t nr_ports; +}; +typedef struct physdev_set_iobitmap physdev_set_iobitmap_t; +DEFINE_XEN_GUEST_HANDLE(physdev_set_iobitmap_t); + +/* + * Read or write an IO-APIC register. + * @arg == pointer to physdev_apic structure. + */ +#define PHYSDEVOP_apic_read 8 +#define PHYSDEVOP_apic_write 9 +struct physdev_apic { + /* IN */ + unsigned long apic_physbase; + uint32_t reg; + /* IN or OUT */ + uint32_t value; +}; +typedef struct physdev_apic physdev_apic_t; +DEFINE_XEN_GUEST_HANDLE(physdev_apic_t); + +/* + * Allocate or free a physical upcall vector for the specified IRQ line. + * @arg == pointer to physdev_irq structure. + */ +#define PHYSDEVOP_alloc_irq_vector 10 +#define PHYSDEVOP_free_irq_vector 11 +struct physdev_irq { + /* IN */ + uint32_t irq; + /* IN or OUT */ + uint32_t vector; +}; +typedef struct physdev_irq physdev_irq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_irq_t); + +#define MAP_PIRQ_TYPE_MSI 0x0 +#define MAP_PIRQ_TYPE_GSI 0x1 +#define MAP_PIRQ_TYPE_UNKNOWN 0x2 +#define MAP_PIRQ_TYPE_MSI_SEG 0x3 +#define MAP_PIRQ_TYPE_MULTI_MSI 0x4 + +#define PHYSDEVOP_map_pirq 13 +struct physdev_map_pirq { + domid_t domid; + /* IN */ + int type; + /* IN (ignored for ..._MULTI_MSI) */ + int index; + /* IN or OUT */ + int pirq; + /* IN - high 16 bits hold segment for ..._MSI_SEG and ..._MULTI_MSI */ + int bus; + /* IN */ + int devfn; + /* IN (also OUT for ..._MULTI_MSI) */ + int entry_nr; + /* IN */ + uint64_t table_base; +}; +typedef struct physdev_map_pirq physdev_map_pirq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t); + +#define PHYSDEVOP_unmap_pirq 14 +struct physdev_unmap_pirq { + domid_t domid; + /* IN */ + int pirq; +}; + +typedef struct physdev_unmap_pirq physdev_unmap_pirq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t); + +#define PHYSDEVOP_manage_pci_add 15 +#define PHYSDEVOP_manage_pci_remove 16 +struct physdev_manage_pci { + /* IN */ + uint8_t bus; + uint8_t devfn; +}; + +typedef struct physdev_manage_pci physdev_manage_pci_t; +DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t); + +#define PHYSDEVOP_restore_msi 19 +struct physdev_restore_msi { + /* IN */ + uint8_t bus; + uint8_t devfn; +}; +typedef struct physdev_restore_msi physdev_restore_msi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t); + +#define PHYSDEVOP_manage_pci_add_ext 20 +struct physdev_manage_pci_ext { + /* IN */ + uint8_t bus; + uint8_t devfn; + unsigned is_extfn; + unsigned is_virtfn; + struct { + uint8_t bus; + uint8_t devfn; + } physfn; +}; + +typedef struct physdev_manage_pci_ext physdev_manage_pci_ext_t; +DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_ext_t); + +/* + * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() + * hypercall since 0x00030202. + */ +struct physdev_op { + uint32_t cmd; + union { + struct physdev_irq_status_query irq_status_query; + struct physdev_set_iopl set_iopl; + struct physdev_set_iobitmap set_iobitmap; + struct physdev_apic apic_op; + struct physdev_irq irq_op; + } u; +}; +typedef struct physdev_op physdev_op_t; +DEFINE_XEN_GUEST_HANDLE(physdev_op_t); + +#define PHYSDEVOP_setup_gsi 21 +struct physdev_setup_gsi { + int gsi; + /* IN */ + uint8_t triggering; + /* IN */ + uint8_t polarity; + /* IN */ +}; + +typedef struct physdev_setup_gsi physdev_setup_gsi_t; +DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t); + +/* leave PHYSDEVOP 22 free */ + +/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI + * the hypercall returns a free pirq */ +#define PHYSDEVOP_get_free_pirq 23 +struct physdev_get_free_pirq { + /* IN */ + int type; + /* OUT */ + uint32_t pirq; +}; + +typedef struct physdev_get_free_pirq physdev_get_free_pirq_t; +DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t); + +#define XEN_PCI_MMCFG_RESERVED 0x1 + +#define PHYSDEVOP_pci_mmcfg_reserved 24 +struct physdev_pci_mmcfg_reserved { + uint64_t address; + uint16_t segment; + uint8_t start_bus; + uint8_t end_bus; + uint32_t flags; +}; +typedef struct physdev_pci_mmcfg_reserved physdev_pci_mmcfg_reserved_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pci_mmcfg_reserved_t); + +#define XEN_PCI_DEV_EXTFN 0x1 +#define XEN_PCI_DEV_VIRTFN 0x2 +#define XEN_PCI_DEV_PXM 0x4 + +#define PHYSDEVOP_pci_device_add 25 +struct physdev_pci_device_add { + /* IN */ + uint16_t seg; + uint8_t bus; + uint8_t devfn; + uint32_t flags; + struct { + uint8_t bus; + uint8_t devfn; + } physfn; + /* + * Optional parameters array. + * First element ([0]) is PXM domain associated with the device (if + * XEN_PCI_DEV_PXM is set) + */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + uint32_t optarr[]; +#elif defined(__GNUC__) + uint32_t optarr[0]; +#endif +}; +typedef struct physdev_pci_device_add physdev_pci_device_add_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_add_t); + +#define PHYSDEVOP_pci_device_remove 26 +#define PHYSDEVOP_restore_msi_ext 27 +/* + * Dom0 should use these two to announce MMIO resources assigned to + * MSI-X capable devices won't (prepare) or may (release) change. + */ +#define PHYSDEVOP_prepare_msix 30 +#define PHYSDEVOP_release_msix 31 +struct physdev_pci_device { + /* IN */ + uint16_t seg; + uint8_t bus; + uint8_t devfn; +}; +typedef struct physdev_pci_device physdev_pci_device_t; +DEFINE_XEN_GUEST_HANDLE(physdev_pci_device_t); + +#define PHYSDEVOP_DBGP_RESET_PREPARE 1 +#define PHYSDEVOP_DBGP_RESET_DONE 2 + +#define PHYSDEVOP_DBGP_BUS_UNKNOWN 0 +#define PHYSDEVOP_DBGP_BUS_PCI 1 + +#define PHYSDEVOP_dbgp_op 29 +struct physdev_dbgp_op { + /* IN */ + uint8_t op; + uint8_t bus; + union { + struct physdev_pci_device pci; + } u; +}; +typedef struct physdev_dbgp_op physdev_dbgp_op_t; +DEFINE_XEN_GUEST_HANDLE(physdev_dbgp_op_t); + +/* + * Notify that some PIRQ-bound event channels have been unmasked. + * ** This command is obsolete since interface version 0x00030202 and is ** + * ** unsupported by newer versions of Xen. ** + */ +#define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4 + +#if __XEN_INTERFACE_VERSION__ < 0x00040600 +/* + * These all-capitals physdev operation names are superceded by the new names + * (defined above) since interface version 0x00030202. The guard above was + * added post-4.5 only though and hence shouldn't check for 0x00030202. + */ +#define PHYSDEVOP_IRQ_STATUS_QUERY PHYSDEVOP_irq_status_query +#define PHYSDEVOP_SET_IOPL PHYSDEVOP_set_iopl +#define PHYSDEVOP_SET_IOBITMAP PHYSDEVOP_set_iobitmap +#define PHYSDEVOP_APIC_READ PHYSDEVOP_apic_read +#define PHYSDEVOP_APIC_WRITE PHYSDEVOP_apic_write +#define PHYSDEVOP_ASSIGN_VECTOR PHYSDEVOP_alloc_irq_vector +#define PHYSDEVOP_FREE_VECTOR PHYSDEVOP_free_irq_vector +#define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY XENIRQSTAT_needs_eoi +#define PHYSDEVOP_IRQ_SHARED XENIRQSTAT_shared +#endif + +#if __XEN_INTERFACE_VERSION__ < 0x00040200 +#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v1 +#else +#define PHYSDEVOP_pirq_eoi_gmfn PHYSDEVOP_pirq_eoi_gmfn_v2 +#endif + +#endif /* __XEN_PUBLIC_PHYSDEV_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/trace.h b/include/xen/trace.h new file mode 100644 index 000000000..a00c01733 --- /dev/null +++ b/include/xen/trace.h @@ -0,0 +1,339 @@ +/****************************************************************************** + * include/public/trace.h + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Mark Williamson, (C) 2004 Intel Research Cambridge + * Copyright (C) 2005 Bin Ren + */ + +#ifndef __XEN_PUBLIC_TRACE_H__ +#define __XEN_PUBLIC_TRACE_H__ + +#define TRACE_EXTRA_MAX 7 +#define TRACE_EXTRA_SHIFT 28 + +/* Trace classes */ +#define TRC_CLS_SHIFT 16 +#define TRC_GEN 0x0001f000 /* General trace */ +#define TRC_SCHED 0x0002f000 /* Xen Scheduler trace */ +#define TRC_DOM0OP 0x0004f000 /* Xen DOM0 operation trace */ +#define TRC_HVM 0x0008f000 /* Xen HVM trace */ +#define TRC_MEM 0x0010f000 /* Xen memory trace */ +#define TRC_PV 0x0020f000 /* Xen PV traces */ +#define TRC_SHADOW 0x0040f000 /* Xen shadow tracing */ +#define TRC_HW 0x0080f000 /* Xen hardware-related traces */ +#define TRC_GUEST 0x0800f000 /* Guest-generated traces */ +#define TRC_ALL 0x0ffff000 +#define TRC_HD_TO_EVENT(x) ((x)&0x0fffffff) +#define TRC_HD_CYCLE_FLAG (1UL<<31) +#define TRC_HD_INCLUDES_CYCLE_COUNT(x) ( !!( (x) & TRC_HD_CYCLE_FLAG ) ) +#define TRC_HD_EXTRA(x) (((x)>>TRACE_EXTRA_SHIFT)&TRACE_EXTRA_MAX) + +/* Trace subclasses */ +#define TRC_SUBCLS_SHIFT 12 + +/* trace subclasses for SVM */ +#define TRC_HVM_ENTRYEXIT 0x00081000 /* VMENTRY and #VMEXIT */ +#define TRC_HVM_HANDLER 0x00082000 /* various HVM handlers */ +#define TRC_HVM_EMUL 0x00084000 /* emulated devices */ + +#define TRC_SCHED_MIN 0x00021000 /* Just runstate changes */ +#define TRC_SCHED_CLASS 0x00022000 /* Scheduler-specific */ +#define TRC_SCHED_VERBOSE 0x00028000 /* More inclusive scheduling */ + +/* + * The highest 3 bits of the last 12 bits of TRC_SCHED_CLASS above are + * reserved for encoding what scheduler produced the information. The + * actual event is encoded in the last 9 bits. + * + * This means we have 8 scheduling IDs available (which means at most 8 + * schedulers generating events) and, in each scheduler, up to 512 + * different events. + */ +#define TRC_SCHED_ID_BITS 3 +#define TRC_SCHED_ID_SHIFT (TRC_SUBCLS_SHIFT - TRC_SCHED_ID_BITS) +#define TRC_SCHED_ID_MASK (((1UL<cpu_offset[cpu]). + */ +struct t_info { + uint16_t tbuf_size; /* Size in pages of each trace buffer */ + uint16_t mfn_offset[]; /* Offset within t_info structure of the page list per cpu */ + /* MFN lists immediately after the header */ +}; + +#endif /* __XEN_PUBLIC_TRACE_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/include/xen/xen-compat.h b/include/xen/xen-compat.h 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 6c9e42b2b..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 @@ -53,17 +53,22 @@ DEFINE_XEN_GUEST_HANDLE(uint64_t); DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); -/* Turn a plain number into a C unsigned (long) constant. */ +/* Turn a plain number into a C unsigned (long (long)) constant. */ #define __xen_mk_uint(x) x ## U #define __xen_mk_ulong(x) x ## UL +#ifndef __xen_mk_ullong +# define __xen_mk_ullong(x) x ## ULL +#endif #define xen_mk_uint(x) __xen_mk_uint(x) #define xen_mk_ulong(x) __xen_mk_ulong(x) +#define xen_mk_ullong(x) __xen_mk_ullong(x) #else /* In assembly code we cannot use C numeric constant suffixes. */ -#define xen_mk_uint(x) x -#define xen_mk_ulong(x) x +#define xen_mk_uint(x) x +#define xen_mk_ulong(x) x +#define xen_mk_ullong(x) x #endif @@ -115,6 +120,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define __HYPERVISOR_tmem_op 38 #define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */ #define __HYPERVISOR_xenpmu_op 40 +#define __HYPERVISOR_dm_op 41 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 @@ -151,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 @@ -205,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: @@ -251,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. @@ -501,6 +507,21 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); /* x86/PAE guests: support PDPTs above 4GB. */ #define VMASST_TYPE_pae_extended_cr3 3 +/* + * x86 guests: Sane behaviour for virtual iopl + * - virtual iopl updated from do_iret() hypercalls. + * - virtual iopl reported in bounce frames. + * - guest kernels assumed to be level 0 for the purpose of iopl checks. + */ +#define VMASST_TYPE_architectural_iopl 4 + +/* + * All guests: activate update indicator in vcpu_runstate_info + * Enable setting the XEN_RUNSTATE_UPDATE flag in guest memory mapped + * vcpu_runstate_info during updates of the runstate information. + */ +#define VMASST_TYPE_runstate_update_flag 5 + /* * x86/64 guests: strictly hide M2P from user mode. * This allows the guest to control respective hypervisor behavior: @@ -529,16 +550,21 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); * is useful to ensure that no mappings to the OS's own heap are accidentally * installed. (e.g., in Linux this could cause havoc as reference counts * aren't adjusted on the I/O-mapping code path). - * This only makes sense in MMUEXT_SET_FOREIGNDOM, but in that context can - * be specified by any calling domain. + * This only makes sense as HYPERVISOR_mmu_update()'s and + * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument. For + * HYPERVISOR_mmu_update() context it can be specified by any calling domain, + * otherwise it's only permitted if the caller is privileged. */ #define DOMID_IO xen_mk_uint(0x7FF1) /* * DOMID_XEN is used to allow privileged domains to map restricted parts of * Xen's heap space (e.g., the machine_to_phys table). - * This only makes sense in MMUEXT_SET_FOREIGNDOM, and is only permitted if - * the caller is privileged. + * This only makes sense as + * - HYPERVISOR_mmu_update()'s, HYPERVISOR_mmuext_op()'s, or + * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument, + * - with XENMAPSPACE_gmfn_foreign, + * and is only permitted if the caller is privileged. */ #define DOMID_XEN xen_mk_uint(0x7FF2) @@ -614,14 +640,22 @@ struct vcpu_time_info { */ uint32_t tsc_to_system_mul; int8_t tsc_shift; +#if __XEN_INTERFACE_VERSION__ > 0x040600 + uint8_t flags; + uint8_t pad1[2]; +#else int8_t pad1[3]; +#endif }; /* 32 bytes */ typedef struct vcpu_time_info vcpu_time_info_t; +#define XEN_PVCLOCK_TSC_STABLE_BIT (1 << 0) +#define XEN_PVCLOCK_GUEST_STOPPED (1 << 1) + struct vcpu_info { /* * 'evtchn_upcall_pending' is written non-zero by Xen to indicate - * a pending notification for a particular VCPU. It is then cleared + * 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 @@ -684,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 @@ -695,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 @@ -736,7 +770,7 @@ typedef struct shared_info shared_info_t; * (may be omitted) * c. list of allocated page frames [mfn_list, nr_pages] * (unless relocated due to XEN_ELFNOTE_INIT_P2M) - * d. start_info_t structure [register ESI (x86)] + * d. start_info_t structure [register rSI (x86)] * in case of dom0 this page contains the console info, too * e. unless dom0: xenstore ring page * f. unless dom0: console ring page @@ -797,29 +831,6 @@ struct start_info { }; typedef struct start_info start_info_t; -/* - * Start of day structure passed to PVH guests in %ebx. - * - * NOTE: nothing will be loaded at physical address 0, so - * a 0 value in any of the address fields should be treated - * as not present. - */ -struct hvm_start_info { -#define HVM_START_MAGIC_VALUE 0x336ec578 - uint32_t magic; /* Contains the magic value 0x336ec578 */ - /* ("xEn3" with the 0x80 bit of the "E" set).*/ - uint32_t flags; /* SIF_xxx flags. */ - uint32_t cmdline_paddr; /* Physical address of the command line. */ - uint32_t nr_modules; /* Number of modules passed to the kernel. */ - uint32_t modlist_paddr; /* Physical address of an array of */ - /* hvm_modlist_entry. */ -}; - -struct hvm_modlist_entry { - uint32_t paddr; /* Physical address of the module. */ - uint32_t size; /* Size of the module in bytes. */ -}; - /* New console union for dom0 introduced in 0x00030203. */ #if __XEN_INTERFACE_VERSION__ < 0x00030203 #define console_mfn console.domU.mfn @@ -919,6 +930,37 @@ __DEFINE_XEN_GUEST_HANDLE(uint16, uint16_t); __DEFINE_XEN_GUEST_HANDLE(uint32, uint32_t); __DEFINE_XEN_GUEST_HANDLE(uint64, uint64_t); +typedef struct { + uint8_t a[16]; +} xen_uuid_t; + +/* + * XEN_DEFINE_UUID(0x00112233, 0x4455, 0x6677, 0x8899, + * 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff) + * will construct UUID 00112233-4455-6677-8899-aabbccddeeff presented as + * {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + * 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + * + * NB: This is compatible with Linux kernel and with libuuid, but it is not + * compatible with Microsoft, as they use mixed-endian encoding (some + * components are little-endian, some are big-endian). + */ +#define XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6) \ + {{((a) >> 24) & 0xFF, ((a) >> 16) & 0xFF, \ + ((a) >> 8) & 0xFF, ((a) >> 0) & 0xFF, \ + ((b) >> 8) & 0xFF, ((b) >> 0) & 0xFF, \ + ((c) >> 8) & 0xFF, ((c) >> 0) & 0xFF, \ + ((d) >> 8) & 0xFF, ((d) >> 0) & 0xFF, \ + e1, e2, e3, e4, e5, e6}} + +#if defined(__STDC_VERSION__) ? __STDC_VERSION__ >= 199901L : defined(__GNUC__) +#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \ + ((xen_uuid_t)XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6)) +#else +#define XEN_DEFINE_UUID(a, b, c, d, e1, e2, e3, e4, e5, e6) \ + XEN_DEFINE_UUID_(a, b, c, d, e1, e2, e3, e4, e5, e6) +#endif /* __STDC_VERSION__ / __GNUC__ */ + #endif /* !__ASSEMBLY__ */ /* Default definitions for macros used by domctl/sysctl. */ diff --git a/m4/00gnulib.m4 b/m4/00gnulib.m4 deleted file mode 100644 index d4ad759fd..000000000 --- a/m4/00gnulib.m4 +++ /dev/null @@ -1,30 +0,0 @@ -# 00gnulib.m4 serial 2 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl This file must be named something that sorts before all other -dnl gnulib-provided .m4 files. It is needed until such time as we can -dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE semantics. - -# AC_DEFUN_ONCE([NAME], VALUE) -# ---------------------------- -# Define NAME to expand to VALUE on the first use (whether by direct -# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses. -# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This -# definition is slower than the version in Autoconf 2.64, because it -# can only use interfaces that existed since 2.59; but it achieves the -# same effect. Quoting is necessary to avoid confusing Automake. -m4_version_prereq([2.63.263], [], -[m4_define([AC][_DEFUN_ONCE], - [AC][_DEFUN([$1], - [AC_REQUIRE([_gl_DEFUN_ONCE([$1])], - [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl -[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])]) - -# gl_00GNULIB -# ----------- -# Witness macro that this file has been included. Needed to force -# Automake to include this file prior to all other gnulib .m4 files. -AC_DEFUN([gl_00GNULIB]) diff --git a/m4/alloca.m4 b/m4/alloca.m4 deleted file mode 100644 index 270abd0cd..000000000 --- a/m4/alloca.m4 +++ /dev/null @@ -1,121 +0,0 @@ -# alloca.m4 serial 14 -dnl Copyright (C) 2002-2004, 2006-2007, 2009-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_ALLOCA], -[ - AC_REQUIRE([AC_FUNC_ALLOCA]) - if test $ac_cv_func_alloca_works = no; then - gl_PREREQ_ALLOCA - fi - - # Define an additional variable used in the Makefile substitution. - if test $ac_cv_working_alloca_h = yes; then - AC_CACHE_CHECK([for alloca as a compiler built-in], [gl_cv_rpl_alloca], [ - AC_EGREP_CPP([Need own alloca], [ -#if defined __GNUC__ || defined _AIX || defined _MSC_VER - Need own alloca -#endif - ], [gl_cv_rpl_alloca=yes], [gl_cv_rpl_alloca=no]) - ]) - if test $gl_cv_rpl_alloca = yes; then - dnl OK, alloca can be implemented through a compiler built-in. - AC_DEFINE([HAVE_ALLOCA], [1], - [Define to 1 if you have 'alloca' after including , - a header that may be supplied by this distribution.]) - ALLOCA_H=alloca.h - else - dnl alloca exists as a library function, i.e. it is slow and probably - dnl a memory leak. Don't define HAVE_ALLOCA in this case. - ALLOCA_H= - fi - else - ALLOCA_H=alloca.h - fi - AC_SUBST([ALLOCA_H]) - AM_CONDITIONAL([GL_GENERATE_ALLOCA_H], [test -n "$ALLOCA_H"]) -]) - -# Prerequisites of lib/alloca.c. -# STACK_DIRECTION is already handled by AC_FUNC_ALLOCA. -AC_DEFUN([gl_PREREQ_ALLOCA], [:]) - -# This works around a bug in autoconf <= 2.68. -# See . - -m4_version_prereq([2.69], [] ,[ - -# This is taken from the following Autoconf patch: -# http://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6cd9f12520b0d6f76d3230d7565feba1ecf29497 - -# _AC_LIBOBJ_ALLOCA -# ----------------- -# Set up the LIBOBJ replacement of 'alloca'. Well, not exactly -# AC_LIBOBJ since we actually set the output variable 'ALLOCA'. -# Nevertheless, for Automake, AC_LIBSOURCES it. -m4_define([_AC_LIBOBJ_ALLOCA], -[# The SVR3 libPW and SVR4 libucb both contain incompatible functions -# that cause trouble. Some versions do not even contain alloca or -# contain a buggy version. If you still want to use their alloca, -# use ar to extract alloca.o from them instead of compiling alloca.c. -AC_LIBSOURCES(alloca.c) -AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.$ac_objext])dnl -AC_DEFINE(C_ALLOCA, 1, [Define to 1 if using 'alloca.c'.]) - -AC_CACHE_CHECK(whether 'alloca.c' needs Cray hooks, ac_cv_os_cray, -[AC_EGREP_CPP(webecray, -[#if defined CRAY && ! defined CRAY2 -webecray -#else -wenotbecray -#endif -], ac_cv_os_cray=yes, ac_cv_os_cray=no)]) -if test $ac_cv_os_cray = yes; then - for ac_func in _getb67 GETB67 getb67; do - AC_CHECK_FUNC($ac_func, - [AC_DEFINE_UNQUOTED(CRAY_STACKSEG_END, $ac_func, - [Define to one of '_getb67', 'GETB67', - 'getb67' for Cray-2 and Cray-YMP - systems. This function is required for - 'alloca.c' support on those systems.]) - break]) - done -fi - -AC_CACHE_CHECK([stack direction for C alloca], - [ac_cv_c_stack_direction], -[AC_RUN_IFELSE([AC_LANG_SOURCE( -[AC_INCLUDES_DEFAULT -int -find_stack_direction (int *addr, int depth) -{ - int dir, dummy = 0; - if (! addr) - addr = &dummy; - *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; - dir = depth ? find_stack_direction (addr, depth - 1) : 0; - return dir + dummy; -} - -int -main (int argc, char **argv) -{ - return find_stack_direction (0, argc + !argv + 20) < 0; -}])], - [ac_cv_c_stack_direction=1], - [ac_cv_c_stack_direction=-1], - [ac_cv_c_stack_direction=0])]) -AH_VERBATIM([STACK_DIRECTION], -[/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at runtime. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -@%:@undef STACK_DIRECTION])dnl -AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction) -])# _AC_LIBOBJ_ALLOCA -]) diff --git a/m4/argp.m4 b/m4/argp.m4 deleted file mode 100644 index 4445d8e6c..000000000 --- a/m4/argp.m4 +++ /dev/null @@ -1,61 +0,0 @@ -# argp.m4 serial 14 -dnl Copyright (C) 2003-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_ARGP], -[ - AC_REQUIRE([AC_C_INLINE]) - AC_REQUIRE([AC_C_RESTRICT]) - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - - AC_CHECK_DECLS([program_invocation_name], [], - [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_NAME], [1], - [Define to 1 to add extern declaration of program_invocation_name to argp.h])], - [[#include ]]) - AC_CHECK_DECLS([program_invocation_short_name], [], - [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_SHORT_NAME], [1], - [Define to 1 to add extern declaration of program_invocation_short_name to argp.h])], - [[#include ]]) - - # Check if program_invocation_name and program_invocation_short_name - # are defined elsewhere. It is improbable that only one of them will - # be defined and other not, I prefer to stay on the safe side and to - # test each one separately. - AC_MSG_CHECKING([whether program_invocation_name is defined]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[program_invocation_name = "test";]])], - [AC_DEFINE([HAVE_PROGRAM_INVOCATION_NAME], [1], - [Define if program_invocation_name is defined]) - AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no])]) - - AC_MSG_CHECKING([whether program_invocation_short_name is defined]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[program_invocation_short_name = "test";]])], - [AC_DEFINE([HAVE_PROGRAM_INVOCATION_SHORT_NAME], [1], - [Define if program_invocation_short_name is defined]) - AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no])]) - - AC_CHECK_DECLS_ONCE([clearerr_unlocked]) - AC_CHECK_DECLS_ONCE([feof_unlocked]) - AC_CHECK_DECLS_ONCE([ferror_unlocked]) - AC_CHECK_DECLS_ONCE([fflush_unlocked]) - AC_CHECK_DECLS_ONCE([fgets_unlocked]) - AC_CHECK_DECLS_ONCE([fputc_unlocked]) - AC_CHECK_DECLS_ONCE([fputs_unlocked]) - AC_CHECK_DECLS_ONCE([fread_unlocked]) - AC_CHECK_DECLS_ONCE([fwrite_unlocked]) - AC_CHECK_DECLS_ONCE([getc_unlocked]) - AC_CHECK_DECLS_ONCE([getchar_unlocked]) - AC_CHECK_DECLS_ONCE([putc_unlocked]) - AC_CHECK_DECLS_ONCE([putchar_unlocked]) - AC_CHECK_FUNCS_ONCE([flockfile funlockfile]) - AC_CHECK_HEADERS_ONCE([features.h linewrap.h]) -]) - -dnl argp-parse.c depends on GNU getopt internals, therefore use GNU getopt -dnl always. -AC_DEFUN([gl_REPLACE_GETOPT_ALWAYS], []) diff --git a/m4/btowc.m4 b/m4/btowc.m4 deleted file mode 100644 index 978a06e9a..000000000 --- a/m4/btowc.m4 +++ /dev/null @@ -1,116 +0,0 @@ -# btowc.m4 serial 10 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_BTOWC], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - - dnl Check whether is usable at all, first. Otherwise the test - dnl program below may lead to an endless loop. See - dnl . - AC_REQUIRE([gl_WCHAR_H_INLINE_OK]) - - AC_CHECK_FUNCS_ONCE([btowc]) - if test $ac_cv_func_btowc = no; then - HAVE_BTOWC=0 - else - - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_FR]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - - dnl Cygwin 1.7.2 btowc('\0') is WEOF, not 0. - AC_CACHE_CHECK([whether btowc(0) is correct], - [gl_cv_func_btowc_nul], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - if (btowc ('\0') != 0) - return 1; - return 0; -}]])], - [gl_cv_func_btowc_nul=yes], - [gl_cv_func_btowc_nul=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess no on Cygwin. - cygwin*) gl_cv_func_btowc_nul="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_btowc_nul="guessing yes" ;; - esac -changequote([,])dnl - ]) - ]) - - dnl IRIX 6.5 btowc(EOF) is 0xFF, not WEOF. - AC_CACHE_CHECK([whether btowc(EOF) is correct], - [gl_cv_func_btowc_eof], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on IRIX. - irix*) gl_cv_func_btowc_eof="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_btowc_eof="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_FR != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) - { - if (btowc (EOF) != WEOF) - return 1; - } - return 0; -}]])], - [gl_cv_func_btowc_eof=yes], - [gl_cv_func_btowc_eof=no], - [:]) - fi - ]) - - case "$gl_cv_func_btowc_nul" in - *yes) ;; - *) REPLACE_BTOWC=1 ;; - esac - case "$gl_cv_func_btowc_eof" in - *yes) ;; - *) REPLACE_BTOWC=1 ;; - esac - fi -]) - -# Prerequisites of lib/btowc.c. -AC_DEFUN([gl_PREREQ_BTOWC], [ - : -]) diff --git a/m4/codeset.m4 b/m4/codeset.m4 deleted file mode 100644 index c2761be2a..000000000 --- a/m4/codeset.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# codeset.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2000-2002, 2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([AM_LANGINFO_CODESET], -[ - AC_CACHE_CHECK([for nl_langinfo and CODESET], [am_cv_langinfo_codeset], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[char* cs = nl_langinfo(CODESET); return !cs;]])], - [am_cv_langinfo_codeset=yes], - [am_cv_langinfo_codeset=no]) - ]) - if test $am_cv_langinfo_codeset = yes; then - AC_DEFINE([HAVE_LANGINFO_CODESET], [1], - [Define if you have and nl_langinfo(CODESET).]) - fi -]) diff --git a/m4/configmake.m4 b/m4/configmake.m4 deleted file mode 100644 index 823ffc0dd..000000000 --- a/m4/configmake.m4 +++ /dev/null @@ -1,50 +0,0 @@ -# configmake.m4 serial 1 -dnl Copyright (C) 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# gl_CONFIGMAKE_PREP -# ------------------ -# Guarantee all of the standard directory variables, even when used with -# autoconf 2.59 (datarootdir wasn't supported until 2.59c) or automake -# 1.9.6 (pkglibexecdir wasn't supported until 1.10b.). -AC_DEFUN([gl_CONFIGMAKE_PREP], -[ - dnl Technically, datadir should default to datarootdir. But if - dnl autoconf is too old to provide datarootdir, then reversing the - dnl definition is a reasonable compromise. Only AC_SUBST a variable - dnl if it was not already defined earlier by autoconf. - if test "x$datarootdir" = x; then - AC_SUBST([datarootdir], ['${datadir}']) - fi - dnl Copy the approach used in autoconf 2.60. - if test "x$docdir" = x; then - AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], - ['${datarootdir}/doc/${PACKAGE_TARNAME}'], - ['${datarootdir}/doc/${PACKAGE}'])]) - fi - dnl The remaining variables missing from autoconf 2.59 are easier. - if test "x$htmldir" = x; then - AC_SUBST([htmldir], ['${docdir}']) - fi - if test "x$dvidir" = x; then - AC_SUBST([dvidir], ['${docdir}']) - fi - if test "x$pdfdir" = x; then - AC_SUBST([pdfdir], ['${docdir}']) - fi - if test "x$psdir" = x; then - AC_SUBST([psdir], ['${docdir}']) - fi - if test "x$lispdir" = x; then - AC_SUBST([lispdir], ['${datarootdir}/emacs/site-lisp']) - fi - if test "x$localedir" = x; then - AC_SUBST([localedir], ['${datarootdir}/locale']) - fi - - dnl Automake 1.9.6 only lacks pkglibexecdir; and since 1.11 merely - dnl provides it without AC_SUBST, this blind use of AC_SUBST is safe. - AC_SUBST([pkglibexecdir], ['${libexecdir}/${PACKAGE}']) -]) diff --git a/m4/dirname.m4 b/m4/dirname.m4 deleted file mode 100644 index 5897a2a8b..000000000 --- a/m4/dirname.m4 +++ /dev/null @@ -1,19 +0,0 @@ -#serial 10 -*- autoconf -*- -dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_DIRNAME], -[ - AC_REQUIRE([gl_DIRNAME_LGPL]) -]) - -AC_DEFUN([gl_DIRNAME_LGPL], -[ - dnl Prerequisites of lib/dirname.h. - AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) - - dnl No prerequisites of lib/basename-lgpl.c, lib/dirname-lgpl.c, - dnl lib/stripslash.c. -]) diff --git a/m4/double-slash-root.m4 b/m4/double-slash-root.m4 deleted file mode 100644 index bd6f86714..000000000 --- a/m4/double-slash-root.m4 +++ /dev/null @@ -1,38 +0,0 @@ -# double-slash-root.m4 serial 4 -*- Autoconf -*- -dnl Copyright (C) 2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_DOUBLE_SLASH_ROOT], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_CACHE_CHECK([whether // is distinct from /], [gl_cv_double_slash_root], - [ if test x"$cross_compiling" = xyes ; then - # When cross-compiling, there is no way to tell whether // is special - # short of a list of hosts. However, the only known hosts to date - # that have a distinct // are Apollo DomainOS (too old to port to), - # Cygwin, and z/OS. If anyone knows of another system for which // has - # special semantics and is distinct from /, please report it to - # . - case $host in - *-cygwin | i370-ibm-openedition) - gl_cv_double_slash_root=yes ;; - *) - # Be optimistic and assume that / and // are the same when we - # don't know. - gl_cv_double_slash_root='unknown, assuming no' ;; - esac - else - set x `ls -di / // 2>/dev/null` - if test "$[2]" = "$[4]" && wc //dev/null >/dev/null 2>&1; then - gl_cv_double_slash_root=no - else - gl_cv_double_slash_root=yes - fi - fi]) - if test "$gl_cv_double_slash_root" = yes; then - AC_DEFINE([DOUBLE_SLASH_IS_DISTINCT_ROOT], [1], - [Define to 1 if // is a file system root distinct from /.]) - fi -]) diff --git a/m4/eealloc.m4 b/m4/eealloc.m4 deleted file mode 100644 index c640ec129..000000000 --- a/m4/eealloc.m4 +++ /dev/null @@ -1,31 +0,0 @@ -# eealloc.m4 serial 3 -dnl Copyright (C) 2003, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_EEALLOC], -[ - AC_REQUIRE([gl_EEMALLOC]) - AC_REQUIRE([gl_EEREALLOC]) -]) - -AC_DEFUN([gl_EEMALLOC], -[ - _AC_FUNC_MALLOC_IF( - [gl_cv_func_malloc_0_nonnull=1], - [gl_cv_func_malloc_0_nonnull=0]) - AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull], - [If malloc(0) is != NULL, define this to 1. Otherwise define this - to 0.]) -]) - -AC_DEFUN([gl_EEREALLOC], -[ - _AC_FUNC_REALLOC_IF( - [gl_cv_func_realloc_0_nonnull=1], - [gl_cv_func_realloc_0_nonnull=0]) - AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull], - [If realloc(NULL,0) is != NULL, define this to 1. Otherwise define this - to 0.]) -]) diff --git a/m4/errno_h.m4 b/m4/errno_h.m4 deleted file mode 100644 index c813ea583..000000000 --- a/m4/errno_h.m4 +++ /dev/null @@ -1,137 +0,0 @@ -# errno_h.m4 serial 12 -dnl Copyright (C) 2004, 2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [ - AC_EGREP_CPP([booboo],[ -#include -#if !defined ETXTBSY -booboo -#endif -#if !defined ENOMSG -booboo -#endif -#if !defined EIDRM -booboo -#endif -#if !defined ENOLINK -booboo -#endif -#if !defined EPROTO -booboo -#endif -#if !defined EMULTIHOP -booboo -#endif -#if !defined EBADMSG -booboo -#endif -#if !defined EOVERFLOW -booboo -#endif -#if !defined ENOTSUP -booboo -#endif -#if !defined ENETRESET -booboo -#endif -#if !defined ECONNABORTED -booboo -#endif -#if !defined ESTALE -booboo -#endif -#if !defined EDQUOT -booboo -#endif -#if !defined ECANCELED -booboo -#endif -#if !defined EOWNERDEAD -booboo -#endif -#if !defined ENOTRECOVERABLE -booboo -#endif -#if !defined EILSEQ -booboo -#endif - ], - [gl_cv_header_errno_h_complete=no], - [gl_cv_header_errno_h_complete=yes]) - ]) - if test $gl_cv_header_errno_h_complete = yes; then - ERRNO_H='' - else - gl_NEXT_HEADERS([errno.h]) - ERRNO_H='errno.h' - fi - AC_SUBST([ERRNO_H]) - AM_CONDITIONAL([GL_GENERATE_ERRNO_H], [test -n "$ERRNO_H"]) - gl_REPLACE_ERRNO_VALUE([EMULTIHOP]) - gl_REPLACE_ERRNO_VALUE([ENOLINK]) - gl_REPLACE_ERRNO_VALUE([EOVERFLOW]) -]) - -# Assuming $1 = EOVERFLOW. -# The EOVERFLOW errno value ought to be defined in , according to -# POSIX. But some systems (like OpenBSD 4.0 or AIX 3) don't define it, and -# some systems (like OSF/1) define it when _XOPEN_SOURCE_EXTENDED is defined. -# Check for the value of EOVERFLOW. -# Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE. -AC_DEFUN([gl_REPLACE_ERRNO_VALUE], -[ - if test -n "$ERRNO_H"; then - AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [ - AC_EGREP_CPP([yes],[ -#include -#ifdef ]$1[ -yes -#endif - ], - [gl_cv_header_errno_h_]$1[=yes], - [gl_cv_header_errno_h_]$1[=no]) - if test $gl_cv_header_errno_h_]$1[ = no; then - AC_EGREP_CPP([yes],[ -#define _XOPEN_SOURCE_EXTENDED 1 -#include -#ifdef ]$1[ -yes -#endif - ], [gl_cv_header_errno_h_]$1[=hidden]) - if test $gl_cv_header_errno_h_]$1[ = hidden; then - dnl The macro exists but is hidden. - dnl Define it to the same value. - AC_COMPUTE_INT([gl_cv_header_errno_h_]$1, $1, [ -#define _XOPEN_SOURCE_EXTENDED 1 -#include -/* The following two lines are a workaround against an autoconf-2.52 bug. */ -#include -#include -]) - fi - fi - ]) - case $gl_cv_header_errno_h_]$1[ in - yes | no) - ]$1[_HIDDEN=0; ]$1[_VALUE= - ;; - *) - ]$1[_HIDDEN=1; ]$1[_VALUE="$gl_cv_header_errno_h_]$1[" - ;; - esac - AC_SUBST($1[_HIDDEN]) - AC_SUBST($1[_VALUE]) - fi -]) - -dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. -dnl Remove this when we can assume autoconf >= 2.61. -m4_ifdef([AC_COMPUTE_INT], [], [ - AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) -]) diff --git a/m4/error.m4 b/m4/error.m4 deleted file mode 100644 index 29e6fdc9c..000000000 --- a/m4/error.m4 +++ /dev/null @@ -1,27 +0,0 @@ -#serial 14 - -# Copyright (C) 1996-1998, 2001-2004, 2009-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_ERROR], -[ - dnl We don't use AC_FUNC_ERROR_AT_LINE any more, because it is no longer - dnl maintained in Autoconf and because it invokes AC_LIBOBJ. - AC_CACHE_CHECK([for error_at_line], [ac_cv_lib_error_at_line], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[error_at_line (0, 0, "", 0, "an error occurred");]])], - [ac_cv_lib_error_at_line=yes], - [ac_cv_lib_error_at_line=no])]) -]) - -# Prerequisites of lib/error.c. -AC_DEFUN([gl_PREREQ_ERROR], -[ - AC_REQUIRE([AC_FUNC_STRERROR_R]) - : -]) diff --git a/m4/exponentd.m4 b/m4/exponentd.m4 deleted file mode 100644 index 09df468c9..000000000 --- a/m4/exponentd.m4 +++ /dev/null @@ -1,116 +0,0 @@ -# exponentd.m4 serial 3 -dnl Copyright (C) 2007-2008, 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -AC_DEFUN([gl_DOUBLE_EXPONENT_LOCATION], -[ - AC_CACHE_CHECK([where to find the exponent in a 'double'], - [gl_cv_cc_double_expbit0], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include -#include -#define NWORDS \ - ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) -typedef union { double value; unsigned int word[NWORDS]; } memory_double; -static unsigned int ored_words[NWORDS]; -static unsigned int anded_words[NWORDS]; -static void add_to_ored_words (double x) -{ - memory_double m; - size_t i; - /* Clear it first, in case sizeof (double) < sizeof (memory_double). */ - memset (&m, 0, sizeof (memory_double)); - m.value = x; - for (i = 0; i < NWORDS; i++) - { - ored_words[i] |= m.word[i]; - anded_words[i] &= m.word[i]; - } -} -int main () -{ - size_t j; - FILE *fp = fopen ("conftest.out", "w"); - if (fp == NULL) - return 1; - for (j = 0; j < NWORDS; j++) - anded_words[j] = ~ (unsigned int) 0; - add_to_ored_words (0.25); - add_to_ored_words (0.5); - add_to_ored_words (1.0); - add_to_ored_words (2.0); - add_to_ored_words (4.0); - /* Remove bits that are common (e.g. if representation of the first mantissa - bit is explicit). */ - for (j = 0; j < NWORDS; j++) - ored_words[j] &= ~anded_words[j]; - /* Now find the nonzero word. */ - for (j = 0; j < NWORDS; j++) - if (ored_words[j] != 0) - break; - if (j < NWORDS) - { - size_t i; - for (i = j + 1; i < NWORDS; i++) - if (ored_words[i] != 0) - { - fprintf (fp, "unknown"); - return (fclose (fp) != 0); - } - for (i = 0; ; i++) - if ((ored_words[j] >> i) & 1) - { - fprintf (fp, "word %d bit %d", (int) j, (int) i); - return (fclose (fp) != 0); - } - } - fprintf (fp, "unknown"); - return (fclose (fp) != 0); -} - ]])], - [gl_cv_cc_double_expbit0=`cat conftest.out`], - [gl_cv_cc_double_expbit0="unknown"], - [ - dnl On ARM, there are two 'double' floating-point formats, used by - dnl different sets of instructions: The older FPA instructions assume - dnl that they are stored in big-endian word order, while the words - dnl (like integer types) are stored in little-endian byte order. - dnl The newer VFP instructions assume little-endian order - dnl consistently. - AC_EGREP_CPP([mixed_endianness], [ -#if defined arm || defined __arm || defined __arm__ - mixed_endianness -#endif - ], - [gl_cv_cc_double_expbit0="unknown"], - [ - pushdef([AC_MSG_CHECKING],[:])dnl - pushdef([AC_MSG_RESULT],[:])dnl - pushdef([AC_MSG_RESULT_UNQUOTED],[:])dnl - AC_C_BIGENDIAN( - [gl_cv_cc_double_expbit0="word 0 bit 20"], - [gl_cv_cc_double_expbit0="word 1 bit 20"], - [gl_cv_cc_double_expbit0="unknown"]) - popdef([AC_MSG_RESULT_UNQUOTED])dnl - popdef([AC_MSG_RESULT])dnl - popdef([AC_MSG_CHECKING])dnl - ]) - ]) - rm -f conftest.out - ]) - case "$gl_cv_cc_double_expbit0" in - word*bit*) - word=`echo "$gl_cv_cc_double_expbit0" | sed -e 's/word //' -e 's/ bit.*//'` - bit=`echo "$gl_cv_cc_double_expbit0" | sed -e 's/word.*bit //'` - AC_DEFINE_UNQUOTED([DBL_EXPBIT0_WORD], [$word], - [Define as the word index where to find the exponent of 'double'.]) - AC_DEFINE_UNQUOTED([DBL_EXPBIT0_BIT], [$bit], - [Define as the bit index in the word where to find bit 0 of the exponent of 'double'.]) - ;; - esac -]) diff --git a/m4/extensions.m4 b/m4/extensions.m4 deleted file mode 100644 index 07ba376c0..000000000 --- a/m4/extensions.m4 +++ /dev/null @@ -1,138 +0,0 @@ -# serial 13 -*- Autoconf -*- -# Enable extensions on systems that normally disable them. - -# Copyright (C) 2003, 2006-2013 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from CVS -# Autoconf. Perhaps we can remove this once we can assume Autoconf -# 2.70 or later everywhere, but since Autoconf mutates rapidly -# enough in this area it's likely we'll need to redefine -# AC_USE_SYSTEM_EXTENSIONS for quite some time. - -# If autoconf reports a warning -# warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS -# or warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS -# the fix is -# 1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked -# but always AC_REQUIREd, -# 2) to ensure that for each occurrence of -# AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) -# or -# AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) -# the corresponding gnulib module description has 'extensions' among -# its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS -# invocation occurs in gl_EARLY, not in gl_INIT. - -# AC_USE_SYSTEM_EXTENSIONS -# ------------------------ -# Enable extensions on systems that normally disable them, -# typically due to standards-conformance issues. -# -# Remember that #undef in AH_VERBATIM gets replaced with #define by -# AC_DEFINE. The goal here is to define all known feature-enabling -# macros, then, if reports of conflicts are made, disable macros that -# cause problems on some platforms (such as __EXTENSIONS__). -AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], -[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl -AC_BEFORE([$0], [AC_RUN_IFELSE])dnl - - AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) - if test "$MINIX" = yes; then - AC_DEFINE([_POSIX_SOURCE], [1], - [Define to 1 if you need to in order for 'stat' and other - things to work.]) - AC_DEFINE([_POSIX_1_SOURCE], [2], - [Define to 2 if the system does not provide POSIX.1 features - except with this defined.]) - AC_DEFINE([_MINIX], [1], - [Define to 1 if on MINIX.]) - AC_DEFINE([_NETBSD_SOURCE], [1], - [Define to 1 to make NetBSD features available. MINIX 3 needs this.]) - fi - -dnl Use a different key than __EXTENSIONS__, as that name broke existing -dnl configure.ac when using autoheader 2.62. - AH_VERBATIM([USE_SYSTEM_EXTENSIONS], -[/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable general extensions on OS X. */ -#ifndef _DARWIN_C_SOURCE -# undef _DARWIN_C_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable X/Open extensions if necessary. HP-UX 11.11 defines - mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of - whether compiling with -Ae or -D_HPUX_SOURCE=1. */ -#ifndef _XOPEN_SOURCE -# undef _XOPEN_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif -]) - AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], - [ac_cv_safe_to_define___extensions__], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ -# define __EXTENSIONS__ 1 - ]AC_INCLUDES_DEFAULT])], - [ac_cv_safe_to_define___extensions__=yes], - [ac_cv_safe_to_define___extensions__=no])]) - test $ac_cv_safe_to_define___extensions__ = yes && - AC_DEFINE([__EXTENSIONS__]) - AC_DEFINE([_ALL_SOURCE]) - AC_DEFINE([_DARWIN_C_SOURCE]) - AC_DEFINE([_GNU_SOURCE]) - AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) - AC_DEFINE([_TANDEM_SOURCE]) - AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined], - [ac_cv_should_define__xopen_source], - [ac_cv_should_define__xopen_source=no - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ - #include - mbstate_t x;]])], - [], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ - #define _XOPEN_SOURCE 500 - #include - mbstate_t x;]])], - [ac_cv_should_define__xopen_source=yes])])]) - test $ac_cv_should_define__xopen_source = yes && - AC_DEFINE([_XOPEN_SOURCE], [500]) -])# AC_USE_SYSTEM_EXTENSIONS - -# gl_USE_SYSTEM_EXTENSIONS -# ------------------------ -# Enable extensions on systems that normally disable them, -# typically due to standards-conformance issues. -AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], -[ - dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS. - dnl gnulib does not need it. But if it gets required by third-party macros - dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a - dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". - dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE, - dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck. - AC_REQUIRE([AC_GNU_SOURCE]) - - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) -]) diff --git a/m4/extern-inline.m4 b/m4/extern-inline.m4 deleted file mode 100644 index e74339a16..000000000 --- a/m4/extern-inline.m4 +++ /dev/null @@ -1,100 +0,0 @@ -dnl 'extern inline' a la ISO C99. - -dnl Copyright 2012-2015 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_EXTERN_INLINE], -[ - AH_VERBATIM([extern_inline], -[/* Please see the Gnulib manual for how to use these macros. - - Suppress extern inline with HP-UX cc, as it appears to be broken; see - . - - Suppress extern inline with Sun C in standards-conformance mode, as it - mishandles inline functions that call each other. E.g., for 'inline void f - (void) { } inline void g (void) { f (); }', c99 incorrectly complains - 'reference to static identifier "f" in extern inline function'. - This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16. - - Suppress extern inline (with or without __attribute__ ((__gnu_inline__))) - on configurations that mistakenly use 'static inline' to implement - functions or macros in standard C headers like . For example, - if isdigit is mistakenly implemented via a static inline function, - a program containing an extern inline function that calls isdigit - may not work since the C standard prohibits extern inline functions - from calling static functions. This bug is known to occur on: - - OS X 10.8 and earlier; see: - http://lists.gnu.org/archive/html/bug-gnulib/2012-12/msg00023.html - - DragonFly; see - http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log - - FreeBSD; see: - http://lists.gnu.org/archive/html/bug-gnulib/2014-07/msg00104.html - - OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and - for clang but remains for g++; see . - Assume DragonFly and FreeBSD will be similar. */ -#if (((defined __APPLE__ && defined __MACH__) \ - || defined __DragonFly__ || defined __FreeBSD__) \ - && (defined __header_inline \ - ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \ - && ! defined __clang__) \ - : ((! defined _DONT_USE_CTYPE_INLINE_ \ - && (defined __GNUC__ || defined __cplusplus)) \ - || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \ - && defined __GNUC__ && ! defined __cplusplus)))) -# define _GL_EXTERN_INLINE_STDHEADER_BUG -#endif -#if ((__GNUC__ \ - ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ - : (199901L <= __STDC_VERSION__ \ - && !defined __HP_cc \ - && !(defined __SUNPRO_C && __STDC__))) \ - && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) -# define _GL_INLINE inline -# define _GL_EXTERN_INLINE extern inline -# define _GL_EXTERN_INLINE_IN_USE -#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \ - && !defined _GL_EXTERN_INLINE_STDHEADER_BUG) -# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__ - /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */ -# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) -# else -# define _GL_INLINE extern inline -# endif -# define _GL_EXTERN_INLINE extern -# define _GL_EXTERN_INLINE_IN_USE -#else -# define _GL_INLINE static _GL_UNUSED -# define _GL_EXTERN_INLINE static _GL_UNUSED -#endif - -/* In GCC, suppress bogus "no previous prototype for 'FOO'" - and "no previous declaration for 'FOO'" diagnostics, - when FOO is an inline function in the header; see - and - . */ -#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) -# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ -# define _GL_INLINE_HEADER_CONST_PRAGMA -# else -# define _GL_INLINE_HEADER_CONST_PRAGMA \ - _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") -# endif -# define _GL_INLINE_HEADER_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \ - _GL_INLINE_HEADER_CONST_PRAGMA -# define _GL_INLINE_HEADER_END \ - _Pragma ("GCC diagnostic pop") -#else -# define _GL_INLINE_HEADER_BEGIN -# define _GL_INLINE_HEADER_END -#endif]) -]) diff --git a/m4/fcntl-o.m4 b/m4/fcntl-o.m4 deleted file mode 100644 index 87cc4bd2d..000000000 --- a/m4/fcntl-o.m4 +++ /dev/null @@ -1,134 +0,0 @@ -# fcntl-o.m4 serial 4 -dnl Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Written by Paul Eggert. - -# Test whether the flags O_NOATIME and O_NOFOLLOW actually work. -# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise. -# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise. -AC_DEFUN([gl_FCNTL_O_FLAGS], -[ - dnl Persuade glibc to define O_NOATIME and O_NOFOLLOW. - dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes - dnl AC_GNU_SOURCE. - m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], - [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], - [AC_REQUIRE([AC_GNU_SOURCE])]) - - AC_CHECK_HEADERS_ONCE([unistd.h]) - AC_CHECK_FUNCS_ONCE([symlink]) - AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include - #if HAVE_UNISTD_H - # include - #else /* on Windows with MSVC */ - # include - # include - # defined sleep(n) _sleep ((n) * 1000) - #endif - #include - #ifndef O_NOATIME - #define O_NOATIME 0 - #endif - #ifndef O_NOFOLLOW - #define O_NOFOLLOW 0 - #endif - static int const constants[] = - { - O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, - O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY - }; - ]], - [[ - int result = !constants; - #if HAVE_SYMLINK - { - static char const sym[] = "conftest.sym"; - if (symlink ("/dev/null", sym) != 0) - result |= 2; - else - { - int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); - if (fd >= 0) - { - close (fd); - result |= 4; - } - } - if (unlink (sym) != 0 || symlink (".", sym) != 0) - result |= 2; - else - { - int fd = open (sym, O_RDONLY | O_NOFOLLOW); - if (fd >= 0) - { - close (fd); - result |= 4; - } - } - unlink (sym); - } - #endif - { - static char const file[] = "confdefs.h"; - int fd = open (file, O_RDONLY | O_NOATIME); - if (fd < 0) - result |= 8; - else - { - struct stat st0; - if (fstat (fd, &st0) != 0) - result |= 16; - else - { - char c; - sleep (1); - if (read (fd, &c, 1) != 1) - result |= 24; - else - { - if (close (fd) != 0) - result |= 32; - else - { - struct stat st1; - if (stat (file, &st1) != 0) - result |= 40; - else - if (st0.st_atime != st1.st_atime) - result |= 64; - } - } - } - } - } - return result;]])], - [gl_cv_header_working_fcntl_h=yes], - [case $? in #( - 4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( - 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( - 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( - *) gl_cv_header_working_fcntl_h='no';; - esac], - [gl_cv_header_working_fcntl_h=cross-compiling])]) - - case $gl_cv_header_working_fcntl_h in #( - *O_NOATIME* | no | cross-compiling) ac_val=0;; #( - *) ac_val=1;; - esac - AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val], - [Define to 1 if O_NOATIME works.]) - - case $gl_cv_header_working_fcntl_h in #( - *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( - *) ac_val=1;; - esac - AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val], - [Define to 1 if O_NOFOLLOW works.]) -]) diff --git a/m4/float_h.m4 b/m4/float_h.m4 deleted file mode 100644 index 397f2d1fa..000000000 --- a/m4/float_h.m4 +++ /dev/null @@ -1,98 +0,0 @@ -# float_h.m4 serial 9 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FLOAT_H], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - FLOAT_H= - REPLACE_FLOAT_LDBL=0 - case "$host_os" in - aix* | beos* | openbsd* | mirbsd* | irix*) - FLOAT_H=float.h - ;; - freebsd*) - case "$host_cpu" in -changequote(,)dnl - i[34567]86 ) -changequote([,])dnl - FLOAT_H=float.h - ;; - x86_64 ) - # On x86_64 systems, the C compiler may still be generating - # 32-bit code. - AC_EGREP_CPP([yes], - [#if defined __LP64__ || defined __x86_64__ || defined __amd64__ - yes - #endif], - [], - [FLOAT_H=float.h]) - ;; - esac - ;; - linux*) - case "$host_cpu" in - powerpc*) - FLOAT_H=float.h - ;; - esac - ;; - esac - case "$host_os" in - aix* | freebsd* | linux*) - if test -n "$FLOAT_H"; then - REPLACE_FLOAT_LDBL=1 - fi - ;; - esac - - dnl Test against glibc-2.7 Linux/SPARC64 bug. - REPLACE_ITOLD=0 - AC_CACHE_CHECK([whether conversion from 'int' to 'long double' works], - [gl_cv_func_itold_works], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -int i = -1; -volatile long double ld; -int main () -{ - ld += i * 1.0L; - if (ld > 0) - return 1; - return 0; -}]])], - [gl_cv_func_itold_works=yes], - [gl_cv_func_itold_works=no], - [case "$host" in - sparc*-*-linux*) - AC_EGREP_CPP([yes], - [#if defined __LP64__ || defined __arch64__ - yes - #endif], - [gl_cv_func_itold_works="guessing no"], - [gl_cv_func_itold_works="guessing yes"]) - ;; - *) gl_cv_func_itold_works="guessing yes" ;; - esac - ]) - ]) - case "$gl_cv_func_itold_works" in - *no) - REPLACE_ITOLD=1 - dnl We add the workaround to but also to , - dnl to increase the chances that the fix function gets pulled in. - FLOAT_H=float.h - ;; - esac - - if test -n "$FLOAT_H"; then - gl_NEXT_HEADERS([float.h]) - fi - AC_SUBST([FLOAT_H]) - AM_CONDITIONAL([GL_GENERATE_FLOAT_H], [test -n "$FLOAT_H"]) - AC_SUBST([REPLACE_ITOLD]) -]) diff --git a/m4/fnmatch.m4 b/m4/fnmatch.m4 deleted file mode 100644 index fa0ba4d22..000000000 --- a/m4/fnmatch.m4 +++ /dev/null @@ -1,156 +0,0 @@ -# Check for fnmatch - serial 9. - -# Copyright (C) 2000-2007, 2009-2013 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Autoconf defines AC_FUNC_FNMATCH, but that is obsolescent. -# New applications should use the macros below instead. - -# Request a POSIX compliant fnmatch function. -AC_DEFUN([gl_FUNC_FNMATCH_POSIX], -[ - m4_divert_text([DEFAULTS], [gl_fnmatch_required=POSIX]) - - dnl Persuade glibc to declare FNM_CASEFOLD etc. - dnl This is only needed if gl_fnmatch_required = GNU. It would be possible - dnl to avoid this dependency for gl_FUNC_FNMATCH_POSIX by putting - dnl gl_FUNC_FNMATCH_GNU into a separate .m4 file. - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - FNMATCH_H= - gl_fnmatch_required_lowercase=` - echo $gl_fnmatch_required | LC_ALL=C tr '[[A-Z]]' '[[a-z]]' - ` - gl_fnmatch_cache_var="gl_cv_func_fnmatch_${gl_fnmatch_required_lowercase}" - AC_CACHE_CHECK([for working $gl_fnmatch_required fnmatch], - [$gl_fnmatch_cache_var], - [dnl Some versions of Solaris, SCO, and the GNU C Library - dnl have a broken or incompatible fnmatch. - dnl So we run a test program. If we are cross-compiling, take no chance. - dnl Thanks to John Oleynick, François Pinard, and Paul Eggert for this - dnl test. - if test $gl_fnmatch_required = GNU; then - gl_fnmatch_gnu_start= - gl_fnmatch_gnu_end= - else - gl_fnmatch_gnu_start='#if 0' - gl_fnmatch_gnu_end='#endif' - fi - AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#include - static int - y (char const *pattern, char const *string, int flags) - { - return fnmatch (pattern, string, flags) == 0; - } - static int - n (char const *pattern, char const *string, int flags) - { - return fnmatch (pattern, string, flags) == FNM_NOMATCH; - } - ]], - [[char const *Apat = 'A' < '\\\\' ? "[A-\\\\\\\\]" : "[\\\\\\\\-A]"; - char const *apat = 'a' < '\\\\' ? "[a-\\\\\\\\]" : "[\\\\\\\\-a]"; - static char const A_1[] = { 'A' - 1, 0 }; - static char const A01[] = { 'A' + 1, 0 }; - static char const a_1[] = { 'a' - 1, 0 }; - static char const a01[] = { 'a' + 1, 0 }; - static char const bs_1[] = { '\\\\' - 1, 0 }; - static char const bs01[] = { '\\\\' + 1, 0 }; - int result = 0; - if (!n ("a*", "", 0)) - return 1; - if (!y ("a*", "abc", 0)) - return 1; - if (!y ("[/b", "[/b", 0)) /*"]]"*/ /* glibc Bugzilla bug 12378 */ - return 1; - if (!n ("d*/*1", "d/s/1", FNM_PATHNAME)) - return 2; - if (!y ("a\\\\bc", "abc", 0)) - return 3; - if (!n ("a\\\\bc", "abc", FNM_NOESCAPE)) - return 3; - if (!y ("*x", ".x", 0)) - return 4; - if (!n ("*x", ".x", FNM_PERIOD)) - return 4; - if (!y (Apat, "\\\\", 0)) - return 5; - if (!y (Apat, "A", 0)) - return 5; - if (!y (apat, "\\\\", 0)) - return 5; - if (!y (apat, "a", 0)) - return 5; - if (!(n (Apat, A_1, 0) == ('A' < '\\\\'))) - return 5; - if (!(n (apat, a_1, 0) == ('a' < '\\\\'))) - return 5; - if (!(y (Apat, A01, 0) == ('A' < '\\\\'))) - return 5; - if (!(y (apat, a01, 0) == ('a' < '\\\\'))) - return 5; - if (!(y (Apat, bs_1, 0) == ('A' < '\\\\'))) - return 5; - if (!(y (apat, bs_1, 0) == ('a' < '\\\\'))) - return 5; - if (!(n (Apat, bs01, 0) == ('A' < '\\\\'))) - return 5; - if (!(n (apat, bs01, 0) == ('a' < '\\\\'))) - return 5; - $gl_fnmatch_gnu_start - if (!y ("xxXX", "xXxX", FNM_CASEFOLD)) - result |= 8; - if (!y ("a++(x|yy)b", "a+xyyyyxb", FNM_EXTMATCH)) - result |= 16; - if (!n ("d*/*1", "d/s/1", FNM_FILE_NAME)) - result |= 32; - if (!y ("*", "x", FNM_FILE_NAME | FNM_LEADING_DIR)) - result |= 64; - if (!y ("x*", "x/y/z", FNM_FILE_NAME | FNM_LEADING_DIR)) - result |= 64; - if (!y ("*c*", "c/x", FNM_FILE_NAME | FNM_LEADING_DIR)) - result |= 64; - $gl_fnmatch_gnu_end - return result; - ]])], - [eval "$gl_fnmatch_cache_var=yes"], - [eval "$gl_fnmatch_cache_var=no"], - [eval "$gl_fnmatch_cache_var=\"guessing no\""]) - ]) - eval "gl_fnmatch_result=\"\$$gl_fnmatch_cache_var\"" - if test "$gl_fnmatch_result" = yes; then - dnl Not strictly necessary. Only to avoid spurious leftover files if people - dnl don't do "make distclean". - rm -f "$gl_source_base/fnmatch.h" - else - FNMATCH_H=fnmatch.h - fi - AC_SUBST([FNMATCH_H]) - AM_CONDITIONAL([GL_GENERATE_FNMATCH_H], [test -n "$FNMATCH_H"]) -]) - -# Request a POSIX compliant fnmatch function with GNU extensions. -AC_DEFUN([gl_FUNC_FNMATCH_GNU], -[ - m4_divert_text([INIT_PREPARE], [gl_fnmatch_required=GNU]) - - AC_REQUIRE([gl_FUNC_FNMATCH_POSIX]) -]) - -AC_DEFUN([gl_PREREQ_FNMATCH], -[ - dnl We must choose a different name for our function, since on ELF systems - dnl a broken fnmatch() in libc.so would override our fnmatch() if it is - dnl compiled into a shared library. - AC_DEFINE_UNQUOTED([fnmatch], [${gl_fnmatch_required_lowercase}_fnmatch], - [Define to a replacement function name for fnmatch().]) - dnl Prerequisites of lib/fnmatch.c. - AC_REQUIRE([AC_TYPE_MBSTATE_T]) - AC_CHECK_DECLS([isblank], [], [], [[#include ]]) - AC_CHECK_FUNCS_ONCE([btowc isblank iswctype mbsrtowcs mempcpy wmemchr wmemcpy wmempcpy]) - AC_CHECK_HEADERS_ONCE([wctype.h]) -]) diff --git a/m4/getdelim.m4 b/m4/getdelim.m4 deleted file mode 100644 index 36f66a108..000000000 --- a/m4/getdelim.m4 +++ /dev/null @@ -1,88 +0,0 @@ -# getdelim.m4 serial 10 - -dnl Copyright (C) 2005-2007, 2009-2013 Free Software Foundation, Inc. -dnl -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_PREREQ([2.59]) - -AC_DEFUN([gl_FUNC_GETDELIM], -[ - AC_REQUIRE([gl_STDIO_H_DEFAULTS]) - - dnl Persuade glibc to declare getdelim(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_CHECK_DECLS_ONCE([getdelim]) - - AC_CHECK_FUNCS_ONCE([getdelim]) - if test $ac_cv_func_getdelim = yes; then - HAVE_GETDELIM=1 - dnl Found it in some library. Verify that it works. - AC_CACHE_CHECK([for working getdelim function], [gl_cv_func_working_getdelim], - [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data - AC_RUN_IFELSE([AC_LANG_SOURCE([[ -# include -# include -# include - int main () - { - FILE *in = fopen ("./conftest.data", "r"); - if (!in) - return 1; - { - /* Test result for a NULL buffer and a zero size. - Based on a test program from Karl Heuer. */ - char *line = NULL; - size_t siz = 0; - int len = getdelim (&line, &siz, '\n', in); - if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) - return 2; - } - { - /* Test result for a NULL buffer and a non-zero size. - This crashes on FreeBSD 8.0. */ - char *line = NULL; - size_t siz = (size_t)(~0) / 4; - if (getdelim (&line, &siz, '\n', in) == -1) - return 3; - } - return 0; - } - ]])], [gl_cv_func_working_getdelim=yes] dnl The library version works. - , [gl_cv_func_working_getdelim=no] dnl The library version does NOT work. - , dnl We're cross compiling. Assume it works on glibc2 systems. - [AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) && !defined __UCLIBC__ - Lucky GNU user - #endif -#endif - ], - [gl_cv_func_working_getdelim="guessing yes"], - [gl_cv_func_working_getdelim="guessing no"])] - )]) - case "$gl_cv_func_working_getdelim" in - *no) - REPLACE_GETDELIM=1 - ;; - esac - else - HAVE_GETDELIM=0 - fi - - if test $ac_cv_have_decl_getdelim = no; then - HAVE_DECL_GETDELIM=0 - fi -]) - -# Prerequisites of lib/getdelim.c. -AC_DEFUN([gl_PREREQ_GETDELIM], -[ - AC_CHECK_FUNCS([flockfile funlockfile]) - AC_CHECK_DECLS([getc_unlocked]) -]) diff --git a/m4/getline.m4 b/m4/getline.m4 deleted file mode 100644 index 342bc9905..000000000 --- a/m4/getline.m4 +++ /dev/null @@ -1,96 +0,0 @@ -# getline.m4 serial 26 - -dnl Copyright (C) 1998-2003, 2005-2007, 2009-2013 Free Software Foundation, -dnl Inc. -dnl -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_PREREQ([2.59]) - -dnl See if there's a working, system-supplied version of the getline function. -dnl We can't just do AC_REPLACE_FUNCS([getline]) because some systems -dnl have a function by that name in -linet that doesn't have anything -dnl to do with the function we need. -AC_DEFUN([gl_FUNC_GETLINE], -[ - AC_REQUIRE([gl_STDIO_H_DEFAULTS]) - - dnl Persuade glibc to declare getline(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_CHECK_DECLS_ONCE([getline]) - - gl_getline_needs_run_time_check=no - AC_CHECK_FUNC([getline], - [dnl Found it in some library. Verify that it works. - gl_getline_needs_run_time_check=yes], - [am_cv_func_working_getline=no]) - if test $gl_getline_needs_run_time_check = yes; then - AC_CACHE_CHECK([for working getline function], [am_cv_func_working_getline], - [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data - AC_RUN_IFELSE([AC_LANG_SOURCE([[ -# include -# include -# include - int main () - { - FILE *in = fopen ("./conftest.data", "r"); - if (!in) - return 1; - { - /* Test result for a NULL buffer and a zero size. - Based on a test program from Karl Heuer. */ - char *line = NULL; - size_t siz = 0; - int len = getline (&line, &siz, in); - if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) - return 2; - } - { - /* Test result for a NULL buffer and a non-zero size. - This crashes on FreeBSD 8.0. */ - char *line = NULL; - size_t siz = (size_t)(~0) / 4; - if (getline (&line, &siz, in) == -1) - return 3; - } - return 0; - } - ]])], [am_cv_func_working_getline=yes] dnl The library version works. - , [am_cv_func_working_getline=no] dnl The library version does NOT work. - , dnl We're cross compiling. Assume it works on glibc2 systems. - [AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) && !defined __UCLIBC__ - Lucky GNU user - #endif -#endif - ], - [am_cv_func_working_getline="guessing yes"], - [am_cv_func_working_getline="guessing no"])] - )]) - fi - - if test $ac_cv_have_decl_getline = no; then - HAVE_DECL_GETLINE=0 - fi - - case "$am_cv_func_working_getline" in - *no) - dnl Set REPLACE_GETLINE always: Even if we have not found the broken - dnl getline function among $LIBS, it may exist in libinet and the - dnl executable may be linked with -linet. - REPLACE_GETLINE=1 - ;; - esac -]) - -# Prerequisites of lib/getline.c. -AC_DEFUN([gl_PREREQ_GETLINE], -[ - : -]) diff --git a/m4/getopt.m4 b/m4/getopt.m4 deleted file mode 100644 index 50f450919..000000000 --- a/m4/getopt.m4 +++ /dev/null @@ -1,368 +0,0 @@ -# getopt.m4 serial 44 -dnl Copyright (C) 2002-2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Request a POSIX compliant getopt function. -AC_DEFUN([gl_FUNC_GETOPT_POSIX], -[ - m4_divert_text([DEFAULTS], [gl_getopt_required=POSIX]) - AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) - AC_REQUIRE([gl_GETOPT_CHECK_HEADERS]) - dnl Other modules can request the gnulib implementation of the getopt - dnl functions unconditionally, by defining gl_REPLACE_GETOPT_ALWAYS. - dnl argp.m4 does this. - m4_ifdef([gl_REPLACE_GETOPT_ALWAYS], [ - REPLACE_GETOPT=1 - ], [ - REPLACE_GETOPT=0 - if test -n "$gl_replace_getopt"; then - REPLACE_GETOPT=1 - fi - ]) - if test $REPLACE_GETOPT = 1; then - dnl Arrange for getopt.h to be created. - gl_GETOPT_SUBSTITUTE_HEADER - fi -]) - -# Request a POSIX compliant getopt function with GNU extensions (such as -# options with optional arguments) and the functions getopt_long, -# getopt_long_only. -AC_DEFUN([gl_FUNC_GETOPT_GNU], -[ - m4_divert_text([INIT_PREPARE], [gl_getopt_required=GNU]) - - AC_REQUIRE([gl_FUNC_GETOPT_POSIX]) -]) - -# Determine whether to replace the entire getopt facility. -AC_DEFUN([gl_GETOPT_CHECK_HEADERS], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_REQUIRE([AC_PROG_AWK]) dnl for awk that supports ENVIRON - - dnl Persuade Solaris to declare optarg, optind, opterr, optopt. - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - gl_CHECK_NEXT_HEADERS([getopt.h]) - if test $ac_cv_header_getopt_h = yes; then - HAVE_GETOPT_H=1 - else - HAVE_GETOPT_H=0 - fi - AC_SUBST([HAVE_GETOPT_H]) - - gl_replace_getopt= - - dnl Test whether is available. - if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then - AC_CHECK_HEADERS([getopt.h], [], [gl_replace_getopt=yes]) - fi - - dnl Test whether the function getopt_long is available. - if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then - AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes]) - fi - - dnl POSIX 2008 does not specify leading '+' behavior, but see - dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on - dnl the next version of POSIX. For now, we only guarantee leading '+' - dnl behavior with getopt-gnu. - if test -z "$gl_replace_getopt"; then - AC_CACHE_CHECK([whether getopt is POSIX compatible], - [gl_cv_func_getopt_posix], - [ - dnl Merging these three different test programs into a single one - dnl would require a reset mechanism. On BSD systems, it can be done - dnl through 'optreset'; on some others (glibc), it can be done by - dnl setting 'optind' to 0; on others again (HP-UX, IRIX, OSF/1, - dnl Solaris 9, musl libc), there is no such mechanism. - if test $cross_compiling = no; then - dnl Sanity check. Succeeds everywhere (except on MSVC, - dnl which lacks and getopt() entirely). - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include - -int -main () -{ - static char program[] = "program"; - static char a[] = "-a"; - static char foo[] = "foo"; - static char bar[] = "bar"; - char *argv[] = { program, a, foo, bar, NULL }; - int c; - - c = getopt (4, argv, "ab"); - if (!(c == 'a')) - return 1; - c = getopt (4, argv, "ab"); - if (!(c == -1)) - return 2; - if (!(optind == 2)) - return 3; - return 0; -} -]])], - [gl_cv_func_getopt_posix=maybe], - [gl_cv_func_getopt_posix=no]) - if test $gl_cv_func_getopt_posix = maybe; then - dnl Sanity check with '+'. Succeeds everywhere (except on MSVC, - dnl which lacks and getopt() entirely). - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include - -int -main () -{ - static char program[] = "program"; - static char donald[] = "donald"; - static char p[] = "-p"; - static char billy[] = "billy"; - static char duck[] = "duck"; - static char a[] = "-a"; - static char bar[] = "bar"; - char *argv[] = { program, donald, p, billy, duck, a, bar, NULL }; - int c; - - c = getopt (7, argv, "+abp:q:"); - if (!(c == -1)) - return 4; - if (!(strcmp (argv[0], "program") == 0)) - return 5; - if (!(strcmp (argv[1], "donald") == 0)) - return 6; - if (!(strcmp (argv[2], "-p") == 0)) - return 7; - if (!(strcmp (argv[3], "billy") == 0)) - return 8; - if (!(strcmp (argv[4], "duck") == 0)) - return 9; - if (!(strcmp (argv[5], "-a") == 0)) - return 10; - if (!(strcmp (argv[6], "bar") == 0)) - return 11; - if (!(optind == 1)) - return 12; - return 0; -} -]])], - [gl_cv_func_getopt_posix=maybe], - [gl_cv_func_getopt_posix=no]) - fi - if test $gl_cv_func_getopt_posix = maybe; then - dnl Detect Mac OS X 10.5, AIX 7.1, mingw bug. - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include - -int -main () -{ - static char program[] = "program"; - static char ab[] = "-ab"; - char *argv[3] = { program, ab, NULL }; - if (getopt (2, argv, "ab:") != 'a') - return 13; - if (getopt (2, argv, "ab:") != '?') - return 14; - if (optopt != 'b') - return 15; - if (optind != 2) - return 16; - return 0; -} -]])], - [gl_cv_func_getopt_posix=yes], - [gl_cv_func_getopt_posix=no]) - fi - else - case "$host_os" in - darwin* | aix* | mingw*) gl_cv_func_getopt_posix="guessing no";; - *) gl_cv_func_getopt_posix="guessing yes";; - esac - fi - ]) - case "$gl_cv_func_getopt_posix" in - *no) gl_replace_getopt=yes ;; - esac - fi - - if test -z "$gl_replace_getopt" && test $gl_getopt_required = GNU; then - AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_getopt_gnu], - [# Even with POSIXLY_CORRECT, the GNU extension of leading '-' in the - # optstring is necessary for programs like m4 that have POSIX-mandated - # semantics for supporting options interspersed with files. - # Also, since getopt_long is a GNU extension, we require optind=0. - # Bash ties 'set -o posix' to a non-exported POSIXLY_CORRECT; - # so take care to revert to the correct (non-)export state. -dnl GNU Coding Standards currently allow awk but not env; besides, env -dnl is ambiguous with environment values that contain newlines. - gl_awk_probe='BEGIN { if ("POSIXLY_CORRECT" in ENVIRON) print "x" }' - case ${POSIXLY_CORRECT+x}`$AWK "$gl_awk_probe" - #include - #include - ]GL_NOCRASH[ - ]], [[ - int result = 0; - - nocrash_init(); - - /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, - and fails on Mac OS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, - OSF/1 5.1, Solaris 10. */ - { - static char conftest[] = "conftest"; - static char plus[] = "-+"; - char *argv[3] = { conftest, plus, NULL }; - opterr = 0; - if (getopt (2, argv, "+a") != '?') - result |= 1; - } - /* This code succeeds on glibc 2.8, mingw, - and fails on Mac OS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, - IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ - { - static char program[] = "program"; - static char p[] = "-p"; - static char foo[] = "foo"; - static char bar[] = "bar"; - char *argv[] = { program, p, foo, bar, NULL }; - - optind = 1; - if (getopt (4, argv, "p::") != 'p') - result |= 2; - else if (optarg != NULL) - result |= 4; - else if (getopt (4, argv, "p::") != -1) - result |= 6; - else if (optind != 2) - result |= 8; - } - /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */ - { - static char program[] = "program"; - static char foo[] = "foo"; - static char p[] = "-p"; - char *argv[] = { program, foo, p, NULL }; - optind = 0; - if (getopt (3, argv, "-p") != 1) - result |= 16; - else if (getopt (3, argv, "-p") != 'p') - result |= 16; - } - /* This code fails on glibc 2.11. */ - { - static char program[] = "program"; - static char b[] = "-b"; - static char a[] = "-a"; - char *argv[] = { program, b, a, NULL }; - optind = opterr = 0; - if (getopt (3, argv, "+:a:b") != 'b') - result |= 32; - else if (getopt (3, argv, "+:a:b") != ':') - result |= 32; - } - /* This code dumps core on glibc 2.14. */ - { - static char program[] = "program"; - static char w[] = "-W"; - static char dummy[] = "dummy"; - char *argv[] = { program, w, dummy, NULL }; - optind = opterr = 1; - if (getopt (3, argv, "W;") != 'W') - result |= 64; - } - return result; - ]])], - [gl_cv_func_getopt_gnu=yes], - [gl_cv_func_getopt_gnu=no], - [dnl Cross compiling. Assume the worst, even on glibc platforms. - gl_cv_func_getopt_gnu="guessing no" - ]) - case $gl_had_POSIXLY_CORRECT in - exported) ;; - yes) AS_UNSET([POSIXLY_CORRECT]); POSIXLY_CORRECT=1 ;; - *) AS_UNSET([POSIXLY_CORRECT]) ;; - esac - ]) - if test "$gl_cv_func_getopt_gnu" != yes; then - gl_replace_getopt=yes - else - AC_CACHE_CHECK([for working GNU getopt_long function], - [gl_cv_func_getopt_long_gnu], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include - #include - ]], - [[static const struct option long_options[] = - { - { "xtremely-",no_argument, NULL, 1003 }, - { "xtra", no_argument, NULL, 1001 }, - { "xtreme", no_argument, NULL, 1002 }, - { "xtremely", no_argument, NULL, 1003 }, - { NULL, 0, NULL, 0 } - }; - /* This code fails on OpenBSD 5.0. */ - { - static char program[] = "program"; - static char xtremel[] = "--xtremel"; - char *argv[] = { program, xtremel, NULL }; - int option_index; - optind = 1; opterr = 0; - if (getopt_long (2, argv, "", long_options, &option_index) != 1003) - return 1; - } - return 0; - ]])], - [gl_cv_func_getopt_long_gnu=yes], - [gl_cv_func_getopt_long_gnu=no], - [dnl Cross compiling. Guess no on OpenBSD, yes otherwise. - case "$host_os" in - openbsd*) gl_cv_func_getopt_long_gnu="guessing no";; - *) gl_cv_func_getopt_long_gnu="guessing yes";; - esac - ]) - ]) - case "$gl_cv_func_getopt_long_gnu" in - *yes) ;; - *) gl_replace_getopt=yes ;; - esac - fi - fi -]) - -AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], -[ - GETOPT_H=getopt.h - AC_DEFINE([__GETOPT_PREFIX], [[rpl_]], - [Define to rpl_ if the getopt replacement functions and variables - should be used.]) - AC_SUBST([GETOPT_H]) -]) - -# Prerequisites of lib/getopt*. -AC_DEFUN([gl_PREREQ_GETOPT], -[ - AC_CHECK_DECLS_ONCE([getenv]) -]) diff --git a/m4/gettext.m4 b/m4/gettext.m4 deleted file mode 100644 index 8d1f0665c..000000000 --- a/m4/gettext.m4 +++ /dev/null @@ -1,401 +0,0 @@ -# gettext.m4 serial 66 (gettext-0.18.2) -dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2006, 2008-2010. - -dnl Macro to add for using GNU gettext. - -dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). -dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The -dnl default (if it is not specified or empty) is 'no-libtool'. -dnl INTLSYMBOL should be 'external' for packages with no intl directory, -dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. -dnl If INTLSYMBOL is 'use-libtool', then a libtool library -dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, -dnl depending on --{enable,disable}-{shared,static} and on the presence of -dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library -dnl $(top_builddir)/intl/libintl.a will be created. -dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext -dnl implementations (in libc or libintl) without the ngettext() function -dnl will be ignored. If NEEDSYMBOL is specified and is -dnl 'need-formatstring-macros', then GNU gettext implementations that don't -dnl support the ISO C 99 formatstring macros will be ignored. -dnl INTLDIR is used to find the intl libraries. If empty, -dnl the value '$(top_builddir)/intl/' is used. -dnl -dnl The result of the configuration is one of three cases: -dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled -dnl and used. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 2) GNU gettext has been found in the system's C library. -dnl Catalog format: GNU --> install in $(datadir) -dnl Catalog extension: .mo after installation, .gmo in source tree -dnl 3) No internationalization, always use English msgid. -dnl Catalog format: none -dnl Catalog extension: none -dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. -dnl The use of .gmo is historical (it was needed to avoid overwriting the -dnl GNU format catalogs when building on a platform with an X/Open gettext), -dnl but we keep it in order not to force irrelevant filename changes on the -dnl maintainers. -dnl -AC_DEFUN([AM_GNU_GETTEXT], -[ - dnl Argument checking. - ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , - [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT -])])])])]) - ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], - [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])]) - ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , - [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT -])])])]) - define([gt_included_intl], - ifelse([$1], [external], - ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]), - [yes])) - define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) - gt_NEEDS_INIT - AM_GNU_GETTEXT_NEED([$2]) - - AC_REQUIRE([AM_PO_SUBDIRS])dnl - ifelse(gt_included_intl, yes, [ - AC_REQUIRE([AM_INTL_SUBDIR])dnl - ]) - - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Sometimes libintl requires libiconv, so first search for libiconv. - dnl Ideally we would do this search only after the - dnl if test "$USE_NLS" = "yes"; then - dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then - dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT - dnl the configure script would need to contain the same shell code - dnl again, outside any 'if'. There are two solutions: - dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. - dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. - dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not - dnl documented, we avoid it. - ifelse(gt_included_intl, yes, , [ - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - ]) - - dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation. - gt_INTL_MACOSX - - dnl Set USE_NLS. - AC_REQUIRE([AM_NLS]) - - ifelse(gt_included_intl, yes, [ - BUILD_INCLUDED_LIBINTL=no - USE_INCLUDED_LIBINTL=no - ]) - LIBINTL= - LTLIBINTL= - POSUB= - - dnl Add a version number to the cache macros. - case " $gt_needs " in - *" need-formatstring-macros "*) gt_api_version=3 ;; - *" need-ngettext "*) gt_api_version=2 ;; - *) gt_api_version=1 ;; - esac - gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" - gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" - - dnl If we use NLS figure out what method - if test "$USE_NLS" = "yes"; then - gt_use_preinstalled_gnugettext=no - ifelse(gt_included_intl, yes, [ - AC_MSG_CHECKING([whether included gettext is requested]) - AC_ARG_WITH([included-gettext], - [ --with-included-gettext use the GNU gettext library included here], - nls_cv_force_use_gnu_gettext=$withval, - nls_cv_force_use_gnu_gettext=no) - AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) - - nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" - if test "$nls_cv_force_use_gnu_gettext" != "yes"; then - ]) - dnl User does not insist on using GNU NLS library. Figure out what - dnl to use. If GNU gettext is available we use this. Else we have - dnl to fall back to GNU NLS library. - - if test $gt_api_version -ge 3; then - gt_revision_test_code=' -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -changequote(,)dnl -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -changequote([,])dnl -' - else - gt_revision_test_code= - fi - if test $gt_api_version -ge 2; then - gt_expression_test_code=' + * ngettext ("", "", 0)' - else - gt_expression_test_code= - fi - - AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -$gt_revision_test_code -extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings; - ]], - [[ -bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings - ]])], - [eval "$gt_func_gnugettext_libc=yes"], - [eval "$gt_func_gnugettext_libc=no"])]) - - if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then - dnl Sometimes libintl requires libiconv, so first search for libiconv. - ifelse(gt_included_intl, yes, , [ - AM_ICONV_LINK - ]) - dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL - dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) - dnl because that would add "-liconv" to LIBINTL and LTLIBINTL - dnl even if libiconv doesn't exist. - AC_LIB_LINKFLAGS_BODY([intl]) - AC_CACHE_CHECK([for GNU gettext in libintl], - [$gt_func_gnugettext_libintl], - [gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $INCINTL" - gt_save_LIBS="$LIBS" - LIBS="$LIBS $LIBINTL" - dnl Now see whether libintl exists and does not depend on libiconv. - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -$gt_revision_test_code -extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *); - ]], - [[ -bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") - ]])], - [eval "$gt_func_gnugettext_libintl=yes"], - [eval "$gt_func_gnugettext_libintl=no"]) - dnl Now see whether libintl exists and depends on libiconv. - if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then - LIBS="$LIBS $LIBICONV" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -$gt_revision_test_code -extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *); - ]], - [[ -bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") - ]])], - [LIBINTL="$LIBINTL $LIBICONV" - LTLIBINTL="$LTLIBINTL $LTLIBICONV" - eval "$gt_func_gnugettext_libintl=yes" - ]) - fi - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS"]) - fi - - dnl If an already present or preinstalled GNU gettext() is found, - dnl use it. But if this macro is used in GNU gettext, and GNU - dnl gettext is already preinstalled in libintl, we update this - dnl libintl. (Cf. the install rule in intl/Makefile.in.) - if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ - || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ - && test "$PACKAGE" != gettext-runtime \ - && test "$PACKAGE" != gettext-tools; }; then - gt_use_preinstalled_gnugettext=yes - else - dnl Reset the values set by searching for libintl. - LIBINTL= - LTLIBINTL= - INCINTL= - fi - - ifelse(gt_included_intl, yes, [ - if test "$gt_use_preinstalled_gnugettext" != "yes"; then - dnl GNU gettext is not found in the C library. - dnl Fall back on included GNU gettext library. - nls_cv_use_gnu_gettext=yes - fi - fi - - if test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions used to generate GNU NLS library. - BUILD_INCLUDED_LIBINTL=yes - USE_INCLUDED_LIBINTL=yes - LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" - LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" - LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` - fi - - CATOBJEXT= - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Mark actions to use GNU gettext tools. - CATOBJEXT=.gmo - fi - ]) - - if test -n "$INTL_MACOSX_LIBS"; then - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - dnl Some extra flags are needed during linking. - LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" - LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" - fi - fi - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - AC_DEFINE([ENABLE_NLS], [1], - [Define to 1 if translation of program messages to the user's native language - is requested.]) - else - USE_NLS=no - fi - fi - - AC_MSG_CHECKING([whether to use NLS]) - AC_MSG_RESULT([$USE_NLS]) - if test "$USE_NLS" = "yes"; then - AC_MSG_CHECKING([where the gettext function comes from]) - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then - gt_source="external libintl" - else - gt_source="libc" - fi - else - gt_source="included intl directory" - fi - AC_MSG_RESULT([$gt_source]) - fi - - if test "$USE_NLS" = "yes"; then - - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then - AC_MSG_CHECKING([how to link with libintl]) - AC_MSG_RESULT([$LIBINTL]) - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) - fi - - dnl For backward compatibility. Some packages may be using this. - AC_DEFINE([HAVE_GETTEXT], [1], - [Define if the GNU gettext() function is already present or preinstalled.]) - AC_DEFINE([HAVE_DCGETTEXT], [1], - [Define if the GNU dcgettext() function is already present or preinstalled.]) - fi - - dnl We need to process the po/ directory. - POSUB=po - fi - - ifelse(gt_included_intl, yes, [ - dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL - dnl to 'yes' because some of the testsuite requires it. - if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then - BUILD_INCLUDED_LIBINTL=yes - fi - - dnl Make all variables we use known to autoconf. - AC_SUBST([BUILD_INCLUDED_LIBINTL]) - AC_SUBST([USE_INCLUDED_LIBINTL]) - AC_SUBST([CATOBJEXT]) - - dnl For backward compatibility. Some configure.ins may be using this. - nls_cv_header_intl= - nls_cv_header_libgt= - - dnl For backward compatibility. Some Makefiles may be using this. - DATADIRNAME=share - AC_SUBST([DATADIRNAME]) - - dnl For backward compatibility. Some Makefiles may be using this. - INSTOBJEXT=.mo - AC_SUBST([INSTOBJEXT]) - - dnl For backward compatibility. Some Makefiles may be using this. - GENCAT=gencat - AC_SUBST([GENCAT]) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLOBJS= - if test "$USE_INCLUDED_LIBINTL" = yes; then - INTLOBJS="\$(GETTOBJS)" - fi - AC_SUBST([INTLOBJS]) - - dnl Enable libtool support if the surrounding package wishes it. - INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix - AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX]) - ]) - - dnl For backward compatibility. Some Makefiles may be using this. - INTLLIBS="$LIBINTL" - AC_SUBST([INTLLIBS]) - - dnl Make all documented variables known to autoconf. - AC_SUBST([LIBINTL]) - AC_SUBST([LTLIBINTL]) - AC_SUBST([POSUB]) -]) - - -dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. -m4_define([gt_NEEDS_INIT], -[ - m4_divert_text([DEFAULTS], [gt_needs=]) - m4_define([gt_NEEDS_INIT], []) -]) - - -dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) -AC_DEFUN([AM_GNU_GETTEXT_NEED], -[ - m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) -]) - - -dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) -AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/m4/glibc2.m4 b/m4/glibc2.m4 deleted file mode 100644 index 0e5068266..000000000 --- a/m4/glibc2.m4 +++ /dev/null @@ -1,31 +0,0 @@ -# glibc2.m4 serial 3 -dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Test for the GNU C Library, version 2.0 or newer. -# From Bruno Haible. - -AC_DEFUN([gt_GLIBC2], - [ - AC_CACHE_CHECK([whether we are using the GNU C Library 2 or newer], - [ac_cv_gnu_library_2], - [AC_EGREP_CPP([Lucky GNU user], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ >= 2) && !defined __UCLIBC__ - Lucky GNU user - #endif -#endif - ], - [ac_cv_gnu_library_2=yes], - [ac_cv_gnu_library_2=no]) - ] - ) - AC_SUBST([GLIBC2]) - GLIBC2="$ac_cv_gnu_library_2" - ] -) diff --git a/m4/glibc21.m4 b/m4/glibc21.m4 deleted file mode 100644 index 613fb2a41..000000000 --- a/m4/glibc21.m4 +++ /dev/null @@ -1,34 +0,0 @@ -# glibc21.m4 serial 5 -dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Test for the GNU C Library, version 2.1 or newer, or uClibc. -# From Bruno Haible. - -AC_DEFUN([gl_GLIBC21], - [ - AC_CACHE_CHECK([whether we are using the GNU C Library >= 2.1 or uClibc], - [ac_cv_gnu_library_2_1], - [AC_EGREP_CPP([Lucky], - [ -#include -#ifdef __GNU_LIBRARY__ - #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) - Lucky GNU user - #endif -#endif -#ifdef __UCLIBC__ - Lucky user -#endif - ], - [ac_cv_gnu_library_2_1=yes], - [ac_cv_gnu_library_2_1=no]) - ] - ) - AC_SUBST([GLIBC21]) - GLIBC21="$ac_cv_gnu_library_2_1" - ] -) diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 deleted file mode 100644 index 408918440..000000000 --- a/m4/gnulib-cache.m4 +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This file is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this file. If not, see . -# -# As a special exception to the GNU General Public License, -# this file may be distributed as part of a program that -# contains a configuration script generated by Autoconf, under -# the same distribution terms as the rest of that program. -# -# Generated by gnulib-tool. -# -# This file represents the specification of how gnulib-tool is used. -# It acts as a cache: It is written and read by gnulib-tool. -# In projects that use version control, this file is meant to be put under -# version control, like the configure.ac and various Makefile.am files. - - -# Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex - -# Specification in the form of a few gnulib-tool.m4 macro invocations: -gl_LOCAL_DIR([]) -gl_MODULES([ - argp - error - fnmatch - getdelim - getline - gettext - progname - regex -]) -gl_AVOID([]) -gl_SOURCE_BASE([grub-core/gnulib]) -gl_M4_BASE([m4]) -gl_PO_BASE([]) -gl_DOC_BASE([doc]) -gl_TESTS_BASE([tests]) -gl_LIB([libgnu]) -gl_MAKEFILE_NAME([]) -gl_MACRO_PREFIX([gl]) -gl_PO_DOMAIN([]) -gl_WITNESS_C_MACRO([]) -gl_VC_FILES([false]) diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 deleted file mode 100644 index 0ae5a9ec6..000000000 --- a/m4/gnulib-common.m4 +++ /dev/null @@ -1,377 +0,0 @@ -# gnulib-common.m4 serial 33 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# gl_COMMON -# is expanded unconditionally through gnulib-tool magic. -AC_DEFUN([gl_COMMON], [ - dnl Use AC_REQUIRE here, so that the code is expanded once only. - AC_REQUIRE([gl_00GNULIB]) - AC_REQUIRE([gl_COMMON_BODY]) -]) -AC_DEFUN([gl_COMMON_BODY], [ - AH_VERBATIM([_Noreturn], -[/* The _Noreturn keyword of C11. */ -#if ! (defined _Noreturn \ - || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) -# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ - || 0x5110 <= __SUNPRO_C) -# define _Noreturn __attribute__ ((__noreturn__)) -# elif defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn -# endif -#endif -]) - AH_VERBATIM([isoc99_inline], -[/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports - the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of - earlier versions), but does not display it by setting __GNUC_STDC_INLINE__. - __APPLE__ && __MACH__ test for Mac OS X. - __APPLE_CC__ tests for the Apple compiler and its version. - __STDC_VERSION__ tests for the C99 mode. */ -#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ -# define __GNUC_STDC_INLINE__ 1 -#endif]) - AH_VERBATIM([unused_parameter], -[/* Define as a marker that can be attached to declarations that might not - be used. This helps to reduce warnings, such as from - GCC -Wunused-parameter. */ -#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -# define _GL_UNUSED __attribute__ ((__unused__)) -#else -# define _GL_UNUSED -#endif -/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name - is a misnomer outside of parameter lists. */ -#define _UNUSED_PARAMETER_ _GL_UNUSED - -/* The __pure__ attribute was added in gcc 2.96. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -#else -# define _GL_ATTRIBUTE_PURE /* empty */ -#endif - -/* The __const__ attribute was added in gcc 2.95. */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) -# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) -#else -# define _GL_ATTRIBUTE_CONST /* empty */ -#endif -]) - dnl Preparation for running test programs: - dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not - dnl to /dev/tty, so they can be redirected to log files. Such diagnostics - dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N. - LIBC_FATAL_STDERR_=1 - export LIBC_FATAL_STDERR_ -]) - -# gl_MODULE_INDICATOR_CONDITION -# expands to a C preprocessor expression that evaluates to 1 or 0, depending -# whether a gnulib module that has been requested shall be considered present -# or not. -m4_define([gl_MODULE_INDICATOR_CONDITION], [1]) - -# gl_MODULE_INDICATOR_SET_VARIABLE([modulename]) -# sets the shell variable that indicates the presence of the given module to -# a C preprocessor expression that will evaluate to 1. -AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE], -[ - gl_MODULE_INDICATOR_SET_VARIABLE_AUX( - [GNULIB_[]m4_translit([[$1]], - [abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])], - [gl_MODULE_INDICATOR_CONDITION]) -]) - -# gl_MODULE_INDICATOR_SET_VARIABLE_AUX([variable]) -# modifies the shell variable to include the gl_MODULE_INDICATOR_CONDITION. -# The shell variable's value is a C preprocessor expression that evaluates -# to 0 or 1. -AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX], -[ - m4_if(m4_defn([gl_MODULE_INDICATOR_CONDITION]), [1], - [ - dnl Simplify the expression VALUE || 1 to 1. - $1=1 - ], - [gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([$1], - [gl_MODULE_INDICATOR_CONDITION])]) -]) - -# gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([variable], [condition]) -# modifies the shell variable to include the given condition. The shell -# variable's value is a C preprocessor expression that evaluates to 0 or 1. -AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR], -[ - dnl Simplify the expression 1 || CONDITION to 1. - if test "$[]$1" != 1; then - dnl Simplify the expression 0 || CONDITION to CONDITION. - if test "$[]$1" = 0; then - $1=$2 - else - $1="($[]$1 || $2)" - fi - fi -]) - -# gl_MODULE_INDICATOR([modulename]) -# defines a C macro indicating the presence of the given module -# in a location where it can be used. -# | Value | Value | -# | in lib/ | in tests/ | -# --------------------------------------------+---------+-----------+ -# Module present among main modules: | 1 | 1 | -# --------------------------------------------+---------+-----------+ -# Module present among tests-related modules: | 0 | 1 | -# --------------------------------------------+---------+-----------+ -# Module not present at all: | 0 | 0 | -# --------------------------------------------+---------+-----------+ -AC_DEFUN([gl_MODULE_INDICATOR], -[ - AC_DEFINE_UNQUOTED([GNULIB_]m4_translit([[$1]], - [abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), - [gl_MODULE_INDICATOR_CONDITION], - [Define to a C preprocessor expression that evaluates to 1 or 0, - depending whether the gnulib module $1 shall be considered present.]) -]) - -# gl_MODULE_INDICATOR_FOR_TESTS([modulename]) -# defines a C macro indicating the presence of the given module -# in lib or tests. This is useful to determine whether the module -# should be tested. -# | Value | Value | -# | in lib/ | in tests/ | -# --------------------------------------------+---------+-----------+ -# Module present among main modules: | 1 | 1 | -# --------------------------------------------+---------+-----------+ -# Module present among tests-related modules: | 1 | 1 | -# --------------------------------------------+---------+-----------+ -# Module not present at all: | 0 | 0 | -# --------------------------------------------+---------+-----------+ -AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], -[ - AC_DEFINE([GNULIB_TEST_]m4_translit([[$1]], - [abcdefghijklmnopqrstuvwxyz./-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), [1], - [Define to 1 when the gnulib module $1 should be tested.]) -]) - -# gl_ASSERT_NO_GNULIB_POSIXCHECK -# asserts that there will never be a need to #define GNULIB_POSIXCHECK. -# and thereby enables an optimization of configure and config.h. -# Used by Emacs. -AC_DEFUN([gl_ASSERT_NO_GNULIB_POSIXCHECK], -[ - dnl Override gl_WARN_ON_USE_PREPARE. - dnl But hide this definition from 'aclocal'. - AC_DEFUN([gl_W][ARN_ON_USE_PREPARE], []) -]) - -# gl_ASSERT_NO_GNULIB_TESTS -# asserts that there will be no gnulib tests in the scope of the configure.ac -# and thereby enables an optimization of config.h. -# Used by Emacs. -AC_DEFUN([gl_ASSERT_NO_GNULIB_TESTS], -[ - dnl Override gl_MODULE_INDICATOR_FOR_TESTS. - AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], []) -]) - -# Test whether exists. -# Set HAVE_FEATURES_H. -AC_DEFUN([gl_FEATURES_H], -[ - AC_CHECK_HEADERS_ONCE([features.h]) - if test $ac_cv_header_features_h = yes; then - HAVE_FEATURES_H=1 - else - HAVE_FEATURES_H=0 - fi - AC_SUBST([HAVE_FEATURES_H]) -]) - -# m4_foreach_w -# is a backport of autoconf-2.59c's m4_foreach_w. -# Remove this macro when we can assume autoconf >= 2.60. -m4_ifndef([m4_foreach_w], - [m4_define([m4_foreach_w], - [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])]) - -# AS_VAR_IF(VAR, VALUE, [IF-MATCH], [IF-NOT-MATCH]) -# ---------------------------------------------------- -# Backport of autoconf-2.63b's macro. -# Remove this macro when we can assume autoconf >= 2.64. -m4_ifndef([AS_VAR_IF], -[m4_define([AS_VAR_IF], -[AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])]) - -# gl_PROG_CC_C99 -# Modifies the value of the shell variable CC in an attempt to make $CC -# understand ISO C99 source code. -# This is like AC_PROG_CC_C99, except that -# - AC_PROG_CC_C99 did not exist in Autoconf versions < 2.60, -# - AC_PROG_CC_C99 does not mix well with AC_PROG_CC_STDC -# , -# but many more packages use AC_PROG_CC_STDC than AC_PROG_CC_C99 -# . -# Remaining problems: -# - When AC_PROG_CC_STDC is invoked twice, it adds the C99 enabling options -# to CC twice -# . -# - AC_PROG_CC_STDC is likely to change now that C11 is an ISO standard. -AC_DEFUN([gl_PROG_CC_C99], -[ - dnl Change that version number to the minimum Autoconf version that supports - dnl mixing AC_PROG_CC_C99 calls with AC_PROG_CC_STDC calls. - m4_version_prereq([9.0], - [AC_REQUIRE([AC_PROG_CC_C99])], - [AC_REQUIRE([AC_PROG_CC_STDC])]) -]) - -# gl_PROG_AR_RANLIB -# Determines the values for AR, ARFLAGS, RANLIB that fit with the compiler. -# The user can set the variables AR, ARFLAGS, RANLIB if he wants to override -# the values. -AC_DEFUN([gl_PROG_AR_RANLIB], -[ - dnl Minix 3 comes with two toolchains: The Amsterdam Compiler Kit compiler - dnl as "cc", and GCC as "gcc". They have different object file formats and - dnl library formats. In particular, the GNU binutils programs ar, ranlib - dnl produce libraries that work only with gcc, not with cc. - AC_REQUIRE([AC_PROG_CC]) - AC_CACHE_CHECK([for Minix Amsterdam compiler], [gl_cv_c_amsterdam_compiler], - [ - AC_EGREP_CPP([Amsterdam], - [ -#ifdef __ACK__ -Amsterdam -#endif - ], - [gl_cv_c_amsterdam_compiler=yes], - [gl_cv_c_amsterdam_compiler=no]) - ]) - if test -z "$AR"; then - if test $gl_cv_c_amsterdam_compiler = yes; then - AR='cc -c.a' - if test -z "$ARFLAGS"; then - ARFLAGS='-o' - fi - else - dnl Use the Automake-documented default values for AR and ARFLAGS, - dnl but prefer ${host}-ar over ar (useful for cross-compiling). - AC_CHECK_TOOL([AR], [ar], [ar]) - if test -z "$ARFLAGS"; then - ARFLAGS='cru' - fi - fi - else - if test -z "$ARFLAGS"; then - ARFLAGS='cru' - fi - fi - AC_SUBST([AR]) - AC_SUBST([ARFLAGS]) - if test -z "$RANLIB"; then - if test $gl_cv_c_amsterdam_compiler = yes; then - RANLIB=':' - else - dnl Use the ranlib program if it is available. - AC_PROG_RANLIB - fi - fi - AC_SUBST([RANLIB]) -]) - -# AC_PROG_MKDIR_P -# is a backport of autoconf-2.60's AC_PROG_MKDIR_P, with a fix -# for interoperability with automake-1.9.6 from autoconf-2.62. -# Remove this macro when we can assume autoconf >= 2.62 or -# autoconf >= 2.60 && automake >= 1.10. -# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. -m4_ifndef([AC_AUTOCONF_VERSION],[ -m4_ifdef([AC_PROG_MKDIR_P], [ - dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed. - m4_define([AC_PROG_MKDIR_P], - m4_defn([AC_PROG_MKDIR_P])[ - AC_SUBST([MKDIR_P])])], [ - dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P. - AC_DEFUN_ONCE([AC_PROG_MKDIR_P], - [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake - MKDIR_P='$(mkdir_p)' - AC_SUBST([MKDIR_P])])]) -]) - -# AC_C_RESTRICT -# This definition overrides the AC_C_RESTRICT macro from autoconf 2.60..2.61, -# so that mixed use of GNU C and GNU C++ and mixed use of Sun C and Sun C++ -# works. -# This definition can be removed once autoconf >= 2.62 can be assumed. -# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. -m4_ifndef([AC_AUTOCONF_VERSION],[ -AC_DEFUN([AC_C_RESTRICT], -[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict], - [ac_cv_c_restrict=no - # The order here caters to the fact that C++ does not require restrict. - for ac_kw in __restrict __restrict__ _Restrict restrict; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM( - [[typedef int * int_ptr; - int foo (int_ptr $ac_kw ip) { - return ip[0]; - }]], - [[int s[1]; - int * $ac_kw t = s; - t[0] = 0; - return foo(t)]])], - [ac_cv_c_restrict=$ac_kw]) - test "$ac_cv_c_restrict" != no && break - done - ]) - AH_VERBATIM([restrict], -[/* Define to the equivalent of the C99 'restrict' keyword, or to - nothing if this is not supported. Do not define if restrict is - supported directly. */ -#undef restrict -/* Work around a bug in Sun C++: it does not support _Restrict, even - though the corresponding Sun C compiler does, which causes - "#define restrict _Restrict" in the previous line. Perhaps some future - version of Sun C++ will work with _Restrict; if so, it'll probably - define __RESTRICT, just as Sun C does. */ -#if defined __SUNPRO_CC && !defined __RESTRICT -# define _Restrict -#endif]) - case $ac_cv_c_restrict in - restrict) ;; - no) AC_DEFINE([restrict], []) ;; - *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;; - esac -]) -]) - -# gl_BIGENDIAN -# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd. -# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some -# macros invoke AC_C_BIGENDIAN with arguments. -AC_DEFUN([gl_BIGENDIAN], -[ - AC_C_BIGENDIAN -]) - -# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it) -# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not -# output a spurious "(cached)" mark in the midst of other configure output. -# This macro should be used instead of AC_CACHE_VAL when it is not surrounded -# by an AC_MSG_CHECKING/AC_MSG_RESULT pair. -AC_DEFUN([gl_CACHE_VAL_SILENT], -[ - saved_as_echo_n="$as_echo_n" - as_echo_n=':' - AC_CACHE_VAL([$1], [$2]) - as_echo_n="$saved_as_echo_n" -]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 deleted file mode 100644 index 7a19f60d8..000000000 --- a/m4/gnulib-comp.m4 +++ /dev/null @@ -1,756 +0,0 @@ -# DO NOT EDIT! GENERATED AUTOMATICALLY! -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This file is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this file. If not, see . -# -# As a special exception to the GNU General Public License, -# this file may be distributed as part of a program that -# contains a configuration script generated by Autoconf, under -# the same distribution terms as the rest of that program. -# -# Generated by gnulib-tool. -# -# This file represents the compiled summary of the specification in -# gnulib-cache.m4. It lists the computed macro invocations that need -# to be invoked from configure.ac. -# In projects that use version control, this file can be treated like -# other built files. - - -# This macro should be invoked from ./configure.ac, in the section -# "Checks for programs", right after AC_PROG_CC, and certainly before -# any checks for libraries, header files, types and library functions. -AC_DEFUN([gl_EARLY], -[ - m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace - m4_pattern_allow([^gl_ES$])dnl a valid locale name - m4_pattern_allow([^gl_LIBOBJS$])dnl a variable - m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable - AC_REQUIRE([gl_PROG_AR_RANLIB]) - AC_REQUIRE([AM_PROG_CC_C_O]) - # Code from module alloca: - # Code from module alloca-opt: - # Code from module argp: - # Code from module btowc: - # Code from module configmake: - # Code from module dirname-lgpl: - # Code from module dosname: - # Code from module double-slash-root: - # Code from module errno: - # Code from module error: - # Code from module extensions: - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - # Code from module extern-inline: - # Code from module float: - # Code from module fnmatch: - # Code from module getdelim: - # Code from module getline: - # Code from module getopt-gnu: - # Code from module getopt-posix: - # Code from module gettext: - # Code from module gettext-h: - # Code from module havelib: - # Code from module include_next: - # Code from module intprops: - # Code from module langinfo: - # Code from module localcharset: - # Code from module locale: - # Code from module localeconv: - # Code from module malloc-gnu: - # Code from module malloc-posix: - # Code from module mbrtowc: - # Code from module mbsinit: - # Code from module mbsrtowcs: - # Code from module mbswidth: - # Code from module mbtowc: - # Code from module memchr: - # Code from module mempcpy: - # Code from module msvc-inval: - # Code from module msvc-nothrow: - # Code from module multiarch: - # Code from module nl_langinfo: - # Code from module nocrash: - # Code from module progname: - # Code from module rawmemchr: - # Code from module realloc-posix: - # Code from module regex: - # Code from module size_max: - # Code from module sleep: - # Code from module snippet/_Noreturn: - # Code from module snippet/arg-nonnull: - # Code from module snippet/c++defs: - # Code from module snippet/warn-on-use: - # Code from module ssize_t: - # Code from module stdalign: - # Code from module stdbool: - # Code from module stddef: - # Code from module stdint: - # Code from module stdio: - # Code from module stdlib: - # Code from module strcase: - # Code from module strchrnul: - # Code from module streq: - # Code from module strerror: - # Code from module strerror-override: - # Code from module string: - # Code from module strings: - # Code from module strndup: - # Code from module strnlen: - # Code from module strnlen1: - # Code from module sys_types: - # Code from module sysexits: - # Code from module unistd: - # Code from module unitypes: - # Code from module uniwidth/base: - # Code from module uniwidth/width: - # Code from module vasnprintf: - # Code from module verify: - # Code from module vsnprintf: - # Code from module wchar: - # Code from module wcrtomb: - # Code from module wctype-h: - # Code from module wcwidth: - # Code from module xsize: -]) - -# This macro should be invoked from ./configure.ac, in the section -# "Check for header files, types and library functions". -AC_DEFUN([gl_INIT], -[ - AM_CONDITIONAL([GL_COND_LIBTOOL], [false]) - gl_cond_libtool=false - gl_libdeps= - gl_ltlibdeps= - gl_m4_base='m4' - m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ])) - m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS])) - m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES])) - m4_pushdef([gl_LIBSOURCES_LIST], []) - m4_pushdef([gl_LIBSOURCES_DIR], []) - gl_COMMON - gl_source_base='grub-core/gnulib' - gl_FUNC_ALLOCA - gl_ARGP - m4_ifdef([AM_XGETTEXT_OPTION], - [AM_][XGETTEXT_OPTION([--flag=argp_error:2:c-format]) - AM_][XGETTEXT_OPTION([--flag=argp_failure:4:c-format])]) - gl_FUNC_BTOWC - if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then - AC_LIBOBJ([btowc]) - gl_PREREQ_BTOWC - fi - gl_WCHAR_MODULE_INDICATOR([btowc]) - gl_CONFIGMAKE_PREP - gl_DIRNAME_LGPL - gl_DOUBLE_SLASH_ROOT - gl_HEADER_ERRNO_H - gl_ERROR - if test $ac_cv_lib_error_at_line = no; then - AC_LIBOBJ([error]) - gl_PREREQ_ERROR - fi - m4_ifdef([AM_XGETTEXT_OPTION], - [AM_][XGETTEXT_OPTION([--flag=error:3:c-format]) - AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])]) - AC_REQUIRE([gl_EXTERN_INLINE]) - gl_FLOAT_H - if test $REPLACE_FLOAT_LDBL = 1; then - AC_LIBOBJ([float]) - fi - if test $REPLACE_ITOLD = 1; then - AC_LIBOBJ([itold]) - fi - gl_FUNC_FNMATCH_POSIX - if test -n "$FNMATCH_H"; then - AC_LIBOBJ([fnmatch]) - gl_PREREQ_FNMATCH - fi - gl_FUNC_GETDELIM - if test $HAVE_GETDELIM = 0 || test $REPLACE_GETDELIM = 1; then - AC_LIBOBJ([getdelim]) - gl_PREREQ_GETDELIM - fi - gl_STDIO_MODULE_INDICATOR([getdelim]) - gl_FUNC_GETLINE - if test $REPLACE_GETLINE = 1; then - AC_LIBOBJ([getline]) - gl_PREREQ_GETLINE - fi - gl_STDIO_MODULE_INDICATOR([getline]) - gl_FUNC_GETOPT_GNU - if test $REPLACE_GETOPT = 1; then - AC_LIBOBJ([getopt]) - AC_LIBOBJ([getopt1]) - gl_PREREQ_GETOPT - dnl Arrange for unistd.h to include getopt.h. - GNULIB_GL_UNISTD_H_GETOPT=1 - fi - AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT]) - gl_MODULE_INDICATOR_FOR_TESTS([getopt-gnu]) - gl_FUNC_GETOPT_POSIX - if test $REPLACE_GETOPT = 1; then - AC_LIBOBJ([getopt]) - AC_LIBOBJ([getopt1]) - gl_PREREQ_GETOPT - dnl Arrange for unistd.h to include getopt.h. - GNULIB_GL_UNISTD_H_GETOPT=1 - fi - AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT]) - dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac. - AM_GNU_GETTEXT_VERSION([0.18.1]) - AC_SUBST([LIBINTL]) - AC_SUBST([LTLIBINTL]) - gl_LANGINFO_H - gl_LOCALCHARSET - LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\"" - AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) - gl_LOCALE_H - gl_FUNC_LOCALECONV - if test $REPLACE_LOCALECONV = 1; then - AC_LIBOBJ([localeconv]) - gl_PREREQ_LOCALECONV - fi - gl_LOCALE_MODULE_INDICATOR([localeconv]) - gl_FUNC_MALLOC_GNU - if test $REPLACE_MALLOC = 1; then - AC_LIBOBJ([malloc]) - fi - gl_MODULE_INDICATOR([malloc-gnu]) - gl_FUNC_MALLOC_POSIX - if test $REPLACE_MALLOC = 1; then - AC_LIBOBJ([malloc]) - fi - gl_STDLIB_MODULE_INDICATOR([malloc-posix]) - gl_FUNC_MBRTOWC - if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then - AC_LIBOBJ([mbrtowc]) - gl_PREREQ_MBRTOWC - fi - gl_WCHAR_MODULE_INDICATOR([mbrtowc]) - gl_FUNC_MBSINIT - if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then - AC_LIBOBJ([mbsinit]) - gl_PREREQ_MBSINIT - fi - gl_WCHAR_MODULE_INDICATOR([mbsinit]) - gl_FUNC_MBSRTOWCS - if test $HAVE_MBSRTOWCS = 0 || test $REPLACE_MBSRTOWCS = 1; then - AC_LIBOBJ([mbsrtowcs]) - AC_LIBOBJ([mbsrtowcs-state]) - gl_PREREQ_MBSRTOWCS - fi - gl_WCHAR_MODULE_INDICATOR([mbsrtowcs]) - gl_MBSWIDTH - gl_FUNC_MBTOWC - if test $REPLACE_MBTOWC = 1; then - AC_LIBOBJ([mbtowc]) - gl_PREREQ_MBTOWC - fi - gl_STDLIB_MODULE_INDICATOR([mbtowc]) - gl_FUNC_MEMCHR - if test $HAVE_MEMCHR = 0 || test $REPLACE_MEMCHR = 1; then - AC_LIBOBJ([memchr]) - gl_PREREQ_MEMCHR - fi - gl_STRING_MODULE_INDICATOR([memchr]) - gl_FUNC_MEMPCPY - if test $HAVE_MEMPCPY = 0; then - AC_LIBOBJ([mempcpy]) - gl_PREREQ_MEMPCPY - fi - gl_STRING_MODULE_INDICATOR([mempcpy]) - gl_MSVC_INVAL - if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then - AC_LIBOBJ([msvc-inval]) - fi - gl_MSVC_NOTHROW - if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then - AC_LIBOBJ([msvc-nothrow]) - fi - gl_MULTIARCH - gl_FUNC_NL_LANGINFO - if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then - AC_LIBOBJ([nl_langinfo]) - fi - gl_LANGINFO_MODULE_INDICATOR([nl_langinfo]) - AC_CHECK_DECLS([program_invocation_name], [], [], [#include ]) - AC_CHECK_DECLS([program_invocation_short_name], [], [], [#include ]) - gl_FUNC_RAWMEMCHR - if test $HAVE_RAWMEMCHR = 0; then - AC_LIBOBJ([rawmemchr]) - gl_PREREQ_RAWMEMCHR - fi - gl_STRING_MODULE_INDICATOR([rawmemchr]) - gl_FUNC_REALLOC_POSIX - if test $REPLACE_REALLOC = 1; then - AC_LIBOBJ([realloc]) - fi - gl_STDLIB_MODULE_INDICATOR([realloc-posix]) - gl_REGEX - if test $ac_use_included_regex = yes; then - AC_LIBOBJ([regex]) - gl_PREREQ_REGEX - fi - gl_SIZE_MAX - gl_FUNC_SLEEP - if test $HAVE_SLEEP = 0 || test $REPLACE_SLEEP = 1; then - AC_LIBOBJ([sleep]) - fi - gl_UNISTD_MODULE_INDICATOR([sleep]) - gt_TYPE_SSIZE_T - gl_STDALIGN_H - AM_STDBOOL_H - gl_STDDEF_H - gl_STDINT_H - gl_STDIO_H - gl_STDLIB_H - gl_STRCASE - if test $HAVE_STRCASECMP = 0; then - AC_LIBOBJ([strcasecmp]) - gl_PREREQ_STRCASECMP - fi - if test $HAVE_STRNCASECMP = 0; then - AC_LIBOBJ([strncasecmp]) - gl_PREREQ_STRNCASECMP - fi - gl_FUNC_STRCHRNUL - if test $HAVE_STRCHRNUL = 0 || test $REPLACE_STRCHRNUL = 1; then - AC_LIBOBJ([strchrnul]) - gl_PREREQ_STRCHRNUL - fi - gl_STRING_MODULE_INDICATOR([strchrnul]) - gl_FUNC_STRERROR - if test $REPLACE_STRERROR = 1; then - AC_LIBOBJ([strerror]) - fi - gl_MODULE_INDICATOR([strerror]) - gl_STRING_MODULE_INDICATOR([strerror]) - AC_REQUIRE([gl_HEADER_ERRNO_H]) - AC_REQUIRE([gl_FUNC_STRERROR_0]) - if test -n "$ERRNO_H" || test $REPLACE_STRERROR_0 = 1; then - AC_LIBOBJ([strerror-override]) - gl_PREREQ_SYS_H_WINSOCK2 - fi - gl_HEADER_STRING_H - gl_HEADER_STRINGS_H - gl_FUNC_STRNDUP - if test $HAVE_STRNDUP = 0 || test $REPLACE_STRNDUP = 1; then - AC_LIBOBJ([strndup]) - fi - gl_STRING_MODULE_INDICATOR([strndup]) - gl_FUNC_STRNLEN - if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then - AC_LIBOBJ([strnlen]) - gl_PREREQ_STRNLEN - fi - gl_STRING_MODULE_INDICATOR([strnlen]) - gl_SYS_TYPES_H - AC_PROG_MKDIR_P - gl_SYSEXITS - gl_UNISTD_H - gl_LIBUNISTRING_LIBHEADER([0.9], [unitypes.h]) - gl_LIBUNISTRING_LIBHEADER([0.9], [uniwidth.h]) - gl_LIBUNISTRING_MODULE([0.9.4], [uniwidth/width]) - gl_FUNC_VASNPRINTF - gl_FUNC_VSNPRINTF - gl_STDIO_MODULE_INDICATOR([vsnprintf]) - gl_WCHAR_H - gl_FUNC_WCRTOMB - if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then - AC_LIBOBJ([wcrtomb]) - gl_PREREQ_WCRTOMB - fi - gl_WCHAR_MODULE_INDICATOR([wcrtomb]) - gl_WCTYPE_H - gl_FUNC_WCWIDTH - if test $HAVE_WCWIDTH = 0 || test $REPLACE_WCWIDTH = 1; then - AC_LIBOBJ([wcwidth]) - fi - gl_WCHAR_MODULE_INDICATOR([wcwidth]) - gl_XSIZE - # End of code from modules - m4_ifval(gl_LIBSOURCES_LIST, [ - m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || - for gl_file in ]gl_LIBSOURCES_LIST[ ; do - if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then - echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2 - exit 1 - fi - done])dnl - m4_if(m4_sysval, [0], [], - [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) - ]) - m4_popdef([gl_LIBSOURCES_DIR]) - m4_popdef([gl_LIBSOURCES_LIST]) - m4_popdef([AC_LIBSOURCES]) - m4_popdef([AC_REPLACE_FUNCS]) - m4_popdef([AC_LIBOBJ]) - AC_CONFIG_COMMANDS_PRE([ - gl_libobjs= - gl_ltlibobjs= - if test -n "$gl_LIBOBJS"; then - # Remove the extension. - sed_drop_objext='s/\.o$//;s/\.obj$//' - for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do - gl_libobjs="$gl_libobjs $i.$ac_objext" - gl_ltlibobjs="$gl_ltlibobjs $i.lo" - done - fi - AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) - AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) - ]) - gltests_libdeps= - gltests_ltlibdeps= - m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ])) - m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS])) - m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES])) - m4_pushdef([gltests_LIBSOURCES_LIST], []) - m4_pushdef([gltests_LIBSOURCES_DIR], []) - gl_COMMON - gl_source_base='tests' -changequote(,)dnl - gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS -changequote([, ])dnl - AC_SUBST([gltests_WITNESS]) - gl_module_indicator_condition=$gltests_WITNESS - m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition]) - m4_popdef([gl_MODULE_INDICATOR_CONDITION]) - m4_ifval(gltests_LIBSOURCES_LIST, [ - m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ || - for gl_file in ]gltests_LIBSOURCES_LIST[ ; do - if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then - echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2 - exit 1 - fi - done])dnl - m4_if(m4_sysval, [0], [], - [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) - ]) - m4_popdef([gltests_LIBSOURCES_DIR]) - m4_popdef([gltests_LIBSOURCES_LIST]) - m4_popdef([AC_LIBSOURCES]) - m4_popdef([AC_REPLACE_FUNCS]) - m4_popdef([AC_LIBOBJ]) - AC_CONFIG_COMMANDS_PRE([ - gltests_libobjs= - gltests_ltlibobjs= - if test -n "$gltests_LIBOBJS"; then - # Remove the extension. - sed_drop_objext='s/\.o$//;s/\.obj$//' - for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do - gltests_libobjs="$gltests_libobjs $i.$ac_objext" - gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" - done - fi - AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) - AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) - ]) - LIBGNU_LIBDEPS="$gl_libdeps" - AC_SUBST([LIBGNU_LIBDEPS]) - LIBGNU_LTLIBDEPS="$gl_ltlibdeps" - AC_SUBST([LIBGNU_LTLIBDEPS]) -]) - -# Like AC_LIBOBJ, except that the module name goes -# into gl_LIBOBJS instead of into LIBOBJS. -AC_DEFUN([gl_LIBOBJ], [ - AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl - gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext" -]) - -# Like AC_REPLACE_FUNCS, except that the module name goes -# into gl_LIBOBJS instead of into LIBOBJS. -AC_DEFUN([gl_REPLACE_FUNCS], [ - m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl - AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)]) -]) - -# Like AC_LIBSOURCES, except the directory where the source file is -# expected is derived from the gnulib-tool parameterization, -# and alloca is special cased (for the alloca-opt module). -# We could also entirely rely on EXTRA_lib..._SOURCES. -AC_DEFUN([gl_LIBSOURCES], [ - m4_foreach([_gl_NAME], [$1], [ - m4_if(_gl_NAME, [alloca.c], [], [ - m4_define([gl_LIBSOURCES_DIR], [grub-core/gnulib]) - m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ]) - ]) - ]) -]) - -# Like AC_LIBOBJ, except that the module name goes -# into gltests_LIBOBJS instead of into LIBOBJS. -AC_DEFUN([gltests_LIBOBJ], [ - AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl - gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext" -]) - -# Like AC_REPLACE_FUNCS, except that the module name goes -# into gltests_LIBOBJS instead of into LIBOBJS. -AC_DEFUN([gltests_REPLACE_FUNCS], [ - m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl - AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)]) -]) - -# Like AC_LIBSOURCES, except the directory where the source file is -# expected is derived from the gnulib-tool parameterization, -# and alloca is special cased (for the alloca-opt module). -# We could also entirely rely on EXTRA_lib..._SOURCES. -AC_DEFUN([gltests_LIBSOURCES], [ - m4_foreach([_gl_NAME], [$1], [ - m4_if(_gl_NAME, [alloca.c], [], [ - m4_define([gltests_LIBSOURCES_DIR], [tests]) - m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ]) - ]) - ]) -]) - -# This macro records the list of files which have been installed by -# gnulib-tool and may be removed by future gnulib-tool invocations. -AC_DEFUN([gl_FILE_LIST], [ - build-aux/config.rpath - build-aux/snippet/_Noreturn.h - build-aux/snippet/arg-nonnull.h - build-aux/snippet/c++defs.h - build-aux/snippet/warn-on-use.h - lib/alloca.c - lib/alloca.in.h - lib/argp-ba.c - lib/argp-eexst.c - lib/argp-fmtstream.c - lib/argp-fmtstream.h - lib/argp-fs-xinl.c - lib/argp-help.c - lib/argp-namefrob.h - lib/argp-parse.c - lib/argp-pin.c - lib/argp-pv.c - lib/argp-pvh.c - lib/argp-xinl.c - lib/argp.h - lib/asnprintf.c - lib/basename-lgpl.c - lib/btowc.c - lib/config.charset - lib/dirname-lgpl.c - lib/dirname.h - lib/dosname.h - lib/errno.in.h - lib/error.c - lib/error.h - lib/float+.h - lib/float.c - lib/float.in.h - lib/fnmatch.c - lib/fnmatch.in.h - lib/fnmatch_loop.c - lib/getdelim.c - lib/getline.c - lib/getopt.c - lib/getopt.in.h - lib/getopt1.c - lib/getopt_int.h - lib/gettext.h - lib/intprops.h - lib/itold.c - lib/langinfo.in.h - lib/localcharset.c - lib/localcharset.h - lib/locale.in.h - lib/localeconv.c - lib/malloc.c - lib/mbrtowc.c - lib/mbsinit.c - lib/mbsrtowcs-impl.h - lib/mbsrtowcs-state.c - lib/mbsrtowcs.c - lib/mbswidth.c - lib/mbswidth.h - lib/mbtowc-impl.h - lib/mbtowc.c - lib/memchr.c - lib/memchr.valgrind - lib/mempcpy.c - lib/msvc-inval.c - lib/msvc-inval.h - lib/msvc-nothrow.c - lib/msvc-nothrow.h - lib/nl_langinfo.c - lib/printf-args.c - lib/printf-args.h - lib/printf-parse.c - lib/printf-parse.h - lib/progname.c - lib/progname.h - lib/rawmemchr.c - lib/rawmemchr.valgrind - lib/realloc.c - lib/ref-add.sin - lib/ref-del.sin - lib/regcomp.c - lib/regex.c - lib/regex.h - lib/regex_internal.c - lib/regex_internal.h - lib/regexec.c - lib/size_max.h - lib/sleep.c - lib/stdalign.in.h - lib/stdbool.in.h - lib/stddef.in.h - lib/stdint.in.h - lib/stdio.in.h - lib/stdlib.in.h - lib/strcasecmp.c - lib/strchrnul.c - lib/strchrnul.valgrind - lib/streq.h - lib/strerror-override.c - lib/strerror-override.h - lib/strerror.c - lib/string.in.h - lib/strings.in.h - lib/stripslash.c - lib/strncasecmp.c - lib/strndup.c - lib/strnlen.c - lib/strnlen1.c - lib/strnlen1.h - lib/sys_types.in.h - lib/sysexits.in.h - lib/unistd.c - lib/unistd.in.h - lib/unitypes.in.h - lib/uniwidth.in.h - lib/uniwidth/cjk.h - lib/uniwidth/width.c - lib/vasnprintf.c - lib/vasnprintf.h - lib/verify.h - lib/vsnprintf.c - lib/wchar.in.h - lib/wcrtomb.c - lib/wctype-h.c - lib/wctype.in.h - lib/wcwidth.c - lib/xsize.c - lib/xsize.h - m4/00gnulib.m4 - m4/alloca.m4 - m4/argp.m4 - m4/btowc.m4 - m4/codeset.m4 - m4/configmake.m4 - m4/dirname.m4 - m4/double-slash-root.m4 - m4/eealloc.m4 - m4/errno_h.m4 - m4/error.m4 - m4/exponentd.m4 - m4/extensions.m4 - m4/extern-inline.m4 - m4/fcntl-o.m4 - m4/float_h.m4 - m4/fnmatch.m4 - m4/getdelim.m4 - m4/getline.m4 - m4/getopt.m4 - m4/gettext.m4 - m4/glibc2.m4 - m4/glibc21.m4 - m4/gnulib-common.m4 - m4/iconv.m4 - m4/include_next.m4 - m4/intdiv0.m4 - m4/intl.m4 - m4/intldir.m4 - m4/intlmacosx.m4 - m4/intmax.m4 - m4/intmax_t.m4 - m4/inttypes-pri.m4 - m4/inttypes_h.m4 - m4/langinfo_h.m4 - m4/lcmessage.m4 - m4/lib-ld.m4 - m4/lib-link.m4 - m4/lib-prefix.m4 - m4/libunistring-base.m4 - m4/localcharset.m4 - m4/locale-fr.m4 - m4/locale-ja.m4 - m4/locale-zh.m4 - m4/locale_h.m4 - m4/localeconv.m4 - m4/lock.m4 - m4/longlong.m4 - m4/malloc.m4 - m4/math_h.m4 - m4/mbrtowc.m4 - m4/mbsinit.m4 - m4/mbsrtowcs.m4 - m4/mbstate_t.m4 - m4/mbswidth.m4 - m4/mbtowc.m4 - m4/memchr.m4 - m4/mempcpy.m4 - m4/mmap-anon.m4 - m4/msvc-inval.m4 - m4/msvc-nothrow.m4 - m4/multiarch.m4 - m4/nl_langinfo.m4 - m4/nls.m4 - m4/nocrash.m4 - m4/off_t.m4 - m4/po.m4 - m4/printf-posix.m4 - m4/printf.m4 - m4/progtest.m4 - m4/rawmemchr.m4 - m4/realloc.m4 - m4/regex.m4 - m4/size_max.m4 - m4/sleep.m4 - m4/ssize_t.m4 - m4/stdalign.m4 - m4/stdbool.m4 - m4/stddef_h.m4 - m4/stdint.m4 - m4/stdint_h.m4 - m4/stdio_h.m4 - m4/stdlib_h.m4 - m4/strcase.m4 - m4/strchrnul.m4 - m4/strerror.m4 - m4/string_h.m4 - m4/strings_h.m4 - m4/strndup.m4 - m4/strnlen.m4 - m4/sys_socket_h.m4 - m4/sys_types_h.m4 - m4/sysexits.m4 - m4/threadlib.m4 - m4/uintmax_t.m4 - m4/unistd_h.m4 - m4/vasnprintf.m4 - m4/visibility.m4 - m4/vsnprintf.m4 - m4/warn-on-use.m4 - m4/wchar_h.m4 - m4/wchar_t.m4 - m4/wcrtomb.m4 - m4/wctype_h.m4 - m4/wcwidth.m4 - m4/wint_t.m4 - m4/xsize.m4 -]) diff --git a/m4/gnulib-tool.m4 b/m4/gnulib-tool.m4 deleted file mode 100644 index f3dea1a9f..000000000 --- a/m4/gnulib-tool.m4 +++ /dev/null @@ -1,57 +0,0 @@ -# gnulib-tool.m4 serial 2 -dnl Copyright (C) 2004-2005, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl The following macros need not be invoked explicitly. -dnl Invoking them does nothing except to declare default arguments -dnl for "gnulib-tool --import". - -dnl Usage: gl_LOCAL_DIR([DIR]) -AC_DEFUN([gl_LOCAL_DIR], []) - -dnl Usage: gl_MODULES([module1 module2 ...]) -AC_DEFUN([gl_MODULES], []) - -dnl Usage: gl_AVOID([module1 module2 ...]) -AC_DEFUN([gl_AVOID], []) - -dnl Usage: gl_SOURCE_BASE([DIR]) -AC_DEFUN([gl_SOURCE_BASE], []) - -dnl Usage: gl_M4_BASE([DIR]) -AC_DEFUN([gl_M4_BASE], []) - -dnl Usage: gl_PO_BASE([DIR]) -AC_DEFUN([gl_PO_BASE], []) - -dnl Usage: gl_DOC_BASE([DIR]) -AC_DEFUN([gl_DOC_BASE], []) - -dnl Usage: gl_TESTS_BASE([DIR]) -AC_DEFUN([gl_TESTS_BASE], []) - -dnl Usage: gl_WITH_TESTS -AC_DEFUN([gl_WITH_TESTS], []) - -dnl Usage: gl_LIB([LIBNAME]) -AC_DEFUN([gl_LIB], []) - -dnl Usage: gl_LGPL or gl_LGPL([VERSION]) -AC_DEFUN([gl_LGPL], []) - -dnl Usage: gl_MAKEFILE_NAME([FILENAME]) -AC_DEFUN([gl_MAKEFILE_NAME], []) - -dnl Usage: gl_LIBTOOL -AC_DEFUN([gl_LIBTOOL], []) - -dnl Usage: gl_MACRO_PREFIX([PREFIX]) -AC_DEFUN([gl_MACRO_PREFIX], []) - -dnl Usage: gl_PO_DOMAIN([DOMAIN]) -AC_DEFUN([gl_PO_DOMAIN], []) - -dnl Usage: gl_VC_FILES([BOOLEAN]) -AC_DEFUN([gl_VC_FILES], []) diff --git a/m4/iconv.m4 b/m4/iconv.m4 deleted file mode 100644 index a50364656..000000000 --- a/m4/iconv.m4 +++ /dev/null @@ -1,268 +0,0 @@ -# iconv.m4 serial 18 (gettext-0.18.2) -dnl Copyright (C) 2000-2002, 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], -[ - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([iconv]) -]) - -AC_DEFUN([AM_ICONV_LINK], -[ - dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and - dnl those with the standalone portable GNU libiconv installed). - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - - dnl Add $INCICONV to CPPFLAGS before performing the following checks, - dnl because if the user has installed libiconv and not disabled its use - dnl via --without-libiconv-prefix, he wants to use it. The first - dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. - am_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) - - AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - ]], - [[iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);]])], - [am_cv_func_iconv=yes]) - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - ]], - [[iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);]])], - [am_cv_lib_iconv=yes] - [am_cv_func_iconv=yes]) - LIBS="$am_save_LIBS" - fi - ]) - if test "$am_cv_func_iconv" = yes; then - AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ - dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, - dnl Solaris 10. - am_save_LIBS="$LIBS" - if test $am_cv_lib_iconv = yes; then - LIBS="$LIBS $LIBICONV" - fi - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -int main () -{ - int result = 0; - /* Test against AIX 5.1 bug: Failures are not distinguishable from successful - returns. */ - { - iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); - if (cd_utf8_to_88591 != (iconv_t)(-1)) - { - static const char input[] = "\342\202\254"; /* EURO SIGN */ - char buf[10]; - const char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_utf8_to_88591, - (char **) &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 1; - iconv_close (cd_utf8_to_88591); - } - } - /* Test against Solaris 10 bug: Failures are not distinguishable from - successful returns. */ - { - iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); - if (cd_ascii_to_88591 != (iconv_t)(-1)) - { - static const char input[] = "\263"; - char buf[10]; - const char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_ascii_to_88591, - (char **) &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 2; - iconv_close (cd_ascii_to_88591); - } - } - /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static const char input[] = "\304"; - static char buf[2] = { (char)0xDE, (char)0xAD }; - const char *inptr = input; - size_t inbytesleft = 1; - char *outptr = buf; - size_t outbytesleft = 1; - size_t res = iconv (cd_88591_to_utf8, - (char **) &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) - result |= 4; - iconv_close (cd_88591_to_utf8); - } - } -#if 0 /* This bug could be worked around by the caller. */ - /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; - char buf[50]; - const char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_88591_to_utf8, - (char **) &inptr, &inbytesleft, - &outptr, &outbytesleft); - if ((int)res > 0) - result |= 8; - iconv_close (cd_88591_to_utf8); - } - } -#endif - /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is - provided. */ - if (/* Try standardized names. */ - iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) - /* Try IRIX, OSF/1 names. */ - && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) - /* Try AIX names. */ - && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) - /* Try HP-UX names. */ - && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) - result |= 16; - return result; -}]])], - [am_cv_func_iconv_works=yes], - [am_cv_func_iconv_works=no], - [ -changequote(,)dnl - case "$host_os" in - aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; - *) am_cv_func_iconv_works="guessing yes" ;; - esac -changequote([,])dnl - ]) - LIBS="$am_save_LIBS" - ]) - case "$am_cv_func_iconv_works" in - *no) am_func_iconv=no am_cv_lib_iconv=no ;; - *) am_func_iconv=yes ;; - esac - else - am_func_iconv=no am_cv_lib_iconv=no - fi - if test "$am_func_iconv" = yes; then - AC_DEFINE([HAVE_ICONV], [1], - [Define if you have the iconv() function and it works.]) - fi - if test "$am_cv_lib_iconv" = yes; then - AC_MSG_CHECKING([how to link with libiconv]) - AC_MSG_RESULT([$LIBICONV]) - else - dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV - dnl either. - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - AC_SUBST([LIBICONV]) - AC_SUBST([LTLIBICONV]) -]) - -dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to -dnl avoid warnings like -dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". -dnl This is tricky because of the way 'aclocal' is implemented: -dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. -dnl Otherwise aclocal's initial scan pass would miss the macro definition. -dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. -dnl Otherwise aclocal would emit many "Use of uninitialized value $1" -dnl warnings. -m4_define([gl_iconv_AC_DEFUN], - m4_version_prereq([2.64], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [m4_ifdef([gl_00GNULIB], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [[AC_DEFUN( - [$1], [$2])]])])) -gl_iconv_AC_DEFUN([AM_ICONV], -[ - AM_ICONV_LINK - if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL([am_cv_proto_iconv], [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - ]], - [[]])], - [am_cv_proto_iconv_arg1=""], - [am_cv_proto_iconv_arg1="const"]) - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([ - $am_cv_proto_iconv]) - AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], - [Define as const if the declaration of iconv() needs const.]) - dnl Also substitute ICONV_CONST in the gnulib generated . - m4_ifdef([gl_ICONV_H_DEFAULTS], - [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) - if test -n "$am_cv_proto_iconv_arg1"; then - ICONV_CONST="const" - fi - ]) - fi -]) diff --git a/m4/include_next.m4 b/m4/include_next.m4 deleted file mode 100644 index 108d94567..000000000 --- a/m4/include_next.m4 +++ /dev/null @@ -1,270 +0,0 @@ -# include_next.m4 serial 23 -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert and Derek Price. - -dnl Sets INCLUDE_NEXT and PRAGMA_SYSTEM_HEADER. -dnl -dnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to -dnl 'include' otherwise. -dnl -dnl INCLUDE_NEXT_AS_FIRST_DIRECTIVE expands to 'include_next' if the compiler -dnl supports it in the special case that it is the first include directive in -dnl the given file, or to 'include' otherwise. -dnl -dnl PRAGMA_SYSTEM_HEADER can be used in files that contain #include_next, -dnl so as to avoid GCC warnings when the gcc option -pedantic is used. -dnl '#pragma GCC system_header' has the same effect as if the file was found -dnl through the include search path specified with '-isystem' options (as -dnl opposed to the search path specified with '-I' options). Namely, gcc -dnl does not warn about some things, and on some systems (Solaris and Interix) -dnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side -dnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead -dnl of plain '__STDC__'. -dnl -dnl PRAGMA_COLUMNS can be used in files that override system header files, so -dnl as to avoid compilation errors on HP NonStop systems when the gnulib file -dnl is included by a system header file that does a "#pragma COLUMNS 80" (which -dnl has the effect of truncating the lines of that file and all files that it -dnl includes to 80 columns) and the gnulib file has lines longer than 80 -dnl columns. - -AC_DEFUN([gl_INCLUDE_NEXT], -[ - AC_LANG_PREPROC_REQUIRE() - AC_CACHE_CHECK([whether the preprocessor supports include_next], - [gl_cv_have_include_next], - [rm -rf conftestd1a conftestd1b conftestd2 - mkdir conftestd1a conftestd1b conftestd2 - dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on - dnl AIX 6.1 support include_next when used as first preprocessor directive - dnl in a file, but not when preceded by another include directive. Check - dnl for this bug by including . - dnl Additionally, with this same compiler, include_next is a no-op when - dnl used in a header file that was included by specifying its absolute - dnl file name. Despite these two bugs, include_next is used in the - dnl compiler's . By virtue of the second bug, we need to use - dnl include_next as well in this case. - cat < conftestd1a/conftest.h -#define DEFINED_IN_CONFTESTD1 -#include_next -#ifdef DEFINED_IN_CONFTESTD2 -int foo; -#else -#error "include_next doesn't work" -#endif -EOF - cat < conftestd1b/conftest.h -#define DEFINED_IN_CONFTESTD1 -#include -#include_next -#ifdef DEFINED_IN_CONFTESTD2 -int foo; -#else -#error "include_next doesn't work" -#endif -EOF - cat < conftestd2/conftest.h -#ifndef DEFINED_IN_CONFTESTD1 -#error "include_next test doesn't work" -#endif -#define DEFINED_IN_CONFTESTD2 -EOF - gl_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2" -dnl We intentionally avoid using AC_LANG_SOURCE here. - AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include ]], - [gl_cv_have_include_next=yes], - [CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2" - AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include ]], - [gl_cv_have_include_next=buggy], - [gl_cv_have_include_next=no]) - ]) - CPPFLAGS="$gl_save_CPPFLAGS" - rm -rf conftestd1a conftestd1b conftestd2 - ]) - PRAGMA_SYSTEM_HEADER= - if test $gl_cv_have_include_next = yes; then - INCLUDE_NEXT=include_next - INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next - if test -n "$GCC"; then - PRAGMA_SYSTEM_HEADER='#pragma GCC system_header' - fi - else - if test $gl_cv_have_include_next = buggy; then - INCLUDE_NEXT=include - INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next - else - INCLUDE_NEXT=include - INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include - fi - fi - AC_SUBST([INCLUDE_NEXT]) - AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE]) - AC_SUBST([PRAGMA_SYSTEM_HEADER]) - AC_CACHE_CHECK([whether system header files limit the line length], - [gl_cv_pragma_columns], - [dnl HP NonStop systems, which define __TANDEM, have this misfeature. - AC_EGREP_CPP([choke me], - [ -#ifdef __TANDEM -choke me -#endif - ], - [gl_cv_pragma_columns=yes], - [gl_cv_pragma_columns=no]) - ]) - if test $gl_cv_pragma_columns = yes; then - PRAGMA_COLUMNS="#pragma COLUMNS 10000" - else - PRAGMA_COLUMNS= - fi - AC_SUBST([PRAGMA_COLUMNS]) -]) - -# gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...) -# ------------------------------------------ -# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be -# ''; otherwise define it to be -# '"///usr/include/foo.h"', or whatever other absolute file name is suitable. -# Also, if #include_next works as first preprocessing directive in a file, -# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be ''; otherwise define it to -# be -# '"///usr/include/foo.h"', or whatever other absolute file name is suitable. -# That way, a header file with the following line: -# #@INCLUDE_NEXT@ @NEXT_FOO_H@ -# or -# #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@ -# behaves (after sed substitution) as if it contained -# #include_next -# even if the compiler does not support include_next. -# The three "///" are to pacify Sun C 5.8, which otherwise would say -# "warning: #include of /usr/include/... may be non-portable". -# Use '""', not '<>', so that the /// cannot be confused with a C99 comment. -# Note: This macro assumes that the header file is not empty after -# preprocessing, i.e. it does not only define preprocessor macros but also -# provides some type/enum definitions or function/variable declarations. -# -# This macro also checks whether each header exists, by invoking -# AC_CHECK_HEADERS_ONCE or AC_CHECK_HEADERS on each argument. -AC_DEFUN([gl_CHECK_NEXT_HEADERS], -[ - gl_NEXT_HEADERS_INTERNAL([$1], [check]) -]) - -# gl_NEXT_HEADERS(HEADER1 HEADER2 ...) -# ------------------------------------ -# Like gl_CHECK_NEXT_HEADERS, except do not check whether the headers exist. -# This is suitable for headers like that are standardized by C89 -# and therefore can be assumed to exist. -AC_DEFUN([gl_NEXT_HEADERS], -[ - gl_NEXT_HEADERS_INTERNAL([$1], [assume]) -]) - -# The guts of gl_CHECK_NEXT_HEADERS and gl_NEXT_HEADERS. -AC_DEFUN([gl_NEXT_HEADERS_INTERNAL], -[ - AC_REQUIRE([gl_INCLUDE_NEXT]) - AC_REQUIRE([AC_CANONICAL_HOST]) - - m4_if([$2], [check], - [AC_CHECK_HEADERS_ONCE([$1]) - ]) - -dnl FIXME: gl_next_header and gl_header_exists must be used unquoted -dnl until we can assume autoconf 2.64 or newer. - m4_foreach_w([gl_HEADER_NAME], [$1], - [AS_VAR_PUSHDEF([gl_next_header], - [gl_cv_next_]m4_defn([gl_HEADER_NAME])) - if test $gl_cv_have_include_next = yes; then - AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) - else - AC_CACHE_CHECK( - [absolute name of <]m4_defn([gl_HEADER_NAME])[>], - m4_defn([gl_next_header]), - [m4_if([$2], [check], - [AS_VAR_PUSHDEF([gl_header_exists], - [ac_cv_header_]m4_defn([gl_HEADER_NAME])) - if test AS_VAR_GET(gl_header_exists) = yes; then - AS_VAR_POPDEF([gl_header_exists]) - ]) - AC_LANG_CONFTEST( - [AC_LANG_SOURCE( - [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]] - )]) - dnl AIX "xlc -E" and "cc -E" omit #line directives for header - dnl files that contain only a #include of other header files and - dnl no non-comment tokens of their own. This leads to a failure - dnl to detect the absolute name of , , - dnl and others. The workaround is to force preservation - dnl of comments through option -C. This ensures all necessary - dnl #line directives are present. GCC supports option -C as well. - case "$host_os" in - aix*) gl_absname_cpp="$ac_cpp -C" ;; - *) gl_absname_cpp="$ac_cpp" ;; - esac -changequote(,) - case "$host_os" in - mingw*) - dnl For the sake of native Windows compilers (excluding gcc), - dnl treat backslash as a directory separator, like /. - dnl Actually, these compilers use a double-backslash as - dnl directory separator, inside the - dnl # line "filename" - dnl directives. - gl_dirsep_regex='[/\\]' - ;; - *) - gl_dirsep_regex='\/' - ;; - esac - dnl A sed expression that turns a string into a basic regular - dnl expression, for use within "/.../". - gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' -changequote([,]) - gl_header_literal_regex=`echo ']m4_defn([gl_HEADER_NAME])[' \ - | sed -e "$gl_make_literal_regex_sed"` - gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ - s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ -changequote(,)dnl - s|^/[^/]|//&| -changequote([,])dnl - p - q - }' - dnl eval is necessary to expand gl_absname_cpp. - dnl Ultrix and Pyramid sh refuse to redirect output of eval, - dnl so use subshell. - AS_VAR_SET(gl_next_header, - ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | - sed -n "$gl_absolute_header_sed"`'"']) - m4_if([$2], [check], - [else - AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) - fi - ]) - ]) - fi - AC_SUBST( - AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])), - [AS_VAR_GET(gl_next_header)]) - if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then - # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' - gl_next_as_first_directive='<'gl_HEADER_NAME'>' - else - # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' - gl_next_as_first_directive=AS_VAR_GET(gl_next_header) - fi - AC_SUBST( - AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])), - [$gl_next_as_first_directive]) - AS_VAR_POPDEF([gl_next_header])]) -]) - -# Autoconf 2.68 added warnings for our use of AC_COMPILE_IFELSE; -# this fallback is safe for all earlier autoconf versions. -m4_define_default([AC_LANG_DEFINES_PROVIDED]) diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4 deleted file mode 100644 index 74d0e80d2..000000000 --- a/m4/intdiv0.m4 +++ /dev/null @@ -1,87 +0,0 @@ -# intdiv0.m4 serial 6 (gettext-0.18.2) -dnl Copyright (C) 2002, 2007-2008, 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([gt_INTDIV0], -[ - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - - AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], - gt_cv_int_divbyzero_sigfpe, - [ - gt_cv_int_divbyzero_sigfpe= -changequote(,)dnl - case "$host_os" in - macos* | darwin[6-9]* | darwin[1-9][0-9]*) - # On Mac OS X 10.2 or newer, just assume the same as when cross- - # compiling. If we were to perform the real test, 1 Crash Report - # dialog window would pop up. - case "$host_cpu" in - i[34567]86 | x86_64) - gt_cv_int_divbyzero_sigfpe="guessing yes" ;; - esac - ;; - esac -changequote([,])dnl - if test -z "$gt_cv_int_divbyzero_sigfpe"; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include - -static void -sigfpe_handler (int sig) -{ - /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ - exit (sig != SIGFPE); -} - -int x = 1; -int y = 0; -int z; -int nan; - -int main () -{ - signal (SIGFPE, sigfpe_handler); -/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ -#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) - signal (SIGTRAP, sigfpe_handler); -#endif -/* Linux/SPARC yields signal SIGILL. */ -#if defined (__sparc__) && defined (__linux__) - signal (SIGILL, sigfpe_handler); -#endif - - z = x / y; - nan = y / y; - exit (2); -} -]])], - [gt_cv_int_divbyzero_sigfpe=yes], - [gt_cv_int_divbyzero_sigfpe=no], - [ - # Guess based on the CPU. -changequote(,)dnl - case "$host_cpu" in - alpha* | i[34567]86 | x86_64 | m68k | s390*) - gt_cv_int_divbyzero_sigfpe="guessing yes";; - *) - gt_cv_int_divbyzero_sigfpe="guessing no";; - esac -changequote([,])dnl - ]) - fi - ]) - case "$gt_cv_int_divbyzero_sigfpe" in - *yes) value=1;; - *) value=0;; - esac - AC_DEFINE_UNQUOTED([INTDIV0_RAISES_SIGFPE], [$value], - [Define if integer division by zero raises signal SIGFPE.]) -]) diff --git a/m4/intl.m4 b/m4/intl.m4 deleted file mode 100644 index 486b5cc64..000000000 --- a/m4/intl.m4 +++ /dev/null @@ -1,300 +0,0 @@ -# intl.m4 serial 22 (gettext-0.18.2) -dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2009. - -AC_PREREQ([2.60]) - -dnl Checks for all prerequisites of the intl subdirectory, -dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, -dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. -AC_DEFUN([AM_INTL_SUBDIR], -[ - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AC_PROG_MKDIR_P])dnl - AC_REQUIRE([AC_PROG_CC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl - AC_REQUIRE([gt_GLIBC2])dnl - AC_REQUIRE([AC_PROG_RANLIB])dnl - AC_REQUIRE([gl_VISIBILITY])dnl - AC_REQUIRE([gt_INTL_SUBDIR_CORE])dnl - AC_REQUIRE([AC_TYPE_LONG_LONG_INT])dnl - AC_REQUIRE([gt_TYPE_WCHAR_T])dnl - AC_REQUIRE([gt_TYPE_WINT_T])dnl - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gt_TYPE_INTMAX_T]) - AC_REQUIRE([gt_PRINTF_POSIX]) - AC_REQUIRE([gl_GLIBC21])dnl - AC_REQUIRE([gl_XSIZE])dnl - AC_REQUIRE([gl_FCNTL_O_FLAGS])dnl - AC_REQUIRE([gt_INTL_MACOSX])dnl - - dnl Support for automake's --enable-silent-rules. - case "$enable_silent_rules" in - yes) INTL_DEFAULT_VERBOSITY=0;; - no) INTL_DEFAULT_VERBOSITY=1;; - *) INTL_DEFAULT_VERBOSITY=1;; - esac - AC_SUBST([INTL_DEFAULT_VERBOSITY]) - - AC_CHECK_TYPE([ptrdiff_t], , - [AC_DEFINE([ptrdiff_t], [long], - [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) - ]) - AC_CHECK_HEADERS([features.h stddef.h stdlib.h string.h]) - AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \ - snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) - - dnl Use the _snprintf function only if it is declared (because on NetBSD it - dnl is defined as a weak alias of snprintf; we prefer to use the latter). - gt_CHECK_DECL(_snprintf, [#include ]) - gt_CHECK_DECL(_snwprintf, [#include ]) - - dnl Use the *_unlocked functions only if they are declared. - dnl (because some of them were defined without being declared in Solaris - dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built - dnl on Solaris 2.5.1 to run on Solaris 2.6). - dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. - gt_CHECK_DECL(getc_unlocked, [#include ]) - - case $gt_cv_func_printf_posix in - *yes) HAVE_POSIX_PRINTF=1 ;; - *) HAVE_POSIX_PRINTF=0 ;; - esac - AC_SUBST([HAVE_POSIX_PRINTF]) - if test "$ac_cv_func_asprintf" = yes; then - HAVE_ASPRINTF=1 - else - HAVE_ASPRINTF=0 - fi - AC_SUBST([HAVE_ASPRINTF]) - if test "$ac_cv_func_snprintf" = yes; then - HAVE_SNPRINTF=1 - else - HAVE_SNPRINTF=0 - fi - AC_SUBST([HAVE_SNPRINTF]) - if test "$ac_cv_func_newlocale" = yes; then - HAVE_NEWLOCALE=1 - else - HAVE_NEWLOCALE=0 - fi - AC_SUBST([HAVE_NEWLOCALE]) - if test "$ac_cv_func_wprintf" = yes; then - HAVE_WPRINTF=1 - else - HAVE_WPRINTF=0 - fi - AC_SUBST([HAVE_WPRINTF]) - - AM_LANGINFO_CODESET - gt_LC_MESSAGES - - dnl Compilation on mingw and Cygwin needs special Makefile rules, because - dnl 1. when we install a shared library, we must arrange to export - dnl auxiliary pointer variables for every exported variable, - dnl 2. when we install a shared library and a static library simultaneously, - dnl the include file specifies __declspec(dllimport) and therefore we - dnl must arrange to define the auxiliary pointer variables for the - dnl exported variables _also_ in the static library. - if test "$enable_shared" = yes; then - case "$host_os" in - mingw* | cygwin*) is_woe32dll=yes ;; - *) is_woe32dll=no ;; - esac - else - is_woe32dll=no - fi - WOE32DLL=$is_woe32dll - AC_SUBST([WOE32DLL]) - - dnl On mingw and Cygwin, we can activate special Makefile rules which add - dnl version information to the shared libraries and executables. - case "$host_os" in - mingw* | cygwin*) is_woe32=yes ;; - *) is_woe32=no ;; - esac - WOE32=$is_woe32 - AC_SUBST([WOE32]) - if test $WOE32 = yes; then - dnl Check for a program that compiles Windows resource files. - AC_CHECK_TOOL([WINDRES], [windres]) - fi - - dnl Determine whether when creating a library, "-lc" should be passed to - dnl libtool or not. On many platforms, it is required for the libtool option - dnl -no-undefined to work. On HP-UX, however, the -lc - stored by libtool - dnl in the *.la files - makes it impossible to create multithreaded programs, - dnl because libtool also reorders the -lc to come before the -pthread, and - dnl this disables pthread_create() . - case "$host_os" in - hpux*) LTLIBC="" ;; - *) LTLIBC="-lc" ;; - esac - AC_SUBST([LTLIBC]) - - dnl Rename some macros and functions used for locking. - AH_BOTTOM([ -#define __libc_lock_t gl_lock_t -#define __libc_lock_define gl_lock_define -#define __libc_lock_define_initialized gl_lock_define_initialized -#define __libc_lock_init gl_lock_init -#define __libc_lock_lock gl_lock_lock -#define __libc_lock_unlock gl_lock_unlock -#define __libc_lock_recursive_t gl_recursive_lock_t -#define __libc_lock_define_recursive gl_recursive_lock_define -#define __libc_lock_define_initialized_recursive gl_recursive_lock_define_initialized -#define __libc_lock_init_recursive gl_recursive_lock_init -#define __libc_lock_lock_recursive gl_recursive_lock_lock -#define __libc_lock_unlock_recursive gl_recursive_lock_unlock -#define glthread_in_use libintl_thread_in_use -#define glthread_lock_init_func libintl_lock_init_func -#define glthread_lock_lock_func libintl_lock_lock_func -#define glthread_lock_unlock_func libintl_lock_unlock_func -#define glthread_lock_destroy_func libintl_lock_destroy_func -#define glthread_rwlock_init_multithreaded libintl_rwlock_init_multithreaded -#define glthread_rwlock_init_func libintl_rwlock_init_func -#define glthread_rwlock_rdlock_multithreaded libintl_rwlock_rdlock_multithreaded -#define glthread_rwlock_rdlock_func libintl_rwlock_rdlock_func -#define glthread_rwlock_wrlock_multithreaded libintl_rwlock_wrlock_multithreaded -#define glthread_rwlock_wrlock_func libintl_rwlock_wrlock_func -#define glthread_rwlock_unlock_multithreaded libintl_rwlock_unlock_multithreaded -#define glthread_rwlock_unlock_func libintl_rwlock_unlock_func -#define glthread_rwlock_destroy_multithreaded libintl_rwlock_destroy_multithreaded -#define glthread_rwlock_destroy_func libintl_rwlock_destroy_func -#define glthread_recursive_lock_init_multithreaded libintl_recursive_lock_init_multithreaded -#define glthread_recursive_lock_init_func libintl_recursive_lock_init_func -#define glthread_recursive_lock_lock_multithreaded libintl_recursive_lock_lock_multithreaded -#define glthread_recursive_lock_lock_func libintl_recursive_lock_lock_func -#define glthread_recursive_lock_unlock_multithreaded libintl_recursive_lock_unlock_multithreaded -#define glthread_recursive_lock_unlock_func libintl_recursive_lock_unlock_func -#define glthread_recursive_lock_destroy_multithreaded libintl_recursive_lock_destroy_multithreaded -#define glthread_recursive_lock_destroy_func libintl_recursive_lock_destroy_func -#define glthread_once_func libintl_once_func -#define glthread_once_singlethreaded libintl_once_singlethreaded -#define glthread_once_multithreaded libintl_once_multithreaded -]) -]) - - -dnl Checks for the core files of the intl subdirectory: -dnl dcigettext.c -dnl eval-plural.h -dnl explodename.c -dnl finddomain.c -dnl gettextP.h -dnl gmo.h -dnl hash-string.h hash-string.c -dnl l10nflist.c -dnl libgnuintl.h.in (except the *printf stuff) -dnl loadinfo.h -dnl loadmsgcat.c -dnl localealias.c -dnl log.c -dnl plural-exp.h plural-exp.c -dnl plural.y -dnl Used by libglocale. -AC_DEFUN([gt_INTL_SUBDIR_CORE], -[ - AC_REQUIRE([AC_C_INLINE])dnl - AC_REQUIRE([AC_TYPE_SIZE_T])dnl - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_REQUIRE([AC_FUNC_ALLOCA])dnl - AC_REQUIRE([AC_FUNC_MMAP])dnl - AC_REQUIRE([gt_INTDIV0])dnl - AC_REQUIRE([gl_AC_TYPE_UINTMAX_T])dnl - AC_REQUIRE([gt_INTTYPES_PRI])dnl - AC_REQUIRE([gl_LOCK])dnl - - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[int foo (int a) { a = __builtin_expect (a, 10); return a == 10 ? 0 : 1; }]], - [[]])], - [AC_DEFINE([HAVE_BUILTIN_EXPECT], [1], - [Define to 1 if the compiler understands __builtin_expect.])]) - - AC_CHECK_HEADERS([argz.h inttypes.h limits.h unistd.h sys/param.h]) - AC_CHECK_FUNCS([getcwd getegid geteuid getgid getuid mempcpy munmap \ - stpcpy strcasecmp strdup strtoul tsearch uselocale argz_count \ - argz_stringify argz_next __fsetlocking]) - - dnl Use the *_unlocked functions only if they are declared. - dnl (because some of them were defined without being declared in Solaris - dnl 2.5.1 but were removed in Solaris 2.6, whereas we want binaries built - dnl on Solaris 2.5.1 to run on Solaris 2.6). - dnl Don't use AC_CHECK_DECLS because it isn't supported in autoconf-2.13. - gt_CHECK_DECL([feof_unlocked], [#include ]) - gt_CHECK_DECL([fgets_unlocked], [#include ]) - - AM_ICONV - - dnl intl/plural.c is generated from intl/plural.y. It requires bison, - dnl because plural.y uses bison specific features. It requires at least - dnl bison-1.26 because earlier versions generate a plural.c that doesn't - dnl compile. - dnl bison is only needed for the maintainer (who touches plural.y). But in - dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put - dnl the rule in general Makefile. Now, some people carelessly touch the - dnl files or have a broken "make" program, hence the plural.c rule will - dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not - dnl present or too old. - AC_CHECK_PROGS([INTLBISON], [bison]) - if test -z "$INTLBISON"; then - ac_verc_fail=yes - else - dnl Found it, now check the version. - AC_MSG_CHECKING([version of bison]) -changequote(<<,>>)dnl - ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` - case $ac_prog_version in - '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; - 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) -changequote([,])dnl - ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; - *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; - esac - AC_MSG_RESULT([$ac_prog_version]) - fi - if test $ac_verc_fail = yes; then - INTLBISON=: - fi -]) - - -dnl gt_CHECK_DECL(FUNC, INCLUDES) -dnl Check whether a function is declared. -AC_DEFUN([gt_CHECK_DECL], -[ - AC_CACHE_CHECK([whether $1 is declared], [ac_cv_have_decl_$1], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[$2]], - [[ -#ifndef $1 - char *p = (char *) $1; -#endif - ]])], - [ac_cv_have_decl_$1=yes], - [ac_cv_have_decl_$1=no])]) - if test $ac_cv_have_decl_$1 = yes; then - gt_value=1 - else - gt_value=0 - fi - AC_DEFINE_UNQUOTED([HAVE_DECL_]m4_translit($1, [a-z], [A-Z]), [$gt_value], - [Define to 1 if you have the declaration of '$1', and to 0 if you don't.]) -]) diff --git a/m4/intldir.m4 b/m4/intldir.m4 deleted file mode 100644 index 388ecd6fd..000000000 --- a/m4/intldir.m4 +++ /dev/null @@ -1,19 +0,0 @@ -# intldir.m4 serial 2 (gettext-0.18) -dnl Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -AC_PREREQ([2.52]) - -dnl Tells the AM_GNU_GETTEXT macro to consider an intl/ directory. -AC_DEFUN([AM_GNU_GETTEXT_INTL_SUBDIR], []) diff --git a/m4/intlmacosx.m4 b/m4/intlmacosx.m4 deleted file mode 100644 index ab97d39f9..000000000 --- a/m4/intlmacosx.m4 +++ /dev/null @@ -1,56 +0,0 @@ -# intlmacosx.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2004-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Checks for special options needed on Mac OS X. -dnl Defines INTL_MACOSX_LIBS. -AC_DEFUN([gt_INTL_MACOSX], -[ - dnl Check for API introduced in Mac OS X 10.2. - AC_CACHE_CHECK([for CFPreferencesCopyAppValue], - [gt_cv_func_CFPreferencesCopyAppValue], - [gt_save_LIBS="$LIBS" - LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[CFPreferencesCopyAppValue(NULL, NULL)]])], - [gt_cv_func_CFPreferencesCopyAppValue=yes], - [gt_cv_func_CFPreferencesCopyAppValue=no]) - LIBS="$gt_save_LIBS"]) - if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then - AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], - [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) - fi - dnl Check for API introduced in Mac OS X 10.3. - AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], - [gt_save_LIBS="$LIBS" - LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[CFLocaleCopyCurrent();]])], - [gt_cv_func_CFLocaleCopyCurrent=yes], - [gt_cv_func_CFLocaleCopyCurrent=no]) - LIBS="$gt_save_LIBS"]) - if test $gt_cv_func_CFLocaleCopyCurrent = yes; then - AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], - [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) - fi - INTL_MACOSX_LIBS= - if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then - INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" - fi - AC_SUBST([INTL_MACOSX_LIBS]) -]) diff --git a/m4/intmax.m4 b/m4/intmax.m4 deleted file mode 100644 index 18733a52e..000000000 --- a/m4/intmax.m4 +++ /dev/null @@ -1,36 +0,0 @@ -# intmax.m4 serial 6 (gettext-0.18.2) -dnl Copyright (C) 2002-2005, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether the system has the 'intmax_t' type, but don't attempt to -dnl find a replacement if it is lacking. - -AC_DEFUN([gt_TYPE_INTMAX_T], -[ - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include -#if HAVE_STDINT_H_WITH_UINTMAX -#include -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -#include -#endif - ]], - [[intmax_t x = -1; - return !x;]])], - [gt_cv_c_intmax_t=yes], - [gt_cv_c_intmax_t=no])]) - if test $gt_cv_c_intmax_t = yes; then - AC_DEFINE([HAVE_INTMAX_T], [1], - [Define if you have the 'intmax_t' type in or .]) - fi -]) diff --git a/m4/intmax_t.m4 b/m4/intmax_t.m4 deleted file mode 100644 index 6ea70531c..000000000 --- a/m4/intmax_t.m4 +++ /dev/null @@ -1,67 +0,0 @@ -# intmax_t.m4 serial 8 -dnl Copyright (C) 1997-2004, 2006-2007, 2009-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -AC_PREREQ([2.53]) - -# Define intmax_t to 'long' or 'long long' -# if it is not already defined in or . - -AC_DEFUN([gl_AC_TYPE_INTMAX_T], -[ - dnl For simplicity, we assume that a header file defines 'intmax_t' if and - dnl only if it defines 'uintmax_t'. - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - test $ac_cv_type_long_long_int = yes \ - && ac_type='long long' \ - || ac_type='long' - AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], - [Define to long or long long if and don't define.]) - else - AC_DEFINE([HAVE_INTMAX_T], [1], - [Define if you have the 'intmax_t' type in or .]) - fi -]) - -dnl An alternative would be to explicitly test for 'intmax_t'. - -AC_DEFUN([gt_AC_TYPE_INTMAX_T], -[ - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_CACHE_CHECK([for intmax_t], [gt_cv_c_intmax_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include -#if HAVE_STDINT_H_WITH_UINTMAX -#include -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -#include -#endif - ]], - [[intmax_t x = -1; return !x;]])], - [gt_cv_c_intmax_t=yes], - [gt_cv_c_intmax_t=no])]) - if test $gt_cv_c_intmax_t = yes; then - AC_DEFINE([HAVE_INTMAX_T], [1], - [Define if you have the 'intmax_t' type in or .]) - else - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - test $ac_cv_type_long_long_int = yes \ - && ac_type='long long' \ - || ac_type='long' - AC_DEFINE_UNQUOTED([intmax_t], [$ac_type], - [Define to long or long long if and don't define.]) - fi -]) diff --git a/m4/inttypes-pri.m4 b/m4/inttypes-pri.m4 deleted file mode 100644 index e5a1e0571..000000000 --- a/m4/inttypes-pri.m4 +++ /dev/null @@ -1,42 +0,0 @@ -# inttypes-pri.m4 serial 7 (gettext-0.18.2) -dnl Copyright (C) 1997-2002, 2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_PREREQ([2.53]) - -# Define PRI_MACROS_BROKEN if exists and defines the PRI* -# macros to non-string values. This is the case on AIX 4.3.3. - -AC_DEFUN([gt_INTTYPES_PRI], -[ - AC_CHECK_HEADERS([inttypes.h]) - if test $ac_cv_header_inttypes_h = yes; then - AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], - [gt_cv_inttypes_pri_broken], - [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#ifdef PRId32 -char *p = PRId32; -#endif - ]], - [[]])], - [gt_cv_inttypes_pri_broken=no], - [gt_cv_inttypes_pri_broken=yes]) - ]) - fi - if test "$gt_cv_inttypes_pri_broken" = yes; then - AC_DEFINE_UNQUOTED([PRI_MACROS_BROKEN], [1], - [Define if exists and defines unusable PRI* macros.]) - PRI_MACROS_BROKEN=1 - else - PRI_MACROS_BROKEN=0 - fi - AC_SUBST([PRI_MACROS_BROKEN]) -]) diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4 deleted file mode 100644 index 5f05ac58c..000000000 --- a/m4/inttypes_h.m4 +++ /dev/null @@ -1,29 +0,0 @@ -# inttypes_h.m4 serial 10 -dnl Copyright (C) 1997-2004, 2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, -# doesn't clash with , and declares uintmax_t. - -AC_DEFUN([gl_AC_HEADER_INTTYPES_H], -[ - AC_CACHE_CHECK([for inttypes.h], [gl_cv_header_inttypes_h], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - ]], - [[uintmax_t i = (uintmax_t) -1; return !i;]])], - [gl_cv_header_inttypes_h=yes], - [gl_cv_header_inttypes_h=no])]) - if test $gl_cv_header_inttypes_h = yes; then - AC_DEFINE_UNQUOTED([HAVE_INTTYPES_H_WITH_UINTMAX], [1], - [Define if exists, doesn't clash with , - and declares uintmax_t. ]) - fi -]) diff --git a/m4/langinfo_h.m4 b/m4/langinfo_h.m4 deleted file mode 100644 index 73bef8bce..000000000 --- a/m4/langinfo_h.m4 +++ /dev/null @@ -1,105 +0,0 @@ -# langinfo_h.m4 serial 7 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_LANGINFO_H], -[ - AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) - - dnl Persuade glibc-2.0.6 to define CODESET. - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - dnl is always overridden, because of GNULIB_POSIXCHECK. - gl_CHECK_NEXT_HEADERS([langinfo.h]) - - dnl Determine whether exists. It is missing on mingw and BeOS. - HAVE_LANGINFO_CODESET=0 - HAVE_LANGINFO_T_FMT_AMPM=0 - HAVE_LANGINFO_ERA=0 - HAVE_LANGINFO_YESEXPR=0 - AC_CHECK_HEADERS_ONCE([langinfo.h]) - if test $ac_cv_header_langinfo_h = yes; then - HAVE_LANGINFO_H=1 - dnl Determine what defines. CODESET and ERA etc. are missing - dnl on OpenBSD 3.8. T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3. - AC_CACHE_CHECK([whether langinfo.h defines CODESET], - [gl_cv_header_langinfo_codeset], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include -int a = CODESET; -]])], - [gl_cv_header_langinfo_codeset=yes], - [gl_cv_header_langinfo_codeset=no]) - ]) - if test $gl_cv_header_langinfo_codeset = yes; then - HAVE_LANGINFO_CODESET=1 - fi - AC_CACHE_CHECK([whether langinfo.h defines T_FMT_AMPM], - [gl_cv_header_langinfo_t_fmt_ampm], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include -int a = T_FMT_AMPM; -]])], - [gl_cv_header_langinfo_t_fmt_ampm=yes], - [gl_cv_header_langinfo_t_fmt_ampm=no]) - ]) - if test $gl_cv_header_langinfo_t_fmt_ampm = yes; then - HAVE_LANGINFO_T_FMT_AMPM=1 - fi - AC_CACHE_CHECK([whether langinfo.h defines ERA], - [gl_cv_header_langinfo_era], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include -int a = ERA; -]])], - [gl_cv_header_langinfo_era=yes], - [gl_cv_header_langinfo_era=no]) - ]) - if test $gl_cv_header_langinfo_era = yes; then - HAVE_LANGINFO_ERA=1 - fi - AC_CACHE_CHECK([whether langinfo.h defines YESEXPR], - [gl_cv_header_langinfo_yesexpr], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include -int a = YESEXPR; -]])], - [gl_cv_header_langinfo_yesexpr=yes], - [gl_cv_header_langinfo_yesexpr=no]) - ]) - if test $gl_cv_header_langinfo_yesexpr = yes; then - HAVE_LANGINFO_YESEXPR=1 - fi - else - HAVE_LANGINFO_H=0 - fi - AC_SUBST([HAVE_LANGINFO_H]) - AC_SUBST([HAVE_LANGINFO_CODESET]) - AC_SUBST([HAVE_LANGINFO_T_FMT_AMPM]) - AC_SUBST([HAVE_LANGINFO_ERA]) - AC_SUBST([HAVE_LANGINFO_YESEXPR]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[#include - ]], [nl_langinfo]) -]) - -AC_DEFUN([gl_LANGINFO_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_LANGINFO_H_DEFAULTS], -[ - GNULIB_NL_LANGINFO=0; AC_SUBST([GNULIB_NL_LANGINFO]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_NL_LANGINFO=1; AC_SUBST([HAVE_NL_LANGINFO]) - REPLACE_NL_LANGINFO=0; AC_SUBST([REPLACE_NL_LANGINFO]) -]) diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4 deleted file mode 100644 index d62a175fc..000000000 --- a/m4/lcmessage.m4 +++ /dev/null @@ -1,35 +0,0 @@ -# lcmessage.m4 serial 7 (gettext-0.18.2) -dnl Copyright (C) 1995-2002, 2004-2005, 2008-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995. - -# Check whether LC_MESSAGES is available in . - -AC_DEFUN([gt_LC_MESSAGES], -[ - AC_CACHE_CHECK([for LC_MESSAGES], [gt_cv_val_LC_MESSAGES], - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[return LC_MESSAGES]])], - [gt_cv_val_LC_MESSAGES=yes], - [gt_cv_val_LC_MESSAGES=no])]) - if test $gt_cv_val_LC_MESSAGES = yes; then - AC_DEFINE([HAVE_LC_MESSAGES], [1], - [Define if your file defines LC_MESSAGES.]) - fi -]) diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4 deleted file mode 100644 index c145e478e..000000000 --- a/m4/lib-ld.m4 +++ /dev/null @@ -1,119 +0,0 @@ -# lib-ld.m4 serial 6 -dnl Copyright (C) 1996-2003, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Subroutines of libtool.m4, -dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid -dnl collision with libtool.m4. - -dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. -AC_DEFUN([AC_LIB_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], -[# I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 /dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` - while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL([acl_cv_path_LD], -[if test -z "$LD"; then - acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$acl_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 = 1.10 to complain if config.rpath is missing. - m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) - AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS - AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host - AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir - AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - ]) - wl="$acl_cv_wl" - acl_libext="$acl_cv_libext" - acl_shlibext="$acl_cv_shlibext" - acl_libname_spec="$acl_cv_libname_spec" - acl_library_names_spec="$acl_cv_library_names_spec" - acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - acl_hardcode_direct="$acl_cv_hardcode_direct" - acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" - dnl Determine whether the user wants rpath handling at all. - AC_ARG_ENABLE([rpath], - [ --disable-rpath do not hardcode runtime library paths], - :, enable_rpath=yes) -]) - -dnl AC_LIB_FROMPACKAGE(name, package) -dnl declares that libname comes from the given package. The configure file -dnl will then not have a --with-libname-prefix option but a -dnl --with-package-prefix option. Several libraries can come from the same -dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar -dnl macro call that searches for libname. -AC_DEFUN([AC_LIB_FROMPACKAGE], -[ - pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - define([acl_frompackage_]NAME, [$2]) - popdef([NAME]) - pushdef([PACK],[$2]) - pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - define([acl_libsinpackage_]PACKUP, - m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) - popdef([PACKUP]) - popdef([PACK]) -]) - -dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. -dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found -dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. -AC_DEFUN([AC_LIB_LINKFLAGS_BODY], -[ - AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) - pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) - pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) - dnl Autoconf >= 2.61 supports dots in --with options. - pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_ARG_WITH(P_A_C_K[-prefix], -[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib - --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/$acl_libdirstem" - if test "$acl_libdirstem2" != "$acl_libdirstem" \ - && ! test -d "$withval/$acl_libdirstem"; then - additional_libdir="$withval/$acl_libdirstem2" - fi - fi - fi -]) - dnl Search the library and its dependencies in $additional_libdir and - dnl $LDFLAGS. Using breadth-first-seach. - LIB[]NAME= - LTLIB[]NAME= - INC[]NAME= - LIB[]NAME[]_PREFIX= - dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been - dnl computed. So it has to be reset here. - HAVE_LIB[]NAME= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='$1 $2' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - dnl See if it was already located by an earlier AC_LIB_LINKFLAGS - dnl or AC_LIB_HAVE_LINKFLAGS call. - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" - else - dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined - dnl that this library doesn't exist. So just drop it. - : - fi - else - dnl Search the library lib$name in $additional_libdir and $LDFLAGS - dnl and the already constructed $LIBNAME/$LTLIBNAME. - found_dir= - found_la= - found_so= - found_a= - eval libname=\"$acl_libname_spec\" # typically: libname=lib$name - if test -n "$acl_shlibext"; then - shrext=".$acl_shlibext" # typically: shrext=.so - else - shrext= - fi - if test $use_additional = yes; then - dir="$additional_libdir" - dnl The same code as in the loop below: - dnl First look for a shared library. - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - dnl Then look for a static library. - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - dnl First look for a shared library. - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - dnl Then look for a static library. - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - dnl Found the library. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - dnl Linking with a shared library. We attempt to hardcode its - dnl directory into the executable's runpath, unless it's the - dnl standard /usr/lib. - if test "$enable_rpath" = no \ - || test "X$found_dir" = "X/usr/$acl_libdirstem" \ - || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then - dnl No hardcoding is needed. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - dnl The hardcoding into $LIBNAME is system dependent. - if test "$acl_hardcode_direct" = yes; then - dnl Using DIR/libNAME.so during linking hardcodes DIR into the - dnl resulting binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - dnl Rely on "-L$found_dir". - dnl But don't add it if it's already contained in the LDFLAGS - dnl or the already constructed $LIBNAME - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" - fi - if test "$acl_hardcode_minus_L" != no; then - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH - dnl here, because this doesn't fit in flags passed to the - dnl compiler. So give up. No hardcoding. This affects only - dnl very old systems. - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - dnl Linking with a static library. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" - else - dnl We shouldn't come here, but anyway it's good to have a - dnl fallback. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" - fi - fi - dnl Assume the include files are nearby. - additional_includedir= - case "$found_dir" in - */$acl_libdirstem | */$acl_libdirstem/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` - if test "$name" = '$1'; then - LIB[]NAME[]_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - */$acl_libdirstem2 | */$acl_libdirstem2/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` - if test "$name" = '$1'; then - LIB[]NAME[]_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - dnl Potentially add $additional_includedir to $INCNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's /usr/local/include and we are using GCC on Linux, - dnl 3. if it's already present in $CPPFLAGS or the already - dnl constructed $INCNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INC[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $INCNAME. - INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - dnl Look for dependencies. - if test -n "$found_la"; then - dnl Read the .la file. It defines the variables - dnl dlname, library_names, old_library, dependency_libs, current, - dnl age, revision, installed, dlopen, dlpreopen, libdir. - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - dnl We use only dependency_libs. - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's /usr/local/lib and we are using GCC on Linux, - dnl 3. if it's already present in $LDFLAGS or the already - dnl constructed $LIBNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ - && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ - || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - dnl Handle this in the next round. Throw away the .la's - dnl directory; it is already contained in a preceding -L - dnl option. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - dnl Most likely an immediate library name. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" - ;; - esac - done - fi - else - dnl Didn't find the library; assume it is in the system directories - dnl known to the linker and runtime loader. (All the system - dnl directories known to the linker should also be known to the - dnl runtime loader, otherwise the system is severely misconfigured.) - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$acl_hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user must - dnl pass all path elements in one option. We can arrange that for a - dnl single library, but not when more than one $LIBNAMEs are used. - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" - done - dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - else - dnl The -rpath options are cumulative. - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - dnl When using libtool, the option that works for both libraries and - dnl executables is -R. The -R options are cumulative. - for found_dir in $ltrpathdirs; do - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" - done - fi - popdef([P_A_C_K]) - popdef([PACKLIBS]) - popdef([PACKUP]) - popdef([PACK]) - popdef([NAME]) -]) - -dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, -dnl unless already present in VAR. -dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes -dnl contains two or three consecutive elements that belong together. -AC_DEFUN([AC_LIB_APPENDTOVAR], -[ - for element in [$2]; do - haveit= - for x in $[$1]; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - [$1]="${[$1]}${[$1]:+ }$element" - fi - done -]) - -dnl For those cases where a variable contains several -L and -l options -dnl referring to unknown libraries and directories, this macro determines the -dnl necessary additional linker options for the runtime path. -dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) -dnl sets LDADDVAR to linker options needed together with LIBSVALUE. -dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, -dnl otherwise linking without libtool is assumed. -AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], -[ - AC_REQUIRE([AC_LIB_RPATH]) - AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) - $1= - if test "$enable_rpath" != no; then - if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode directories into the resulting - dnl binary. - rpathdirs= - next= - for opt in $2; do - if test -n "$next"; then - dir="$next" - dnl No need to hardcode the standard /usr/lib. - if test "X$dir" != "X/usr/$acl_libdirstem" \ - && test "X$dir" != "X/usr/$acl_libdirstem2"; then - rpathdirs="$rpathdirs $dir" - fi - next= - else - case $opt in - -L) next=yes ;; - -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` - dnl No need to hardcode the standard /usr/lib. - if test "X$dir" != "X/usr/$acl_libdirstem" \ - && test "X$dir" != "X/usr/$acl_libdirstem2"; then - rpathdirs="$rpathdirs $dir" - fi - next= ;; - *) next= ;; - esac - fi - done - if test "X$rpathdirs" != "X"; then - if test -n ""$3""; then - dnl libtool is used for linking. Use -R options. - for dir in $rpathdirs; do - $1="${$1}${$1:+ }-R$dir" - done - else - dnl The linker is used for linking directly. - if test -n "$acl_hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user - dnl must pass all path elements in one option. - alldirs= - for dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - $1="$flag" - else - dnl The -rpath options are cumulative. - for dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$dir" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - $1="${$1}${$1:+ }$flag" - done - fi - fi - fi - fi - fi - AC_SUBST([$1]) -]) diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4 deleted file mode 100644 index 60908e8fb..000000000 --- a/m4/lib-prefix.m4 +++ /dev/null @@ -1,224 +0,0 @@ -# lib-prefix.m4 serial 7 (gettext-0.18) -dnl Copyright (C) 2001-2005, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and -dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't -dnl require excessive bracketing. -ifdef([AC_HELP_STRING], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], -[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) - -dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed -dnl to access previously installed libraries. The basic assumption is that -dnl a user will want packages to use other packages he previously installed -dnl with the same --prefix option. -dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate -dnl libraries, but is otherwise very convenient. -AC_DEFUN([AC_LIB_PREFIX], -[ - AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/$acl_libdirstem" - fi - fi -]) - if test $use_additional = yes; then - dnl Potentially add $additional_includedir to $CPPFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's already present in $CPPFLAGS, - dnl 3. if it's /usr/local/include and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - for x in $CPPFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $CPPFLAGS. - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" - fi - fi - fi - fi - dnl Potentially add $additional_libdir to $LDFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's already present in $LDFLAGS, - dnl 3. if it's /usr/local/lib and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then - haveit= - for x in $LDFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LDFLAGS. - LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" - fi - fi - fi - fi - fi -]) - -dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, -dnl acl_final_exec_prefix, containing the values to which $prefix and -dnl $exec_prefix will expand at the end of the configure script. -AC_DEFUN([AC_LIB_PREPARE_PREFIX], -[ - dnl Unfortunately, prefix and exec_prefix get only finally determined - dnl at the end of configure. - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the -dnl variables prefix and exec_prefix bound to the values they will have -dnl at the end of the configure script. -AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], -[ - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - $1 - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_PREPARE_MULTILIB creates -dnl - a variable acl_libdirstem, containing the basename of the libdir, either -dnl "lib" or "lib64" or "lib/64", -dnl - a variable acl_libdirstem2, as a secondary possible value for -dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or -dnl "lib/amd64". -AC_DEFUN([AC_LIB_PREPARE_MULTILIB], -[ - dnl There is no formal standard regarding lib and lib64. - dnl On glibc systems, the current practice is that on a system supporting - dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under - dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine - dnl the compiler's default mode by looking at the compiler's library search - dnl path. If at least one of its elements ends in /lib64 or points to a - dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. - dnl Otherwise we use the default, namely "lib". - dnl On Solaris systems, the current practice is that on a system supporting - dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under - dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or - dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. - AC_REQUIRE([AC_CANONICAL_HOST]) - acl_libdirstem=lib - acl_libdirstem2= - case "$host_os" in - solaris*) - dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment - dnl . - dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." - dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the - dnl symlink is missing, so we set acl_libdirstem2 too. - AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], - [AC_EGREP_CPP([sixtyfour bits], [ -#ifdef _LP64 -sixtyfour bits -#endif - ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) - ]) - if test $gl_cv_solaris_64bit = yes; then - acl_libdirstem=lib/64 - case "$host_cpu" in - sparc*) acl_libdirstem2=lib/sparcv9 ;; - i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; - esac - fi - ;; - *) - searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` - if test -n "$searchpath"; then - acl_save_IFS="${IFS= }"; IFS=":" - for searchdir in $searchpath; do - if test -d "$searchdir"; then - case "$searchdir" in - */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; - */../ | */.. ) - # Better ignore directories of this form. They are misleading. - ;; - *) searchdir=`cd "$searchdir" && pwd` - case "$searchdir" in - */lib64 ) acl_libdirstem=lib64 ;; - esac ;; - esac - fi - done - IFS="$acl_save_IFS" - fi - ;; - esac - test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" -]) diff --git a/m4/libunistring-base.m4 b/m4/libunistring-base.m4 deleted file mode 100644 index d105c7217..000000000 --- a/m4/libunistring-base.m4 +++ /dev/null @@ -1,141 +0,0 @@ -# libunistring-base.m4 serial 5 -dnl Copyright (C) 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paolo Bonzini and Bruno Haible. - -dnl gl_LIBUNISTRING_MODULE([VERSION], [Module]) -dnl Declares that the source files of Module should be compiled, unless we -dnl are linking with libunistring and its version is >= the given VERSION. -dnl Defines an automake conditional LIBUNISTRING_COMPILE_$MODULE that is -dnl true if the source files of Module should be compiled. -dnl This macro is to be used for public libunistring API, not for -dnl undocumented API. -dnl -dnl You have to bump the VERSION argument to the next projected version -dnl number each time you make a change that affects the behaviour of the -dnl functions defined in Module (even if the sources of Module itself do not -dnl change). - -AC_DEFUN([gl_LIBUNISTRING_MODULE], -[ - AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) - dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from - dnl gl_LIBUNISTRING_CORE if that macro has been run. - AM_CONDITIONAL(AS_TR_CPP([LIBUNISTRING_COMPILE_$2]), - [gl_LIBUNISTRING_VERSION_CMP([$1])]) -]) - -dnl gl_LIBUNISTRING_LIBHEADER([VERSION], [HeaderFile]) -dnl Declares that HeaderFile should be created, unless we are linking -dnl with libunistring and its version is >= the given VERSION. -dnl HeaderFile should be relative to the lib directory and end in '.h'. -dnl Prepares for substituting LIBUNISTRING_HEADERFILE (to HeaderFile or empty). -dnl -dnl When we are linking with the already installed libunistring and its version -dnl is < VERSION, we create HeaderFile here, because we may compile functions -dnl (via gl_LIBUNISTRING_MODULE above) that are not contained in the installed -dnl version. -dnl When we are linking with the already installed libunistring and its version -dnl is > VERSION, we don't create HeaderFile here: it could cause compilation -dnl errors in other libunistring header files if some types are missing. -dnl -dnl You have to bump the VERSION argument to the next projected version -dnl number each time you make a non-comment change to the HeaderFile. - -AC_DEFUN([gl_LIBUNISTRING_LIBHEADER], -[ - AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) - dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from - dnl gl_LIBUNISTRING_CORE if that macro has been run. - if gl_LIBUNISTRING_VERSION_CMP([$1]); then - LIBUNISTRING_[]AS_TR_CPP([$2])='$2' - else - LIBUNISTRING_[]AS_TR_CPP([$2])= - fi - AC_SUBST([LIBUNISTRING_]AS_TR_CPP([$2])) -]) - -dnl Miscellaneous preparations/initializations. - -AC_DEFUN([gl_LIBUNISTRING_LIB_PREPARE], -[ - dnl Ensure that HAVE_LIBUNISTRING is fully determined at this point. - m4_ifdef([gl_LIBUNISTRING], [AC_REQUIRE([gl_LIBUNISTRING])]) - - AC_REQUIRE([AC_PROG_AWK]) - -dnl Sed expressions to extract the parts of a version number. -changequote(,) -gl_libunistring_sed_extract_major='/^[0-9]/{s/^\([0-9]*\).*/\1/p;q;} -i\ -0 -q -' -gl_libunistring_sed_extract_minor='/^[0-9][0-9]*[.][0-9]/{s/^[0-9]*[.]\([0-9]*\).*/\1/p;q;} -i\ -0 -q -' -gl_libunistring_sed_extract_subminor='/^[0-9][0-9]*[.][0-9][0-9]*[.][0-9]/{s/^[0-9]*[.][0-9]*[.]\([0-9]*\).*/\1/p;q;} -i\ -0 -q -' -changequote([,]) - - if test "$HAVE_LIBUNISTRING" = yes; then - LIBUNISTRING_VERSION_MAJOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_major"` - LIBUNISTRING_VERSION_MINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_minor"` - LIBUNISTRING_VERSION_SUBMINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_subminor"` - fi -]) - -dnl gl_LIBUNISTRING_VERSION_CMP([VERSION]) -dnl Expands to a shell statement that evaluates to true if LIBUNISTRING_VERSION -dnl is less than the VERSION argument. -AC_DEFUN([gl_LIBUNISTRING_VERSION_CMP], -[ { test "$HAVE_LIBUNISTRING" != yes \ - || { - dnl AS_LITERAL_IF exists and works fine since autoconf-2.59 at least. - AS_LITERAL_IF([$1], - [dnl This is the optimized variant, that assumes the argument is a literal: - m4_pushdef([requested_version_major], - [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^\([0-9]*\).*], [\1]), [])]) - m4_pushdef([requested_version_minor], - [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) - m4_pushdef([requested_version_subminor], - [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.][0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) - test $LIBUNISTRING_VERSION_MAJOR -lt requested_version_major \ - || { test $LIBUNISTRING_VERSION_MAJOR -eq requested_version_major \ - && { test $LIBUNISTRING_VERSION_MINOR -lt requested_version_minor \ - || { test $LIBUNISTRING_VERSION_MINOR -eq requested_version_minor \ - && test $LIBUNISTRING_VERSION_SUBMINOR -lt requested_version_subminor - } - } - } - m4_popdef([requested_version_subminor]) - m4_popdef([requested_version_minor]) - m4_popdef([requested_version_major]) - ], - [dnl This is the unoptimized variant: - requested_version_major=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_major"` - requested_version_minor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_minor"` - requested_version_subminor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_subminor"` - test $LIBUNISTRING_VERSION_MAJOR -lt $requested_version_major \ - || { test $LIBUNISTRING_VERSION_MAJOR -eq $requested_version_major \ - && { test $LIBUNISTRING_VERSION_MINOR -lt $requested_version_minor \ - || { test $LIBUNISTRING_VERSION_MINOR -eq $requested_version_minor \ - && test $LIBUNISTRING_VERSION_SUBMINOR -lt $requested_version_subminor - } - } - } - ]) - } - }]) - -dnl gl_LIBUNISTRING_ARG_OR_ZERO([ARG], [ORIG]) expands to ARG if it is not the -dnl same as ORIG, otherwise to 0. -m4_define([gl_LIBUNISTRING_ARG_OR_ZERO], [m4_if([$1], [$2], [0], [$1])]) diff --git a/m4/localcharset.m4 b/m4/localcharset.m4 deleted file mode 100644 index 2e93e5818..000000000 --- a/m4/localcharset.m4 +++ /dev/null @@ -1,17 +0,0 @@ -# localcharset.m4 serial 7 -dnl Copyright (C) 2002, 2004, 2006, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_LOCALCHARSET], -[ - dnl Prerequisites of lib/localcharset.c. - AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_REQUIRE([gl_FCNTL_O_FLAGS]) - AC_CHECK_DECLS_ONCE([getc_unlocked]) - - dnl Prerequisites of the lib/Makefile.am snippet. - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([gl_GLIBC21]) -]) diff --git a/m4/locale-fr.m4 b/m4/locale-fr.m4 deleted file mode 100644 index ef199e397..000000000 --- a/m4/locale-fr.m4 +++ /dev/null @@ -1,250 +0,0 @@ -# locale-fr.m4 serial 17 -dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl Determine the name of a french locale with traditional encoding. -AC_DEFUN([gt_LOCALE_FR], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a traditional french locale], [gt_cv_locale_fr], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl -#include -#include -#if HAVE_LANGINFO_CODESET -# include -#endif -#include -#include -struct tm t; -char buf[16]; -int main () { - /* Check whether the given locale name is recognized by the system. */ -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ - /* On native Windows, setlocale(category, "") looks at the system settings, - not at the environment variables. Also, when an encoding suffix such - as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE - category of the locale to "C". */ - if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL - || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) - return 1; -#else - if (setlocale (LC_ALL, "") == NULL) return 1; -#endif - /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". - On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) - is empty, and the behaviour of Tcl 8.4 in this locale is not useful. - On OpenBSD 4.0, when an unsupported locale is specified, setlocale() - succeeds but then nl_langinfo(CODESET) is "646". In this situation, - some unit tests fail. - On MirBSD 10, when an unsupported locale is specified, setlocale() - succeeds but then nl_langinfo(CODESET) is "UTF-8". */ -#if HAVE_LANGINFO_CODESET - { - const char *cs = nl_langinfo (CODESET); - if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 - || strcmp (cs, "UTF-8") == 0) - return 1; - } -#endif -#ifdef __CYGWIN__ - /* On Cygwin, avoid locale names without encoding suffix, because the - locale_charset() function relies on the encoding suffix. Note that - LC_ALL is set on the command line. */ - if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; -#endif - /* Check whether in the abbreviation of the second month, the second - character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is only - one byte long. This excludes the UTF-8 encoding. */ - t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; - if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1; -#if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ - /* Check whether the decimal separator is a comma. - On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point - are nl_langinfo(RADIXCHAR) are both ".". */ - if (localeconv () ->decimal_point[0] != ',') return 1; -#endif - return 0; -} -changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - case "$host_os" in - # Handle native Windows specially, because there setlocale() interprets - # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", - # "fr" or "fra" as "French" or "French_France.1252", - # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", - # "ja" as "Japanese" or "Japanese_Japan.932", - # and similar. - mingw*) - # Test for the native Windows locale name. - if (LC_ALL=French_France.1252 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=French_France.1252 - else - # None found. - gt_cv_locale_fr=none - fi - ;; - *) - # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because - # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the - # configure script would override the LC_ALL setting. Likewise for - # LC_CTYPE, which is also set at the beginning of the configure script. - # Test for the usual locale name. - if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR - else - # Test for the locale name with explicit encoding suffix. - if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR.ISO-8859-1 - else - # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name. - if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR.ISO8859-1 - else - # Test for the HP-UX locale name. - if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr_FR.iso88591 - else - # Test for the Solaris 7 locale name. - if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr=fr - else - # None found. - gt_cv_locale_fr=none - fi - fi - fi - fi - fi - ;; - esac - fi - rm -fr conftest* - ]) - LOCALE_FR=$gt_cv_locale_fr - AC_SUBST([LOCALE_FR]) -]) - -dnl Determine the name of a french locale with UTF-8 encoding. -AC_DEFUN([gt_LOCALE_FR_UTF8], -[ - AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a french Unicode locale], [gt_cv_locale_fr_utf8], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl -#include -#include -#if HAVE_LANGINFO_CODESET -# include -#endif -#include -#include -struct tm t; -char buf[16]; -int main () { - /* On BeOS and Haiku, locales are not implemented in libc. Rather, libintl - imitates locale dependent behaviour by looking at the environment - variables, and all locales use the UTF-8 encoding. */ -#if !(defined __BEOS__ || defined __HAIKU__) - /* Check whether the given locale name is recognized by the system. */ -# if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ - /* On native Windows, setlocale(category, "") looks at the system settings, - not at the environment variables. Also, when an encoding suffix such - as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE - category of the locale to "C". */ - if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL - || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) - return 1; -# else - if (setlocale (LC_ALL, "") == NULL) return 1; -# endif - /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". - On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) - is empty, and the behaviour of Tcl 8.4 in this locale is not useful. - On OpenBSD 4.0, when an unsupported locale is specified, setlocale() - succeeds but then nl_langinfo(CODESET) is "646". In this situation, - some unit tests fail. */ -# if HAVE_LANGINFO_CODESET - { - const char *cs = nl_langinfo (CODESET); - if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) - return 1; - } -# endif -# ifdef __CYGWIN__ - /* On Cygwin, avoid locale names without encoding suffix, because the - locale_charset() function relies on the encoding suffix. Note that - LC_ALL is set on the command line. */ - if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; -# endif - /* Check whether in the abbreviation of the second month, the second - character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is - two bytes long, with UTF-8 encoding. */ - t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; - if (strftime (buf, sizeof (buf), "%b", &t) < 4 - || buf[1] != (char) 0xc3 || buf[2] != (char) 0xa9 || buf[3] != 'v') - return 1; -#endif -#if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ - /* Check whether the decimal separator is a comma. - On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point - are nl_langinfo(RADIXCHAR) are both ".". */ - if (localeconv () ->decimal_point[0] != ',') return 1; -#endif - return 0; -} -changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - case "$host_os" in - # Handle native Windows specially, because there setlocale() interprets - # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", - # "fr" or "fra" as "French" or "French_France.1252", - # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", - # "ja" as "Japanese" or "Japanese_Japan.932", - # and similar. - mingw*) - # Test for the hypothetical native Windows locale name. - if (LC_ALL=French_France.65001 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr_utf8=French_France.65001 - else - # None found. - gt_cv_locale_fr_utf8=none - fi - ;; - *) - # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because - # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the - # configure script would override the LC_ALL setting. Likewise for - # LC_CTYPE, which is also set at the beginning of the configure script. - # Test for the usual locale name. - if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr_utf8=fr_FR - else - # Test for the locale name with explicit encoding suffix. - if (LC_ALL=fr_FR.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr_utf8=fr_FR.UTF-8 - else - # Test for the Solaris 7 locale name. - if (LC_ALL=fr.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_fr_utf8=fr.UTF-8 - else - # None found. - gt_cv_locale_fr_utf8=none - fi - fi - fi - ;; - esac - fi - rm -fr conftest* - ]) - LOCALE_FR_UTF8=$gt_cv_locale_fr_utf8 - AC_SUBST([LOCALE_FR_UTF8]) -]) diff --git a/m4/locale-ja.m4 b/m4/locale-ja.m4 deleted file mode 100644 index 132a3e779..000000000 --- a/m4/locale-ja.m4 +++ /dev/null @@ -1,136 +0,0 @@ -# locale-ja.m4 serial 12 -dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl Determine the name of a japanese locale with EUC-JP encoding. -AC_DEFUN([gt_LOCALE_JA], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a traditional japanese locale], [gt_cv_locale_ja], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl -#include -#include -#if HAVE_LANGINFO_CODESET -# include -#endif -#include -#include -struct tm t; -char buf[16]; -int main () -{ - const char *p; - /* Check whether the given locale name is recognized by the system. */ -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ - /* On native Windows, setlocale(category, "") looks at the system settings, - not at the environment variables. Also, when an encoding suffix such - as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE - category of the locale to "C". */ - if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL - || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) - return 1; -#else - if (setlocale (LC_ALL, "") == NULL) return 1; -#endif - /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". - On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) - is empty, and the behaviour of Tcl 8.4 in this locale is not useful. - On OpenBSD 4.0, when an unsupported locale is specified, setlocale() - succeeds but then nl_langinfo(CODESET) is "646". In this situation, - some unit tests fail. - On MirBSD 10, when an unsupported locale is specified, setlocale() - succeeds but then nl_langinfo(CODESET) is "UTF-8". */ -#if HAVE_LANGINFO_CODESET - { - const char *cs = nl_langinfo (CODESET); - if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 - || strcmp (cs, "UTF-8") == 0) - return 1; - } -#endif -#ifdef __CYGWIN__ - /* On Cygwin, avoid locale names without encoding suffix, because the - locale_charset() function relies on the encoding suffix. Note that - LC_ALL is set on the command line. */ - if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; -#endif - /* Check whether MB_CUR_MAX is > 1. This excludes the dysfunctional locales - on Cygwin 1.5.x. */ - if (MB_CUR_MAX == 1) - return 1; - /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. - This excludes the UTF-8 encoding (except on MirBSD). */ - t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; - if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; - for (p = buf; *p != '\0'; p++) - if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) - return 1; - return 0; -} -changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - case "$host_os" in - # Handle native Windows specially, because there setlocale() interprets - # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", - # "fr" or "fra" as "French" or "French_France.1252", - # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", - # "ja" as "Japanese" or "Japanese_Japan.932", - # and similar. - mingw*) - # Note that on native Windows, the Japanese locale is - # Japanese_Japan.932, and CP932 is very different from EUC-JP, so we - # cannot use it here. - gt_cv_locale_ja=none - ;; - *) - # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because - # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the - # configure script would override the LC_ALL setting. Likewise for - # LC_CTYPE, which is also set at the beginning of the configure script. - # Test for the AIX locale name. - if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP - else - # Test for the locale name with explicit encoding suffix. - if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP.EUC-JP - else - # Test for the HP-UX, OSF/1, NetBSD locale name. - if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP.eucJP - else - # Test for the IRIX, FreeBSD locale name. - if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja_JP.EUC - else - # Test for the Solaris 7 locale name. - if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_ja=ja - else - # Special test for NetBSD 1.6. - if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then - gt_cv_locale_ja=ja_JP.eucJP - else - # None found. - gt_cv_locale_ja=none - fi - fi - fi - fi - fi - fi - ;; - esac - fi - rm -fr conftest* - ]) - LOCALE_JA=$gt_cv_locale_ja - AC_SUBST([LOCALE_JA]) -]) diff --git a/m4/locale-zh.m4 b/m4/locale-zh.m4 deleted file mode 100644 index 4eed73f40..000000000 --- a/m4/locale-zh.m4 +++ /dev/null @@ -1,130 +0,0 @@ -# locale-zh.m4 serial 12 -dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl Determine the name of a chinese locale with GB18030 encoding. -AC_DEFUN([gt_LOCALE_ZH_CN], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AM_LANGINFO_CODESET]) - AC_CACHE_CHECK([for a transitional chinese locale], [gt_cv_locale_zh_CN], [ - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -changequote(,)dnl -#include -#include -#include -#if HAVE_LANGINFO_CODESET -# include -#endif -#include -#include -struct tm t; -char buf[16]; -int main () -{ - const char *p; - /* Check whether the given locale name is recognized by the system. */ -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ - /* On native Windows, setlocale(category, "") looks at the system settings, - not at the environment variables. Also, when an encoding suffix such - as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE - category of the locale to "C". */ - if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL - || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) - return 1; -#else - if (setlocale (LC_ALL, "") == NULL) return 1; -#endif - /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". - On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) - is empty, and the behaviour of Tcl 8.4 in this locale is not useful. - On OpenBSD 4.0, when an unsupported locale is specified, setlocale() - succeeds but then nl_langinfo(CODESET) is "646". In this situation, - some unit tests fail. - On MirBSD 10, when an unsupported locale is specified, setlocale() - succeeds but then nl_langinfo(CODESET) is "UTF-8". */ -#if HAVE_LANGINFO_CODESET - { - const char *cs = nl_langinfo (CODESET); - if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 - || strcmp (cs, "UTF-8") == 0) - return 1; - } -#endif -#ifdef __CYGWIN__ - /* On Cygwin, avoid locale names without encoding suffix, because the - locale_charset() function relies on the encoding suffix. Note that - LC_ALL is set on the command line. */ - if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; -#endif - /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. - This excludes the UTF-8 encoding (except on MirBSD). */ - t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; - if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; - for (p = buf; *p != '\0'; p++) - if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0) - return 1; - /* Check whether a typical GB18030 multibyte sequence is recognized as a - single wide character. This excludes the GB2312 and GBK encodings. */ - if (mblen ("\203\062\332\066", 5) != 4) - return 1; - return 0; -} -changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - case "$host_os" in - # Handle native Windows specially, because there setlocale() interprets - # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", - # "fr" or "fra" as "French" or "French_France.1252", - # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", - # "ja" as "Japanese" or "Japanese_Japan.932", - # and similar. - mingw*) - # Test for the hypothetical native Windows locale name. - if (LC_ALL=Chinese_China.54936 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_zh_CN=Chinese_China.54936 - else - # None found. - gt_cv_locale_zh_CN=none - fi - ;; - solaris2.8) - # On Solaris 8, the locales zh_CN.GB18030, zh_CN.GBK, zh.GBK are - # broken. One witness is the test case in gl_MBRTOWC_SANITYCHECK. - # Another witness is that "LC_ALL=zh_CN.GB18030 bash -c true" dumps core. - gt_cv_locale_zh_CN=none - ;; - *) - # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because - # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the - # configure script would override the LC_ALL setting. Likewise for - # LC_CTYPE, which is also set at the beginning of the configure script. - # Test for the locale name without encoding suffix. - if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_zh_CN=zh_CN - else - # Test for the locale name with explicit encoding suffix. - if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then - gt_cv_locale_zh_CN=zh_CN.GB18030 - else - # None found. - gt_cv_locale_zh_CN=none - fi - fi - ;; - esac - else - # If there was a link error, due to mblen(), the system is so old that - # it certainly doesn't have a chinese locale. - gt_cv_locale_zh_CN=none - fi - rm -fr conftest* - ]) - LOCALE_ZH_CN=$gt_cv_locale_zh_CN - AC_SUBST([LOCALE_ZH_CN]) -]) diff --git a/m4/locale_h.m4 b/m4/locale_h.m4 deleted file mode 100644 index 8bd12e80e..000000000 --- a/m4/locale_h.m4 +++ /dev/null @@ -1,122 +0,0 @@ -# locale_h.m4 serial 19 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_LOCALE_H], -[ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. - AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) - - dnl Persuade glibc to define locale_t and the int_p_*, int_n_* - dnl members of 'struct lconv'. - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - - dnl If is replaced, then must also be replaced. - AC_REQUIRE([gl_STDDEF_H]) - - dnl Solaris 11 2011-11 defines the int_p_*, int_n_* members of 'struct lconv' - dnl only if _LCONV_C99 is defined. - AC_REQUIRE([AC_CANONICAL_HOST]) - case "$host_os" in - solaris*) - AC_DEFINE([_LCONV_C99], [1], [Define to 1 on Solaris.]) - ;; - esac - - AC_CACHE_CHECK([whether locale.h conforms to POSIX:2001], - [gl_cv_header_locale_h_posix2001], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - int x = LC_MESSAGES; - int y = sizeof (((struct lconv *) 0)->decimal_point);]], - [[]])], - [gl_cv_header_locale_h_posix2001=yes], - [gl_cv_header_locale_h_posix2001=no])]) - - dnl Check for . - AC_CHECK_HEADERS_ONCE([xlocale.h]) - if test $ac_cv_header_xlocale_h = yes; then - HAVE_XLOCALE_H=1 - dnl Check whether use of locale_t requires inclusion of , - dnl e.g. on Mac OS X 10.5. If does not define locale_t by - dnl itself, we assume that will do so. - AC_CACHE_CHECK([whether locale.h defines locale_t], - [gl_cv_header_locale_has_locale_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - locale_t x;]], - [[]])], - [gl_cv_header_locale_has_locale_t=yes], - [gl_cv_header_locale_has_locale_t=no]) - ]) - if test $gl_cv_header_locale_has_locale_t = yes; then - gl_cv_header_locale_h_needs_xlocale_h=no - else - gl_cv_header_locale_h_needs_xlocale_h=yes - fi - else - HAVE_XLOCALE_H=0 - gl_cv_header_locale_h_needs_xlocale_h=no - fi - AC_SUBST([HAVE_XLOCALE_H]) - - dnl Check whether 'struct lconv' is complete. - dnl Bionic libc's 'struct lconv' is just a dummy. - dnl On OpenBSD 4.9, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 1.5.x, - dnl mingw, MSVC 9, it lacks the int_p_* and int_n_* members. - AC_CACHE_CHECK([whether struct lconv is properly defined], - [gl_cv_sys_struct_lconv_ok], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - struct lconv l; - int x = sizeof (l.decimal_point); - int y = sizeof (l.int_p_cs_precedes);]], - [[]])], - [gl_cv_sys_struct_lconv_ok=yes], - [gl_cv_sys_struct_lconv_ok=no]) - ]) - if test $gl_cv_sys_struct_lconv_ok = no; then - REPLACE_STRUCT_LCONV=1 - fi - - dnl is always overridden, because of GNULIB_POSIXCHECK. - gl_NEXT_HEADERS([locale.h]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[#include -/* Some systems provide declarations in a non-standard header. */ -#if HAVE_XLOCALE_H -# include -#endif - ]], - [setlocale duplocale]) -]) - -AC_DEFUN([gl_LOCALE_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_LOCALE_H_DEFAULTS], -[ - GNULIB_LOCALECONV=0; AC_SUBST([GNULIB_LOCALECONV]) - GNULIB_SETLOCALE=0; AC_SUBST([GNULIB_SETLOCALE]) - GNULIB_DUPLOCALE=0; AC_SUBST([GNULIB_DUPLOCALE]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_DUPLOCALE=1; AC_SUBST([HAVE_DUPLOCALE]) - REPLACE_LOCALECONV=0; AC_SUBST([REPLACE_LOCALECONV]) - REPLACE_SETLOCALE=0; AC_SUBST([REPLACE_SETLOCALE]) - REPLACE_DUPLOCALE=0; AC_SUBST([REPLACE_DUPLOCALE]) - REPLACE_STRUCT_LCONV=0; AC_SUBST([REPLACE_STRUCT_LCONV]) -]) diff --git a/m4/localeconv.m4 b/m4/localeconv.m4 deleted file mode 100644 index b8bb5964b..000000000 --- a/m4/localeconv.m4 +++ /dev/null @@ -1,22 +0,0 @@ -# localeconv.m4 serial 1 -dnl Copyright (C) 2012-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_LOCALECONV], -[ - AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) - AC_REQUIRE([gl_LOCALE_H]) - - if test $REPLACE_STRUCT_LCONV = 1; then - REPLACE_LOCALECONV=1 - fi -]) - -# Prerequisites of lib/localeconv.c. -AC_DEFUN([gl_PREREQ_LOCALECONV], -[ - AC_CHECK_MEMBERS([struct lconv.decimal_point], [], [], - [[#include ]]) -]) diff --git a/m4/lock.m4 b/m4/lock.m4 deleted file mode 100644 index d3fc1eff0..000000000 --- a/m4/lock.m4 +++ /dev/null @@ -1,39 +0,0 @@ -# lock.m4 serial 13 (gettext-0.18.2) -dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([gl_LOCK], -[ - AC_REQUIRE([gl_THREADLIB]) - if test "$gl_threads_api" = posix; then - # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the - # pthread_rwlock_* functions. - AC_CHECK_TYPE([pthread_rwlock_t], - [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1], - [Define if the POSIX multithreading library has read/write locks.])], - [], - [#include ]) - # glibc defines PTHREAD_MUTEX_RECURSIVE as enum, not as a macro. - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM( - [[#include ]], - [[ -#if __FreeBSD__ == 4 -error "No, in FreeBSD 4.0 recursive mutexes actually don't work." -#else -int x = (int)PTHREAD_MUTEX_RECURSIVE; -return !x; -#endif - ]])], - [AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE], [1], - [Define if the defines PTHREAD_MUTEX_RECURSIVE.])]) - fi - gl_PREREQ_LOCK -]) - -# Prerequisites of lib/glthread/lock.c. -AC_DEFUN([gl_PREREQ_LOCK], [:]) diff --git a/m4/longlong.m4 b/m4/longlong.m4 deleted file mode 100644 index 3af6ab5aa..000000000 --- a/m4/longlong.m4 +++ /dev/null @@ -1,113 +0,0 @@ -# longlong.m4 serial 17 -dnl Copyright (C) 1999-2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_LONG_LONG_INT if 'long long int' works. -# This fixes a bug in Autoconf 2.61, and can be faster -# than what's in Autoconf 2.62 through 2.68. - -# Note: If the type 'long long int' exists but is only 32 bits large -# (as on some very old compilers), HAVE_LONG_LONG_INT will not be -# defined. In this case you can treat 'long long int' like 'long int'. - -AC_DEFUN([AC_TYPE_LONG_LONG_INT], -[ - AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) - AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], - [ac_cv_type_long_long_int=yes - if test "x${ac_cv_prog_cc_c99-no}" = xno; then - ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int - if test $ac_cv_type_long_long_int = yes; then - dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. - dnl If cross compiling, assume the bug is not important, since - dnl nobody cross compiles for this platform as far as we know. - AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[@%:@include - @%:@ifndef LLONG_MAX - @%:@ define HALF \ - (1LL << (sizeof (long long int) * CHAR_BIT - 2)) - @%:@ define LLONG_MAX (HALF - 1 + HALF) - @%:@endif]], - [[long long int n = 1; - int i; - for (i = 0; ; i++) - { - long long int m = n << i; - if (m >> i != n) - return 1; - if (LLONG_MAX / 2 < m) - break; - } - return 0;]])], - [], - [ac_cv_type_long_long_int=no], - [:]) - fi - fi]) - if test $ac_cv_type_long_long_int = yes; then - AC_DEFINE([HAVE_LONG_LONG_INT], [1], - [Define to 1 if the system has the type 'long long int'.]) - fi -]) - -# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. -# This fixes a bug in Autoconf 2.61, and can be faster -# than what's in Autoconf 2.62 through 2.68. - -# Note: If the type 'unsigned long long int' exists but is only 32 bits -# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT -# will not be defined. In this case you can treat 'unsigned long long int' -# like 'unsigned long int'. - -AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], -[ - AC_CACHE_CHECK([for unsigned long long int], - [ac_cv_type_unsigned_long_long_int], - [ac_cv_type_unsigned_long_long_int=yes - if test "x${ac_cv_prog_cc_c99-no}" = xno; then - AC_LINK_IFELSE( - [_AC_TYPE_LONG_LONG_SNIPPET], - [], - [ac_cv_type_unsigned_long_long_int=no]) - fi]) - if test $ac_cv_type_unsigned_long_long_int = yes; then - AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], - [Define to 1 if the system has the type 'unsigned long long int'.]) - fi -]) - -# Expands to a C program that can be used to test for simultaneous support -# of 'long long' and 'unsigned long long'. We don't want to say that -# 'long long' is available if 'unsigned long long' is not, or vice versa, -# because too many programs rely on the symmetry between signed and unsigned -# integer types (excluding 'bool'). -AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], -[ - AC_LANG_PROGRAM( - [[/* For now, do not test the preprocessor; as of 2007 there are too many - implementations with broken preprocessors. Perhaps this can - be revisited in 2012. In the meantime, code should not expect - #if to work with literals wider than 32 bits. */ - /* Test literals. */ - long long int ll = 9223372036854775807ll; - long long int nll = -9223372036854775807LL; - unsigned long long int ull = 18446744073709551615ULL; - /* Test constant expressions. */ - typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) - ? 1 : -1)]; - typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 - ? 1 : -1)]; - int i = 63;]], - [[/* Test availability of runtime routines for shift and division. */ - long long int llmax = 9223372036854775807ll; - unsigned long long int ullmax = 18446744073709551615ull; - return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) - | (llmax / ll) | (llmax % ll) - | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) - | (ullmax / ull) | (ullmax % ull));]]) -]) diff --git a/m4/malloc.m4 b/m4/malloc.m4 deleted file mode 100644 index 4b24a0b11..000000000 --- a/m4/malloc.m4 +++ /dev/null @@ -1,98 +0,0 @@ -# malloc.m4 serial 14 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -m4_version_prereq([2.70], [] ,[ - -# This is taken from the following Autoconf patch: -# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 -AC_DEFUN([_AC_FUNC_MALLOC_IF], -[ - AC_REQUIRE([AC_HEADER_STDC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles - AC_CHECK_HEADERS([stdlib.h]) - AC_CACHE_CHECK([for GNU libc compatible malloc], - [ac_cv_func_malloc_0_nonnull], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H - # include - #else - char *malloc (); - #endif - ]], - [[return ! malloc (0);]]) - ], - [ac_cv_func_malloc_0_nonnull=yes], - [ac_cv_func_malloc_0_nonnull=no], - [case "$host_os" in - # Guess yes on platforms where we know the result. - *-gnu* | freebsd* | netbsd* | openbsd* \ - | hpux* | solaris* | cygwin* | mingw*) - ac_cv_func_malloc_0_nonnull=yes ;; - # If we don't know, assume the worst. - *) ac_cv_func_malloc_0_nonnull=no ;; - esac - ]) - ]) - AS_IF([test $ac_cv_func_malloc_0_nonnull = yes], [$1], [$2]) -])# _AC_FUNC_MALLOC_IF - -]) - -# gl_FUNC_MALLOC_GNU -# ------------------ -# Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if -# it is not. -AC_DEFUN([gl_FUNC_MALLOC_GNU], -[ - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - dnl _AC_FUNC_MALLOC_IF is defined in Autoconf. - _AC_FUNC_MALLOC_IF( - [AC_DEFINE([HAVE_MALLOC_GNU], [1], - [Define to 1 if your system has a GNU libc compatible 'malloc' - function, and to 0 otherwise.])], - [AC_DEFINE([HAVE_MALLOC_GNU], [0]) - REPLACE_MALLOC=1 - ]) -]) - -# gl_FUNC_MALLOC_POSIX -# -------------------- -# Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it -# fails), and replace malloc if it is not. -AC_DEFUN([gl_FUNC_MALLOC_POSIX], -[ - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) - if test $gl_cv_func_malloc_posix = yes; then - AC_DEFINE([HAVE_MALLOC_POSIX], [1], - [Define if the 'malloc' function is POSIX compliant.]) - else - REPLACE_MALLOC=1 - fi -]) - -# Test whether malloc, realloc, calloc are POSIX compliant, -# Set gl_cv_func_malloc_posix to yes or no accordingly. -AC_DEFUN([gl_CHECK_MALLOC_POSIX], -[ - AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant], - [gl_cv_func_malloc_posix], - [ - dnl It is too dangerous to try to allocate a large amount of memory: - dnl some systems go to their knees when you do that. So assume that - dnl all Unix implementations of the function are POSIX compliant. - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[]], - [[#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - choke me - #endif - ]])], - [gl_cv_func_malloc_posix=yes], - [gl_cv_func_malloc_posix=no]) - ]) -]) diff --git a/m4/math_h.m4 b/m4/math_h.m4 deleted file mode 100644 index bf0845fd1..000000000 --- a/m4/math_h.m4 +++ /dev/null @@ -1,353 +0,0 @@ -# math_h.m4 serial 114 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_MATH_H], -[ - AC_REQUIRE([gl_MATH_H_DEFAULTS]) - gl_CHECK_NEXT_HEADERS([math.h]) - - AC_CACHE_CHECK([whether NAN macro works], [gl_cv_header_math_nan_works], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[/* Solaris 10 has a broken definition of NAN. Other platforms - fail to provide NAN, or provide it only in C99 mode; this - test only needs to fail when NAN is provided but wrong. */ - float f = 1.0f; -#ifdef NAN - f = NAN; -#endif - return f == 0;]])], - [gl_cv_header_math_nan_works=yes], - [gl_cv_header_math_nan_works=no])]) - if test $gl_cv_header_math_nan_works = no; then - REPLACE_NAN=1 - fi - AC_CACHE_CHECK([whether HUGE_VAL works], [gl_cv_header_math_huge_val_works], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[/* Solaris 10 has a broken definition of HUGE_VAL. */ - double d = HUGE_VAL; - return d == 0;]])], - [gl_cv_header_math_huge_val_works=yes], - [gl_cv_header_math_huge_val_works=no])]) - if test $gl_cv_header_math_huge_val_works = no; then - REPLACE_HUGE_VAL=1 - fi - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[#include ]], - [acosf acosl asinf asinl atanf atanl - cbrt cbrtf cbrtl ceilf ceill copysign copysignf copysignl cosf cosl coshf - expf expl exp2 exp2f exp2l expm1 expm1f expm1l - fabsf fabsl floorf floorl fma fmaf fmal - fmod fmodf fmodl frexpf frexpl hypotf hypotl - ilogb ilogbf ilogbl - ldexpf ldexpl - log logf logl log10 log10f log10l log1p log1pf log1pl log2 log2f log2l - logb logbf logbl - modf modff modfl powf - remainder remainderf remainderl - rint rintf rintl round roundf roundl sinf sinl sinhf sqrtf sqrtl - tanf tanl tanhf trunc truncf truncl]) -]) - -AC_DEFUN([gl_MATH_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_MATH_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_MATH_H_DEFAULTS], -[ - GNULIB_ACOSF=0; AC_SUBST([GNULIB_ACOSF]) - GNULIB_ACOSL=0; AC_SUBST([GNULIB_ACOSL]) - GNULIB_ASINF=0; AC_SUBST([GNULIB_ASINF]) - GNULIB_ASINL=0; AC_SUBST([GNULIB_ASINL]) - GNULIB_ATANF=0; AC_SUBST([GNULIB_ATANF]) - GNULIB_ATANL=0; AC_SUBST([GNULIB_ATANL]) - GNULIB_ATAN2F=0; AC_SUBST([GNULIB_ATAN2F]) - GNULIB_CBRT=0; AC_SUBST([GNULIB_CBRT]) - GNULIB_CBRTF=0; AC_SUBST([GNULIB_CBRTF]) - GNULIB_CBRTL=0; AC_SUBST([GNULIB_CBRTL]) - GNULIB_CEIL=0; AC_SUBST([GNULIB_CEIL]) - GNULIB_CEILF=0; AC_SUBST([GNULIB_CEILF]) - GNULIB_CEILL=0; AC_SUBST([GNULIB_CEILL]) - GNULIB_COPYSIGN=0; AC_SUBST([GNULIB_COPYSIGN]) - GNULIB_COPYSIGNF=0; AC_SUBST([GNULIB_COPYSIGNF]) - GNULIB_COPYSIGNL=0; AC_SUBST([GNULIB_COPYSIGNL]) - GNULIB_COSF=0; AC_SUBST([GNULIB_COSF]) - GNULIB_COSL=0; AC_SUBST([GNULIB_COSL]) - GNULIB_COSHF=0; AC_SUBST([GNULIB_COSHF]) - GNULIB_EXPF=0; AC_SUBST([GNULIB_EXPF]) - GNULIB_EXPL=0; AC_SUBST([GNULIB_EXPL]) - GNULIB_EXP2=0; AC_SUBST([GNULIB_EXP2]) - GNULIB_EXP2F=0; AC_SUBST([GNULIB_EXP2F]) - GNULIB_EXP2L=0; AC_SUBST([GNULIB_EXP2L]) - GNULIB_EXPM1=0; AC_SUBST([GNULIB_EXPM1]) - GNULIB_EXPM1F=0; AC_SUBST([GNULIB_EXPM1F]) - GNULIB_EXPM1L=0; AC_SUBST([GNULIB_EXPM1L]) - GNULIB_FABSF=0; AC_SUBST([GNULIB_FABSF]) - GNULIB_FABSL=0; AC_SUBST([GNULIB_FABSL]) - GNULIB_FLOOR=0; AC_SUBST([GNULIB_FLOOR]) - GNULIB_FLOORF=0; AC_SUBST([GNULIB_FLOORF]) - GNULIB_FLOORL=0; AC_SUBST([GNULIB_FLOORL]) - GNULIB_FMA=0; AC_SUBST([GNULIB_FMA]) - GNULIB_FMAF=0; AC_SUBST([GNULIB_FMAF]) - GNULIB_FMAL=0; AC_SUBST([GNULIB_FMAL]) - GNULIB_FMOD=0; AC_SUBST([GNULIB_FMOD]) - GNULIB_FMODF=0; AC_SUBST([GNULIB_FMODF]) - GNULIB_FMODL=0; AC_SUBST([GNULIB_FMODL]) - GNULIB_FREXPF=0; AC_SUBST([GNULIB_FREXPF]) - GNULIB_FREXP=0; AC_SUBST([GNULIB_FREXP]) - GNULIB_FREXPL=0; AC_SUBST([GNULIB_FREXPL]) - GNULIB_HYPOT=0; AC_SUBST([GNULIB_HYPOT]) - GNULIB_HYPOTF=0; AC_SUBST([GNULIB_HYPOTF]) - GNULIB_HYPOTL=0; AC_SUBST([GNULIB_HYPOTL]) - GNULIB_ILOGB=0; AC_SUBST([GNULIB_ILOGB]) - GNULIB_ILOGBF=0; AC_SUBST([GNULIB_ILOGBF]) - GNULIB_ILOGBL=0; AC_SUBST([GNULIB_ILOGBL]) - GNULIB_ISFINITE=0; AC_SUBST([GNULIB_ISFINITE]) - GNULIB_ISINF=0; AC_SUBST([GNULIB_ISINF]) - GNULIB_ISNAN=0; AC_SUBST([GNULIB_ISNAN]) - GNULIB_ISNANF=0; AC_SUBST([GNULIB_ISNANF]) - GNULIB_ISNAND=0; AC_SUBST([GNULIB_ISNAND]) - GNULIB_ISNANL=0; AC_SUBST([GNULIB_ISNANL]) - GNULIB_LDEXPF=0; AC_SUBST([GNULIB_LDEXPF]) - GNULIB_LDEXPL=0; AC_SUBST([GNULIB_LDEXPL]) - GNULIB_LOG=0; AC_SUBST([GNULIB_LOG]) - GNULIB_LOGF=0; AC_SUBST([GNULIB_LOGF]) - GNULIB_LOGL=0; AC_SUBST([GNULIB_LOGL]) - GNULIB_LOG10=0; AC_SUBST([GNULIB_LOG10]) - GNULIB_LOG10F=0; AC_SUBST([GNULIB_LOG10F]) - GNULIB_LOG10L=0; AC_SUBST([GNULIB_LOG10L]) - GNULIB_LOG1P=0; AC_SUBST([GNULIB_LOG1P]) - GNULIB_LOG1PF=0; AC_SUBST([GNULIB_LOG1PF]) - GNULIB_LOG1PL=0; AC_SUBST([GNULIB_LOG1PL]) - GNULIB_LOG2=0; AC_SUBST([GNULIB_LOG2]) - GNULIB_LOG2F=0; AC_SUBST([GNULIB_LOG2F]) - GNULIB_LOG2L=0; AC_SUBST([GNULIB_LOG2L]) - GNULIB_LOGB=0; AC_SUBST([GNULIB_LOGB]) - GNULIB_LOGBF=0; AC_SUBST([GNULIB_LOGBF]) - GNULIB_LOGBL=0; AC_SUBST([GNULIB_LOGBL]) - GNULIB_MODF=0; AC_SUBST([GNULIB_MODF]) - GNULIB_MODFF=0; AC_SUBST([GNULIB_MODFF]) - GNULIB_MODFL=0; AC_SUBST([GNULIB_MODFL]) - GNULIB_POWF=0; AC_SUBST([GNULIB_POWF]) - GNULIB_REMAINDER=0; AC_SUBST([GNULIB_REMAINDER]) - GNULIB_REMAINDERF=0; AC_SUBST([GNULIB_REMAINDERF]) - GNULIB_REMAINDERL=0; AC_SUBST([GNULIB_REMAINDERL]) - GNULIB_RINT=0; AC_SUBST([GNULIB_RINT]) - GNULIB_RINTF=0; AC_SUBST([GNULIB_RINTF]) - GNULIB_RINTL=0; AC_SUBST([GNULIB_RINTL]) - GNULIB_ROUND=0; AC_SUBST([GNULIB_ROUND]) - GNULIB_ROUNDF=0; AC_SUBST([GNULIB_ROUNDF]) - GNULIB_ROUNDL=0; AC_SUBST([GNULIB_ROUNDL]) - GNULIB_SIGNBIT=0; AC_SUBST([GNULIB_SIGNBIT]) - GNULIB_SINF=0; AC_SUBST([GNULIB_SINF]) - GNULIB_SINL=0; AC_SUBST([GNULIB_SINL]) - GNULIB_SINHF=0; AC_SUBST([GNULIB_SINHF]) - GNULIB_SQRTF=0; AC_SUBST([GNULIB_SQRTF]) - GNULIB_SQRTL=0; AC_SUBST([GNULIB_SQRTL]) - GNULIB_TANF=0; AC_SUBST([GNULIB_TANF]) - GNULIB_TANL=0; AC_SUBST([GNULIB_TANL]) - GNULIB_TANHF=0; AC_SUBST([GNULIB_TANHF]) - GNULIB_TRUNC=0; AC_SUBST([GNULIB_TRUNC]) - GNULIB_TRUNCF=0; AC_SUBST([GNULIB_TRUNCF]) - GNULIB_TRUNCL=0; AC_SUBST([GNULIB_TRUNCL]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_ACOSF=1; AC_SUBST([HAVE_ACOSF]) - HAVE_ACOSL=1; AC_SUBST([HAVE_ACOSL]) - HAVE_ASINF=1; AC_SUBST([HAVE_ASINF]) - HAVE_ASINL=1; AC_SUBST([HAVE_ASINL]) - HAVE_ATANF=1; AC_SUBST([HAVE_ATANF]) - HAVE_ATANL=1; AC_SUBST([HAVE_ATANL]) - HAVE_ATAN2F=1; AC_SUBST([HAVE_ATAN2F]) - HAVE_CBRT=1; AC_SUBST([HAVE_CBRT]) - HAVE_CBRTF=1; AC_SUBST([HAVE_CBRTF]) - HAVE_CBRTL=1; AC_SUBST([HAVE_CBRTL]) - HAVE_COPYSIGN=1; AC_SUBST([HAVE_COPYSIGN]) - HAVE_COPYSIGNL=1; AC_SUBST([HAVE_COPYSIGNL]) - HAVE_COSF=1; AC_SUBST([HAVE_COSF]) - HAVE_COSL=1; AC_SUBST([HAVE_COSL]) - HAVE_COSHF=1; AC_SUBST([HAVE_COSHF]) - HAVE_EXPF=1; AC_SUBST([HAVE_EXPF]) - HAVE_EXPL=1; AC_SUBST([HAVE_EXPL]) - HAVE_EXPM1=1; AC_SUBST([HAVE_EXPM1]) - HAVE_EXPM1F=1; AC_SUBST([HAVE_EXPM1F]) - HAVE_FABSF=1; AC_SUBST([HAVE_FABSF]) - HAVE_FABSL=1; AC_SUBST([HAVE_FABSL]) - HAVE_FMA=1; AC_SUBST([HAVE_FMA]) - HAVE_FMAF=1; AC_SUBST([HAVE_FMAF]) - HAVE_FMAL=1; AC_SUBST([HAVE_FMAL]) - HAVE_FMODF=1; AC_SUBST([HAVE_FMODF]) - HAVE_FMODL=1; AC_SUBST([HAVE_FMODL]) - HAVE_FREXPF=1; AC_SUBST([HAVE_FREXPF]) - HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF]) - HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL]) - HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB]) - HAVE_ILOGBF=1; AC_SUBST([HAVE_ILOGBF]) - HAVE_ILOGBL=1; AC_SUBST([HAVE_ILOGBL]) - HAVE_ISNANF=1; AC_SUBST([HAVE_ISNANF]) - HAVE_ISNAND=1; AC_SUBST([HAVE_ISNAND]) - HAVE_ISNANL=1; AC_SUBST([HAVE_ISNANL]) - HAVE_LDEXPF=1; AC_SUBST([HAVE_LDEXPF]) - HAVE_LOGF=1; AC_SUBST([HAVE_LOGF]) - HAVE_LOGL=1; AC_SUBST([HAVE_LOGL]) - HAVE_LOG10F=1; AC_SUBST([HAVE_LOG10F]) - HAVE_LOG10L=1; AC_SUBST([HAVE_LOG10L]) - HAVE_LOG1P=1; AC_SUBST([HAVE_LOG1P]) - HAVE_LOG1PF=1; AC_SUBST([HAVE_LOG1PF]) - HAVE_LOG1PL=1; AC_SUBST([HAVE_LOG1PL]) - HAVE_LOGBF=1; AC_SUBST([HAVE_LOGBF]) - HAVE_LOGBL=1; AC_SUBST([HAVE_LOGBL]) - HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) - HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) - HAVE_POWF=1; AC_SUBST([HAVE_POWF]) - HAVE_REMAINDER=1; AC_SUBST([HAVE_REMAINDER]) - HAVE_REMAINDERF=1; AC_SUBST([HAVE_REMAINDERF]) - HAVE_RINT=1; AC_SUBST([HAVE_RINT]) - HAVE_RINTL=1; AC_SUBST([HAVE_RINTL]) - HAVE_SINF=1; AC_SUBST([HAVE_SINF]) - HAVE_SINL=1; AC_SUBST([HAVE_SINL]) - HAVE_SINHF=1; AC_SUBST([HAVE_SINHF]) - HAVE_SQRTF=1; AC_SUBST([HAVE_SQRTF]) - HAVE_SQRTL=1; AC_SUBST([HAVE_SQRTL]) - HAVE_TANF=1; AC_SUBST([HAVE_TANF]) - HAVE_TANL=1; AC_SUBST([HAVE_TANL]) - HAVE_TANHF=1; AC_SUBST([HAVE_TANHF]) - HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) - HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) - HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) - HAVE_DECL_CBRTF=1; AC_SUBST([HAVE_DECL_CBRTF]) - HAVE_DECL_CBRTL=1; AC_SUBST([HAVE_DECL_CBRTL]) - HAVE_DECL_CEILF=1; AC_SUBST([HAVE_DECL_CEILF]) - HAVE_DECL_CEILL=1; AC_SUBST([HAVE_DECL_CEILL]) - HAVE_DECL_COPYSIGNF=1; AC_SUBST([HAVE_DECL_COPYSIGNF]) - HAVE_DECL_COSL=1; AC_SUBST([HAVE_DECL_COSL]) - HAVE_DECL_EXPL=1; AC_SUBST([HAVE_DECL_EXPL]) - HAVE_DECL_EXP2=1; AC_SUBST([HAVE_DECL_EXP2]) - HAVE_DECL_EXP2F=1; AC_SUBST([HAVE_DECL_EXP2F]) - HAVE_DECL_EXP2L=1; AC_SUBST([HAVE_DECL_EXP2L]) - HAVE_DECL_EXPM1L=1; AC_SUBST([HAVE_DECL_EXPM1L]) - HAVE_DECL_FLOORF=1; AC_SUBST([HAVE_DECL_FLOORF]) - HAVE_DECL_FLOORL=1; AC_SUBST([HAVE_DECL_FLOORL]) - HAVE_DECL_FREXPL=1; AC_SUBST([HAVE_DECL_FREXPL]) - HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL]) - HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL]) - HAVE_DECL_LOG10L=1; AC_SUBST([HAVE_DECL_LOG10L]) - HAVE_DECL_LOG2=1; AC_SUBST([HAVE_DECL_LOG2]) - HAVE_DECL_LOG2F=1; AC_SUBST([HAVE_DECL_LOG2F]) - HAVE_DECL_LOG2L=1; AC_SUBST([HAVE_DECL_LOG2L]) - HAVE_DECL_LOGB=1; AC_SUBST([HAVE_DECL_LOGB]) - HAVE_DECL_REMAINDER=1; AC_SUBST([HAVE_DECL_REMAINDER]) - HAVE_DECL_REMAINDERL=1; AC_SUBST([HAVE_DECL_REMAINDERL]) - HAVE_DECL_RINTF=1; AC_SUBST([HAVE_DECL_RINTF]) - HAVE_DECL_ROUND=1; AC_SUBST([HAVE_DECL_ROUND]) - HAVE_DECL_ROUNDF=1; AC_SUBST([HAVE_DECL_ROUNDF]) - HAVE_DECL_ROUNDL=1; AC_SUBST([HAVE_DECL_ROUNDL]) - HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL]) - HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL]) - HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL]) - HAVE_DECL_TRUNC=1; AC_SUBST([HAVE_DECL_TRUNC]) - HAVE_DECL_TRUNCF=1; AC_SUBST([HAVE_DECL_TRUNCF]) - HAVE_DECL_TRUNCL=1; AC_SUBST([HAVE_DECL_TRUNCL]) - REPLACE_CBRTF=0; AC_SUBST([REPLACE_CBRTF]) - REPLACE_CBRTL=0; AC_SUBST([REPLACE_CBRTL]) - REPLACE_CEIL=0; AC_SUBST([REPLACE_CEIL]) - REPLACE_CEILF=0; AC_SUBST([REPLACE_CEILF]) - REPLACE_CEILL=0; AC_SUBST([REPLACE_CEILL]) - REPLACE_EXPM1=0; AC_SUBST([REPLACE_EXPM1]) - REPLACE_EXPM1F=0; AC_SUBST([REPLACE_EXPM1F]) - REPLACE_EXP2=0; AC_SUBST([REPLACE_EXP2]) - REPLACE_EXP2L=0; AC_SUBST([REPLACE_EXP2L]) - REPLACE_FABSL=0; AC_SUBST([REPLACE_FABSL]) - REPLACE_FLOOR=0; AC_SUBST([REPLACE_FLOOR]) - REPLACE_FLOORF=0; AC_SUBST([REPLACE_FLOORF]) - REPLACE_FLOORL=0; AC_SUBST([REPLACE_FLOORL]) - REPLACE_FMA=0; AC_SUBST([REPLACE_FMA]) - REPLACE_FMAF=0; AC_SUBST([REPLACE_FMAF]) - REPLACE_FMAL=0; AC_SUBST([REPLACE_FMAL]) - REPLACE_FMOD=0; AC_SUBST([REPLACE_FMOD]) - REPLACE_FMODF=0; AC_SUBST([REPLACE_FMODF]) - REPLACE_FMODL=0; AC_SUBST([REPLACE_FMODL]) - REPLACE_FREXPF=0; AC_SUBST([REPLACE_FREXPF]) - REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) - REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) - REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL]) - REPLACE_HYPOT=0; AC_SUBST([REPLACE_HYPOT]) - REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF]) - REPLACE_HYPOTL=0; AC_SUBST([REPLACE_HYPOTL]) - REPLACE_ILOGB=0; AC_SUBST([REPLACE_ILOGB]) - REPLACE_ILOGBF=0; AC_SUBST([REPLACE_ILOGBF]) - REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) - REPLACE_ISINF=0; AC_SUBST([REPLACE_ISINF]) - REPLACE_ISNAN=0; AC_SUBST([REPLACE_ISNAN]) - REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) - REPLACE_LOG=0; AC_SUBST([REPLACE_LOG]) - REPLACE_LOGF=0; AC_SUBST([REPLACE_LOGF]) - REPLACE_LOGL=0; AC_SUBST([REPLACE_LOGL]) - REPLACE_LOG10=0; AC_SUBST([REPLACE_LOG10]) - REPLACE_LOG10F=0; AC_SUBST([REPLACE_LOG10F]) - REPLACE_LOG10L=0; AC_SUBST([REPLACE_LOG10L]) - REPLACE_LOG1P=0; AC_SUBST([REPLACE_LOG1P]) - REPLACE_LOG1PF=0; AC_SUBST([REPLACE_LOG1PF]) - REPLACE_LOG1PL=0; AC_SUBST([REPLACE_LOG1PL]) - REPLACE_LOG2=0; AC_SUBST([REPLACE_LOG2]) - REPLACE_LOG2F=0; AC_SUBST([REPLACE_LOG2F]) - REPLACE_LOG2L=0; AC_SUBST([REPLACE_LOG2L]) - REPLACE_LOGB=0; AC_SUBST([REPLACE_LOGB]) - REPLACE_LOGBF=0; AC_SUBST([REPLACE_LOGBF]) - REPLACE_LOGBL=0; AC_SUBST([REPLACE_LOGBL]) - REPLACE_MODF=0; AC_SUBST([REPLACE_MODF]) - REPLACE_MODFF=0; AC_SUBST([REPLACE_MODFF]) - REPLACE_MODFL=0; AC_SUBST([REPLACE_MODFL]) - REPLACE_NAN=0; AC_SUBST([REPLACE_NAN]) - REPLACE_REMAINDER=0; AC_SUBST([REPLACE_REMAINDER]) - REPLACE_REMAINDERF=0; AC_SUBST([REPLACE_REMAINDERF]) - REPLACE_REMAINDERL=0; AC_SUBST([REPLACE_REMAINDERL]) - REPLACE_ROUND=0; AC_SUBST([REPLACE_ROUND]) - REPLACE_ROUNDF=0; AC_SUBST([REPLACE_ROUNDF]) - REPLACE_ROUNDL=0; AC_SUBST([REPLACE_ROUNDL]) - REPLACE_SIGNBIT=0; AC_SUBST([REPLACE_SIGNBIT]) - REPLACE_SIGNBIT_USING_GCC=0; AC_SUBST([REPLACE_SIGNBIT_USING_GCC]) - REPLACE_SQRTL=0; AC_SUBST([REPLACE_SQRTL]) - REPLACE_TRUNC=0; AC_SUBST([REPLACE_TRUNC]) - REPLACE_TRUNCF=0; AC_SUBST([REPLACE_TRUNCF]) - REPLACE_TRUNCL=0; AC_SUBST([REPLACE_TRUNCL]) -]) - -# gl_LONG_DOUBLE_VS_DOUBLE -# determines whether 'long double' and 'double' have the same representation. -# Sets variable HAVE_SAME_LONG_DOUBLE_AS_DOUBLE to 0 or 1, and defines -# HAVE_SAME_LONG_DOUBLE_AS_DOUBLE accordingly. -# The currently known platforms where this is the case are: -# Linux/HPPA, Minix 3.1.8, AIX 5, AIX 6 and 7 with xlc, MSVC 9. -AC_DEFUN([gl_LONG_DOUBLE_VS_DOUBLE], -[ - AC_CACHE_CHECK([whether long double and double are the same], - [gl_cv_long_double_equals_double], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[typedef int check[sizeof (long double) == sizeof (double) - && LDBL_MANT_DIG == DBL_MANT_DIG - && LDBL_MAX_EXP == DBL_MAX_EXP - && LDBL_MIN_EXP == DBL_MIN_EXP - ? 1 : -1]; - ]])], - [gl_cv_long_double_equals_double=yes], - [gl_cv_long_double_equals_double=no]) - ]) - if test $gl_cv_long_double_equals_double = yes; then - AC_DEFINE([HAVE_SAME_LONG_DOUBLE_AS_DOUBLE], [1], - [Define to 1 if 'long double' and 'double' have the same representation.]) - HAVE_SAME_LONG_DOUBLE_AS_DOUBLE=1 - else - HAVE_SAME_LONG_DOUBLE_AS_DOUBLE=0 - fi - AC_SUBST([HAVE_SAME_LONG_DOUBLE_AS_DOUBLE]) -]) diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4 deleted file mode 100644 index 4c9f38861..000000000 --- a/m4/mbrtowc.m4 +++ /dev/null @@ -1,572 +0,0 @@ -# mbrtowc.m4 serial 25 -dnl Copyright (C) 2001-2002, 2004-2005, 2008-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_MBRTOWC], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - - AC_REQUIRE([AC_TYPE_MBSTATE_T]) - gl_MBSTATE_T_BROKEN - - AC_CHECK_FUNCS_ONCE([mbrtowc]) - if test $ac_cv_func_mbrtowc = no; then - HAVE_MBRTOWC=0 - AC_CHECK_DECLS([mbrtowc],,, [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -]]) - if test $ac_cv_have_decl_mbrtowc = yes; then - dnl On Minix 3.1.8, the system's declares mbrtowc() although - dnl it does not have the function. Avoid a collision with gnulib's - dnl replacement. - REPLACE_MBRTOWC=1 - fi - else - if test $REPLACE_MBSTATE_T = 1; then - REPLACE_MBRTOWC=1 - else - gl_MBRTOWC_NULL_ARG1 - gl_MBRTOWC_NULL_ARG2 - gl_MBRTOWC_RETVAL - gl_MBRTOWC_NUL_RETVAL - case "$gl_cv_func_mbrtowc_null_arg1" in - *yes) ;; - *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1], - [Define if the mbrtowc function has the NULL pwc argument bug.]) - REPLACE_MBRTOWC=1 - ;; - esac - case "$gl_cv_func_mbrtowc_null_arg2" in - *yes) ;; - *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1], - [Define if the mbrtowc function has the NULL string argument bug.]) - REPLACE_MBRTOWC=1 - ;; - esac - case "$gl_cv_func_mbrtowc_retval" in - *yes) ;; - *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1], - [Define if the mbrtowc function returns a wrong return value.]) - REPLACE_MBRTOWC=1 - ;; - esac - case "$gl_cv_func_mbrtowc_nul_retval" in - *yes) ;; - *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1], - [Define if the mbrtowc function does not return 0 for a NUL character.]) - REPLACE_MBRTOWC=1 - ;; - esac - fi - fi -]) - -dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that -dnl redefines the semantics of the given mbstate_t type. -dnl Result is REPLACE_MBSTATE_T. -dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to -dnl avoid inconsistencies. - -AC_DEFUN([gl_MBSTATE_T_BROKEN], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - - AC_REQUIRE([AC_TYPE_MBSTATE_T]) - AC_CHECK_FUNCS_ONCE([mbsinit]) - AC_CHECK_FUNCS_ONCE([mbrtowc]) - if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then - gl_MBRTOWC_INCOMPLETE_STATE - gl_MBRTOWC_SANITYCHECK - REPLACE_MBSTATE_T=0 - case "$gl_cv_func_mbrtowc_incomplete_state" in - *yes) ;; - *) REPLACE_MBSTATE_T=1 ;; - esac - case "$gl_cv_func_mbrtowc_sanitycheck" in - *yes) ;; - *) REPLACE_MBSTATE_T=1 ;; - esac - else - REPLACE_MBSTATE_T=1 - fi -]) - -dnl Test whether mbrtowc puts the state into non-initial state when parsing an -dnl incomplete multibyte character. -dnl Result is gl_cv_func_mbrtowc_incomplete_state. - -AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_JA]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether mbrtowc handles incomplete characters], - [gl_cv_func_mbrtowc_incomplete_state], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on AIX and OSF/1. - aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_JA != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) - { - const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */ - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) - if (mbsinit (&state)) - return 1; - } - return 0; -}]])], - [gl_cv_func_mbrtowc_incomplete_state=yes], - [gl_cv_func_mbrtowc_incomplete_state=no], - [:]) - fi - ]) -]) - -dnl Test whether mbrtowc works not worse than mbtowc. -dnl Result is gl_cv_func_mbrtowc_sanitycheck. - -AC_DEFUN([gl_MBRTOWC_SANITYCHECK], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_ZH_CN]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc], - [gl_cv_func_mbrtowc_sanitycheck], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on Solaris 8. - solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_ZH_CN != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - /* This fails on Solaris 8: - mbrtowc returns 2, and sets wc to 0x00F0. - mbtowc returns 4 (correct) and sets wc to 0x5EDC. */ - if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) - { - char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */ - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, input + 3, 6, &state) != 4 - && mbtowc (&wc, input + 3, 6) == 4) - return 1; - } - return 0; -}]])], - [gl_cv_func_mbrtowc_sanitycheck=yes], - [gl_cv_func_mbrtowc_sanitycheck=no], - [:]) - fi - ]) -]) - -dnl Test whether mbrtowc supports a NULL pwc argument correctly. -dnl Result is gl_cv_func_mbrtowc_null_arg1. - -AC_DEFUN([gl_MBRTOWC_NULL_ARG1], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_FR_UTF8]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument], - [gl_cv_func_mbrtowc_null_arg1], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on Solaris. - solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_FR_UTF8 != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - int result = 0; - - if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) - { - char input[] = "\303\237er"; - mbstate_t state; - wchar_t wc; - size_t ret; - - memset (&state, '\0', sizeof (mbstate_t)); - wc = (wchar_t) 0xBADFACE; - ret = mbrtowc (&wc, input, 5, &state); - if (ret != 2) - result |= 1; - if (!mbsinit (&state)) - result |= 2; - - memset (&state, '\0', sizeof (mbstate_t)); - ret = mbrtowc (NULL, input, 5, &state); - if (ret != 2) /* Solaris 7 fails here: ret is -1. */ - result |= 4; - if (!mbsinit (&state)) - result |= 8; - } - return result; -}]])], - [gl_cv_func_mbrtowc_null_arg1=yes], - [gl_cv_func_mbrtowc_null_arg1=no], - [:]) - fi - ]) -]) - -dnl Test whether mbrtowc supports a NULL string argument correctly. -dnl Result is gl_cv_func_mbrtowc_null_arg2. - -AC_DEFUN([gl_MBRTOWC_NULL_ARG2], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_FR_UTF8]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], - [gl_cv_func_mbrtowc_null_arg2], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on OSF/1. - osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_FR_UTF8 != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) - { - mbstate_t state; - wchar_t wc; - int ret; - - memset (&state, '\0', sizeof (mbstate_t)); - wc = (wchar_t) 0xBADFACE; - mbrtowc (&wc, NULL, 5, &state); - /* Check that wc was not modified. */ - if (wc != (wchar_t) 0xBADFACE) - return 1; - } - return 0; -}]])], - [gl_cv_func_mbrtowc_null_arg2=yes], - [gl_cv_func_mbrtowc_null_arg2=no], - [:]) - fi - ]) -]) - -dnl Test whether mbrtowc, when parsing the end of a multibyte character, -dnl correctly returns the number of bytes that were needed to complete the -dnl character (not the total number of bytes of the multibyte character). -dnl Result is gl_cv_func_mbrtowc_retval. - -AC_DEFUN([gl_MBRTOWC_RETVAL], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_FR_UTF8]) - AC_REQUIRE([gt_LOCALE_JA]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_CACHE_CHECK([whether mbrtowc has a correct return value], - [gl_cv_func_mbrtowc_retval], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on HP-UX, Solaris, native Windows. - hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbrtowc_retval="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \ - || { case "$host_os" in mingw*) true;; *) false;; esac; }; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - int result = 0; - int found_some_locale = 0; - /* This fails on Solaris. */ - if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) - { - char input[] = "B\303\274\303\237er"; /* "Büßer" */ - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) - { - input[1] = '\0'; - if (mbrtowc (&wc, input + 2, 5, &state) != 1) - result |= 1; - } - found_some_locale = 1; - } - /* This fails on HP-UX 11.11. */ - if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) - { - char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */ - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2)) - { - input[1] = '\0'; - if (mbrtowc (&wc, input + 2, 5, &state) != 2) - result |= 2; - } - found_some_locale = 1; - } - /* This fails on native Windows. */ - if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL) - { - char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */ - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) - { - input[3] = '\0'; - if (mbrtowc (&wc, input + 4, 4, &state) != 1) - result |= 4; - } - found_some_locale = 1; - } - if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL) - { - char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */ - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) - { - input[3] = '\0'; - if (mbrtowc (&wc, input + 4, 4, &state) != 1) - result |= 8; - } - found_some_locale = 1; - } - if (setlocale (LC_ALL, "Chinese_China.936") != NULL) - { - char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */ - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) - { - input[3] = '\0'; - if (mbrtowc (&wc, input + 4, 4, &state) != 1) - result |= 16; - } - found_some_locale = 1; - } - return (found_some_locale ? result : 77); -}]])], - [gl_cv_func_mbrtowc_retval=yes], - [if test $? != 77; then - gl_cv_func_mbrtowc_retval=no - fi - ], - [:]) - fi - ]) -]) - -dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0. -dnl Result is gl_cv_func_mbrtowc_nul_retval. - -AC_DEFUN([gl_MBRTOWC_NUL_RETVAL], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_ZH_CN]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character], - [gl_cv_func_mbrtowc_nul_retval], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on Solaris 8 and 9. - solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbrtowc_nul_retval="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_ZH_CN != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - /* This fails on Solaris 8 and 9. */ - if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) - { - mbstate_t state; - wchar_t wc; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (&wc, "", 1, &state) != 0) - return 1; - } - return 0; -}]])], - [gl_cv_func_mbrtowc_nul_retval=yes], - [gl_cv_func_mbrtowc_nul_retval=no], - [:]) - fi - ]) -]) - -# Prerequisites of lib/mbrtowc.c. -AC_DEFUN([gl_PREREQ_MBRTOWC], [ - : -]) - - -dnl From Paul Eggert - -dnl This is an override of an autoconf macro. - -AC_DEFUN([AC_FUNC_MBRTOWC], -[ - dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. - AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], - gl_cv_func_mbrtowc, - [AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include ]], - [[wchar_t wc; - char const s[] = ""; - size_t n = 1; - mbstate_t state; - return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])], - gl_cv_func_mbrtowc=yes, - gl_cv_func_mbrtowc=no)]) - if test $gl_cv_func_mbrtowc = yes; then - AC_DEFINE([HAVE_MBRTOWC], [1], - [Define to 1 if mbrtowc and mbstate_t are properly declared.]) - fi -]) diff --git a/m4/mbsinit.m4 b/m4/mbsinit.m4 deleted file mode 100644 index 2e6d0921a..000000000 --- a/m4/mbsinit.m4 +++ /dev/null @@ -1,51 +0,0 @@ -# mbsinit.m4 serial 8 -dnl Copyright (C) 2008, 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_MBSINIT], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - AC_REQUIRE([AC_CANONICAL_HOST]) - - AC_REQUIRE([AC_TYPE_MBSTATE_T]) - gl_MBSTATE_T_BROKEN - - AC_CHECK_FUNCS_ONCE([mbsinit]) - if test $ac_cv_func_mbsinit = no; then - HAVE_MBSINIT=0 - AC_CHECK_DECLS([mbsinit],,, [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -]]) - if test $ac_cv_have_decl_mbsinit = yes; then - dnl On Minix 3.1.8, the system's declares mbsinit() although - dnl it does not have the function. Avoid a collision with gnulib's - dnl replacement. - REPLACE_MBSINIT=1 - fi - else - if test $REPLACE_MBSTATE_T = 1; then - REPLACE_MBSINIT=1 - else - dnl On mingw, mbsinit() always returns 1, which is inappropriate for - dnl states produced by mbrtowc() for an incomplete multibyte character - dnl in multibyte locales. - case "$host_os" in - mingw*) REPLACE_MBSINIT=1 ;; - esac - fi - fi -]) - -# Prerequisites of lib/mbsinit.c. -AC_DEFUN([gl_PREREQ_MBSINIT], [ - : -]) diff --git a/m4/mbsrtowcs.m4 b/m4/mbsrtowcs.m4 deleted file mode 100644 index c4934c281..000000000 --- a/m4/mbsrtowcs.m4 +++ /dev/null @@ -1,155 +0,0 @@ -# mbsrtowcs.m4 serial 13 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_MBSRTOWCS], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - - AC_REQUIRE([AC_TYPE_MBSTATE_T]) - gl_MBSTATE_T_BROKEN - - AC_CHECK_FUNCS_ONCE([mbsrtowcs]) - if test $ac_cv_func_mbsrtowcs = no; then - HAVE_MBSRTOWCS=0 - AC_CHECK_DECLS([mbsrtowcs],,, [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -]]) - if test $ac_cv_have_decl_mbsrtowcs = yes; then - dnl On Minix 3.1.8, the system's declares mbsrtowcs() although - dnl it does not have the function. Avoid a collision with gnulib's - dnl replacement. - REPLACE_MBSRTOWCS=1 - fi - else - if test $REPLACE_MBSTATE_T = 1; then - REPLACE_MBSRTOWCS=1 - else - gl_MBSRTOWCS_WORKS - case "$gl_cv_func_mbsrtowcs_works" in - *yes) ;; - *) REPLACE_MBSRTOWCS=1 ;; - esac - fi - fi -]) - -dnl Test whether mbsrtowcs works. -dnl Result is gl_cv_func_mbsrtowcs_works. - -AC_DEFUN([gl_MBSRTOWCS_WORKS], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_FR]) - AC_REQUIRE([gt_LOCALE_FR_UTF8]) - AC_REQUIRE([gt_LOCALE_JA]) - AC_REQUIRE([gt_LOCALE_ZH_CN]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether mbsrtowcs works], - [gl_cv_func_mbsrtowcs_works], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on HP-UX, Solaris, mingw. - hpux* | solaris* | mingw*) gl_cv_func_mbsrtowcs_works="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_mbsrtowcs_works="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - int result = 0; - /* Test whether the function supports a NULL destination argument. - This fails on native Windows. */ - if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) - { - const char input[] = "\337er"; - const char *src = input; - mbstate_t state; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbsrtowcs (NULL, &src, 1, &state) != 3 - || src != input) - result |= 1; - } - /* Test whether the function works when started with a conversion state - in non-initial state. This fails on HP-UX 11.11 and Solaris 10. */ - if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) - { - const char input[] = "B\303\274\303\237er"; - mbstate_t state; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2)) - if (!mbsinit (&state)) - { - const char *src = input + 2; - if (mbsrtowcs (NULL, &src, 10, &state) != 4) - result |= 2; - } - } - if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) - { - const char input[] = "<\306\374\313\334\270\354>"; - mbstate_t state; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (NULL, input + 3, 1, &state) == (size_t)(-2)) - if (!mbsinit (&state)) - { - const char *src = input + 4; - if (mbsrtowcs (NULL, &src, 10, &state) != 3) - result |= 4; - } - } - if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) - { - const char input[] = "B\250\271\201\060\211\070er"; - mbstate_t state; - - memset (&state, '\0', sizeof (mbstate_t)); - if (mbrtowc (NULL, input + 1, 1, &state) == (size_t)(-2)) - if (!mbsinit (&state)) - { - const char *src = input + 2; - if (mbsrtowcs (NULL, &src, 10, &state) != 4) - result |= 8; - } - } - return result; -}]])], - [gl_cv_func_mbsrtowcs_works=yes], - [gl_cv_func_mbsrtowcs_works=no], - [:]) - fi - ]) -]) - -# Prerequisites of lib/mbsrtowcs.c. -AC_DEFUN([gl_PREREQ_MBSRTOWCS], [ - : -]) diff --git a/m4/mbstate_t.m4 b/m4/mbstate_t.m4 deleted file mode 100644 index ed0011798..000000000 --- a/m4/mbstate_t.m4 +++ /dev/null @@ -1,41 +0,0 @@ -# mbstate_t.m4 serial 13 -dnl Copyright (C) 2000-2002, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# From Paul Eggert. - -# BeOS 5 has but does not define mbstate_t, -# so you can't declare an object of that type. -# Check for this incompatibility with Standard C. - -# AC_TYPE_MBSTATE_T -# ----------------- -AC_DEFUN([AC_TYPE_MBSTATE_T], -[ - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl for HP-UX 11.11 - - AC_CACHE_CHECK([for mbstate_t], [ac_cv_type_mbstate_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [AC_INCLUDES_DEFAULT[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include ]], - [[mbstate_t x; return sizeof x;]])], - [ac_cv_type_mbstate_t=yes], - [ac_cv_type_mbstate_t=no])]) - if test $ac_cv_type_mbstate_t = yes; then - AC_DEFINE([HAVE_MBSTATE_T], [1], - [Define to 1 if declares mbstate_t.]) - else - AC_DEFINE([mbstate_t], [int], - [Define to a type if does not define.]) - fi -]) diff --git a/m4/mbswidth.m4 b/m4/mbswidth.m4 deleted file mode 100644 index 39760fcd2..000000000 --- a/m4/mbswidth.m4 +++ /dev/null @@ -1,46 +0,0 @@ -# mbswidth.m4 serial 18 -dnl Copyright (C) 2000-2002, 2004, 2006-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl autoconf tests required for use of mbswidth.c -dnl From Bruno Haible. - -AC_DEFUN([gl_MBSWIDTH], -[ - AC_CHECK_HEADERS_ONCE([wchar.h]) - AC_CHECK_FUNCS_ONCE([isascii mbsinit]) - - dnl UnixWare 7.1.1 has a declaration of a function mbswidth() - dnl that clashes with ours. - AC_CACHE_CHECK([whether mbswidth is declared in ], - [ac_cv_have_decl_mbswidth], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be included - before . */ -#include -#include -#include -#include - ]], - [[ - char *p = (char *) mbswidth; - return !p; - ]])], - [ac_cv_have_decl_mbswidth=yes], - [ac_cv_have_decl_mbswidth=no])]) - if test $ac_cv_have_decl_mbswidth = yes; then - ac_val=1 - else - ac_val=0 - fi - AC_DEFINE_UNQUOTED([HAVE_DECL_MBSWIDTH_IN_WCHAR_H], [$ac_val], - [Define to 1 if you have a declaration of mbswidth() in , and to 0 otherwise.]) - - AC_TYPE_MBSTATE_T -]) diff --git a/m4/mbtowc.m4 b/m4/mbtowc.m4 deleted file mode 100644 index e47946196..000000000 --- a/m4/mbtowc.m4 +++ /dev/null @@ -1,19 +0,0 @@ -# mbtowc.m4 serial 2 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_MBTOWC], -[ - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - - if false; then - REPLACE_MBTOWC=1 - fi -]) - -# Prerequisites of lib/mbtowc.c. -AC_DEFUN([gl_PREREQ_MBTOWC], [ - : -]) diff --git a/m4/memchr.m4 b/m4/memchr.m4 deleted file mode 100644 index 2d8abe75d..000000000 --- a/m4/memchr.m4 +++ /dev/null @@ -1,88 +0,0 @@ -# memchr.m4 serial 12 -dnl Copyright (C) 2002-2004, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN_ONCE([gl_FUNC_MEMCHR], -[ - dnl Check for prerequisites for memory fence checks. - gl_FUNC_MMAP_ANON - AC_CHECK_HEADERS_ONCE([sys/mman.h]) - AC_CHECK_FUNCS_ONCE([mprotect]) - - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - m4_ifdef([gl_FUNC_MEMCHR_OBSOLETE], [ - dnl These days, we assume memchr is present. But if support for old - dnl platforms is desired: - AC_CHECK_FUNCS_ONCE([memchr]) - if test $ac_cv_func_memchr = no; then - HAVE_MEMCHR=0 - fi - ]) - if test $HAVE_MEMCHR = 1; then - # Detect platform-specific bugs in some versions of glibc: - # memchr should not dereference anything with length 0 - # http://bugzilla.redhat.com/499689 - # memchr should not dereference overestimated length after a match - # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=521737 - # http://sourceware.org/bugzilla/show_bug.cgi?id=10162 - # Assume that memchr works on platforms that lack mprotect. - AC_CACHE_CHECK([whether memchr works], [gl_cv_func_memchr_works], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include -#if HAVE_SYS_MMAN_H -# include -# include -# include -# include -# ifndef MAP_FILE -# define MAP_FILE 0 -# endif -#endif -]], [[ - int result = 0; - char *fence = NULL; -#if HAVE_SYS_MMAN_H && HAVE_MPROTECT -# if HAVE_MAP_ANONYMOUS - const int flags = MAP_ANONYMOUS | MAP_PRIVATE; - const int fd = -1; -# else /* !HAVE_MAP_ANONYMOUS */ - const int flags = MAP_FILE | MAP_PRIVATE; - int fd = open ("/dev/zero", O_RDONLY, 0666); - if (fd >= 0) -# endif - { - int pagesize = getpagesize (); - char *two_pages = - (char *) mmap (NULL, 2 * pagesize, PROT_READ | PROT_WRITE, - flags, fd, 0); - if (two_pages != (char *)(-1) - && mprotect (two_pages + pagesize, pagesize, PROT_NONE) == 0) - fence = two_pages + pagesize; - } -#endif - if (fence) - { - if (memchr (fence, 0, 0)) - result |= 1; - strcpy (fence - 9, "12345678"); - if (memchr (fence - 9, 0, 79) != fence - 1) - result |= 2; - if (memchr (fence - 1, 0, 3) != fence - 1) - result |= 4; - } - return result; -]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no], - [dnl Be pessimistic for now. - gl_cv_func_memchr_works="guessing no"])]) - if test "$gl_cv_func_memchr_works" != yes; then - REPLACE_MEMCHR=1 - fi - fi -]) - -# Prerequisites of lib/memchr.c. -AC_DEFUN([gl_PREREQ_MEMCHR], [ - AC_CHECK_HEADERS([bp-sym.h]) -]) diff --git a/m4/mempcpy.m4 b/m4/mempcpy.m4 deleted file mode 100644 index a48f2d107..000000000 --- a/m4/mempcpy.m4 +++ /dev/null @@ -1,26 +0,0 @@ -# mempcpy.m4 serial 11 -dnl Copyright (C) 2003-2004, 2006-2007, 2009-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_MEMPCPY], -[ - dnl Persuade glibc to declare mempcpy(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - dnl The mempcpy() declaration in lib/string.in.h uses 'restrict'. - AC_REQUIRE([AC_C_RESTRICT]) - - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - AC_CHECK_FUNCS([mempcpy]) - if test $ac_cv_func_mempcpy = no; then - HAVE_MEMPCPY=0 - fi -]) - -# Prerequisites of lib/mempcpy.c. -AC_DEFUN([gl_PREREQ_MEMPCPY], [ - : -]) diff --git a/m4/mmap-anon.m4 b/m4/mmap-anon.m4 deleted file mode 100644 index 9b60ddfa4..000000000 --- a/m4/mmap-anon.m4 +++ /dev/null @@ -1,55 +0,0 @@ -# mmap-anon.m4 serial 10 -dnl Copyright (C) 2005, 2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Detect how mmap can be used to create anonymous (not file-backed) memory -# mappings. -# - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS -# and MAP_ANON exist and have the same value. -# - On HP-UX, only MAP_ANONYMOUS exists. -# - On Mac OS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists. -# - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be -# used. - -AC_DEFUN([gl_FUNC_MMAP_ANON], -[ - dnl Persuade glibc to define MAP_ANONYMOUS. - AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - - # Check for mmap(). Don't use AC_FUNC_MMAP, because it checks too much: it - # fails on HP-UX 11, because MAP_FIXED mappings do not work. But this is - # irrelevant for anonymous mappings. - AC_CHECK_FUNC([mmap], [gl_have_mmap=yes], [gl_have_mmap=no]) - - # Try to allow MAP_ANONYMOUS. - gl_have_mmap_anonymous=no - if test $gl_have_mmap = yes; then - AC_MSG_CHECKING([for MAP_ANONYMOUS]) - AC_EGREP_CPP([I cannot identify this map], [ -#include -#ifdef MAP_ANONYMOUS - I cannot identify this map -#endif -], - [gl_have_mmap_anonymous=yes]) - if test $gl_have_mmap_anonymous != yes; then - AC_EGREP_CPP([I cannot identify this map], [ -#include -#ifdef MAP_ANON - I cannot identify this map -#endif -], - [AC_DEFINE([MAP_ANONYMOUS], [MAP_ANON], - [Define to a substitute value for mmap()'s MAP_ANONYMOUS flag.]) - gl_have_mmap_anonymous=yes]) - fi - AC_MSG_RESULT([$gl_have_mmap_anonymous]) - if test $gl_have_mmap_anonymous = yes; then - AC_DEFINE([HAVE_MAP_ANONYMOUS], [1], - [Define to 1 if mmap()'s MAP_ANONYMOUS flag is available after including - config.h and .]) - fi - fi -]) diff --git a/m4/msvc-inval.m4 b/m4/msvc-inval.m4 deleted file mode 100644 index 9a6a47a74..000000000 --- a/m4/msvc-inval.m4 +++ /dev/null @@ -1,19 +0,0 @@ -# msvc-inval.m4 serial 1 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_MSVC_INVAL], -[ - AC_CHECK_FUNCS_ONCE([_set_invalid_parameter_handler]) - if test $ac_cv_func__set_invalid_parameter_handler = yes; then - HAVE_MSVC_INVALID_PARAMETER_HANDLER=1 - AC_DEFINE([HAVE_MSVC_INVALID_PARAMETER_HANDLER], [1], - [Define to 1 on MSVC platforms that have the "invalid parameter handler" - concept.]) - else - HAVE_MSVC_INVALID_PARAMETER_HANDLER=0 - fi - AC_SUBST([HAVE_MSVC_INVALID_PARAMETER_HANDLER]) -]) diff --git a/m4/msvc-nothrow.m4 b/m4/msvc-nothrow.m4 deleted file mode 100644 index a39618a41..000000000 --- a/m4/msvc-nothrow.m4 +++ /dev/null @@ -1,10 +0,0 @@ -# msvc-nothrow.m4 serial 1 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_MSVC_NOTHROW], -[ - AC_REQUIRE([gl_MSVC_INVAL]) -]) diff --git a/m4/multiarch.m4 b/m4/multiarch.m4 deleted file mode 100644 index 552ec7e71..000000000 --- a/m4/multiarch.m4 +++ /dev/null @@ -1,62 +0,0 @@ -# multiarch.m4 serial 7 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Determine whether the compiler is or may be producing universal binaries. -# -# On Mac OS X 10.5 and later systems, the user can create libraries and -# executables that work on multiple system types--known as "fat" or -# "universal" binaries--by specifying multiple '-arch' options to the -# compiler but only a single '-arch' option to the preprocessor. Like -# this: -# -# ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ -# CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ -# CPP="gcc -E" CXXCPP="g++ -E" -# -# Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly. - -AC_DEFUN_ONCE([gl_MULTIARCH], -[ - dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN. - gl_cv_c_multiarch=no - AC_COMPILE_IFELSE( - [AC_LANG_SOURCE( - [[#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - ]])], - [ - dnl Check for potential -arch flags. It is not universal unless - dnl there are at least two -arch flags with different values. - arch= - prev= - for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do - if test -n "$prev"; then - case $word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$arch" || test "$arch" = "$word"; then - arch="$word" - else - gl_cv_c_multiarch=yes - fi - ;; - esac - prev= - else - if test "x$word" = "x-arch"; then - prev=arch - fi - fi - done - ]) - if test $gl_cv_c_multiarch = yes; then - APPLE_UNIVERSAL_BUILD=1 - else - APPLE_UNIVERSAL_BUILD=0 - fi - AC_SUBST([APPLE_UNIVERSAL_BUILD]) -]) diff --git a/m4/nl_langinfo.m4 b/m4/nl_langinfo.m4 deleted file mode 100644 index 25e210155..000000000 --- a/m4/nl_langinfo.m4 +++ /dev/null @@ -1,50 +0,0 @@ -# nl_langinfo.m4 serial 5 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_NL_LANGINFO], -[ - AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) - AC_REQUIRE([gl_LANGINFO_H]) - AC_CHECK_FUNCS_ONCE([nl_langinfo]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - if test $ac_cv_func_nl_langinfo = yes; then - # On Irix 6.5, YESEXPR is defined, but nl_langinfo(YESEXPR) is broken. - AC_CACHE_CHECK([whether YESEXPR works], - [gl_cv_func_nl_langinfo_yesexpr_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[#include -]], [[return !*nl_langinfo(YESEXPR); -]])], - [gl_cv_func_nl_langinfo_yesexpr_works=yes], - [gl_cv_func_nl_langinfo_yesexpr_works=no], - [ - case "$host_os" in - # Guess no on irix systems. - irix*) gl_cv_func_nl_langinfo_yesexpr_works="guessing no";; - # Guess yes elsewhere. - *) gl_cv_func_nl_langinfo_yesexpr_works="guessing yes";; - esac - ]) - ]) - case $gl_cv_func_nl_langinfo_yesexpr_works in - *yes) FUNC_NL_LANGINFO_YESEXPR_WORKS=1 ;; - *) FUNC_NL_LANGINFO_YESEXPR_WORKS=0 ;; - esac - AC_DEFINE_UNQUOTED([FUNC_NL_LANGINFO_YESEXPR_WORKS], - [$FUNC_NL_LANGINFO_YESEXPR_WORKS], - [Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string.]) - if test $HAVE_LANGINFO_CODESET = 1 && test $HAVE_LANGINFO_ERA = 1 \ - && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1; then - : - else - REPLACE_NL_LANGINFO=1 - AC_DEFINE([REPLACE_NL_LANGINFO], [1], - [Define if nl_langinfo exists but is overridden by gnulib.]) - fi - else - HAVE_NL_LANGINFO=0 - fi -]) diff --git a/m4/nls.m4 b/m4/nls.m4 deleted file mode 100644 index 8f8a147be..000000000 --- a/m4/nls.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# nls.m4 serial 5 (gettext-0.18) -dnl Copyright (C) 1995-2003, 2005-2006, 2008-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2003. - -AC_PREREQ([2.50]) - -AC_DEFUN([AM_NLS], -[ - AC_MSG_CHECKING([whether NLS is requested]) - dnl Default is enabled NLS - AC_ARG_ENABLE([nls], - [ --disable-nls do not use Native Language Support], - USE_NLS=$enableval, USE_NLS=yes) - AC_MSG_RESULT([$USE_NLS]) - AC_SUBST([USE_NLS]) -]) diff --git a/m4/nocrash.m4 b/m4/nocrash.m4 deleted file mode 100644 index 105b884f1..000000000 --- a/m4/nocrash.m4 +++ /dev/null @@ -1,130 +0,0 @@ -# nocrash.m4 serial 4 -dnl Copyright (C) 2005, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Based on libsigsegv, from Bruno Haible and Paolo Bonzini. - -AC_PREREQ([2.13]) - -dnl Expands to some code for use in .c programs that will cause the configure -dnl test to exit instead of crashing. This is useful to avoid triggering -dnl action from a background debugger and to avoid core dumps. -dnl Usage: ... -dnl ]GL_NOCRASH[ -dnl ... -dnl int main() { nocrash_init(); ... } -AC_DEFUN([GL_NOCRASH],[[ -#include -#if defined __MACH__ && defined __APPLE__ -/* Avoid a crash on Mac OS X. */ -#include -#include -#include -#include -#include -#include -/* The exception port on which our thread listens. */ -static mach_port_t our_exception_port; -/* The main function of the thread listening for exceptions of type - EXC_BAD_ACCESS. */ -static void * -mach_exception_thread (void *arg) -{ - /* Buffer for a message to be received. */ - struct { - mach_msg_header_t head; - mach_msg_body_t msgh_body; - char data[1024]; - } msg; - mach_msg_return_t retval; - /* Wait for a message on the exception port. */ - retval = mach_msg (&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof (msg), - our_exception_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - if (retval != MACH_MSG_SUCCESS) - abort (); - exit (1); -} -static void -nocrash_init (void) -{ - mach_port_t self = mach_task_self (); - /* Allocate a port on which the thread shall listen for exceptions. */ - if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port) - == KERN_SUCCESS) { - /* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html. */ - if (mach_port_insert_right (self, our_exception_port, our_exception_port, - MACH_MSG_TYPE_MAKE_SEND) - == KERN_SUCCESS) { - /* The exceptions we want to catch. Only EXC_BAD_ACCESS is interesting - for us. */ - exception_mask_t mask = EXC_MASK_BAD_ACCESS; - /* Create the thread listening on the exception port. */ - pthread_attr_t attr; - pthread_t thread; - if (pthread_attr_init (&attr) == 0 - && pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) == 0 - && pthread_create (&thread, &attr, mach_exception_thread, NULL) == 0) { - pthread_attr_destroy (&attr); - /* Replace the exception port info for these exceptions with our own. - Note that we replace the exception port for the entire task, not only - for a particular thread. This has the effect that when our exception - port gets the message, the thread specific exception port has already - been asked, and we don't need to bother about it. - See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */ - task_set_exception_ports (self, mask, our_exception_port, - EXCEPTION_DEFAULT, MACHINE_THREAD_STATE); - } - } - } -} -#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ -/* Avoid a crash on native Windows. */ -#define WIN32_LEAN_AND_MEAN -#include -#include -static LONG WINAPI -exception_filter (EXCEPTION_POINTERS *ExceptionInfo) -{ - switch (ExceptionInfo->ExceptionRecord->ExceptionCode) - { - case EXCEPTION_ACCESS_VIOLATION: - case EXCEPTION_IN_PAGE_ERROR: - case EXCEPTION_STACK_OVERFLOW: - case EXCEPTION_GUARD_PAGE: - case EXCEPTION_PRIV_INSTRUCTION: - case EXCEPTION_ILLEGAL_INSTRUCTION: - case EXCEPTION_DATATYPE_MISALIGNMENT: - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - exit (1); - } - return EXCEPTION_CONTINUE_SEARCH; -} -static void -nocrash_init (void) -{ - SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) exception_filter); -} -#else -/* Avoid a crash on POSIX systems. */ -#include -/* A POSIX signal handler. */ -static void -exception_handler (int sig) -{ - exit (1); -} -static void -nocrash_init (void) -{ -#ifdef SIGSEGV - signal (SIGSEGV, exception_handler); -#endif -#ifdef SIGBUS - signal (SIGBUS, exception_handler); -#endif -} -#endif -]]) diff --git a/m4/off_t.m4 b/m4/off_t.m4 deleted file mode 100644 index d355d0131..000000000 --- a/m4/off_t.m4 +++ /dev/null @@ -1,18 +0,0 @@ -# off_t.m4 serial 1 -dnl Copyright (C) 2012-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Check whether to override the 'off_t' type. -dnl Set WINDOWS_64_BIT_OFF_T. - -AC_DEFUN([gl_TYPE_OFF_T], -[ - m4_ifdef([gl_LARGEFILE], [ - AC_REQUIRE([gl_LARGEFILE]) - ], [ - WINDOWS_64_BIT_OFF_T=0 - ]) - AC_SUBST([WINDOWS_64_BIT_OFF_T]) -]) diff --git a/m4/po.m4 b/m4/po.m4 deleted file mode 100644 index f39572343..000000000 --- a/m4/po.m4 +++ /dev/null @@ -1,452 +0,0 @@ -# po.m4 serial 20 (gettext-0.18.2) -dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1995-2000. -dnl Bruno Haible , 2000-2003. - -AC_PREREQ([2.60]) - -dnl Checks for all prerequisites of the po subdirectory. -AC_DEFUN([AM_PO_SUBDIRS], -[ - AC_REQUIRE([AC_PROG_MAKE_SET])dnl - AC_REQUIRE([AC_PROG_INSTALL])dnl - AC_REQUIRE([AC_PROG_MKDIR_P])dnl - AC_REQUIRE([AM_NLS])dnl - - dnl Release version of the gettext macros. This is used to ensure that - dnl the gettext macros and po/Makefile.in.in are in sync. - AC_SUBST([GETTEXT_MACRO_VERSION], [0.18]) - - dnl Perform the following tests also if --disable-nls has been given, - dnl because they are needed for "make dist" to work. - - dnl Search for GNU msgfmt in the PATH. - dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. - dnl The second test excludes FreeBSD msgfmt. - AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, - [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && - (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) - - dnl Test whether it is GNU msgfmt >= 0.15. -changequote(,)dnl - case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; - *) MSGFMT_015=$MSGFMT ;; - esac -changequote([,])dnl - AC_SUBST([MSGFMT_015]) -changequote(,)dnl - case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; - *) GMSGFMT_015=$GMSGFMT ;; - esac -changequote([,])dnl - AC_SUBST([GMSGFMT_015]) - - dnl Search for GNU xgettext 0.12 or newer in the PATH. - dnl The first test excludes Solaris xgettext and early GNU xgettext versions. - dnl The second test excludes FreeBSD xgettext. - AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, - [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && - (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], - :) - dnl Remove leftover from FreeBSD xgettext call. - rm -f messages.po - - dnl Test whether it is GNU xgettext >= 0.15. -changequote(,)dnl - case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; - *) XGETTEXT_015=$XGETTEXT ;; - esac -changequote([,])dnl - AC_SUBST([XGETTEXT_015]) - - dnl Search for GNU msgmerge 0.11 or newer in the PATH. - AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, - [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) - - dnl Installation directories. - dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we - dnl have to define it here, so that it can be used in po/Makefile. - test -n "$localedir" || localedir='${datadir}/locale' - AC_SUBST([localedir]) - - dnl Support for AM_XGETTEXT_OPTION. - test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= - AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) - - AC_CONFIG_COMMANDS([po-directories], [[ - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - # Treat a directory as a PO directory if and only if it has a - # POTFILES.in file. This allows packages to have multiple PO - # directories under different names or in different locations. - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - gt_tab=`printf '\t'` - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - POMAKEFILEDEPS="POTFILES.in" - # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$OBSOLETE_ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" - else - # The set of available languages was given in configure.in. - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' - fi - # Compute POFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) - # Compute UPDATEPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) - # Compute DUMMYPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) - # Compute GMOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - UPDATEPOFILES= - DUMMYPOFILES= - GMOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done]], - [# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it - # from automake < 1.5. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - ]) -]) - -dnl Postprocesses a Makefile in a directory containing PO files. -AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], -[ - # When this code is run, in config.status, two variables have already been - # set: - # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, - # - LINGUAS is the value of the environment variable LINGUAS at configure - # time. - -changequote(,)dnl - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - # Find a way to echo strings without interpreting backslash. - if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then - gt_echo='echo' - else - if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then - gt_echo='printf %s\n' - else - echo_func () { - cat < "$ac_file.tmp" - tab=`printf '\t'` - if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then - # Add dependencies that cannot be formulated as a simple suffix rule. - for lang in $ALL_LINGUAS; do - frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` - cat >> "$ac_file.tmp" < /dev/null; then - # Add dependencies that cannot be formulated as a simple suffix rule. - for lang in $ALL_LINGUAS; do - frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` - cat >> "$ac_file.tmp" <> "$ac_file.tmp" < -#include -/* The string "%2$d %1$d", with dollar characters protected from the shell's - dollar expansion (possibly an autoconf bug). */ -static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; -static char buf[100]; -int main () -{ - sprintf (buf, format, 33, 55); - return (strcmp (buf, "55 33") != 0); -}]])], - [gt_cv_func_printf_posix=yes], - [gt_cv_func_printf_posix=no], - [ - AC_EGREP_CPP([notposix], [ -#if defined __NetBSD__ || defined __BEOS__ || defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ - notposix -#endif - ], - [gt_cv_func_printf_posix="guessing no"], - [gt_cv_func_printf_posix="guessing yes"]) - ]) - ]) - case $gt_cv_func_printf_posix in - *yes) - AC_DEFINE([HAVE_POSIX_PRINTF], [1], - [Define if your printf() function supports format strings with positions.]) - ;; - esac -]) diff --git a/m4/printf.m4 b/m4/printf.m4 deleted file mode 100644 index ef44f7851..000000000 --- a/m4/printf.m4 +++ /dev/null @@ -1,1570 +0,0 @@ -# printf.m4 serial 50 -dnl Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Test whether the *printf family of functions supports the 'j', 'z', 't', -dnl 'L' size specifiers. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_printf_sizes_c99. - -AC_DEFUN([gl_PRINTF_SIZES_C99], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports size specifiers as in C99], - [gl_cv_func_printf_sizes_c99], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include -#include -#if HAVE_STDINT_H_WITH_UINTMAX -# include -#endif -#if HAVE_INTTYPES_H_WITH_UINTMAX -# include -#endif -static char buf[100]; -int main () -{ - int result = 0; -#if HAVE_STDINT_H_WITH_UINTMAX || HAVE_INTTYPES_H_WITH_UINTMAX - buf[0] = '\0'; - if (sprintf (buf, "%ju %d", (uintmax_t) 12345671, 33, 44, 55) < 0 - || strcmp (buf, "12345671 33") != 0) - result |= 1; -#endif - buf[0] = '\0'; - if (sprintf (buf, "%zu %d", (size_t) 12345672, 33, 44, 55) < 0 - || strcmp (buf, "12345672 33") != 0) - result |= 2; - buf[0] = '\0'; - if (sprintf (buf, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55) < 0 - || strcmp (buf, "12345673 33") != 0) - result |= 4; - buf[0] = '\0'; - if (sprintf (buf, "%Lg %d", (long double) 1.5, 33, 44, 55) < 0 - || strcmp (buf, "1.5 33") != 0) - result |= 8; - return result; -}]])], - [gl_cv_func_printf_sizes_c99=yes], - [gl_cv_func_printf_sizes_c99=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_sizes_c99="guessing yes";; - # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_printf_sizes_c99="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";; - # Guess yes on Mac OS X >= 10.3. - darwin[1-6].*) gl_cv_func_printf_sizes_c99="guessing no";; - darwin*) gl_cv_func_printf_sizes_c99="guessing yes";; - # Guess yes on OpenBSD >= 3.9. - openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) - gl_cv_func_printf_sizes_c99="guessing no";; - openbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; - # Guess yes on Solaris >= 2.10. - solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";; - solaris*) gl_cv_func_printf_sizes_c99="guessing no";; - # Guess yes on NetBSD >= 3. - netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) - gl_cv_func_printf_sizes_c99="guessing no";; - netbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_sizes_c99="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports 'long double' -dnl arguments together with the 'L' size specifier. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_printf_long_double. - -AC_DEFUN([gl_PRINTF_LONG_DOUBLE], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports 'long double' arguments], - [gl_cv_func_printf_long_double], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static char buf[10000]; -int main () -{ - int result = 0; - buf[0] = '\0'; - if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0 - || strcmp (buf, "1.750000 33") != 0) - result |= 1; - buf[0] = '\0'; - if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0 - || strcmp (buf, "1.750000e+00 33") != 0) - result |= 2; - buf[0] = '\0'; - if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0 - || strcmp (buf, "1.75 33") != 0) - result |= 4; - return result; -}]])], - [gl_cv_func_printf_long_double=yes], - [gl_cv_func_printf_long_double=no], - [ -changequote(,)dnl - case "$host_os" in - beos*) gl_cv_func_printf_long_double="guessing no";; - mingw* | pw*) gl_cv_func_printf_long_double="guessing no";; - *) gl_cv_func_printf_long_double="guessing yes";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports infinite and NaN -dnl 'double' arguments and negative zero arguments in the %f, %e, %g -dnl directives. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_printf_infinite. - -AC_DEFUN([gl_PRINTF_INFINITE], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports infinite 'double' arguments], - [gl_cv_func_printf_infinite], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static int -strisnan (const char *string, size_t start_index, size_t end_index) -{ - if (start_index < end_index) - { - if (string[start_index] == '-') - start_index++; - if (start_index + 3 <= end_index - && memcmp (string + start_index, "nan", 3) == 0) - { - start_index += 3; - if (start_index == end_index - || (string[start_index] == '(' && string[end_index - 1] == ')')) - return 1; - } - } - return 0; -} -static int -have_minus_zero () -{ - static double plus_zero = 0.0; - double minus_zero = - plus_zero; - return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0; -} -static char buf[10000]; -static double zero = 0.0; -int main () -{ - int result = 0; - if (sprintf (buf, "%f", 1.0 / zero) < 0 - || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) - result |= 1; - if (sprintf (buf, "%f", -1.0 / zero) < 0 - || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) - result |= 1; - if (sprintf (buf, "%f", zero / zero) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 2; - if (sprintf (buf, "%e", 1.0 / zero) < 0 - || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) - result |= 4; - if (sprintf (buf, "%e", -1.0 / zero) < 0 - || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) - result |= 4; - if (sprintf (buf, "%e", zero / zero) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 8; - if (sprintf (buf, "%g", 1.0 / zero) < 0 - || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) - result |= 16; - if (sprintf (buf, "%g", -1.0 / zero) < 0 - || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) - result |= 16; - if (sprintf (buf, "%g", zero / zero) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 32; - /* This test fails on HP-UX 10.20. */ - if (have_minus_zero ()) - if (sprintf (buf, "%g", - zero) < 0 - || strcmp (buf, "-0") != 0) - result |= 64; - return result; -}]])], - [gl_cv_func_printf_infinite=yes], - [gl_cv_func_printf_infinite=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_infinite="guessing yes";; - # Guess yes on FreeBSD >= 6. - freebsd[1-5]*) gl_cv_func_printf_infinite="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";; - # Guess yes on Mac OS X >= 10.3. - darwin[1-6].*) gl_cv_func_printf_infinite="guessing no";; - darwin*) gl_cv_func_printf_infinite="guessing yes";; - # Guess yes on HP-UX >= 11. - hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite="guessing no";; - hpux*) gl_cv_func_printf_infinite="guessing yes";; - # Guess yes on NetBSD >= 3. - netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) - gl_cv_func_printf_infinite="guessing no";; - netbsd*) gl_cv_func_printf_infinite="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_printf_infinite="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_infinite="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports infinite and NaN -dnl 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_printf_infinite_long_double. - -AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE], -[ - AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gl_BIGENDIAN]) - AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - dnl The user can set or unset the variable gl_printf_safe to indicate - dnl that he wishes a safe handling of non-IEEE-754 'long double' values. - if test -n "$gl_printf_safe"; then - AC_DEFINE([CHECK_PRINTF_SAFE], [1], - [Define if you wish *printf() functions that have a safe handling of - non-IEEE-754 'long double' values.]) - fi - case "$gl_cv_func_printf_long_double" in - *yes) - AC_CACHE_CHECK([whether printf supports infinite 'long double' arguments], - [gl_cv_func_printf_infinite_long_double], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -]GL_NOCRASH[ -#include -#include -#include -static int -strisnan (const char *string, size_t start_index, size_t end_index) -{ - if (start_index < end_index) - { - if (string[start_index] == '-') - start_index++; - if (start_index + 3 <= end_index - && memcmp (string + start_index, "nan", 3) == 0) - { - start_index += 3; - if (start_index == end_index - || (string[start_index] == '(' && string[end_index - 1] == ')')) - return 1; - } - } - return 0; -} -static char buf[10000]; -static long double zeroL = 0.0L; -int main () -{ - int result = 0; - nocrash_init(); - if (sprintf (buf, "%Lf", 1.0L / zeroL) < 0 - || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) - result |= 1; - if (sprintf (buf, "%Lf", -1.0L / zeroL) < 0 - || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) - result |= 1; - if (sprintf (buf, "%Lf", zeroL / zeroL) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 1; - if (sprintf (buf, "%Le", 1.0L / zeroL) < 0 - || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) - result |= 1; - if (sprintf (buf, "%Le", -1.0L / zeroL) < 0 - || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) - result |= 1; - if (sprintf (buf, "%Le", zeroL / zeroL) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 1; - if (sprintf (buf, "%Lg", 1.0L / zeroL) < 0 - || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) - result |= 1; - if (sprintf (buf, "%Lg", -1.0L / zeroL) < 0 - || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) - result |= 1; - if (sprintf (buf, "%Lg", zeroL / zeroL) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 1; -#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE -/* Representation of an 80-bit 'long double' as an initializer for a sequence - of 'unsigned int' words. */ -# ifdef WORDS_BIGENDIAN -# define LDBL80_WORDS(exponent,manthi,mantlo) \ - { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \ - ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \ - (unsigned int) (mantlo) << 16 \ - } -# else -# define LDBL80_WORDS(exponent,manthi,mantlo) \ - { mantlo, manthi, exponent } -# endif - { /* Quiet NaN. */ - static union { unsigned int word[4]; long double value; } x = - { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 2; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 2; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 2; - } - { - /* Signalling NaN. */ - static union { unsigned int word[4]; long double value; } x = - { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 2; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 2; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 2; - } - { /* Pseudo-NaN. */ - static union { unsigned int word[4]; long double value; } x = - { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 4; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 4; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 4; - } - { /* Pseudo-Infinity. */ - static union { unsigned int word[4]; long double value; } x = - { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 8; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 8; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 8; - } - { /* Pseudo-Zero. */ - static union { unsigned int word[4]; long double value; } x = - { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 16; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 16; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 16; - } - { /* Unnormalized number. */ - static union { unsigned int word[4]; long double value; } x = - { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 32; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 32; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 32; - } - { /* Pseudo-Denormal. */ - static union { unsigned int word[4]; long double value; } x = - { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; - if (sprintf (buf, "%Lf", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 64; - if (sprintf (buf, "%Le", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 64; - if (sprintf (buf, "%Lg", x.value) < 0 - || !strisnan (buf, 0, strlen (buf))) - result |= 64; - } -#endif - return result; -}]])], - [gl_cv_func_printf_infinite_long_double=yes], - [gl_cv_func_printf_infinite_long_double=no], - [ -changequote(,)dnl - case "$host_cpu" in - # Guess no on ia64, x86_64, i386. - ia64 | x86_64 | i*86) gl_cv_func_printf_infinite_long_double="guessing no";; - *) - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_infinite_long_double="guessing yes";; - # Guess yes on FreeBSD >= 6. - freebsd[1-5]*) gl_cv_func_printf_infinite_long_double="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; - # Guess yes on HP-UX >= 11. - hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";; - hpux*) gl_cv_func_printf_infinite_long_double="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_infinite_long_double="guessing no";; - esac - ;; - esac -changequote([,])dnl - ]) - ]) - ;; - *) - gl_cv_func_printf_infinite_long_double="irrelevant" - ;; - esac -]) - -dnl Test whether the *printf family of functions supports the 'a' and 'A' -dnl conversion specifier for hexadecimal output of floating-point numbers. -dnl (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_printf_directive_a. - -AC_DEFUN([gl_PRINTF_DIRECTIVE_A], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports the 'a' and 'A' directives], - [gl_cv_func_printf_directive_a], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static char buf[100]; -static double zero = 0.0; -int main () -{ - int result = 0; - if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0 - || (strcmp (buf, "0x1.922p+1 33") != 0 - && strcmp (buf, "0x3.244p+0 33") != 0 - && strcmp (buf, "0x6.488p-1 33") != 0 - && strcmp (buf, "0xc.91p-2 33") != 0)) - result |= 1; - if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0 - || (strcmp (buf, "-0X1.922P+1 33") != 0 - && strcmp (buf, "-0X3.244P+0 33") != 0 - && strcmp (buf, "-0X6.488P-1 33") != 0 - && strcmp (buf, "-0XC.91P-2 33") != 0)) - result |= 2; - /* This catches a FreeBSD 6.1 bug: it doesn't round. */ - if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0 - || (strcmp (buf, "0x1.83p+0 33") != 0 - && strcmp (buf, "0x3.05p-1 33") != 0 - && strcmp (buf, "0x6.0ap-2 33") != 0 - && strcmp (buf, "0xc.14p-3 33") != 0)) - result |= 4; - /* This catches a FreeBSD 6.1 bug. See - */ - if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0 - || buf[0] == '0') - result |= 8; - /* This catches a Mac OS X 10.3.9 (Darwin 7.9) bug. */ - if (sprintf (buf, "%.1a", 1.999) < 0 - || (strcmp (buf, "0x1.0p+1") != 0 - && strcmp (buf, "0x2.0p+0") != 0 - && strcmp (buf, "0x4.0p-1") != 0 - && strcmp (buf, "0x8.0p-2") != 0)) - result |= 16; - /* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a - glibc 2.4 bug . */ - if (sprintf (buf, "%.1La", 1.999L) < 0 - || (strcmp (buf, "0x1.0p+1") != 0 - && strcmp (buf, "0x2.0p+0") != 0 - && strcmp (buf, "0x4.0p-1") != 0 - && strcmp (buf, "0x8.0p-2") != 0)) - result |= 32; - return result; -}]])], - [gl_cv_func_printf_directive_a=yes], - [gl_cv_func_printf_directive_a=no], - [ - case "$host_os" in - # Guess yes on glibc >= 2.5 systems. - *-gnu*) - AC_EGREP_CPP([BZ2908], [ - #include - #ifdef __GNU_LIBRARY__ - #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)) && !defined __UCLIBC__ - BZ2908 - #endif - #endif - ], - [gl_cv_func_printf_directive_a="guessing yes"], - [gl_cv_func_printf_directive_a="guessing no"]) - ;; - # If we don't know, assume the worst. - *) gl_cv_func_printf_directive_a="guessing no";; - esac - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports the %F format -dnl directive. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_printf_directive_f. - -AC_DEFUN([gl_PRINTF_DIRECTIVE_F], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports the 'F' directive], - [gl_cv_func_printf_directive_f], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static char buf[100]; -static double zero = 0.0; -int main () -{ - int result = 0; - if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0 - || strcmp (buf, "1234567.000000 33") != 0) - result |= 1; - if (sprintf (buf, "%F", 1.0 / zero) < 0 - || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0)) - result |= 2; - /* This catches a Cygwin 1.5.x bug. */ - if (sprintf (buf, "%.F", 1234.0) < 0 - || strcmp (buf, "1234") != 0) - result |= 4; - return result; -}]])], - [gl_cv_func_printf_directive_f=yes], - [gl_cv_func_printf_directive_f=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_directive_f="guessing yes";; - # Guess yes on FreeBSD >= 6. - freebsd[1-5]*) gl_cv_func_printf_directive_f="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";; - # Guess yes on Mac OS X >= 10.3. - darwin[1-6].*) gl_cv_func_printf_directive_f="guessing no";; - darwin*) gl_cv_func_printf_directive_f="guessing yes";; - # Guess yes on Solaris >= 2.10. - solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";; - solaris*) gl_cv_func_printf_sizes_c99="guessing no";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_directive_f="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports the %n format -dnl directive. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_printf_directive_n. - -AC_DEFUN([gl_PRINTF_DIRECTIVE_N], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports the 'n' directive], - [gl_cv_func_printf_directive_n], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#include -#ifdef _MSC_VER -/* See page about "Parameter Validation" on msdn.microsoft.com. */ -static void cdecl -invalid_parameter_handler (const wchar_t *expression, - const wchar_t *function, - const wchar_t *file, unsigned int line, - uintptr_t dummy) -{ - exit (1); -} -#endif -static char fmtstring[10]; -static char buf[100]; -int main () -{ - int count = -1; -#ifdef _MSC_VER - _set_invalid_parameter_handler (invalid_parameter_handler); -#endif - /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) - support %n in format strings in read-only memory but not in writable - memory. */ - strcpy (fmtstring, "%d %n"); - if (sprintf (buf, fmtstring, 123, &count, 33, 44, 55) < 0 - || strcmp (buf, "123 ") != 0 - || count != 4) - return 1; - return 0; -}]])], - [gl_cv_func_printf_directive_n=yes], - [gl_cv_func_printf_directive_n=no], - [ -changequote(,)dnl - case "$host_os" in - mingw*) gl_cv_func_printf_directive_n="guessing no";; - *) gl_cv_func_printf_directive_n="guessing yes";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports the %ls format -dnl directive and in particular, when a precision is specified, whether -dnl the functions stop converting the wide string argument when the number -dnl of bytes that have been produced by this conversion equals or exceeds -dnl the precision. -dnl Result is gl_cv_func_printf_directive_ls. - -AC_DEFUN([gl_PRINTF_DIRECTIVE_LS], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports the 'ls' directive], - [gl_cv_func_printf_directive_ls], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -#include -int main () -{ - int result = 0; - char buf[100]; - /* Test whether %ls works at all. - This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on - Cygwin 1.5. */ - { - static const wchar_t wstring[] = { 'a', 'b', 'c', 0 }; - buf[0] = '\0'; - if (sprintf (buf, "%ls", wstring) < 0 - || strcmp (buf, "abc") != 0) - result |= 1; - } - /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an - assertion failure inside libc), but not on OpenBSD 4.0. */ - { - static const wchar_t wstring[] = { 'a', 0 }; - buf[0] = '\0'; - if (sprintf (buf, "%ls", wstring) < 0 - || strcmp (buf, "a") != 0) - result |= 2; - } - /* Test whether precisions in %ls are supported as specified in ISO C 99 - section 7.19.6.1: - "If a precision is specified, no more than that many bytes are written - (including shift sequences, if any), and the array shall contain a - null wide character if, to equal the multibyte character sequence - length given by the precision, the function would need to access a - wide character one past the end of the array." - This test fails on Solaris 10. */ - { - static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 }; - buf[0] = '\0'; - if (sprintf (buf, "%.2ls", wstring) < 0 - || strcmp (buf, "ab") != 0) - result |= 8; - } - return result; -}]])], - [gl_cv_func_printf_directive_ls=yes], - [gl_cv_func_printf_directive_ls=no], - [ -changequote(,)dnl - case "$host_os" in - openbsd*) gl_cv_func_printf_directive_ls="guessing no";; - irix*) gl_cv_func_printf_directive_ls="guessing no";; - solaris*) gl_cv_func_printf_directive_ls="guessing no";; - cygwin*) gl_cv_func_printf_directive_ls="guessing no";; - beos* | haiku*) gl_cv_func_printf_directive_ls="guessing no";; - *) gl_cv_func_printf_directive_ls="guessing yes";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports POSIX/XSI format -dnl strings with positions. (POSIX:2001) -dnl Result is gl_cv_func_printf_positions. - -AC_DEFUN([gl_PRINTF_POSITIONS], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports POSIX/XSI format strings with positions], - [gl_cv_func_printf_positions], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* The string "%2$d %1$d", with dollar characters protected from the shell's - dollar expansion (possibly an autoconf bug). */ -static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; -static char buf[100]; -int main () -{ - sprintf (buf, format, 33, 55); - return (strcmp (buf, "55 33") != 0); -}]])], - [gl_cv_func_printf_positions=yes], - [gl_cv_func_printf_positions=no], - [ -changequote(,)dnl - case "$host_os" in - netbsd[1-3]* | netbsdelf[1-3]* | netbsdaout[1-3]* | netbsdcoff[1-3]*) - gl_cv_func_printf_positions="guessing no";; - beos*) gl_cv_func_printf_positions="guessing no";; - mingw* | pw*) gl_cv_func_printf_positions="guessing no";; - *) gl_cv_func_printf_positions="guessing yes";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports POSIX/XSI format -dnl strings with the ' flag for grouping of decimal digits. (POSIX:2001) -dnl Result is gl_cv_func_printf_flag_grouping. - -AC_DEFUN([gl_PRINTF_FLAG_GROUPING], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports the grouping flag], - [gl_cv_func_printf_flag_grouping], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static char buf[100]; -int main () -{ - if (sprintf (buf, "%'d %d", 1234567, 99) < 0 - || buf[strlen (buf) - 1] != '9') - return 1; - return 0; -}]])], - [gl_cv_func_printf_flag_grouping=yes], - [gl_cv_func_printf_flag_grouping=no], - [ -changequote(,)dnl - case "$host_os" in - cygwin*) gl_cv_func_printf_flag_grouping="guessing no";; - netbsd*) gl_cv_func_printf_flag_grouping="guessing no";; - mingw* | pw*) gl_cv_func_printf_flag_grouping="guessing no";; - *) gl_cv_func_printf_flag_grouping="guessing yes";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports the - flag correctly. -dnl (ISO C99.) See -dnl -dnl Result is gl_cv_func_printf_flag_leftadjust. - -AC_DEFUN([gl_PRINTF_FLAG_LEFTADJUST], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports the left-adjust flag correctly], - [gl_cv_func_printf_flag_leftadjust], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static char buf[100]; -int main () -{ - /* Check that a '-' flag is not annihilated by a negative width. */ - if (sprintf (buf, "a%-*sc", -3, "b") < 0 - || strcmp (buf, "ab c") != 0) - return 1; - return 0; -}]])], - [gl_cv_func_printf_flag_leftadjust=yes], - [gl_cv_func_printf_flag_leftadjust=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on HP-UX 11. - hpux11*) gl_cv_func_printf_flag_leftadjust="guessing yes";; - # Guess no on HP-UX 10 and older. - hpux*) gl_cv_func_printf_flag_leftadjust="guessing no";; - # Guess yes otherwise. - *) gl_cv_func_printf_flag_leftadjust="guessing yes";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports padding of non-finite -dnl values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See -dnl -dnl Result is gl_cv_func_printf_flag_zero. - -AC_DEFUN([gl_PRINTF_FLAG_ZERO], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports the zero flag correctly], - [gl_cv_func_printf_flag_zero], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static char buf[100]; -static double zero = 0.0; -int main () -{ - if (sprintf (buf, "%010f", 1.0 / zero, 33, 44, 55) < 0 - || (strcmp (buf, " inf") != 0 - && strcmp (buf, " infinity") != 0)) - return 1; - return 0; -}]])], - [gl_cv_func_printf_flag_zero=yes], - [gl_cv_func_printf_flag_zero=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_flag_zero="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_printf_flag_zero="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_flag_zero="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions supports large precisions. -dnl On mingw, precisions larger than 512 are treated like 512, in integer, -dnl floating-point or pointer output. On Solaris 10/x86, precisions larger -dnl than 510 in floating-point output crash the program. On Solaris 10/SPARC, -dnl precisions larger than 510 in floating-point output yield wrong results. -dnl On AIX 7.1, precisions larger than 998 in floating-point output yield -dnl wrong results. On BeOS, precisions larger than 1044 crash the program. -dnl Result is gl_cv_func_printf_precision. - -AC_DEFUN([gl_PRINTF_PRECISION], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf supports large precisions], - [gl_cv_func_printf_precision], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static char buf[5000]; -int main () -{ - int result = 0; -#ifdef __BEOS__ - /* On BeOS, this would crash and show a dialog box. Avoid the crash. */ - return 1; -#endif - if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3) - result |= 1; - if (sprintf (buf, "%.4000f %d", 1.0, 33, 44) < 4000 + 5) - result |= 2; - if (sprintf (buf, "%.511f %d", 1.0, 33, 44) < 511 + 5 - || buf[0] != '1') - result |= 4; - if (sprintf (buf, "%.999f %d", 1.0, 33, 44) < 999 + 5 - || buf[0] != '1') - result |= 4; - return result; -}]])], - [gl_cv_func_printf_precision=yes], - [gl_cv_func_printf_precision=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess no only on Solaris, native Windows, and BeOS systems. - solaris*) gl_cv_func_printf_precision="guessing no" ;; - mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;; - beos*) gl_cv_func_printf_precision="guessing no" ;; - *) gl_cv_func_printf_precision="guessing yes" ;; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the *printf family of functions recovers gracefully in case -dnl of an out-of-memory condition, or whether it crashes the entire program. -dnl Result is gl_cv_func_printf_enomem. - -AC_DEFUN([gl_PRINTF_ENOMEM], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gl_MULTIARCH]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether printf survives out-of-memory conditions], - [gl_cv_func_printf_enomem], - [ - gl_cv_func_printf_enomem="guessing no" - if test "$cross_compiling" = no; then - if test $APPLE_UNIVERSAL_BUILD = 0; then - AC_LANG_CONFTEST([AC_LANG_SOURCE([ -]GL_NOCRASH[ -changequote(,)dnl -#include -#include -#include -#include -#include -int main() -{ - struct rlimit limit; - int ret; - nocrash_init (); - /* Some printf implementations allocate temporary space with malloc. */ - /* On BSD systems, malloc() is limited by RLIMIT_DATA. */ -#ifdef RLIMIT_DATA - if (getrlimit (RLIMIT_DATA, &limit) < 0) - return 77; - if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) - limit.rlim_max = 5000000; - limit.rlim_cur = limit.rlim_max; - if (setrlimit (RLIMIT_DATA, &limit) < 0) - return 77; -#endif - /* On Linux systems, malloc() is limited by RLIMIT_AS. */ -#ifdef RLIMIT_AS - if (getrlimit (RLIMIT_AS, &limit) < 0) - return 77; - if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) - limit.rlim_max = 5000000; - limit.rlim_cur = limit.rlim_max; - if (setrlimit (RLIMIT_AS, &limit) < 0) - return 77; -#endif - /* Some printf implementations allocate temporary space on the stack. */ -#ifdef RLIMIT_STACK - if (getrlimit (RLIMIT_STACK, &limit) < 0) - return 77; - if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000) - limit.rlim_max = 5000000; - limit.rlim_cur = limit.rlim_max; - if (setrlimit (RLIMIT_STACK, &limit) < 0) - return 77; -#endif - ret = printf ("%.5000000f", 1.0); - return !(ret == 5000002 || (ret < 0 && errno == ENOMEM)); -} -changequote([,])dnl - ])]) - if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then - (./conftest 2>&AS_MESSAGE_LOG_FD - result=$? - _AS_ECHO_LOG([\$? = $result]) - if test $result != 0 && test $result != 77; then result=1; fi - exit $result - ) >/dev/null 2>/dev/null - case $? in - 0) gl_cv_func_printf_enomem="yes" ;; - 77) gl_cv_func_printf_enomem="guessing no" ;; - *) gl_cv_func_printf_enomem="no" ;; - esac - else - gl_cv_func_printf_enomem="guessing no" - fi - rm -fr conftest* - else - dnl A universal build on Apple Mac OS X platforms. - dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode. - dnl But we need a configuration result that is valid in both modes. - gl_cv_func_printf_enomem="guessing no" - fi - fi - if test "$gl_cv_func_printf_enomem" = "guessing no"; then -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on Solaris. - solaris*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on AIX. - aix*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on HP-UX/hppa. - hpux*) case "$host_cpu" in - hppa*) gl_cv_func_printf_enomem="guessing yes";; - *) gl_cv_func_printf_enomem="guessing no";; - esac - ;; - # Guess yes on IRIX. - irix*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on OSF/1. - osf*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_printf_enomem="guessing yes";; - # Guess yes on Haiku. - haiku*) gl_cv_func_printf_enomem="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_printf_enomem="guessing no";; - esac -changequote([,])dnl - fi - ]) -]) - -dnl Test whether the snprintf function exists. (ISO C99, POSIX:2001) -dnl Result is ac_cv_func_snprintf. - -AC_DEFUN([gl_SNPRINTF_PRESENCE], -[ - AC_CHECK_FUNCS_ONCE([snprintf]) -]) - -dnl Test whether the string produced by the snprintf function is always NUL -dnl terminated. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_snprintf_truncation_c99. - -AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_REQUIRE([gl_SNPRINTF_PRESENCE]) - AC_CACHE_CHECK([whether snprintf truncates the result as in C99], - [gl_cv_func_snprintf_truncation_c99], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#if HAVE_SNPRINTF -# define my_snprintf snprintf -#else -# include -static int my_snprintf (char *buf, int size, const char *format, ...) -{ - va_list args; - int ret; - va_start (args, format); - ret = vsnprintf (buf, size, format, args); - va_end (args); - return ret; -} -#endif -static char buf[100]; -int main () -{ - strcpy (buf, "ABCDEF"); - my_snprintf (buf, 3, "%d %d", 4567, 89); - if (memcmp (buf, "45\0DEF", 6) != 0) - return 1; - return 0; -}]])], - [gl_cv_func_snprintf_truncation_c99=yes], - [gl_cv_func_snprintf_truncation_c99=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on Mac OS X >= 10.3. - darwin[1-6].*) gl_cv_func_snprintf_truncation_c99="guessing no";; - darwin*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on OpenBSD >= 3.9. - openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) - gl_cv_func_snprintf_truncation_c99="guessing no";; - openbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on Solaris >= 2.6. - solaris2.[0-5] | solaris2.[0-5].*) - gl_cv_func_snprintf_truncation_c99="guessing no";; - solaris*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on AIX >= 4. - aix[1-3]*) gl_cv_func_snprintf_truncation_c99="guessing no";; - aix*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on HP-UX >= 11. - hpux[7-9]* | hpux10*) gl_cv_func_snprintf_truncation_c99="guessing no";; - hpux*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on IRIX >= 6.5. - irix6.5) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on OSF/1 >= 5. - osf[3-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; - osf*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on NetBSD >= 3. - netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) - gl_cv_func_snprintf_truncation_c99="guessing no";; - netbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_snprintf_truncation_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_snprintf_truncation_c99="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the return value of the snprintf function is the number -dnl of bytes (excluding the terminating NUL) that would have been produced -dnl if the buffer had been large enough. (ISO C99, POSIX:2001) -dnl For example, this test program fails on IRIX 6.5: -dnl --------------------------------------------------------------------- -dnl #include -dnl int main() -dnl { -dnl static char buf[8]; -dnl int retval = snprintf (buf, 3, "%d", 12345); -dnl return retval >= 0 && retval < 3; -dnl } -dnl --------------------------------------------------------------------- -dnl Result is gl_cv_func_snprintf_retval_c99. - -AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_REQUIRE([gl_SNPRINTF_PRESENCE]) - AC_CACHE_CHECK([whether snprintf returns a byte count as in C99], - [gl_cv_func_snprintf_retval_c99], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#if HAVE_SNPRINTF -# define my_snprintf snprintf -#else -# include -static int my_snprintf (char *buf, int size, const char *format, ...) -{ - va_list args; - int ret; - va_start (args, format); - ret = vsnprintf (buf, size, format, args); - va_end (args); - return ret; -} -#endif -static char buf[100]; -int main () -{ - strcpy (buf, "ABCDEF"); - if (my_snprintf (buf, 3, "%d %d", 4567, 89) != 7) - return 1; - if (my_snprintf (buf, 0, "%d %d", 4567, 89) != 7) - return 2; - if (my_snprintf (NULL, 0, "%d %d", 4567, 89) != 7) - return 3; - return 0; -}]])], - [gl_cv_func_snprintf_retval_c99=yes], - [gl_cv_func_snprintf_retval_c99=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_snprintf_retval_c99="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # Guess yes on Mac OS X >= 10.3. - darwin[1-6].*) gl_cv_func_snprintf_retval_c99="guessing no";; - darwin*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # Guess yes on OpenBSD >= 3.9. - openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) - gl_cv_func_snprintf_retval_c99="guessing no";; - openbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # Guess yes on Solaris >= 2.10. - solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";; - solaris*) gl_cv_func_printf_sizes_c99="guessing no";; - # Guess yes on AIX >= 4. - aix[1-3]*) gl_cv_func_snprintf_retval_c99="guessing no";; - aix*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # Guess yes on NetBSD >= 3. - netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) - gl_cv_func_snprintf_retval_c99="guessing no";; - netbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_snprintf_retval_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_snprintf_retval_c99="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the snprintf function supports the %n format directive -dnl also in truncated portions of the format string. (ISO C99, POSIX:2001) -dnl Result is gl_cv_func_snprintf_directive_n. - -AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_REQUIRE([gl_SNPRINTF_PRESENCE]) - AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive], - [gl_cv_func_snprintf_directive_n], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -#if HAVE_SNPRINTF -# define my_snprintf snprintf -#else -# include -static int my_snprintf (char *buf, int size, const char *format, ...) -{ - va_list args; - int ret; - va_start (args, format); - ret = vsnprintf (buf, size, format, args); - va_end (args); - return ret; -} -#endif -static char fmtstring[10]; -static char buf[100]; -int main () -{ - int count = -1; - /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) - support %n in format strings in read-only memory but not in writable - memory. */ - strcpy (fmtstring, "%d %n"); - my_snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55); - if (count != 6) - return 1; - return 0; -}]])], - [gl_cv_func_snprintf_directive_n=yes], - [gl_cv_func_snprintf_directive_n=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_snprintf_directive_n="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on Mac OS X >= 10.3. - darwin[1-6].*) gl_cv_func_snprintf_directive_n="guessing no";; - darwin*) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on Solaris >= 2.6. - solaris2.[0-5] | solaris2.[0-5].*) - gl_cv_func_snprintf_directive_n="guessing no";; - solaris*) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on AIX >= 4. - aix[1-3]*) gl_cv_func_snprintf_directive_n="guessing no";; - aix*) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on IRIX >= 6.5. - irix6.5) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on OSF/1 >= 5. - osf[3-4]*) gl_cv_func_snprintf_directive_n="guessing no";; - osf*) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on NetBSD >= 3. - netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) - gl_cv_func_snprintf_directive_n="guessing no";; - netbsd*) gl_cv_func_snprintf_directive_n="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_snprintf_directive_n="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_snprintf_directive_n="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl Test whether the snprintf function, when passed a size = 1, writes any -dnl output without bounds in this case, behaving like sprintf. This is the -dnl case on Linux libc5. -dnl Result is gl_cv_func_snprintf_size1. - -AC_DEFUN([gl_SNPRINTF_SIZE1], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gl_SNPRINTF_PRESENCE]) - AC_CACHE_CHECK([whether snprintf respects a size of 1], - [gl_cv_func_snprintf_size1], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#if HAVE_SNPRINTF -# define my_snprintf snprintf -#else -# include -static int my_snprintf (char *buf, int size, const char *format, ...) -{ - va_list args; - int ret; - va_start (args, format); - ret = vsnprintf (buf, size, format, args); - va_end (args); - return ret; -} -#endif -int main() -{ - static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; - my_snprintf (buf, 1, "%d", 12345); - return buf[1] != 'E'; -}]])], - [gl_cv_func_snprintf_size1=yes], - [gl_cv_func_snprintf_size1=no], - [gl_cv_func_snprintf_size1="guessing yes"]) - ]) -]) - -dnl Test whether the vsnprintf function, when passed a zero size, produces no -dnl output. (ISO C99, POSIX:2001) -dnl For example, snprintf nevertheless writes a NUL byte in this case -dnl on OSF/1 5.1: -dnl --------------------------------------------------------------------- -dnl #include -dnl int main() -dnl { -dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; -dnl snprintf (buf, 0, "%d", 12345); -dnl return buf[0] != 'D'; -dnl } -dnl --------------------------------------------------------------------- -dnl And vsnprintf writes any output without bounds in this case, behaving like -dnl vsprintf, on HP-UX 11 and OSF/1 5.1: -dnl --------------------------------------------------------------------- -dnl #include -dnl #include -dnl static int my_snprintf (char *buf, int size, const char *format, ...) -dnl { -dnl va_list args; -dnl int ret; -dnl va_start (args, format); -dnl ret = vsnprintf (buf, size, format, args); -dnl va_end (args); -dnl return ret; -dnl } -dnl int main() -dnl { -dnl static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; -dnl my_snprintf (buf, 0, "%d", 12345); -dnl return buf[0] != 'D'; -dnl } -dnl --------------------------------------------------------------------- -dnl Result is gl_cv_func_vsnprintf_zerosize_c99. - -AC_DEFUN([gl_VSNPRINTF_ZEROSIZE_C99], -[ - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether vsnprintf respects a zero size as in C99], - [gl_cv_func_vsnprintf_zerosize_c99], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -static int my_snprintf (char *buf, int size, const char *format, ...) -{ - va_list args; - int ret; - va_start (args, format); - ret = vsnprintf (buf, size, format, args); - va_end (args); - return ret; -} -int main() -{ - static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; - my_snprintf (buf, 0, "%d", 12345); - return buf[0] != 'D'; -}]])], - [gl_cv_func_vsnprintf_zerosize_c99=yes], - [gl_cv_func_vsnprintf_zerosize_c99=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on FreeBSD >= 5. - freebsd[1-4]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; - freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on Mac OS X >= 10.3. - darwin[1-6].*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; - darwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on Cygwin. - cygwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on Solaris >= 2.6. - solaris2.[0-5] | solaris2.[0-5].*) - gl_cv_func_vsnprintf_zerosize_c99="guessing no";; - solaris*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on AIX >= 4. - aix[1-3]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; - aix*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on IRIX >= 6.5. - irix6.5) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on NetBSD >= 3. - netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) - gl_cv_func_vsnprintf_zerosize_c99="guessing no";; - netbsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on BeOS. - beos*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # Guess yes on mingw. - mingw* | pw*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; - # If we don't know, assume the worst. - *) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; - esac -changequote([,])dnl - ]) - ]) -]) - -dnl The results of these tests on various platforms are: -dnl -dnl 1 = gl_PRINTF_SIZES_C99 -dnl 2 = gl_PRINTF_LONG_DOUBLE -dnl 3 = gl_PRINTF_INFINITE -dnl 4 = gl_PRINTF_INFINITE_LONG_DOUBLE -dnl 5 = gl_PRINTF_DIRECTIVE_A -dnl 6 = gl_PRINTF_DIRECTIVE_F -dnl 7 = gl_PRINTF_DIRECTIVE_N -dnl 8 = gl_PRINTF_DIRECTIVE_LS -dnl 9 = gl_PRINTF_POSITIONS -dnl 10 = gl_PRINTF_FLAG_GROUPING -dnl 11 = gl_PRINTF_FLAG_LEFTADJUST -dnl 12 = gl_PRINTF_FLAG_ZERO -dnl 13 = gl_PRINTF_PRECISION -dnl 14 = gl_PRINTF_ENOMEM -dnl 15 = gl_SNPRINTF_PRESENCE -dnl 16 = gl_SNPRINTF_TRUNCATION_C99 -dnl 17 = gl_SNPRINTF_RETVAL_C99 -dnl 18 = gl_SNPRINTF_DIRECTIVE_N -dnl 19 = gl_SNPRINTF_SIZE1 -dnl 20 = gl_VSNPRINTF_ZEROSIZE_C99 -dnl -dnl 1 = checking whether printf supports size specifiers as in C99... -dnl 2 = checking whether printf supports 'long double' arguments... -dnl 3 = checking whether printf supports infinite 'double' arguments... -dnl 4 = checking whether printf supports infinite 'long double' arguments... -dnl 5 = checking whether printf supports the 'a' and 'A' directives... -dnl 6 = checking whether printf supports the 'F' directive... -dnl 7 = checking whether printf supports the 'n' directive... -dnl 8 = checking whether printf supports the 'ls' directive... -dnl 9 = checking whether printf supports POSIX/XSI format strings with positions... -dnl 10 = checking whether printf supports the grouping flag... -dnl 11 = checking whether printf supports the left-adjust flag correctly... -dnl 12 = checking whether printf supports the zero flag correctly... -dnl 13 = checking whether printf supports large precisions... -dnl 14 = checking whether printf survives out-of-memory conditions... -dnl 15 = checking for snprintf... -dnl 16 = checking whether snprintf truncates the result as in C99... -dnl 17 = checking whether snprintf returns a byte count as in C99... -dnl 18 = checking whether snprintf fully supports the 'n' directive... -dnl 19 = checking whether snprintf respects a size of 1... -dnl 20 = checking whether vsnprintf respects a zero size as in C99... -dnl -dnl . = yes, # = no. -dnl -dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -dnl glibc 2.5 . . . . . . . . . . . . . . . . . . . . -dnl glibc 2.3.6 . . . . # . . . . . . . . . . . . . . . -dnl FreeBSD 5.4, 6.1 . . . . # . . . . . . # . # . . . . . . -dnl Mac OS X 10.5.8 . . . # # . . . . . . # . . . . . . . . -dnl Mac OS X 10.3.9 . . . . # . . . . . . # . # . . . . . . -dnl OpenBSD 3.9, 4.0 . . # # # # . # . # . # . # . . . . . . -dnl Cygwin 1.7.0 (2009) . . . # . . . ? . . . . . ? . . . . . . -dnl Cygwin 1.5.25 (2008) . . . # # . . # . . . . . # . . . . . . -dnl Cygwin 1.5.19 (2006) # . . # # # . # . # . # # # . . . . . . -dnl Solaris 11 2011-11 . . # # # . . # . . . # . . . . . . . . -dnl Solaris 10 . . # # # . . # . . . # # . . . . . . . -dnl Solaris 2.6 ... 9 # . # # # # . # . . . # # . . . # . . . -dnl Solaris 2.5.1 # . # # # # . # . . . # . . # # # # # # -dnl AIX 7.1 . . # # # . . . . . . # # . . . . . . . -dnl AIX 5.2 . . # # # . . . . . . # . . . . . . . . -dnl AIX 4.3.2, 5.1 # . # # # # . . . . . # . . . . # . . . -dnl HP-UX 11.31 . . . . # . . . . . . # . . . . # # . . -dnl HP-UX 11.{00,11,23} # . . . # # . . . . . # . . . . # # . # -dnl HP-UX 10.20 # . # . # # . ? . . # # . . . . # # ? # -dnl IRIX 6.5 # . # # # # . # . . . # . . . . # . . . -dnl OSF/1 5.1 # . # # # # . . . . . # . . . . # . . # -dnl OSF/1 4.0d # . # # # # . . . . . # . . # # # # # # -dnl NetBSD 5.0 . . . # # . . . . . . # . # . . . . . . -dnl NetBSD 4.0 . ? ? ? ? ? . ? . ? ? ? ? ? . . . ? ? ? -dnl NetBSD 3.0 . . . . # # . ? # # ? # . # . . . . . . -dnl Haiku . . . # # # . # . . . . . ? . . ? . . . -dnl BeOS # # . # # # . ? # . ? . # ? . . ? . . . -dnl old mingw / msvcrt # # # # # # . . # # . # # ? . # # # . . -dnl MSVC 9 # # # # # # # . # # . # # ? # # # # . . -dnl mingw 2009-2011 . # . # . . . . # # . . . ? . . . . . . -dnl mingw-w64 2011 # # # # # # . . # # . # # ? . # # # . . diff --git a/m4/progtest.m4 b/m4/progtest.m4 deleted file mode 100644 index 7b3912329..000000000 --- a/m4/progtest.m4 +++ /dev/null @@ -1,91 +0,0 @@ -# progtest.m4 serial 7 (gettext-0.18.2) -dnl Copyright (C) 1996-2003, 2005, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl This file can can be used in projects which are not available under -dnl the GNU General Public License or the GNU Library General Public -dnl License but which still want to provide support for the GNU gettext -dnl functionality. -dnl Please note that the actual code of the GNU gettext library is covered -dnl by the GNU Library General Public License, and the rest of the GNU -dnl gettext package package is covered by the GNU General Public License. -dnl They are *not* in the public domain. - -dnl Authors: -dnl Ulrich Drepper , 1996. - -AC_PREREQ([2.50]) - -# Search path for a program which passes the given test. - -dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, -dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) -AC_DEFUN([AM_PATH_PROG_WITH_TEST], -[ -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which - # contains only /bin. Note that ksh looks also at the FPATH variable, - # so we have to set that as well for the test. - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "$2", so it can be a program name with args. -set dummy $2; ac_word=[$]2 -AC_MSG_CHECKING([for $ac_word]) -AC_CACHE_VAL([ac_cv_path_$1], -[case "[$]$1" in - [[\\/]]* | ?:[[\\/]]*) - ac_cv_path_$1="[$]$1" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in ifelse([$5], , $PATH, [$5]); do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD - if [$3]; then - ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" -dnl If no 4th arg is given, leave the cache variable unset, -dnl so AC_PATH_PROGS will keep looking. -ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" -])dnl - ;; -esac])dnl -$1="$ac_cv_path_$1" -if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then - AC_MSG_RESULT([$][$1]) -else - AC_MSG_RESULT([no]) -fi -AC_SUBST([$1])dnl -]) diff --git a/m4/rawmemchr.m4 b/m4/rawmemchr.m4 deleted file mode 100644 index 8c500547c..000000000 --- a/m4/rawmemchr.m4 +++ /dev/null @@ -1,20 +0,0 @@ -# rawmemchr.m4 serial 2 -dnl Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_RAWMEMCHR], -[ - dnl Persuade glibc to declare rawmemchr(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - AC_CHECK_FUNCS([rawmemchr]) - if test $ac_cv_func_rawmemchr = no; then - HAVE_RAWMEMCHR=0 - fi -]) - -# Prerequisites of lib/strchrnul.c. -AC_DEFUN([gl_PREREQ_RAWMEMCHR], [:]) diff --git a/m4/realloc.m4 b/m4/realloc.m4 deleted file mode 100644 index d477fb470..000000000 --- a/m4/realloc.m4 +++ /dev/null @@ -1,76 +0,0 @@ -# realloc.m4 serial 13 -dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -m4_version_prereq([2.70], [] ,[ - -# This is taken from the following Autoconf patch: -# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 -AC_DEFUN([_AC_FUNC_REALLOC_IF], -[ - AC_REQUIRE([AC_HEADER_STDC])dnl - AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles - AC_CHECK_HEADERS([stdlib.h]) - AC_CACHE_CHECK([for GNU libc compatible realloc], - [ac_cv_func_realloc_0_nonnull], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H - # include - #else - char *realloc (); - #endif - ]], - [[return ! realloc (0, 0);]]) - ], - [ac_cv_func_realloc_0_nonnull=yes], - [ac_cv_func_realloc_0_nonnull=no], - [case "$host_os" in - # Guess yes on platforms where we know the result. - *-gnu* | freebsd* | netbsd* | openbsd* \ - | hpux* | solaris* | cygwin* | mingw*) - ac_cv_func_realloc_0_nonnull=yes ;; - # If we don't know, assume the worst. - *) ac_cv_func_realloc_0_nonnull=no ;; - esac - ]) - ]) - AS_IF([test $ac_cv_func_realloc_0_nonnull = yes], [$1], [$2]) -])# AC_FUNC_REALLOC - -]) - -# gl_FUNC_REALLOC_GNU -# ------------------- -# Test whether 'realloc (0, 0)' is handled like in GNU libc, and replace -# realloc if it is not. -AC_DEFUN([gl_FUNC_REALLOC_GNU], -[ - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - dnl _AC_FUNC_REALLOC_IF is defined in Autoconf. - _AC_FUNC_REALLOC_IF( - [AC_DEFINE([HAVE_REALLOC_GNU], [1], - [Define to 1 if your system has a GNU libc compatible 'realloc' - function, and to 0 otherwise.])], - [AC_DEFINE([HAVE_REALLOC_GNU], [0]) - REPLACE_REALLOC=1 - ]) -])# gl_FUNC_REALLOC_GNU - -# gl_FUNC_REALLOC_POSIX -# --------------------- -# Test whether 'realloc' is POSIX compliant (sets errno to ENOMEM when it -# fails), and replace realloc if it is not. -AC_DEFUN([gl_FUNC_REALLOC_POSIX], -[ - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) - if test $gl_cv_func_malloc_posix = yes; then - AC_DEFINE([HAVE_REALLOC_POSIX], [1], - [Define if the 'realloc' function is POSIX compliant.]) - else - REPLACE_REALLOC=1 - fi -]) diff --git a/m4/regex.m4 b/m4/regex.m4 deleted file mode 100644 index 3334c1041..000000000 --- a/m4/regex.m4 +++ /dev/null @@ -1,261 +0,0 @@ -# serial 64 - -# Copyright (C) 1996-2001, 2003-2013 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -dnl Initially derived from code in GNU grep. -dnl Mostly written by Jim Meyering. - -AC_PREREQ([2.50]) - -AC_DEFUN([gl_REGEX], -[ - AC_ARG_WITH([included-regex], - [AS_HELP_STRING([--without-included-regex], - [don't compile regex; this is the default on systems - with recent-enough versions of the GNU C Library - (use with caution on other systems).])]) - - case $with_included_regex in #( - yes|no) ac_use_included_regex=$with_included_regex - ;; - '') - # If the system regex support is good enough that it passes the - # following run test, then default to *not* using the included regex.c. - # If cross compiling, assume the test would fail and use the included - # regex.c. - AC_CHECK_DECLS_ONCE([alarm]) - AC_CACHE_CHECK([for working re_compile_pattern], - [gl_cv_func_re_compile_pattern_working], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#include - - #include - #include - #include - #if HAVE_DECL_ALARM - # include - # include - #endif - ]], - [[int result = 0; - static struct re_pattern_buffer regex; - unsigned char folded_chars[UCHAR_MAX + 1]; - int i; - const char *s; - struct re_registers regs; - -#if HAVE_DECL_ALARM - /* Some builds of glibc go into an infinite loop on this test. */ - signal (SIGALRM, SIG_DFL); - alarm (2); -#endif - if (setlocale (LC_ALL, "en_US.UTF-8")) - { - { - /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html - This test needs valgrind to catch the bug on Debian - GNU/Linux 3.1 x86, but it might catch the bug better - on other platforms and it shouldn't hurt to try the - test here. */ - static char const pat[] = "insert into"; - static char const data[] = - "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK"; - re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE - | RE_ICASE); - memset (®ex, 0, sizeof regex); - s = re_compile_pattern (pat, sizeof pat - 1, ®ex); - if (s) - result |= 1; - else if (re_search (®ex, data, sizeof data - 1, - 0, sizeof data - 1, ®s) - != -1) - result |= 1; - } - - { - /* This test is from glibc bug 15078. - The test case is from Andreas Schwab in - . - */ - static char const pat[] = "[^x]x"; - static char const data[] = - "\xe1\x80\x80\xe1\x80\xbb\xe1\x80\xbd\xe1\x80\x94\xe1\x80" - "\xba\xe1\x80\xaf\xe1\x80\x95\xe1\x80\xbax"; - re_set_syntax (0); - memset (®ex, 0, sizeof regex); - s = re_compile_pattern (pat, sizeof pat - 1, ®ex); - if (s) - result |= 1; - else if (re_search (®ex, data, sizeof data - 1, - 0, sizeof data - 1, 0) - != 21) - result |= 1; - } - - if (! setlocale (LC_ALL, "C")) - return 1; - } - - /* This test is from glibc bug 3957, reported by Andrew Mackey. */ - re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE); - memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("a[^x]b", 6, ®ex); - if (s) - result |= 2; - /* This should fail, but succeeds for glibc-2.5. */ - else if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) - result |= 2; - - /* This regular expression is from Spencer ere test number 75 - in grep-2.3. */ - re_set_syntax (RE_SYNTAX_POSIX_EGREP); - memset (®ex, 0, sizeof regex); - for (i = 0; i <= UCHAR_MAX; i++) - folded_chars[i] = i; - regex.translate = folded_chars; - s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); - /* This should fail with _Invalid character class name_ error. */ - if (!s) - result |= 4; - - /* Ensure that [b-a] is diagnosed as invalid, when - using RE_NO_EMPTY_RANGES. */ - re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_NO_EMPTY_RANGES); - memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("a[b-a]", 6, ®ex); - if (s == 0) - result |= 8; - - /* This should succeed, but does not for glibc-2.1.3. */ - memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("{1", 2, ®ex); - if (s) - result |= 8; - - /* The following example is derived from a problem report - against gawk from Jorge Stolfi . */ - memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("[an\371]*n", 7, ®ex); - if (s) - result |= 8; - /* This should match, but does not for glibc-2.2.1. */ - else if (re_match (®ex, "an", 2, 0, ®s) != 2) - result |= 8; - - memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("x", 1, ®ex); - if (s) - result |= 8; - /* glibc-2.2.93 does not work with a negative RANGE argument. */ - else if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) - result |= 8; - - /* The version of regex.c in older versions of gnulib - ignored RE_ICASE. Detect that problem too. */ - re_set_syntax (RE_SYNTAX_EMACS | RE_ICASE); - memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("x", 1, ®ex); - if (s) - result |= 16; - else if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) - result |= 16; - - /* Catch a bug reported by Vin Shelton in - http://lists.gnu.org/archive/html/bug-coreutils/2007-06/msg00089.html - */ - re_set_syntax (RE_SYNTAX_POSIX_BASIC - & ~RE_CONTEXT_INVALID_DUP - & ~RE_NO_EMPTY_RANGES); - memset (®ex, 0, sizeof regex); - s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, ®ex); - if (s) - result |= 32; - - /* REG_STARTEND was added to glibc on 2004-01-15. - Reject older versions. */ - if (! REG_STARTEND) - result |= 64; - -#if 0 - /* It would be nice to reject hosts whose regoff_t values are too - narrow (including glibc on hosts with 64-bit ptrdiff_t and - 32-bit int), but we should wait until glibc implements this - feature. Otherwise, support for equivalence classes and - multibyte collation symbols would always be broken except - when compiling --without-included-regex. */ - if (sizeof (regoff_t) < sizeof (ptrdiff_t) - || sizeof (regoff_t) < sizeof (ssize_t)) - result |= 64; -#endif - - return result; - ]])], - [gl_cv_func_re_compile_pattern_working=yes], - [gl_cv_func_re_compile_pattern_working=no], - dnl When crosscompiling, assume it is not working. - [gl_cv_func_re_compile_pattern_working=no])]) - case $gl_cv_func_re_compile_pattern_working in #( - yes) ac_use_included_regex=no;; #( - no) ac_use_included_regex=yes;; - esac - ;; - *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex]) - ;; - esac - - if test $ac_use_included_regex = yes; then - AC_DEFINE([_REGEX_INCLUDE_LIMITS_H], [1], - [Define if you want to include , so that it - consistently overrides 's RE_DUP_MAX.]) - AC_DEFINE([_REGEX_LARGE_OFFSETS], [1], - [Define if you want regoff_t to be at least as wide POSIX requires.]) - AC_DEFINE([re_syntax_options], [rpl_re_syntax_options], - [Define to rpl_re_syntax_options if the replacement should be used.]) - AC_DEFINE([re_set_syntax], [rpl_re_set_syntax], - [Define to rpl_re_set_syntax if the replacement should be used.]) - AC_DEFINE([re_compile_pattern], [rpl_re_compile_pattern], - [Define to rpl_re_compile_pattern if the replacement should be used.]) - AC_DEFINE([re_compile_fastmap], [rpl_re_compile_fastmap], - [Define to rpl_re_compile_fastmap if the replacement should be used.]) - AC_DEFINE([re_search], [rpl_re_search], - [Define to rpl_re_search if the replacement should be used.]) - AC_DEFINE([re_search_2], [rpl_re_search_2], - [Define to rpl_re_search_2 if the replacement should be used.]) - AC_DEFINE([re_match], [rpl_re_match], - [Define to rpl_re_match if the replacement should be used.]) - AC_DEFINE([re_match_2], [rpl_re_match_2], - [Define to rpl_re_match_2 if the replacement should be used.]) - AC_DEFINE([re_set_registers], [rpl_re_set_registers], - [Define to rpl_re_set_registers if the replacement should be used.]) - AC_DEFINE([re_comp], [rpl_re_comp], - [Define to rpl_re_comp if the replacement should be used.]) - AC_DEFINE([re_exec], [rpl_re_exec], - [Define to rpl_re_exec if the replacement should be used.]) - AC_DEFINE([regcomp], [rpl_regcomp], - [Define to rpl_regcomp if the replacement should be used.]) - AC_DEFINE([regexec], [rpl_regexec], - [Define to rpl_regexec if the replacement should be used.]) - AC_DEFINE([regerror], [rpl_regerror], - [Define to rpl_regerror if the replacement should be used.]) - AC_DEFINE([regfree], [rpl_regfree], - [Define to rpl_regfree if the replacement should be used.]) - fi -]) - -# Prerequisites of lib/regex.c and lib/regex_internal.c. -AC_DEFUN([gl_PREREQ_REGEX], -[ - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - AC_REQUIRE([AC_C_INLINE]) - AC_REQUIRE([AC_C_RESTRICT]) - AC_REQUIRE([AC_TYPE_MBSTATE_T]) - AC_REQUIRE([gl_EEMALLOC]) - AC_CHECK_HEADERS([libintl.h]) - AC_CHECK_FUNCS_ONCE([isblank iswctype wcscoll]) - AC_CHECK_DECLS([isblank], [], [], [[#include ]]) -]) diff --git a/m4/size_max.m4 b/m4/size_max.m4 deleted file mode 100644 index 4b247abc0..000000000 --- a/m4/size_max.m4 +++ /dev/null @@ -1,79 +0,0 @@ -# size_max.m4 serial 10 -dnl Copyright (C) 2003, 2005-2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([gl_SIZE_MAX], -[ - AC_CHECK_HEADERS([stdint.h]) - dnl First test whether the system already has SIZE_MAX. - AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [ - gl_cv_size_max= - AC_EGREP_CPP([Found it], [ -#include -#if HAVE_STDINT_H -#include -#endif -#ifdef SIZE_MAX -Found it -#endif -], [gl_cv_size_max=yes]) - if test -z "$gl_cv_size_max"; then - dnl Define it ourselves. Here we assume that the type 'size_t' is not wider - dnl than the type 'unsigned long'. Try hard to find a definition that can - dnl be used in a preprocessor #if, i.e. doesn't contain a cast. - AC_COMPUTE_INT([size_t_bits_minus_1], [sizeof (size_t) * CHAR_BIT - 1], - [#include -#include ], [size_t_bits_minus_1=]) - AC_COMPUTE_INT([fits_in_uint], [sizeof (size_t) <= sizeof (unsigned int)], - [#include ], [fits_in_uint=]) - if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then - if test $fits_in_uint = 1; then - dnl Even though SIZE_MAX fits in an unsigned int, it must be of type - dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - extern size_t foo; - extern unsigned long foo; - ]], - [[]])], - [fits_in_uint=0]) - fi - dnl We cannot use 'expr' to simplify this expression, because 'expr' - dnl works only with 'long' integers in the host environment, while we - dnl might be cross-compiling from a 32-bit platform to a 64-bit platform. - if test $fits_in_uint = 1; then - gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)" - else - gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)" - fi - else - dnl Shouldn't happen, but who knows... - gl_cv_size_max='((size_t)~(size_t)0)' - fi - fi - ]) - if test "$gl_cv_size_max" != yes; then - AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max], - [Define as the maximum value of type 'size_t', if the system doesn't define it.]) - fi - dnl Don't redefine SIZE_MAX in config.h if config.h is re-included after - dnl . Remember that the #undef in AH_VERBATIM gets replaced with - dnl #define by AC_DEFINE_UNQUOTED. - AH_VERBATIM([SIZE_MAX], -[/* Define as the maximum value of type 'size_t', if the system doesn't define - it. */ -#ifndef SIZE_MAX -# undef SIZE_MAX -#endif]) -]) - -dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. -dnl Remove this when we can assume autoconf >= 2.61. -m4_ifdef([AC_COMPUTE_INT], [], [ - AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) -]) diff --git a/m4/sleep.m4 b/m4/sleep.m4 deleted file mode 100644 index a27baa6d5..000000000 --- a/m4/sleep.m4 +++ /dev/null @@ -1,62 +0,0 @@ -# sleep.m4 serial 7 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_SLEEP], -[ - AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - dnl We expect to see the declaration of sleep() in a header file. - dnl Older versions of mingw have a sleep() function that is an alias to - dnl _sleep() in MSVCRT. It has a different signature than POSIX sleep(): - dnl it takes the number of milliseconds as argument and returns void. - dnl mingw does not declare this function. - AC_CHECK_DECLS([sleep], , , [[#include ]]) - AC_CHECK_FUNCS_ONCE([sleep]) - if test $ac_cv_have_decl_sleep != yes; then - HAVE_SLEEP=0 - else - dnl Cygwin 1.5.x has a bug where sleep can't exceed 49.7 days. - AC_CACHE_CHECK([for working sleep], [gl_cv_func_sleep_works], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include -#include -#include -static void -handle_alarm (int sig) -{ - if (sig != SIGALRM) - _exit (2); -} -]], [[ - /* Failure to compile this test due to missing alarm is okay, - since all such platforms (mingw) also lack sleep. */ - unsigned int pentecost = 50 * 24 * 60 * 60; /* 50 days. */ - unsigned int remaining; - signal (SIGALRM, handle_alarm); - alarm (1); - remaining = sleep (pentecost); - if (remaining > pentecost) - return 3; - if (remaining <= pentecost - 10) - return 4; - return 0; - ]])], - [gl_cv_func_sleep_works=yes], [gl_cv_func_sleep_works=no], - [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_sleep_works="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_sleep_works="guessing no" ;; - esac - ])]) - case "$gl_cv_func_sleep_works" in - *yes) ;; - *) - REPLACE_SLEEP=1 - ;; - esac - fi -]) diff --git a/m4/ssize_t.m4 b/m4/ssize_t.m4 deleted file mode 100644 index 633813434..000000000 --- a/m4/ssize_t.m4 +++ /dev/null @@ -1,23 +0,0 @@ -# ssize_t.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2001-2003, 2006, 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether ssize_t is defined. - -AC_DEFUN([gt_TYPE_SSIZE_T], -[ - AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[int x = sizeof (ssize_t *) + sizeof (ssize_t); - return !x;]])], - [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])]) - if test $gt_cv_ssize_t = no; then - AC_DEFINE([ssize_t], [int], - [Define as a signed type of the same size as size_t.]) - fi -]) diff --git a/m4/stdalign.m4 b/m4/stdalign.m4 deleted file mode 100644 index a866ff670..000000000 --- a/m4/stdalign.m4 +++ /dev/null @@ -1,52 +0,0 @@ -# Check for stdalign.h that conforms to C11. - -dnl Copyright 2011-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# Prepare for substituting if it is not supported. - -AC_DEFUN([gl_STDALIGN_H], -[ - AC_CACHE_CHECK([for working stdalign.h], - [gl_cv_header_working_stdalign_h], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include - - /* Test that alignof yields a result consistent with offsetof. - This catches GCC bug 52023 - . */ - #ifdef __cplusplus - template struct alignof_helper { char a; t b; }; - # define ao(type) offsetof (alignof_helper, b) - #else - # define ao(type) offsetof (struct { char a; type b; }, b) - #endif - char test_double[ao (double) % _Alignof (double) == 0 ? 1 : -1]; - char test_long[ao (long int) % _Alignof (long int) == 0 ? 1 : -1]; - char test_alignof[alignof (double) == _Alignof (double) ? 1 : -1]; - - /* Test _Alignas only on platforms where gnulib can help. */ - #if \ - (__GNUC__ || __IBMC__ || __IBMCPP__ \ - || 0x5110 <= __SUNPRO_C || 1300 <= _MSC_VER) - struct alignas_test { char c; char alignas (8) alignas_8; }; - char test_alignas[offsetof (struct alignas_test, alignas_8) == 8 - ? 1 : -1]; - #endif - ]])], - [gl_cv_header_working_stdalign_h=yes], - [gl_cv_header_working_stdalign_h=no])]) - - if test $gl_cv_header_working_stdalign_h = yes; then - STDALIGN_H='' - else - STDALIGN_H='stdalign.h' - fi - - AC_SUBST([STDALIGN_H]) - AM_CONDITIONAL([GL_GENERATE_STDALIGN_H], [test -n "$STDALIGN_H"]) -]) diff --git a/m4/stdbool.m4 b/m4/stdbool.m4 deleted file mode 100644 index 80d5559ab..000000000 --- a/m4/stdbool.m4 +++ /dev/null @@ -1,100 +0,0 @@ -# Check for stdbool.h that conforms to C99. - -dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -#serial 5 - -# Prepare for substituting if it is not supported. - -AC_DEFUN([AM_STDBOOL_H], -[ - AC_REQUIRE([AC_CHECK_HEADER_STDBOOL]) - - # Define two additional variables used in the Makefile substitution. - - if test "$ac_cv_header_stdbool_h" = yes; then - STDBOOL_H='' - else - STDBOOL_H='stdbool.h' - fi - AC_SUBST([STDBOOL_H]) - AM_CONDITIONAL([GL_GENERATE_STDBOOL_H], [test -n "$STDBOOL_H"]) - - if test "$ac_cv_type__Bool" = yes; then - HAVE__BOOL=1 - else - HAVE__BOOL=0 - fi - AC_SUBST([HAVE__BOOL]) -]) - -# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future. -AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H]) - -# This version of the macro is needed in autoconf <= 2.68. - -AC_DEFUN([AC_CHECK_HEADER_STDBOOL], - [AC_CACHE_CHECK([for stdbool.h that conforms to C99], - [ac_cv_header_stdbool_h], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #include - #ifndef bool - "error: bool is not defined" - #endif - #ifndef false - "error: false is not defined" - #endif - #if false - "error: false is not 0" - #endif - #ifndef true - "error: true is not defined" - #endif - #if true != 1 - "error: true is not 1" - #endif - #ifndef __bool_true_false_are_defined - "error: __bool_true_false_are_defined is not defined" - #endif - - struct s { _Bool s: 1; _Bool t; } s; - - char a[true == 1 ? 1 : -1]; - char b[false == 0 ? 1 : -1]; - char c[__bool_true_false_are_defined == 1 ? 1 : -1]; - char d[(bool) 0.5 == true ? 1 : -1]; - /* See body of main program for 'e'. */ - char f[(_Bool) 0.0 == false ? 1 : -1]; - char g[true]; - char h[sizeof (_Bool)]; - char i[sizeof s.t]; - enum { j = false, k = true, l = false * true, m = true * 256 }; - /* The following fails for - HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ - _Bool n[m]; - char o[sizeof n == m * sizeof n[0] ? 1 : -1]; - char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; - /* Catch a bug in an HP-UX C compiler. See - http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html - */ - _Bool q = true; - _Bool *pq = &q; - ]], - [[ - bool e = &s; - *pq |= q; - *pq |= ! q; - /* Refer to every declared value, to avoid compiler optimizations. */ - return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l - + !m + !n + !o + !p + !q + !pq); - ]])], - [ac_cv_header_stdbool_h=yes], - [ac_cv_header_stdbool_h=no])]) - AC_CHECK_TYPES([_Bool]) -]) diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 deleted file mode 100644 index 5da8ab1ec..000000000 --- a/m4/stddef_h.m4 +++ /dev/null @@ -1,47 +0,0 @@ -dnl A placeholder for POSIX 2008 , for platforms that have issues. -# stddef_h.m4 serial 4 -dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_STDDEF_H], -[ - AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) - AC_REQUIRE([gt_TYPE_WCHAR_T]) - STDDEF_H= - if test $gt_cv_c_wchar_t = no; then - HAVE_WCHAR_T=0 - STDDEF_H=stddef.h - fi - AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions], - [gl_cv_decl_null_works], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include - int test[2 * (sizeof NULL == sizeof (void *)) -1]; -]])], - [gl_cv_decl_null_works=yes], - [gl_cv_decl_null_works=no])]) - if test $gl_cv_decl_null_works = no; then - REPLACE_NULL=1 - STDDEF_H=stddef.h - fi - AC_SUBST([STDDEF_H]) - AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"]) - if test -n "$STDDEF_H"; then - gl_NEXT_HEADERS([stddef.h]) - fi -]) - -AC_DEFUN([gl_STDDEF_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) -]) - -AC_DEFUN([gl_STDDEF_H_DEFAULTS], -[ - dnl Assume proper GNU behavior unless another module says otherwise. - REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) - HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T]) -]) diff --git a/m4/stdint.m4 b/m4/stdint.m4 deleted file mode 100644 index 27cdcdb9a..000000000 --- a/m4/stdint.m4 +++ /dev/null @@ -1,484 +0,0 @@ -# stdint.m4 serial 43 -dnl Copyright (C) 2001-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert and Bruno Haible. -dnl Test whether is supported or must be substituted. - -AC_DEFUN_ONCE([gl_STDINT_H], -[ - AC_PREREQ([2.59])dnl - - dnl Check for long long int and unsigned long long int. - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - if test $ac_cv_type_long_long_int = yes; then - HAVE_LONG_LONG_INT=1 - else - HAVE_LONG_LONG_INT=0 - fi - AC_SUBST([HAVE_LONG_LONG_INT]) - AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) - if test $ac_cv_type_unsigned_long_long_int = yes; then - HAVE_UNSIGNED_LONG_LONG_INT=1 - else - HAVE_UNSIGNED_LONG_LONG_INT=0 - fi - AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT]) - - dnl Check for , in the same way as gl_WCHAR_H does. - AC_CHECK_HEADERS_ONCE([wchar.h]) - if test $ac_cv_header_wchar_h = yes; then - HAVE_WCHAR_H=1 - else - HAVE_WCHAR_H=0 - fi - AC_SUBST([HAVE_WCHAR_H]) - - dnl Check for . - dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h. - if test $ac_cv_header_inttypes_h = yes; then - HAVE_INTTYPES_H=1 - else - HAVE_INTTYPES_H=0 - fi - AC_SUBST([HAVE_INTTYPES_H]) - - dnl Check for . - dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h. - if test $ac_cv_header_sys_types_h = yes; then - HAVE_SYS_TYPES_H=1 - else - HAVE_SYS_TYPES_H=0 - fi - AC_SUBST([HAVE_SYS_TYPES_H]) - - gl_CHECK_NEXT_HEADERS([stdint.h]) - if test $ac_cv_header_stdint_h = yes; then - HAVE_STDINT_H=1 - else - HAVE_STDINT_H=0 - fi - AC_SUBST([HAVE_STDINT_H]) - - dnl Now see whether we need a substitute . - if test $ac_cv_header_stdint_h = yes; then - AC_CACHE_CHECK([whether stdint.h conforms to C99], - [gl_cv_header_working_stdint_h], - [gl_cv_header_working_stdint_h=no - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ -#include -/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in . */ -#if !(defined WCHAR_MIN && defined WCHAR_MAX) -#error "WCHAR_MIN, WCHAR_MAX not defined in " -#endif -] -gl_STDINT_INCLUDES -[ -#ifdef INT8_MAX -int8_t a1 = INT8_MAX; -int8_t a1min = INT8_MIN; -#endif -#ifdef INT16_MAX -int16_t a2 = INT16_MAX; -int16_t a2min = INT16_MIN; -#endif -#ifdef INT32_MAX -int32_t a3 = INT32_MAX; -int32_t a3min = INT32_MIN; -#endif -#ifdef INT64_MAX -int64_t a4 = INT64_MAX; -int64_t a4min = INT64_MIN; -#endif -#ifdef UINT8_MAX -uint8_t b1 = UINT8_MAX; -#else -typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; -#endif -#ifdef UINT16_MAX -uint16_t b2 = UINT16_MAX; -#endif -#ifdef UINT32_MAX -uint32_t b3 = UINT32_MAX; -#endif -#ifdef UINT64_MAX -uint64_t b4 = UINT64_MAX; -#endif -int_least8_t c1 = INT8_C (0x7f); -int_least8_t c1max = INT_LEAST8_MAX; -int_least8_t c1min = INT_LEAST8_MIN; -int_least16_t c2 = INT16_C (0x7fff); -int_least16_t c2max = INT_LEAST16_MAX; -int_least16_t c2min = INT_LEAST16_MIN; -int_least32_t c3 = INT32_C (0x7fffffff); -int_least32_t c3max = INT_LEAST32_MAX; -int_least32_t c3min = INT_LEAST32_MIN; -int_least64_t c4 = INT64_C (0x7fffffffffffffff); -int_least64_t c4max = INT_LEAST64_MAX; -int_least64_t c4min = INT_LEAST64_MIN; -uint_least8_t d1 = UINT8_C (0xff); -uint_least8_t d1max = UINT_LEAST8_MAX; -uint_least16_t d2 = UINT16_C (0xffff); -uint_least16_t d2max = UINT_LEAST16_MAX; -uint_least32_t d3 = UINT32_C (0xffffffff); -uint_least32_t d3max = UINT_LEAST32_MAX; -uint_least64_t d4 = UINT64_C (0xffffffffffffffff); -uint_least64_t d4max = UINT_LEAST64_MAX; -int_fast8_t e1 = INT_FAST8_MAX; -int_fast8_t e1min = INT_FAST8_MIN; -int_fast16_t e2 = INT_FAST16_MAX; -int_fast16_t e2min = INT_FAST16_MIN; -int_fast32_t e3 = INT_FAST32_MAX; -int_fast32_t e3min = INT_FAST32_MIN; -int_fast64_t e4 = INT_FAST64_MAX; -int_fast64_t e4min = INT_FAST64_MIN; -uint_fast8_t f1 = UINT_FAST8_MAX; -uint_fast16_t f2 = UINT_FAST16_MAX; -uint_fast32_t f3 = UINT_FAST32_MAX; -uint_fast64_t f4 = UINT_FAST64_MAX; -#ifdef INTPTR_MAX -intptr_t g = INTPTR_MAX; -intptr_t gmin = INTPTR_MIN; -#endif -#ifdef UINTPTR_MAX -uintptr_t h = UINTPTR_MAX; -#endif -intmax_t i = INTMAX_MAX; -uintmax_t j = UINTMAX_MAX; - -#include /* for CHAR_BIT */ -#define TYPE_MINIMUM(t) \ - ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t))) -#define TYPE_MAXIMUM(t) \ - ((t) ((t) 0 < (t) -1 \ - ? (t) -1 \ - : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) -struct s { - int check_PTRDIFF: - PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) - && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t) - ? 1 : -1; - /* Detect bug in FreeBSD 6.0 / ia64. */ - int check_SIG_ATOMIC: - SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t) - && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t) - ? 1 : -1; - int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1; - int check_WCHAR: - WCHAR_MIN == TYPE_MINIMUM (wchar_t) - && WCHAR_MAX == TYPE_MAXIMUM (wchar_t) - ? 1 : -1; - /* Detect bug in mingw. */ - int check_WINT: - WINT_MIN == TYPE_MINIMUM (wint_t) - && WINT_MAX == TYPE_MAXIMUM (wint_t) - ? 1 : -1; - - /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ - int check_UINT8_C: - (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; - int check_UINT16_C: - (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; - - /* Detect bugs in OpenBSD 3.9 stdint.h. */ -#ifdef UINT8_MAX - int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; -#endif -#ifdef UINT16_MAX - int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; -#endif -#ifdef UINT32_MAX - int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; -#endif -#ifdef UINT64_MAX - int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; -#endif - int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; - int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; - int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; - int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; - int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; - int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; - int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; - int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; - int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; - int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; - int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; -}; - ]])], - [dnl Determine whether the various *_MIN, *_MAX macros are usable - dnl in preprocessor expression. We could do it by compiling a test - dnl program for each of these macros. It is faster to run a program - dnl that inspects the macro expansion. - dnl This detects a bug on HP-UX 11.23/ia64. - AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[ -#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ -#include -] -gl_STDINT_INCLUDES -[ -#include -#include -#define MVAL(macro) MVAL1(macro) -#define MVAL1(expression) #expression -static const char *macro_values[] = - { -#ifdef INT8_MAX - MVAL (INT8_MAX), -#endif -#ifdef INT16_MAX - MVAL (INT16_MAX), -#endif -#ifdef INT32_MAX - MVAL (INT32_MAX), -#endif -#ifdef INT64_MAX - MVAL (INT64_MAX), -#endif -#ifdef UINT8_MAX - MVAL (UINT8_MAX), -#endif -#ifdef UINT16_MAX - MVAL (UINT16_MAX), -#endif -#ifdef UINT32_MAX - MVAL (UINT32_MAX), -#endif -#ifdef UINT64_MAX - MVAL (UINT64_MAX), -#endif - NULL - }; -]], [[ - const char **mv; - for (mv = macro_values; *mv != NULL; mv++) - { - const char *value = *mv; - /* Test whether it looks like a cast expression. */ - if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0 - || strncmp (value, "((unsigned short)"/*)*/, 17) == 0 - || strncmp (value, "((unsigned char)"/*)*/, 16) == 0 - || strncmp (value, "((int)"/*)*/, 6) == 0 - || strncmp (value, "((signed short)"/*)*/, 15) == 0 - || strncmp (value, "((signed char)"/*)*/, 14) == 0) - return mv - macro_values + 1; - } - return 0; -]])], - [gl_cv_header_working_stdint_h=yes], - [], - [dnl When cross-compiling, assume it works. - gl_cv_header_working_stdint_h=yes - ]) - ]) - ]) - fi - if test "$gl_cv_header_working_stdint_h" = yes; then - STDINT_H= - else - dnl Check for , and for - dnl (used in Linux libc4 >= 4.6.7 and libc5). - AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h]) - if test $ac_cv_header_sys_inttypes_h = yes; then - HAVE_SYS_INTTYPES_H=1 - else - HAVE_SYS_INTTYPES_H=0 - fi - AC_SUBST([HAVE_SYS_INTTYPES_H]) - if test $ac_cv_header_sys_bitypes_h = yes; then - HAVE_SYS_BITYPES_H=1 - else - HAVE_SYS_BITYPES_H=0 - fi - AC_SUBST([HAVE_SYS_BITYPES_H]) - - gl_STDINT_TYPE_PROPERTIES - STDINT_H=stdint.h - fi - AC_SUBST([STDINT_H]) - AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"]) -]) - -dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES) -dnl Determine the size of each of the given types in bits. -AC_DEFUN([gl_STDINT_BITSIZEOF], -[ - dnl Use a shell loop, to avoid bloating configure, and - dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into - dnl config.h.in, - dnl - extra AC_SUBST calls, so that the right substitutions are made. - m4_foreach_w([gltype], [$1], - [AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), - [Define to the number of bits in type ']gltype['.])]) - for gltype in $1 ; do - AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}], - [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT], - [$2 -#include ], [result=unknown]) - eval gl_cv_bitsizeof_${gltype}=\$result - ]) - eval result=\$gl_cv_bitsizeof_${gltype} - if test $result = unknown; then - dnl Use a nonempty default, because some compilers, such as IRIX 5 cc, - dnl do a syntax check even on unused #if conditions and give an error - dnl on valid C code like this: - dnl #if 0 - dnl # if > 32 - dnl # endif - dnl #endif - result=0 - fi - GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` - AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result]) - eval BITSIZEOF_${GLTYPE}=\$result - done - m4_foreach_w([gltype], [$1], - [AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) -]) - -dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES) -dnl Determine the signedness of each of the given types. -dnl Define HAVE_SIGNED_TYPE if type is signed. -AC_DEFUN([gl_CHECK_TYPES_SIGNED], -[ - dnl Use a shell loop, to avoid bloating configure, and - dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into - dnl config.h.in, - dnl - extra AC_SUBST calls, so that the right substitutions are made. - m4_foreach_w([gltype], [$1], - [AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), - [Define to 1 if ']gltype[' is a signed integer type.])]) - for gltype in $1 ; do - AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([$2[ - int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])], - result=yes, result=no) - eval gl_cv_type_${gltype}_signed=\$result - ]) - eval result=\$gl_cv_type_${gltype}_signed - GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` - if test "$result" = yes; then - AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1]) - eval HAVE_SIGNED_${GLTYPE}=1 - else - eval HAVE_SIGNED_${GLTYPE}=0 - fi - done - m4_foreach_w([gltype], [$1], - [AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) -]) - -dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES) -dnl Determine the suffix to use for integer constants of the given types. -dnl Define t_SUFFIX for each such type. -AC_DEFUN([gl_INTEGER_TYPE_SUFFIX], -[ - dnl Use a shell loop, to avoid bloating configure, and - dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into - dnl config.h.in, - dnl - extra AC_SUBST calls, so that the right substitutions are made. - m4_foreach_w([gltype], [$1], - [AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX], - [Define to l, ll, u, ul, ull, etc., as suitable for - constants of type ']gltype['.])]) - for gltype in $1 ; do - AC_CACHE_CHECK([for $gltype integer literal suffix], - [gl_cv_type_${gltype}_suffix], - [eval gl_cv_type_${gltype}_suffix=no - eval result=\$gl_cv_type_${gltype}_signed - if test "$result" = yes; then - glsufu= - else - glsufu=u - fi - for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do - case $glsuf in - '') gltype1='int';; - l) gltype1='long int';; - ll) gltype1='long long int';; - i64) gltype1='__int64';; - u) gltype1='unsigned int';; - ul) gltype1='unsigned long int';; - ull) gltype1='unsigned long long int';; - ui64)gltype1='unsigned __int64';; - esac - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([$2[ - extern $gltype foo; - extern $gltype1 foo;]])], - [eval gl_cv_type_${gltype}_suffix=\$glsuf]) - eval result=\$gl_cv_type_${gltype}_suffix - test "$result" != no && break - done]) - GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` - eval result=\$gl_cv_type_${gltype}_suffix - test "$result" = no && result= - eval ${GLTYPE}_SUFFIX=\$result - AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result]) - done - m4_foreach_w([gltype], [$1], - [AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])]) -]) - -dnl gl_STDINT_INCLUDES -AC_DEFUN([gl_STDINT_INCLUDES], -[[ - /* BSD/OS 4.0.1 has a bug: , and must be - included before . */ - #include - #include - #if HAVE_WCHAR_H - # include - # include - # include - #endif -]]) - -dnl gl_STDINT_TYPE_PROPERTIES -dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t -dnl of interest to stdint.in.h. -AC_DEFUN([gl_STDINT_TYPE_PROPERTIES], -[ - AC_REQUIRE([gl_MULTIARCH]) - if test $APPLE_UNIVERSAL_BUILD = 0; then - gl_STDINT_BITSIZEOF([ptrdiff_t size_t], - [gl_STDINT_INCLUDES]) - fi - gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t], - [gl_STDINT_INCLUDES]) - gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t], - [gl_STDINT_INCLUDES]) - gl_cv_type_ptrdiff_t_signed=yes - gl_cv_type_size_t_signed=no - if test $APPLE_UNIVERSAL_BUILD = 0; then - gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t], - [gl_STDINT_INCLUDES]) - fi - gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t], - [gl_STDINT_INCLUDES]) - - dnl If wint_t is smaller than 'int', it cannot satisfy the ISO C 99 - dnl requirement that wint_t is "unchanged by default argument promotions". - dnl In this case gnulib's and override wint_t. - dnl Set the variable BITSIZEOF_WINT_T accordingly. - if test $BITSIZEOF_WINT_T -lt 32; then - BITSIZEOF_WINT_T=32 - fi -]) - -dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. -dnl Remove this when we can assume autoconf >= 2.61. -m4_ifdef([AC_COMPUTE_INT], [], [ - AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) -]) - -# Hey Emacs! -# Local Variables: -# indent-tabs-mode: nil -# End: diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4 deleted file mode 100644 index 511ab4e9c..000000000 --- a/m4/stdint_h.m4 +++ /dev/null @@ -1,27 +0,0 @@ -# stdint_h.m4 serial 9 -dnl Copyright (C) 1997-2004, 2006, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -# Define HAVE_STDINT_H_WITH_UINTMAX if exists, -# doesn't clash with , and declares uintmax_t. - -AC_DEFUN([gl_AC_HEADER_STDINT_H], -[ - AC_CACHE_CHECK([for stdint.h], [gl_cv_header_stdint_h], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include ]], - [[uintmax_t i = (uintmax_t) -1; return !i;]])], - [gl_cv_header_stdint_h=yes], - [gl_cv_header_stdint_h=no])]) - if test $gl_cv_header_stdint_h = yes; then - AC_DEFINE_UNQUOTED([HAVE_STDINT_H_WITH_UINTMAX], [1], - [Define if exists, doesn't clash with , - and declares uintmax_t. ]) - fi -]) diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 deleted file mode 100644 index ebade067d..000000000 --- a/m4/stdio_h.m4 +++ /dev/null @@ -1,194 +0,0 @@ -# stdio_h.m4 serial 43 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_STDIO_H], -[ - AC_REQUIRE([gl_STDIO_H_DEFAULTS]) - gl_NEXT_HEADERS([stdio.h]) - - dnl No need to create extra modules for these functions. Everyone who uses - dnl likely needs them. - GNULIB_FSCANF=1 - gl_MODULE_INDICATOR([fscanf]) - GNULIB_SCANF=1 - gl_MODULE_INDICATOR([scanf]) - GNULIB_FGETC=1 - GNULIB_GETC=1 - GNULIB_GETCHAR=1 - GNULIB_FGETS=1 - GNULIB_FREAD=1 - dnl This ifdef is necessary to avoid an error "missing file lib/stdio-read.c" - dnl "expected source file, required through AC_LIBSOURCES, not found". It is - dnl also an optimization, to avoid performing a configure check whose result - dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING - dnl or GNULIB_NONBLOCKING redundant. - m4_ifdef([gl_NONBLOCKING_IO], [ - gl_NONBLOCKING_IO - if test $gl_cv_have_nonblocking != yes; then - REPLACE_STDIO_READ_FUNCS=1 - AC_LIBOBJ([stdio-read]) - fi - ]) - - dnl No need to create extra modules for these functions. Everyone who uses - dnl likely needs them. - GNULIB_FPRINTF=1 - GNULIB_PRINTF=1 - GNULIB_VFPRINTF=1 - GNULIB_VPRINTF=1 - GNULIB_FPUTC=1 - GNULIB_PUTC=1 - GNULIB_PUTCHAR=1 - GNULIB_FPUTS=1 - GNULIB_PUTS=1 - GNULIB_FWRITE=1 - dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c" - dnl "expected source file, required through AC_LIBSOURCES, not found". It is - dnl also an optimization, to avoid performing a configure check whose result - dnl is not used. But it does not make the test of GNULIB_STDIO_H_SIGPIPE or - dnl GNULIB_SIGPIPE redundant. - m4_ifdef([gl_SIGNAL_SIGPIPE], [ - gl_SIGNAL_SIGPIPE - if test $gl_cv_header_signal_h_SIGPIPE != yes; then - REPLACE_STDIO_WRITE_FUNCS=1 - AC_LIBOBJ([stdio-write]) - fi - ]) - dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c" - dnl "expected source file, required through AC_LIBSOURCES, not found". It is - dnl also an optimization, to avoid performing a configure check whose result - dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING - dnl or GNULIB_NONBLOCKING redundant. - m4_ifdef([gl_NONBLOCKING_IO], [ - gl_NONBLOCKING_IO - if test $gl_cv_have_nonblocking != yes; then - REPLACE_STDIO_WRITE_FUNCS=1 - AC_LIBOBJ([stdio-write]) - fi - ]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use, and which is not - dnl guaranteed by both C89 and C11. - gl_WARN_ON_USE_PREPARE([[#include - ]], [dprintf fpurge fseeko ftello getdelim getline gets pclose popen - renameat snprintf tmpfile vdprintf vsnprintf]) -]) - -AC_DEFUN([gl_STDIO_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_STDIO_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_STDIO_H_DEFAULTS], -[ - GNULIB_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF]) - GNULIB_FCLOSE=0; AC_SUBST([GNULIB_FCLOSE]) - GNULIB_FDOPEN=0; AC_SUBST([GNULIB_FDOPEN]) - GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH]) - GNULIB_FGETC=0; AC_SUBST([GNULIB_FGETC]) - GNULIB_FGETS=0; AC_SUBST([GNULIB_FGETS]) - GNULIB_FOPEN=0; AC_SUBST([GNULIB_FOPEN]) - GNULIB_FPRINTF=0; AC_SUBST([GNULIB_FPRINTF]) - GNULIB_FPRINTF_POSIX=0; AC_SUBST([GNULIB_FPRINTF_POSIX]) - GNULIB_FPURGE=0; AC_SUBST([GNULIB_FPURGE]) - GNULIB_FPUTC=0; AC_SUBST([GNULIB_FPUTC]) - GNULIB_FPUTS=0; AC_SUBST([GNULIB_FPUTS]) - GNULIB_FREAD=0; AC_SUBST([GNULIB_FREAD]) - GNULIB_FREOPEN=0; AC_SUBST([GNULIB_FREOPEN]) - GNULIB_FSCANF=0; AC_SUBST([GNULIB_FSCANF]) - GNULIB_FSEEK=0; AC_SUBST([GNULIB_FSEEK]) - GNULIB_FSEEKO=0; AC_SUBST([GNULIB_FSEEKO]) - GNULIB_FTELL=0; AC_SUBST([GNULIB_FTELL]) - GNULIB_FTELLO=0; AC_SUBST([GNULIB_FTELLO]) - GNULIB_FWRITE=0; AC_SUBST([GNULIB_FWRITE]) - GNULIB_GETC=0; AC_SUBST([GNULIB_GETC]) - GNULIB_GETCHAR=0; AC_SUBST([GNULIB_GETCHAR]) - GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM]) - GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE]) - GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) - GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX]) - GNULIB_PCLOSE=0; AC_SUBST([GNULIB_PCLOSE]) - GNULIB_PERROR=0; AC_SUBST([GNULIB_PERROR]) - GNULIB_POPEN=0; AC_SUBST([GNULIB_POPEN]) - GNULIB_PRINTF=0; AC_SUBST([GNULIB_PRINTF]) - GNULIB_PRINTF_POSIX=0; AC_SUBST([GNULIB_PRINTF_POSIX]) - GNULIB_PUTC=0; AC_SUBST([GNULIB_PUTC]) - GNULIB_PUTCHAR=0; AC_SUBST([GNULIB_PUTCHAR]) - GNULIB_PUTS=0; AC_SUBST([GNULIB_PUTS]) - GNULIB_REMOVE=0; AC_SUBST([GNULIB_REMOVE]) - GNULIB_RENAME=0; AC_SUBST([GNULIB_RENAME]) - GNULIB_RENAMEAT=0; AC_SUBST([GNULIB_RENAMEAT]) - GNULIB_SCANF=0; AC_SUBST([GNULIB_SCANF]) - GNULIB_SNPRINTF=0; AC_SUBST([GNULIB_SNPRINTF]) - GNULIB_SPRINTF_POSIX=0; AC_SUBST([GNULIB_SPRINTF_POSIX]) - GNULIB_STDIO_H_NONBLOCKING=0; AC_SUBST([GNULIB_STDIO_H_NONBLOCKING]) - GNULIB_STDIO_H_SIGPIPE=0; AC_SUBST([GNULIB_STDIO_H_SIGPIPE]) - GNULIB_TMPFILE=0; AC_SUBST([GNULIB_TMPFILE]) - GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF]) - GNULIB_VFSCANF=0; AC_SUBST([GNULIB_VFSCANF]) - GNULIB_VSCANF=0; AC_SUBST([GNULIB_VSCANF]) - GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF]) - GNULIB_VFPRINTF=0; AC_SUBST([GNULIB_VFPRINTF]) - GNULIB_VFPRINTF_POSIX=0; AC_SUBST([GNULIB_VFPRINTF_POSIX]) - GNULIB_VPRINTF=0; AC_SUBST([GNULIB_VPRINTF]) - GNULIB_VPRINTF_POSIX=0; AC_SUBST([GNULIB_VPRINTF_POSIX]) - GNULIB_VSNPRINTF=0; AC_SUBST([GNULIB_VSNPRINTF]) - GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE]) - HAVE_DECL_FSEEKO=1; AC_SUBST([HAVE_DECL_FSEEKO]) - HAVE_DECL_FTELLO=1; AC_SUBST([HAVE_DECL_FTELLO]) - HAVE_DECL_GETDELIM=1; AC_SUBST([HAVE_DECL_GETDELIM]) - HAVE_DECL_GETLINE=1; AC_SUBST([HAVE_DECL_GETLINE]) - HAVE_DECL_OBSTACK_PRINTF=1; AC_SUBST([HAVE_DECL_OBSTACK_PRINTF]) - HAVE_DECL_SNPRINTF=1; AC_SUBST([HAVE_DECL_SNPRINTF]) - HAVE_DECL_VSNPRINTF=1; AC_SUBST([HAVE_DECL_VSNPRINTF]) - HAVE_DPRINTF=1; AC_SUBST([HAVE_DPRINTF]) - HAVE_FSEEKO=1; AC_SUBST([HAVE_FSEEKO]) - HAVE_FTELLO=1; AC_SUBST([HAVE_FTELLO]) - HAVE_PCLOSE=1; AC_SUBST([HAVE_PCLOSE]) - HAVE_POPEN=1; AC_SUBST([HAVE_POPEN]) - HAVE_RENAMEAT=1; AC_SUBST([HAVE_RENAMEAT]) - HAVE_VASPRINTF=1; AC_SUBST([HAVE_VASPRINTF]) - HAVE_VDPRINTF=1; AC_SUBST([HAVE_VDPRINTF]) - REPLACE_DPRINTF=0; AC_SUBST([REPLACE_DPRINTF]) - REPLACE_FCLOSE=0; AC_SUBST([REPLACE_FCLOSE]) - REPLACE_FDOPEN=0; AC_SUBST([REPLACE_FDOPEN]) - REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH]) - REPLACE_FOPEN=0; AC_SUBST([REPLACE_FOPEN]) - REPLACE_FPRINTF=0; AC_SUBST([REPLACE_FPRINTF]) - REPLACE_FPURGE=0; AC_SUBST([REPLACE_FPURGE]) - REPLACE_FREOPEN=0; AC_SUBST([REPLACE_FREOPEN]) - REPLACE_FSEEK=0; AC_SUBST([REPLACE_FSEEK]) - REPLACE_FSEEKO=0; AC_SUBST([REPLACE_FSEEKO]) - REPLACE_FTELL=0; AC_SUBST([REPLACE_FTELL]) - REPLACE_FTELLO=0; AC_SUBST([REPLACE_FTELLO]) - REPLACE_GETDELIM=0; AC_SUBST([REPLACE_GETDELIM]) - REPLACE_GETLINE=0; AC_SUBST([REPLACE_GETLINE]) - REPLACE_OBSTACK_PRINTF=0; AC_SUBST([REPLACE_OBSTACK_PRINTF]) - REPLACE_PERROR=0; AC_SUBST([REPLACE_PERROR]) - REPLACE_POPEN=0; AC_SUBST([REPLACE_POPEN]) - REPLACE_PRINTF=0; AC_SUBST([REPLACE_PRINTF]) - REPLACE_REMOVE=0; AC_SUBST([REPLACE_REMOVE]) - REPLACE_RENAME=0; AC_SUBST([REPLACE_RENAME]) - REPLACE_RENAMEAT=0; AC_SUBST([REPLACE_RENAMEAT]) - REPLACE_SNPRINTF=0; AC_SUBST([REPLACE_SNPRINTF]) - REPLACE_SPRINTF=0; AC_SUBST([REPLACE_SPRINTF]) - REPLACE_STDIO_READ_FUNCS=0; AC_SUBST([REPLACE_STDIO_READ_FUNCS]) - REPLACE_STDIO_WRITE_FUNCS=0; AC_SUBST([REPLACE_STDIO_WRITE_FUNCS]) - REPLACE_TMPFILE=0; AC_SUBST([REPLACE_TMPFILE]) - REPLACE_VASPRINTF=0; AC_SUBST([REPLACE_VASPRINTF]) - REPLACE_VDPRINTF=0; AC_SUBST([REPLACE_VDPRINTF]) - REPLACE_VFPRINTF=0; AC_SUBST([REPLACE_VFPRINTF]) - REPLACE_VPRINTF=0; AC_SUBST([REPLACE_VPRINTF]) - REPLACE_VSNPRINTF=0; AC_SUBST([REPLACE_VSNPRINTF]) - REPLACE_VSPRINTF=0; AC_SUBST([REPLACE_VSPRINTF]) -]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 deleted file mode 100644 index 2027ab3c1..000000000 --- a/m4/stdlib_h.m4 +++ /dev/null @@ -1,117 +0,0 @@ -# stdlib_h.m4 serial 42 -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_STDLIB_H], -[ - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - gl_NEXT_HEADERS([stdlib.h]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use, and which is not - dnl guaranteed by C89. - gl_WARN_ON_USE_PREPARE([[#include -#if HAVE_SYS_LOADAVG_H -# include -#endif -#if HAVE_RANDOM_H -# include -#endif - ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt - initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps - posix_openpt ptsname ptsname_r random random_r realpath rpmatch - secure_getenv setenv setstate setstate_r srandom srandom_r - strtod strtoll strtoull unlockpt unsetenv]) -]) - -AC_DEFUN([gl_STDLIB_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_STDLIB_H_DEFAULTS], -[ - GNULIB__EXIT=0; AC_SUBST([GNULIB__EXIT]) - GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL]) - GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX]) - GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME]) - GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG]) - GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT]) - GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT]) - GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX]) - GNULIB_MBTOWC=0; AC_SUBST([GNULIB_MBTOWC]) - GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP]) - GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP]) - GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS]) - GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP]) - GNULIB_MKSTEMPS=0; AC_SUBST([GNULIB_MKSTEMPS]) - GNULIB_POSIX_OPENPT=0; AC_SUBST([GNULIB_POSIX_OPENPT]) - GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME]) - GNULIB_PTSNAME_R=0; AC_SUBST([GNULIB_PTSNAME_R]) - GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV]) - GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM]) - GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) - GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX]) - GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH]) - GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH]) - GNULIB_SECURE_GETENV=0; AC_SUBST([GNULIB_SECURE_GETENV]) - GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV]) - GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD]) - GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL]) - GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL]) - GNULIB_SYSTEM_POSIX=0; AC_SUBST([GNULIB_SYSTEM_POSIX]) - GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT]) - GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV]) - GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE__EXIT=1; AC_SUBST([HAVE__EXIT]) - HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL]) - HAVE_CANONICALIZE_FILE_NAME=1; AC_SUBST([HAVE_CANONICALIZE_FILE_NAME]) - HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG]) - HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT]) - HAVE_GRANTPT=1; AC_SUBST([HAVE_GRANTPT]) - HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP]) - HAVE_MKOSTEMP=1; AC_SUBST([HAVE_MKOSTEMP]) - HAVE_MKOSTEMPS=1; AC_SUBST([HAVE_MKOSTEMPS]) - HAVE_MKSTEMP=1; AC_SUBST([HAVE_MKSTEMP]) - HAVE_MKSTEMPS=1; AC_SUBST([HAVE_MKSTEMPS]) - HAVE_POSIX_OPENPT=1; AC_SUBST([HAVE_POSIX_OPENPT]) - HAVE_PTSNAME=1; AC_SUBST([HAVE_PTSNAME]) - HAVE_PTSNAME_R=1; AC_SUBST([HAVE_PTSNAME_R]) - HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM]) - HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H]) - HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) - HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH]) - HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH]) - HAVE_SECURE_GETENV=1; AC_SUBST([HAVE_SECURE_GETENV]) - HAVE_SETENV=1; AC_SUBST([HAVE_SETENV]) - HAVE_DECL_SETENV=1; AC_SUBST([HAVE_DECL_SETENV]) - HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD]) - HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL]) - HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL]) - HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA]) - HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) - HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT]) - HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV]) - REPLACE_CALLOC=0; AC_SUBST([REPLACE_CALLOC]) - REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME]) - REPLACE_MALLOC=0; AC_SUBST([REPLACE_MALLOC]) - REPLACE_MBTOWC=0; AC_SUBST([REPLACE_MBTOWC]) - REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP]) - REPLACE_PTSNAME=0; AC_SUBST([REPLACE_PTSNAME]) - REPLACE_PTSNAME_R=0; AC_SUBST([REPLACE_PTSNAME_R]) - REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV]) - REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R]) - REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC]) - REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) - REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV]) - REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD]) - REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) - REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB]) -]) diff --git a/m4/strcase.m4 b/m4/strcase.m4 deleted file mode 100644 index 22bf57c95..000000000 --- a/m4/strcase.m4 +++ /dev/null @@ -1,45 +0,0 @@ -# strcase.m4 serial 11 -dnl Copyright (C) 2002, 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_STRCASE], -[ - gl_FUNC_STRCASECMP - gl_FUNC_STRNCASECMP -]) - -AC_DEFUN([gl_FUNC_STRCASECMP], -[ - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) - AC_CHECK_FUNCS([strcasecmp]) - if test $ac_cv_func_strcasecmp = no; then - HAVE_STRCASECMP=0 - fi -]) - -AC_DEFUN([gl_FUNC_STRNCASECMP], -[ - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) - AC_CHECK_FUNCS([strncasecmp]) - if test $ac_cv_func_strncasecmp = yes; then - HAVE_STRNCASECMP=1 - else - HAVE_STRNCASECMP=0 - fi - AC_CHECK_DECLS([strncasecmp]) - if test $ac_cv_have_decl_strncasecmp = no; then - HAVE_DECL_STRNCASECMP=0 - fi -]) - -# Prerequisites of lib/strcasecmp.c. -AC_DEFUN([gl_PREREQ_STRCASECMP], [ - : -]) - -# Prerequisites of lib/strncasecmp.c. -AC_DEFUN([gl_PREREQ_STRNCASECMP], [ - : -]) diff --git a/m4/strchrnul.m4 b/m4/strchrnul.m4 deleted file mode 100644 index b59eda9d7..000000000 --- a/m4/strchrnul.m4 +++ /dev/null @@ -1,50 +0,0 @@ -# strchrnul.m4 serial 9 -dnl Copyright (C) 2003, 2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_STRCHRNUL], -[ - dnl Persuade glibc to declare strchrnul(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - AC_CHECK_FUNCS([strchrnul]) - if test $ac_cv_func_strchrnul = no; then - HAVE_STRCHRNUL=0 - else - AC_CACHE_CHECK([whether strchrnul works], - [gl_cv_func_strchrnul_works], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include /* for strchrnul */ -]], [[const char *buf = "a"; - return strchrnul (buf, 'b') != buf + 1; - ]])], - [gl_cv_func_strchrnul_works=yes], - [gl_cv_func_strchrnul_works=no], - [dnl Cygwin 1.7.9 introduced strchrnul, but it was broken until 1.7.10 - AC_EGREP_CPP([Lucky user], - [ -#if defined __CYGWIN__ - #include - #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 9) - Lucky user - #endif -#else - Lucky user -#endif - ], - [gl_cv_func_strchrnul_works="guessing yes"], - [gl_cv_func_strchrnul_works="guessing no"]) - ]) - ]) - case "$gl_cv_func_strchrnul_works" in - *yes) ;; - *) REPLACE_STRCHRNUL=1 ;; - esac - fi -]) - -# Prerequisites of lib/strchrnul.c. -AC_DEFUN([gl_PREREQ_STRCHRNUL], [:]) diff --git a/m4/strerror.m4 b/m4/strerror.m4 deleted file mode 100644 index 3989844b2..000000000 --- a/m4/strerror.m4 +++ /dev/null @@ -1,96 +0,0 @@ -# strerror.m4 serial 17 -dnl Copyright (C) 2002, 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_STRERROR], -[ - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - AC_REQUIRE([gl_HEADER_ERRNO_H]) - AC_REQUIRE([gl_FUNC_STRERROR_0]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - m4_ifdef([gl_FUNC_STRERROR_R_WORKS], [ - AC_REQUIRE([gl_FUNC_STRERROR_R_WORKS]) - ]) - if test "$ERRNO_H:$REPLACE_STRERROR_0" = :0; then - AC_CACHE_CHECK([for working strerror function], - [gl_cv_func_working_strerror], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#include - ]], - [[if (!*strerror (-2)) return 1;]])], - [gl_cv_func_working_strerror=yes], - [gl_cv_func_working_strerror=no], - [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_working_strerror="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_working_strerror="guessing no" ;; - esac - ]) - ]) - case "$gl_cv_func_working_strerror" in - *yes) ;; - *) - dnl The system's strerror() fails to return a string for out-of-range - dnl integers. Replace it. - REPLACE_STRERROR=1 - ;; - esac - m4_ifdef([gl_FUNC_STRERROR_R_WORKS], [ - dnl If the system's strerror_r or __xpg_strerror_r clobbers strerror's - dnl buffer, we must replace strerror. - case "$gl_cv_func_strerror_r_works" in - *no) REPLACE_STRERROR=1 ;; - esac - ]) - else - dnl The system's strerror() cannot know about the new errno values we add - dnl to , or any fix for strerror(0). Replace it. - REPLACE_STRERROR=1 - fi -]) - -dnl Detect if strerror(0) passes (that is, does not set errno, and does not -dnl return a string that matches strerror(-1)). -AC_DEFUN([gl_FUNC_STRERROR_0], -[ - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - REPLACE_STRERROR_0=0 - AC_CACHE_CHECK([whether strerror(0) succeeds], - [gl_cv_func_strerror_0_works], - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[#include - #include - ]], - [[int result = 0; - char *str; - errno = 0; - str = strerror (0); - if (!*str) result |= 1; - if (errno) result |= 2; - if (strstr (str, "nknown") || strstr (str, "ndefined")) - result |= 4; - return result;]])], - [gl_cv_func_strerror_0_works=yes], - [gl_cv_func_strerror_0_works=no], - [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_strerror_0_works="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_strerror_0_works="guessing no" ;; - esac - ]) - ]) - case "$gl_cv_func_strerror_0_works" in - *yes) ;; - *) - REPLACE_STRERROR_0=1 - AC_DEFINE([REPLACE_STRERROR_0], [1], [Define to 1 if strerror(0) - does not return a message implying success.]) - ;; - esac -]) diff --git a/m4/string_h.m4 b/m4/string_h.m4 deleted file mode 100644 index cc5fbbb32..000000000 --- a/m4/string_h.m4 +++ /dev/null @@ -1,120 +0,0 @@ -# Configure a GNU-like replacement for . - -# Copyright (C) 2007-2013 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 21 - -# Written by Paul Eggert. - -AC_DEFUN([gl_HEADER_STRING_H], -[ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. - AC_REQUIRE([gl_HEADER_STRING_H_BODY]) -]) - -AC_DEFUN([gl_HEADER_STRING_H_BODY], -[ - AC_REQUIRE([AC_C_RESTRICT]) - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - gl_NEXT_HEADERS([string.h]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use, and which is not - dnl guaranteed by C89. - gl_WARN_ON_USE_PREPARE([[#include - ]], - [ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul - strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r - strerror_r strsignal strverscmp]) -]) - -AC_DEFUN([gl_STRING_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], -[ - GNULIB_FFSL=0; AC_SUBST([GNULIB_FFSL]) - GNULIB_FFSLL=0; AC_SUBST([GNULIB_FFSLL]) - GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) - GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) - GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) - GNULIB_MEMRCHR=0; AC_SUBST([GNULIB_MEMRCHR]) - GNULIB_RAWMEMCHR=0; AC_SUBST([GNULIB_RAWMEMCHR]) - GNULIB_STPCPY=0; AC_SUBST([GNULIB_STPCPY]) - GNULIB_STPNCPY=0; AC_SUBST([GNULIB_STPNCPY]) - GNULIB_STRCHRNUL=0; AC_SUBST([GNULIB_STRCHRNUL]) - GNULIB_STRDUP=0; AC_SUBST([GNULIB_STRDUP]) - GNULIB_STRNCAT=0; AC_SUBST([GNULIB_STRNCAT]) - GNULIB_STRNDUP=0; AC_SUBST([GNULIB_STRNDUP]) - GNULIB_STRNLEN=0; AC_SUBST([GNULIB_STRNLEN]) - GNULIB_STRPBRK=0; AC_SUBST([GNULIB_STRPBRK]) - GNULIB_STRSEP=0; AC_SUBST([GNULIB_STRSEP]) - GNULIB_STRSTR=0; AC_SUBST([GNULIB_STRSTR]) - GNULIB_STRCASESTR=0; AC_SUBST([GNULIB_STRCASESTR]) - GNULIB_STRTOK_R=0; AC_SUBST([GNULIB_STRTOK_R]) - GNULIB_MBSLEN=0; AC_SUBST([GNULIB_MBSLEN]) - GNULIB_MBSNLEN=0; AC_SUBST([GNULIB_MBSNLEN]) - GNULIB_MBSCHR=0; AC_SUBST([GNULIB_MBSCHR]) - GNULIB_MBSRCHR=0; AC_SUBST([GNULIB_MBSRCHR]) - GNULIB_MBSSTR=0; AC_SUBST([GNULIB_MBSSTR]) - GNULIB_MBSCASECMP=0; AC_SUBST([GNULIB_MBSCASECMP]) - GNULIB_MBSNCASECMP=0; AC_SUBST([GNULIB_MBSNCASECMP]) - GNULIB_MBSPCASECMP=0; AC_SUBST([GNULIB_MBSPCASECMP]) - GNULIB_MBSCASESTR=0; AC_SUBST([GNULIB_MBSCASESTR]) - GNULIB_MBSCSPN=0; AC_SUBST([GNULIB_MBSCSPN]) - GNULIB_MBSPBRK=0; AC_SUBST([GNULIB_MBSPBRK]) - GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN]) - GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP]) - GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R]) - GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR]) - GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R]) - GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) - GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) - HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) - HAVE_FFSLL=1; AC_SUBST([HAVE_FFSLL]) - HAVE_MEMCHR=1; AC_SUBST([HAVE_MEMCHR]) - HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) - HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) - HAVE_DECL_MEMRCHR=1; AC_SUBST([HAVE_DECL_MEMRCHR]) - HAVE_RAWMEMCHR=1; AC_SUBST([HAVE_RAWMEMCHR]) - HAVE_STPCPY=1; AC_SUBST([HAVE_STPCPY]) - HAVE_STPNCPY=1; AC_SUBST([HAVE_STPNCPY]) - HAVE_STRCHRNUL=1; AC_SUBST([HAVE_STRCHRNUL]) - HAVE_DECL_STRDUP=1; AC_SUBST([HAVE_DECL_STRDUP]) - HAVE_DECL_STRNDUP=1; AC_SUBST([HAVE_DECL_STRNDUP]) - HAVE_DECL_STRNLEN=1; AC_SUBST([HAVE_DECL_STRNLEN]) - HAVE_STRPBRK=1; AC_SUBST([HAVE_STRPBRK]) - HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP]) - HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) - HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) - HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R]) - HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) - HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) - REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) - REPLACE_MEMMEM=0; AC_SUBST([REPLACE_MEMMEM]) - REPLACE_STPNCPY=0; AC_SUBST([REPLACE_STPNCPY]) - REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) - REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) - REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR]) - REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) - REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) - REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) - REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) - REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) - REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) - REPLACE_STRSIGNAL=0; AC_SUBST([REPLACE_STRSIGNAL]) - REPLACE_STRTOK_R=0; AC_SUBST([REPLACE_STRTOK_R]) - UNDEFINE_STRTOK_R=0; AC_SUBST([UNDEFINE_STRTOK_R]) -]) diff --git a/m4/strings_h.m4 b/m4/strings_h.m4 deleted file mode 100644 index 76ef2424e..000000000 --- a/m4/strings_h.m4 +++ /dev/null @@ -1,52 +0,0 @@ -# Configure a replacement for . -# serial 6 - -# Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_HEADER_STRINGS_H], -[ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. - AC_REQUIRE([gl_HEADER_STRINGS_H_BODY]) -]) - -AC_DEFUN([gl_HEADER_STRINGS_H_BODY], -[ - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) - - gl_CHECK_NEXT_HEADERS([strings.h]) - if test $ac_cv_header_strings_h = yes; then - HAVE_STRINGS_H=1 - else - HAVE_STRINGS_H=0 - fi - AC_SUBST([HAVE_STRINGS_H]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[ - /* Minix 3.1.8 has a bug: must be included before - . */ - #include - #include - ]], [ffs strcasecmp strncasecmp]) -]) - -AC_DEFUN([gl_STRINGS_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) -]) - -AC_DEFUN([gl_HEADER_STRINGS_H_DEFAULTS], -[ - GNULIB_FFS=0; AC_SUBST([GNULIB_FFS]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_FFS=1; AC_SUBST([HAVE_FFS]) - HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) - HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) -]) diff --git a/m4/strndup.m4 b/m4/strndup.m4 deleted file mode 100644 index a1f82743f..000000000 --- a/m4/strndup.m4 +++ /dev/null @@ -1,55 +0,0 @@ -# strndup.m4 serial 21 -dnl Copyright (C) 2002-2003, 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_STRNDUP], -[ - dnl Persuade glibc to declare strndup(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - AC_CHECK_DECLS_ONCE([strndup]) - AC_CHECK_FUNCS_ONCE([strndup]) - if test $ac_cv_have_decl_strndup = no; then - HAVE_DECL_STRNDUP=0 - fi - - if test $ac_cv_func_strndup = yes; then - HAVE_STRNDUP=1 - # AIX 4.3.3, AIX 5.1 have a function that fails to add the terminating '\0'. - AC_CACHE_CHECK([for working strndup], [gl_cv_func_strndup_works], - [AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[#include - #include ]], [[ -#if !HAVE_DECL_STRNDUP - extern - #ifdef __cplusplus - "C" - #endif - char *strndup (const char *, size_t); -#endif - char *s; - s = strndup ("some longer string", 15); - free (s); - s = strndup ("shorter string", 13); - return s[13] != '\0';]])], - [gl_cv_func_strndup_works=yes], - [gl_cv_func_strndup_works=no], - [ -changequote(,)dnl - case $host_os in - aix | aix[3-6]*) gl_cv_func_strndup_works="guessing no";; - *) gl_cv_func_strndup_works="guessing yes";; - esac -changequote([,])dnl - ])]) - case $gl_cv_func_strndup_works in - *no) REPLACE_STRNDUP=1 ;; - esac - else - HAVE_STRNDUP=0 - fi -]) diff --git a/m4/strnlen.m4 b/m4/strnlen.m4 deleted file mode 100644 index eae82b772..000000000 --- a/m4/strnlen.m4 +++ /dev/null @@ -1,30 +0,0 @@ -# strnlen.m4 serial 13 -dnl Copyright (C) 2002-2003, 2005-2007, 2009-2013 Free Software Foundation, -dnl Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_STRNLEN], -[ - AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) - - dnl Persuade glibc to declare strnlen(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_CHECK_DECLS_ONCE([strnlen]) - if test $ac_cv_have_decl_strnlen = no; then - HAVE_DECL_STRNLEN=0 - else - m4_pushdef([AC_LIBOBJ], [:]) - dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]). - AC_FUNC_STRNLEN - m4_popdef([AC_LIBOBJ]) - if test $ac_cv_func_strnlen_working = no; then - REPLACE_STRNLEN=1 - fi - fi -]) - -# Prerequisites of lib/strnlen.c. -AC_DEFUN([gl_PREREQ_STRNLEN], [:]) diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4 deleted file mode 100644 index 94863776d..000000000 --- a/m4/sys_socket_h.m4 +++ /dev/null @@ -1,176 +0,0 @@ -# sys_socket_h.m4 serial 23 -dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Simon Josefsson. - -AC_DEFUN([gl_HEADER_SYS_SOCKET], -[ - AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) - AC_REQUIRE([AC_CANONICAL_HOST]) - - dnl On OSF/1, the functions recv(), send(), recvfrom(), sendto() have - dnl old-style declarations (with return type 'int' instead of 'ssize_t') - dnl unless _POSIX_PII_SOCKET is defined. - case "$host_os" in - osf*) - AC_DEFINE([_POSIX_PII_SOCKET], [1], - [Define to 1 in order to get the POSIX compatible declarations - of socket functions.]) - ;; - esac - - AC_CACHE_CHECK([whether is self-contained], - [gl_cv_header_sys_socket_h_selfcontained], - [ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[]])], - [gl_cv_header_sys_socket_h_selfcontained=yes], - [gl_cv_header_sys_socket_h_selfcontained=no]) - ]) - if test $gl_cv_header_sys_socket_h_selfcontained = yes; then - dnl If the shutdown function exists, should define - dnl SHUT_RD, SHUT_WR, SHUT_RDWR. - AC_CHECK_FUNCS([shutdown]) - if test $ac_cv_func_shutdown = yes; then - AC_CACHE_CHECK([whether defines the SHUT_* macros], - [gl_cv_header_sys_socket_h_shut], - [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[int a[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };]])], - [gl_cv_header_sys_socket_h_shut=yes], - [gl_cv_header_sys_socket_h_shut=no]) - ]) - if test $gl_cv_header_sys_socket_h_shut = no; then - SYS_SOCKET_H='sys/socket.h' - fi - fi - fi - # We need to check for ws2tcpip.h now. - gl_PREREQ_SYS_H_SOCKET - AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ - /* sys/types.h is not needed according to POSIX, but the - sys/socket.h in i386-unknown-freebsd4.10 and - powerpc-apple-darwin5.5 required it. */ -#include -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WS2TCPIP_H -#include -#endif -]) - if test $ac_cv_type_struct_sockaddr_storage = no; then - HAVE_STRUCT_SOCKADDR_STORAGE=0 - fi - if test $ac_cv_type_sa_family_t = no; then - HAVE_SA_FAMILY_T=0 - fi - if test $ac_cv_type_struct_sockaddr_storage != no; then - AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], - [], - [HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=0], - [#include - #ifdef HAVE_SYS_SOCKET_H - #include - #endif - #ifdef HAVE_WS2TCPIP_H - #include - #endif - ]) - fi - if test $HAVE_STRUCT_SOCKADDR_STORAGE = 0 || test $HAVE_SA_FAMILY_T = 0 \ - || test $HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = 0; then - SYS_SOCKET_H='sys/socket.h' - fi - gl_PREREQ_SYS_H_WINSOCK2 - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[ -/* Some systems require prerequisite headers. */ -#include -#include - ]], [socket connect accept bind getpeername getsockname getsockopt - listen recv send recvfrom sendto setsockopt shutdown accept4]) -]) - -AC_DEFUN([gl_PREREQ_SYS_H_SOCKET], -[ - dnl Check prerequisites of the replacement. - AC_REQUIRE([gl_CHECK_SOCKET_HEADERS]) - gl_CHECK_NEXT_HEADERS([sys/socket.h]) - if test $ac_cv_header_sys_socket_h = yes; then - HAVE_SYS_SOCKET_H=1 - HAVE_WS2TCPIP_H=0 - else - HAVE_SYS_SOCKET_H=0 - if test $ac_cv_header_ws2tcpip_h = yes; then - HAVE_WS2TCPIP_H=1 - else - HAVE_WS2TCPIP_H=0 - fi - fi - AC_SUBST([HAVE_SYS_SOCKET_H]) - AC_SUBST([HAVE_WS2TCPIP_H]) -]) - -# Common prerequisites of the replacement and of the -# replacement. -# Sets and substitutes HAVE_WINSOCK2_H. -AC_DEFUN([gl_PREREQ_SYS_H_WINSOCK2], -[ - m4_ifdef([gl_UNISTD_H_DEFAULTS], [AC_REQUIRE([gl_UNISTD_H_DEFAULTS])]) - m4_ifdef([gl_SYS_IOCTL_H_DEFAULTS], [AC_REQUIRE([gl_SYS_IOCTL_H_DEFAULTS])]) - AC_CHECK_HEADERS_ONCE([sys/socket.h]) - if test $ac_cv_header_sys_socket_h != yes; then - dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make - dnl the check for those headers unconditional; yet cygwin reports - dnl that the headers are present but cannot be compiled (since on - dnl cygwin, all socket information should come from sys/socket.h). - AC_CHECK_HEADERS([winsock2.h]) - fi - if test "$ac_cv_header_winsock2_h" = yes; then - HAVE_WINSOCK2_H=1 - UNISTD_H_HAVE_WINSOCK2_H=1 - SYS_IOCTL_H_HAVE_WINSOCK2_H=1 - else - HAVE_WINSOCK2_H=0 - fi - AC_SUBST([HAVE_WINSOCK2_H]) -]) - -AC_DEFUN([gl_SYS_SOCKET_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS], -[ - GNULIB_SOCKET=0; AC_SUBST([GNULIB_SOCKET]) - GNULIB_CONNECT=0; AC_SUBST([GNULIB_CONNECT]) - GNULIB_ACCEPT=0; AC_SUBST([GNULIB_ACCEPT]) - GNULIB_BIND=0; AC_SUBST([GNULIB_BIND]) - GNULIB_GETPEERNAME=0; AC_SUBST([GNULIB_GETPEERNAME]) - GNULIB_GETSOCKNAME=0; AC_SUBST([GNULIB_GETSOCKNAME]) - GNULIB_GETSOCKOPT=0; AC_SUBST([GNULIB_GETSOCKOPT]) - GNULIB_LISTEN=0; AC_SUBST([GNULIB_LISTEN]) - GNULIB_RECV=0; AC_SUBST([GNULIB_RECV]) - GNULIB_SEND=0; AC_SUBST([GNULIB_SEND]) - GNULIB_RECVFROM=0; AC_SUBST([GNULIB_RECVFROM]) - GNULIB_SENDTO=0; AC_SUBST([GNULIB_SENDTO]) - GNULIB_SETSOCKOPT=0; AC_SUBST([GNULIB_SETSOCKOPT]) - GNULIB_SHUTDOWN=0; AC_SUBST([GNULIB_SHUTDOWN]) - GNULIB_ACCEPT4=0; AC_SUBST([GNULIB_ACCEPT4]) - HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) - HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; - AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) - HAVE_SA_FAMILY_T=1; AC_SUBST([HAVE_SA_FAMILY_T]) - HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4]) -]) diff --git a/m4/sys_types_h.m4 b/m4/sys_types_h.m4 deleted file mode 100644 index d15c1b370..000000000 --- a/m4/sys_types_h.m4 +++ /dev/null @@ -1,24 +0,0 @@ -# sys_types_h.m4 serial 5 -dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN_ONCE([gl_SYS_TYPES_H], -[ - AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS]) - gl_NEXT_HEADERS([sys/types.h]) - - dnl Ensure the type pid_t gets defined. - AC_REQUIRE([AC_TYPE_PID_T]) - - dnl Ensure the type mode_t gets defined. - AC_REQUIRE([AC_TYPE_MODE_T]) - - dnl Whether to override the 'off_t' type. - AC_REQUIRE([gl_TYPE_OFF_T]) -]) - -AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS], -[ -]) diff --git a/m4/sysexits.m4 b/m4/sysexits.m4 deleted file mode 100644 index bd8abaa0d..000000000 --- a/m4/sysexits.m4 +++ /dev/null @@ -1,44 +0,0 @@ -# sysexits.m4 serial 6 -dnl Copyright (C) 2003, 2005, 2007, 2009-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_SYSEXITS], -[ - AC_CHECK_HEADERS_ONCE([sysexits.h]) - if test $ac_cv_header_sysexits_h = yes; then - HAVE_SYSEXITS_H=1 - gl_CHECK_NEXT_HEADERS([sysexits.h]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[switch (0) - { - case EX_OK: - case EX_USAGE: - case EX_DATAERR: - case EX_NOINPUT: - case EX_NOUSER: - case EX_NOHOST: - case EX_UNAVAILABLE: - case EX_SOFTWARE: - case EX_OSERR: - case EX_OSFILE: - case EX_CANTCREAT: - case EX_IOERR: - case EX_TEMPFAIL: - case EX_PROTOCOL: - case EX_NOPERM: - case EX_CONFIG: - break; - } - ]])], - [SYSEXITS_H=], - [SYSEXITS_H=sysexits.h]) - else - HAVE_SYSEXITS_H=0 - SYSEXITS_H=sysexits.h - fi - AC_SUBST([HAVE_SYSEXITS_H]) - AC_SUBST([SYSEXITS_H]) - AM_CONDITIONAL([GL_GENERATE_SYSEXITS_H], [test -n "$SYSEXITS_H"]) -]) diff --git a/m4/threadlib.m4 b/m4/threadlib.m4 deleted file mode 100644 index 26bdeb58a..000000000 --- a/m4/threadlib.m4 +++ /dev/null @@ -1,371 +0,0 @@ -# threadlib.m4 serial 10 (gettext-0.18.2) -dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl gl_THREADLIB -dnl ------------ -dnl Tests for a multithreading library to be used. -dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO -dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the -dnl default is 'no', otherwise it is system dependent. In both cases, the user -dnl can change the choice through the options --enable-threads=choice or -dnl --disable-threads. -dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS, -dnl USE_PTH_THREADS, USE_WINDOWS_THREADS -dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use -dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with -dnl libtool). -dnl Sets the variables LIBMULTITHREAD and LTLIBMULTITHREAD similarly, for -dnl programs that really need multithread functionality. The difference -dnl between LIBTHREAD and LIBMULTITHREAD is that on platforms supporting weak -dnl symbols, typically LIBTHREAD="" whereas LIBMULTITHREAD="-lpthread". -dnl Adds to CPPFLAGS the flag -D_REENTRANT or -D_THREAD_SAFE if needed for -dnl multithread-safe programs. - -AC_DEFUN([gl_THREADLIB_EARLY], -[ - AC_REQUIRE([gl_THREADLIB_EARLY_BODY]) -]) - -dnl The guts of gl_THREADLIB_EARLY. Needs to be expanded only once. - -AC_DEFUN([gl_THREADLIB_EARLY_BODY], -[ - dnl Ordering constraints: This macro modifies CPPFLAGS in a way that - dnl influences the result of the autoconf tests that test for *_unlocked - dnl declarations, on AIX 5 at least. Therefore it must come early. - AC_BEFORE([$0], [gl_FUNC_GLIBC_UNLOCKED_IO])dnl - AC_BEFORE([$0], [gl_ARGP])dnl - - AC_REQUIRE([AC_CANONICAL_HOST]) - dnl _GNU_SOURCE is needed for pthread_rwlock_t on glibc systems. - dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes - dnl AC_GNU_SOURCE. - m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], - [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], - [AC_REQUIRE([AC_GNU_SOURCE])]) - dnl Check for multithreading. - m4_ifdef([gl_THREADLIB_DEFAULT_NO], - [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])], - [m4_divert_text([DEFAULTS], [gl_use_threads_default=])]) - AC_ARG_ENABLE([threads], -AC_HELP_STRING([--enable-threads={posix|solaris|pth|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [ -AC_HELP_STRING([--disable-threads], [build without multithread safety])]), - [gl_use_threads=$enableval], - [if test -n "$gl_use_threads_default"; then - gl_use_threads="$gl_use_threads_default" - else -changequote(,)dnl - case "$host_os" in - dnl Disable multithreading by default on OSF/1, because it interferes - dnl with fork()/exec(): When msgexec is linked with -lpthread, its - dnl child process gets an endless segmentation fault inside execvp(). - dnl Disable multithreading by default on Cygwin 1.5.x, because it has - dnl bugs that lead to endless loops or crashes. See - dnl . - osf*) gl_use_threads=no ;; - cygwin*) - case `uname -r` in - 1.[0-5].*) gl_use_threads=no ;; - *) gl_use_threads=yes ;; - esac - ;; - *) gl_use_threads=yes ;; - esac -changequote([,])dnl - fi - ]) - if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then - # For using : - case "$host_os" in - osf*) - # On OSF/1, the compiler needs the flag -D_REENTRANT so that it - # groks . cc also understands the flag -pthread, but - # we don't use it because 1. gcc-2.95 doesn't understand -pthread, - # 2. putting a flag into CPPFLAGS that has an effect on the linker - # causes the AC_LINK_IFELSE test below to succeed unexpectedly, - # leading to wrong values of LIBTHREAD and LTLIBTHREAD. - CPPFLAGS="$CPPFLAGS -D_REENTRANT" - ;; - esac - # Some systems optimize for single-threaded programs by default, and - # need special flags to disable these optimizations. For example, the - # definition of 'errno' in . - case "$host_os" in - aix* | freebsd*) CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" ;; - solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" ;; - esac - fi -]) - -dnl The guts of gl_THREADLIB. Needs to be expanded only once. - -AC_DEFUN([gl_THREADLIB_BODY], -[ - AC_REQUIRE([gl_THREADLIB_EARLY_BODY]) - gl_threads_api=none - LIBTHREAD= - LTLIBTHREAD= - LIBMULTITHREAD= - LTLIBMULTITHREAD= - if test "$gl_use_threads" != no; then - dnl Check whether the compiler and linker support weak declarations. - AC_CACHE_CHECK([whether imported symbols can be declared weak], - [gl_cv_have_weak], - [gl_cv_have_weak=no - dnl First, test whether the compiler accepts it syntactically. - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[extern void xyzzy (); -#pragma weak xyzzy]], - [[xyzzy();]])], - [gl_cv_have_weak=maybe]) - if test $gl_cv_have_weak = maybe; then - dnl Second, test whether it actually works. On Cygwin 1.7.2, with - dnl gcc 4.3, symbols declared weak always evaluate to the address 0. - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#pragma weak fputs -int main () -{ - return (fputs == NULL); -}]])], - [gl_cv_have_weak=yes], - [gl_cv_have_weak=no], - [dnl When cross-compiling, assume that only ELF platforms support - dnl weak symbols. - AC_EGREP_CPP([Extensible Linking Format], - [#ifdef __ELF__ - Extensible Linking Format - #endif - ], - [gl_cv_have_weak="guessing yes"], - [gl_cv_have_weak="guessing no"]) - ]) - fi - ]) - if test "$gl_use_threads" = yes || test "$gl_use_threads" = posix; then - # On OSF/1, the compiler needs the flag -pthread or -D_REENTRANT so that - # it groks . It's added above, in gl_THREADLIB_EARLY_BODY. - AC_CHECK_HEADER([pthread.h], - [gl_have_pthread_h=yes], [gl_have_pthread_h=no]) - if test "$gl_have_pthread_h" = yes; then - # Other possible tests: - # -lpthreads (FSU threads, PCthreads) - # -lgthreads - gl_have_pthread= - # Test whether both pthread_mutex_lock and pthread_mutexattr_init exist - # in libc. IRIX 6.5 has the first one in both libc and libpthread, but - # the second one only in libpthread, and lock.c needs it. - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[#include ]], - [[pthread_mutex_lock((pthread_mutex_t*)0); - pthread_mutexattr_init((pthread_mutexattr_t*)0);]])], - [gl_have_pthread=yes]) - # Test for libpthread by looking for pthread_kill. (Not pthread_self, - # since it is defined as a macro on OSF/1.) - if test -n "$gl_have_pthread"; then - # The program links fine without libpthread. But it may actually - # need to link with libpthread in order to create multiple threads. - AC_CHECK_LIB([pthread], [pthread_kill], - [LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread - # On Solaris and HP-UX, most pthread functions exist also in libc. - # Therefore pthread_in_use() needs to actually try to create a - # thread: pthread_create from libc will fail, whereas - # pthread_create will actually create a thread. - case "$host_os" in - solaris* | hpux*) - AC_DEFINE([PTHREAD_IN_USE_DETECTION_HARD], [1], - [Define if the pthread_in_use() detection is hard.]) - esac - ]) - else - # Some library is needed. Try libpthread and libc_r. - AC_CHECK_LIB([pthread], [pthread_kill], - [gl_have_pthread=yes - LIBTHREAD=-lpthread LTLIBTHREAD=-lpthread - LIBMULTITHREAD=-lpthread LTLIBMULTITHREAD=-lpthread]) - if test -z "$gl_have_pthread"; then - # For FreeBSD 4. - AC_CHECK_LIB([c_r], [pthread_kill], - [gl_have_pthread=yes - LIBTHREAD=-lc_r LTLIBTHREAD=-lc_r - LIBMULTITHREAD=-lc_r LTLIBMULTITHREAD=-lc_r]) - fi - fi - if test -n "$gl_have_pthread"; then - gl_threads_api=posix - AC_DEFINE([USE_POSIX_THREADS], [1], - [Define if the POSIX multithreading library can be used.]) - if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then - if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then - AC_DEFINE([USE_POSIX_THREADS_WEAK], [1], - [Define if references to the POSIX multithreading library should be made weak.]) - LIBTHREAD= - LTLIBTHREAD= - fi - fi - fi - fi - fi - if test -z "$gl_have_pthread"; then - if test "$gl_use_threads" = yes || test "$gl_use_threads" = solaris; then - gl_have_solaristhread= - gl_save_LIBS="$LIBS" - LIBS="$LIBS -lthread" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - ]], - [[thr_self();]])], - [gl_have_solaristhread=yes]) - LIBS="$gl_save_LIBS" - if test -n "$gl_have_solaristhread"; then - gl_threads_api=solaris - LIBTHREAD=-lthread - LTLIBTHREAD=-lthread - LIBMULTITHREAD="$LIBTHREAD" - LTLIBMULTITHREAD="$LTLIBTHREAD" - AC_DEFINE([USE_SOLARIS_THREADS], [1], - [Define if the old Solaris multithreading library can be used.]) - if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then - AC_DEFINE([USE_SOLARIS_THREADS_WEAK], [1], - [Define if references to the old Solaris multithreading library should be made weak.]) - LIBTHREAD= - LTLIBTHREAD= - fi - fi - fi - fi - if test "$gl_use_threads" = pth; then - gl_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_LINKFLAGS([pth]) - gl_have_pth= - gl_save_LIBS="$LIBS" - LIBS="$LIBS $LIBPTH" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include ]], [[pth_self();]])], - [gl_have_pth=yes]) - LIBS="$gl_save_LIBS" - if test -n "$gl_have_pth"; then - gl_threads_api=pth - LIBTHREAD="$LIBPTH" - LTLIBTHREAD="$LTLIBPTH" - LIBMULTITHREAD="$LIBTHREAD" - LTLIBMULTITHREAD="$LTLIBTHREAD" - AC_DEFINE([USE_PTH_THREADS], [1], - [Define if the GNU Pth multithreading library can be used.]) - if test -n "$LIBMULTITHREAD" || test -n "$LTLIBMULTITHREAD"; then - if case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then - AC_DEFINE([USE_PTH_THREADS_WEAK], [1], - [Define if references to the GNU Pth multithreading library should be made weak.]) - LIBTHREAD= - LTLIBTHREAD= - fi - fi - else - CPPFLAGS="$gl_save_CPPFLAGS" - fi - fi - if test -z "$gl_have_pthread"; then - case "$gl_use_threads" in - yes | windows | win32) # The 'win32' is for backward compatibility. - if { case "$host_os" in - mingw*) true;; - *) false;; - esac - }; then - gl_threads_api=windows - AC_DEFINE([USE_WINDOWS_THREADS], [1], - [Define if the native Windows multithreading API can be used.]) - fi - ;; - esac - fi - fi - AC_MSG_CHECKING([for multithread API to use]) - AC_MSG_RESULT([$gl_threads_api]) - AC_SUBST([LIBTHREAD]) - AC_SUBST([LTLIBTHREAD]) - AC_SUBST([LIBMULTITHREAD]) - AC_SUBST([LTLIBMULTITHREAD]) -]) - -AC_DEFUN([gl_THREADLIB], -[ - AC_REQUIRE([gl_THREADLIB_EARLY]) - AC_REQUIRE([gl_THREADLIB_BODY]) -]) - - -dnl gl_DISABLE_THREADS -dnl ------------------ -dnl Sets the gl_THREADLIB default so that threads are not used by default. -dnl The user can still override it at installation time, by using the -dnl configure option '--enable-threads'. - -AC_DEFUN([gl_DISABLE_THREADS], [ - m4_divert_text([INIT_PREPARE], [gl_use_threads_default=no]) -]) - - -dnl Survey of platforms: -dnl -dnl Platform Available Compiler Supports test-lock -dnl flavours option weak result -dnl --------------- --------- --------- -------- --------- -dnl Linux 2.4/glibc posix -lpthread Y OK -dnl -dnl GNU Hurd/glibc posix -dnl -dnl FreeBSD 5.3 posix -lc_r Y -dnl posix -lkse ? Y -dnl posix -lpthread ? Y -dnl posix -lthr Y -dnl -dnl FreeBSD 5.2 posix -lc_r Y -dnl posix -lkse Y -dnl posix -lthr Y -dnl -dnl FreeBSD 4.0,4.10 posix -lc_r Y OK -dnl -dnl NetBSD 1.6 -- -dnl -dnl OpenBSD 3.4 posix -lpthread Y OK -dnl -dnl Mac OS X 10.[123] posix -lpthread Y OK -dnl -dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK -dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK -dnl -dnl HP-UX 11 posix -lpthread N (cc) OK -dnl Y (gcc) -dnl -dnl IRIX 6.5 posix -lpthread Y 0.5 -dnl -dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK -dnl -dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK -dnl -lpthread (gcc) Y -dnl -dnl Cygwin posix -lpthread Y OK -dnl -dnl Any of the above pth -lpth 0.0 -dnl -dnl Mingw windows N OK -dnl -dnl BeOS 5 -- -dnl -dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is -dnl turned off: -dnl OK if all three tests terminate OK, -dnl 0.5 if the first test terminates OK but the second one loops endlessly, -dnl 0.0 if the first test already loops endlessly. diff --git a/m4/uintmax_t.m4 b/m4/uintmax_t.m4 deleted file mode 100644 index c6ff80067..000000000 --- a/m4/uintmax_t.m4 +++ /dev/null @@ -1,30 +0,0 @@ -# uintmax_t.m4 serial 12 -dnl Copyright (C) 1997-2004, 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Paul Eggert. - -AC_PREREQ([2.13]) - -# Define uintmax_t to 'unsigned long' or 'unsigned long long' -# if it is not already defined in or . - -AC_DEFUN([gl_AC_TYPE_UINTMAX_T], -[ - AC_REQUIRE([gl_AC_HEADER_INTTYPES_H]) - AC_REQUIRE([gl_AC_HEADER_STDINT_H]) - if test $gl_cv_header_inttypes_h = no && test $gl_cv_header_stdint_h = no; then - AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) - test $ac_cv_type_unsigned_long_long_int = yes \ - && ac_type='unsigned long long' \ - || ac_type='unsigned long' - AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type], - [Define to unsigned long or unsigned long long - if and don't define.]) - else - AC_DEFINE([HAVE_UINTMAX_T], [1], - [Define if you have the 'uintmax_t' type in or .]) - fi -]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 deleted file mode 100644 index 32dcfa582..000000000 --- a/m4/unistd_h.m4 +++ /dev/null @@ -1,186 +0,0 @@ -# unistd_h.m4 serial 66 -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Written by Simon Josefsson, Bruno Haible. - -AC_DEFUN([gl_UNISTD_H], -[ - dnl Use AC_REQUIRE here, so that the default behavior below is expanded - dnl once only, before all statements that occur in other macros. - AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) - - gl_CHECK_NEXT_HEADERS([unistd.h]) - if test $ac_cv_header_unistd_h = yes; then - HAVE_UNISTD_H=1 - else - HAVE_UNISTD_H=0 - fi - AC_SUBST([HAVE_UNISTD_H]) - - dnl Ensure the type pid_t gets defined. - AC_REQUIRE([AC_TYPE_PID_T]) - - dnl Determine WINDOWS_64_BIT_OFF_T. - AC_REQUIRE([gl_TYPE_OFF_T]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[ -#if HAVE_UNISTD_H -# include -#endif -/* Some systems declare various items in the wrong headers. */ -#if !(defined __GLIBC__ && !defined __UCLIBC__) -# include -# include -# include -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ -# include -# endif -#endif - ]], [chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir fchownat - fdatasync fsync ftruncate getcwd getdomainname getdtablesize getgroups - gethostname getlogin getlogin_r getpagesize - getusershell setusershell endusershell - group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite - readlink readlinkat rmdir sethostname sleep symlink symlinkat ttyname_r - unlink unlinkat usleep]) -]) - -AC_DEFUN([gl_UNISTD_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_UNISTD_H_DEFAULTS], -[ - GNULIB_CHDIR=0; AC_SUBST([GNULIB_CHDIR]) - GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) - GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE]) - GNULIB_DUP=0; AC_SUBST([GNULIB_DUP]) - GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) - GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3]) - GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) - GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS]) - GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT]) - GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) - GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) - GNULIB_FDATASYNC=0; AC_SUBST([GNULIB_FDATASYNC]) - GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC]) - GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) - GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) - GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME]) - GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE]) - GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS]) - GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME]) - GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN]) - GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R]) - GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) - GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL]) - GNULIB_GROUP_MEMBER=0; AC_SUBST([GNULIB_GROUP_MEMBER]) - GNULIB_ISATTY=0; AC_SUBST([GNULIB_ISATTY]) - GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) - GNULIB_LINK=0; AC_SUBST([GNULIB_LINK]) - GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT]) - GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) - GNULIB_PIPE=0; AC_SUBST([GNULIB_PIPE]) - GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2]) - GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD]) - GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE]) - GNULIB_READ=0; AC_SUBST([GNULIB_READ]) - GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) - GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT]) - GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR]) - GNULIB_SETHOSTNAME=0; AC_SUBST([GNULIB_SETHOSTNAME]) - GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) - GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK]) - GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT]) - GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R]) - GNULIB_UNISTD_H_NONBLOCKING=0; AC_SUBST([GNULIB_UNISTD_H_NONBLOCKING]) - GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE]) - GNULIB_UNLINK=0; AC_SUBST([GNULIB_UNLINK]) - GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT]) - GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP]) - GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) - HAVE_DUP2=1; AC_SUBST([HAVE_DUP2]) - HAVE_DUP3=1; AC_SUBST([HAVE_DUP3]) - HAVE_EUIDACCESS=1; AC_SUBST([HAVE_EUIDACCESS]) - HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) - HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) - HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) - HAVE_FDATASYNC=1; AC_SUBST([HAVE_FDATASYNC]) - HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) - HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) - HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) - HAVE_GETGROUPS=1; AC_SUBST([HAVE_GETGROUPS]) - HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME]) - HAVE_GETLOGIN=1; AC_SUBST([HAVE_GETLOGIN]) - HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE]) - HAVE_GROUP_MEMBER=1; AC_SUBST([HAVE_GROUP_MEMBER]) - HAVE_LCHOWN=1; AC_SUBST([HAVE_LCHOWN]) - HAVE_LINK=1; AC_SUBST([HAVE_LINK]) - HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT]) - HAVE_PIPE=1; AC_SUBST([HAVE_PIPE]) - HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2]) - HAVE_PREAD=1; AC_SUBST([HAVE_PREAD]) - HAVE_PWRITE=1; AC_SUBST([HAVE_PWRITE]) - HAVE_READLINK=1; AC_SUBST([HAVE_READLINK]) - HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT]) - HAVE_SETHOSTNAME=1; AC_SUBST([HAVE_SETHOSTNAME]) - HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) - HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK]) - HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT]) - HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT]) - HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP]) - HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON]) - HAVE_DECL_FCHDIR=1; AC_SUBST([HAVE_DECL_FCHDIR]) - HAVE_DECL_FDATASYNC=1; AC_SUBST([HAVE_DECL_FDATASYNC]) - HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME]) - HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R]) - HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE]) - HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL]) - HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME]) - HAVE_DECL_TTYNAME_R=1; AC_SUBST([HAVE_DECL_TTYNAME_R]) - HAVE_OS_H=0; AC_SUBST([HAVE_OS_H]) - HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H]) - REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN]) - REPLACE_CLOSE=0; AC_SUBST([REPLACE_CLOSE]) - REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) - REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) - REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) - REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) - REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) - REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) - REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) - REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) - REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) - REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY]) - REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) - REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) - REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT]) - REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) - REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD]) - REPLACE_PWRITE=0; AC_SUBST([REPLACE_PWRITE]) - REPLACE_READ=0; AC_SUBST([REPLACE_READ]) - REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK]) - REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) - REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) - REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK]) - REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R]) - REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK]) - REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT]) - REPLACE_USLEEP=0; AC_SUBST([REPLACE_USLEEP]) - REPLACE_WRITE=0; AC_SUBST([REPLACE_WRITE]) - UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H]) - UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0; - AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS]) -]) diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 deleted file mode 100644 index d730e435a..000000000 --- a/m4/vasnprintf.m4 +++ /dev/null @@ -1,291 +0,0 @@ -# vasnprintf.m4 serial 36 -dnl Copyright (C) 2002-2004, 2006-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_VASNPRINTF], -[ - AC_CHECK_FUNCS_ONCE([vasnprintf]) - if test $ac_cv_func_vasnprintf = no; then - gl_REPLACE_VASNPRINTF - fi -]) - -AC_DEFUN([gl_REPLACE_VASNPRINTF], -[ - AC_CHECK_FUNCS_ONCE([vasnprintf]) - AC_LIBOBJ([vasnprintf]) - AC_LIBOBJ([printf-args]) - AC_LIBOBJ([printf-parse]) - AC_LIBOBJ([asnprintf]) - if test $ac_cv_func_vasnprintf = yes; then - AC_DEFINE([REPLACE_VASNPRINTF], [1], - [Define if vasnprintf exists but is overridden by gnulib.]) - fi - gl_PREREQ_PRINTF_ARGS - gl_PREREQ_PRINTF_PARSE - gl_PREREQ_VASNPRINTF - gl_PREREQ_ASNPRINTF -]) - -# Prerequisites of lib/printf-args.h, lib/printf-args.c. -AC_DEFUN([gl_PREREQ_PRINTF_ARGS], -[ - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - AC_REQUIRE([gt_TYPE_WCHAR_T]) - AC_REQUIRE([gt_TYPE_WINT_T]) -]) - -# Prerequisites of lib/printf-parse.h, lib/printf-parse.c. -AC_DEFUN([gl_PREREQ_PRINTF_PARSE], -[ - AC_REQUIRE([gl_FEATURES_H]) - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - AC_REQUIRE([gt_TYPE_WCHAR_T]) - AC_REQUIRE([gt_TYPE_WINT_T]) - AC_REQUIRE([AC_TYPE_SIZE_T]) - AC_CHECK_TYPE([ptrdiff_t], , - [AC_DEFINE([ptrdiff_t], [long], - [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) - ]) - AC_REQUIRE([gt_AC_TYPE_INTMAX_T]) -]) - -# Prerequisites of lib/vasnprintf.c. -AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF], -[ - AC_REQUIRE([AC_FUNC_ALLOCA]) - AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) - AC_REQUIRE([gt_TYPE_WCHAR_T]) - AC_REQUIRE([gt_TYPE_WINT_T]) - AC_CHECK_FUNCS([snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) - dnl Use the _snprintf function only if it is declared (because on NetBSD it - dnl is defined as a weak alias of snprintf; we prefer to use the latter). - AC_CHECK_DECLS([_snprintf], , , [[#include ]]) - dnl Knowing DBL_EXPBIT0_WORD and DBL_EXPBIT0_BIT enables an optimization - dnl in the code for NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE. - AC_REQUIRE([gl_DOUBLE_EXPONENT_LOCATION]) - dnl We can avoid a lot of code by assuming that snprintf's return value - dnl conforms to ISO C99. So check that. - AC_REQUIRE([gl_SNPRINTF_RETVAL_C99]) - case "$gl_cv_func_snprintf_retval_c99" in - *yes) - AC_DEFINE([HAVE_SNPRINTF_RETVAL_C99], [1], - [Define if the return value of the snprintf function is the number of - of bytes (excluding the terminating NUL) that would have been produced - if the buffer had been large enough.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting 'long double' -# arguments. -AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE], -[ - AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) - case "$gl_cv_func_printf_long_double" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], - [Define if the vasnprintf implementation needs special code for - 'long double' arguments.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'double' -# arguments. -AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE], -[ - AC_REQUIRE([gl_PRINTF_INFINITE]) - case "$gl_cv_func_printf_infinite" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_INFINITE_DOUBLE], [1], - [Define if the vasnprintf implementation needs special code for - infinite 'double' arguments.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting infinite 'long double' -# arguments. -AC_DEFUN([gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE], -[ - AC_REQUIRE([gl_PRINTF_INFINITE_LONG_DOUBLE]) - dnl There is no need to set NEED_PRINTF_INFINITE_LONG_DOUBLE if - dnl NEED_PRINTF_LONG_DOUBLE is already set. - AC_REQUIRE([gl_PREREQ_VASNPRINTF_LONG_DOUBLE]) - case "$gl_cv_func_printf_long_double" in - *yes) - case "$gl_cv_func_printf_infinite_long_double" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_INFINITE_LONG_DOUBLE], [1], - [Define if the vasnprintf implementation needs special code for - infinite 'long double' arguments.]) - ;; - esac - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting the 'a' directive. -AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_A], -[ - AC_REQUIRE([gl_PRINTF_DIRECTIVE_A]) - case "$gl_cv_func_printf_directive_a" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_DIRECTIVE_A], [1], - [Define if the vasnprintf implementation needs special code for - the 'a' and 'A' directives.]) - AC_CHECK_FUNCS([nl_langinfo]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting the 'F' directive. -AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_F], -[ - AC_REQUIRE([gl_PRINTF_DIRECTIVE_F]) - case "$gl_cv_func_printf_directive_f" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_DIRECTIVE_F], [1], - [Define if the vasnprintf implementation needs special code for - the 'F' directive.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting the 'ls' directive. -AC_DEFUN([gl_PREREQ_VASNPRINTF_DIRECTIVE_LS], -[ - AC_REQUIRE([gl_PRINTF_DIRECTIVE_LS]) - case "$gl_cv_func_printf_directive_ls" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_DIRECTIVE_LS], [1], - [Define if the vasnprintf implementation needs special code for - the 'ls' directive.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting the ' flag. -AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_GROUPING], -[ - AC_REQUIRE([gl_PRINTF_FLAG_GROUPING]) - case "$gl_cv_func_printf_flag_grouping" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_FLAG_GROUPING], [1], - [Define if the vasnprintf implementation needs special code for the - ' flag.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting the '-' flag. -AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST], -[ - AC_REQUIRE([gl_PRINTF_FLAG_LEFTADJUST]) - case "$gl_cv_func_printf_flag_leftadjust" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_FLAG_LEFTADJUST], [1], - [Define if the vasnprintf implementation needs special code for the - '-' flag.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting the 0 flag. -AC_DEFUN([gl_PREREQ_VASNPRINTF_FLAG_ZERO], -[ - AC_REQUIRE([gl_PRINTF_FLAG_ZERO]) - case "$gl_cv_func_printf_flag_zero" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_FLAG_ZERO], [1], - [Define if the vasnprintf implementation needs special code for the - 0 flag.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for supporting large precisions. -AC_DEFUN([gl_PREREQ_VASNPRINTF_PRECISION], -[ - AC_REQUIRE([gl_PRINTF_PRECISION]) - case "$gl_cv_func_printf_precision" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_UNBOUNDED_PRECISION], [1], - [Define if the vasnprintf implementation needs special code for - supporting large precisions without arbitrary bounds.]) - AC_DEFINE([NEED_PRINTF_DOUBLE], [1], - [Define if the vasnprintf implementation needs special code for - 'double' arguments.]) - AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], - [Define if the vasnprintf implementation needs special code for - 'long double' arguments.]) - ;; - esac -]) - -# Extra prerequisites of lib/vasnprintf.c for surviving out-of-memory -# conditions. -AC_DEFUN([gl_PREREQ_VASNPRINTF_ENOMEM], -[ - AC_REQUIRE([gl_PRINTF_ENOMEM]) - case "$gl_cv_func_printf_enomem" in - *yes) - ;; - *) - AC_DEFINE([NEED_PRINTF_ENOMEM], [1], - [Define if the vasnprintf implementation needs special code for - surviving out-of-memory conditions.]) - AC_DEFINE([NEED_PRINTF_DOUBLE], [1], - [Define if the vasnprintf implementation needs special code for - 'double' arguments.]) - AC_DEFINE([NEED_PRINTF_LONG_DOUBLE], [1], - [Define if the vasnprintf implementation needs special code for - 'long double' arguments.]) - ;; - esac -]) - -# Prerequisites of lib/vasnprintf.c including all extras for POSIX compliance. -AC_DEFUN([gl_PREREQ_VASNPRINTF_WITH_EXTRAS], -[ - AC_REQUIRE([gl_PREREQ_VASNPRINTF]) - gl_PREREQ_VASNPRINTF_LONG_DOUBLE - gl_PREREQ_VASNPRINTF_INFINITE_DOUBLE - gl_PREREQ_VASNPRINTF_INFINITE_LONG_DOUBLE - gl_PREREQ_VASNPRINTF_DIRECTIVE_A - gl_PREREQ_VASNPRINTF_DIRECTIVE_F - gl_PREREQ_VASNPRINTF_DIRECTIVE_LS - gl_PREREQ_VASNPRINTF_FLAG_GROUPING - gl_PREREQ_VASNPRINTF_FLAG_LEFTADJUST - gl_PREREQ_VASNPRINTF_FLAG_ZERO - gl_PREREQ_VASNPRINTF_PRECISION - gl_PREREQ_VASNPRINTF_ENOMEM -]) - -# Prerequisites of lib/asnprintf.c. -AC_DEFUN([gl_PREREQ_ASNPRINTF], -[ -]) diff --git a/m4/visibility.m4 b/m4/visibility.m4 deleted file mode 100644 index 6cbd7e5f2..000000000 --- a/m4/visibility.m4 +++ /dev/null @@ -1,77 +0,0 @@ -# visibility.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2005, 2008, 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl Tests whether the compiler supports the command-line option -dnl -fvisibility=hidden and the function and variable attributes -dnl __attribute__((__visibility__("hidden"))) and -dnl __attribute__((__visibility__("default"))). -dnl Does *not* test for __visibility__("protected") - which has tricky -dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on -dnl Mac OS X. -dnl Does *not* test for __visibility__("internal") - which has processor -dnl dependent semantics. -dnl Does *not* test for #pragma GCC visibility push(hidden) - which is -dnl "really only recommended for legacy code". -dnl Set the variable CFLAG_VISIBILITY. -dnl Defines and sets the variable HAVE_VISIBILITY. - -AC_DEFUN([gl_VISIBILITY], -[ - AC_REQUIRE([AC_PROG_CC]) - CFLAG_VISIBILITY= - HAVE_VISIBILITY=0 - if test -n "$GCC"; then - dnl First, check whether -Werror can be added to the command line, or - dnl whether it leads to an error because of some other option that the - dnl user has put into $CC $CFLAGS $CPPFLAGS. - AC_MSG_CHECKING([whether the -Werror option is usable]) - AC_CACHE_VAL([gl_cv_cc_vis_werror], [ - gl_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror" - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[]])], - [gl_cv_cc_vis_werror=yes], - [gl_cv_cc_vis_werror=no]) - CFLAGS="$gl_save_CFLAGS"]) - AC_MSG_RESULT([$gl_cv_cc_vis_werror]) - dnl Now check whether visibility declarations are supported. - AC_MSG_CHECKING([for simple visibility declarations]) - AC_CACHE_VAL([gl_cv_cc_visibility], [ - gl_save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fvisibility=hidden" - dnl We use the option -Werror and a function dummyfunc, because on some - dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning - dnl "visibility attribute not supported in this configuration; ignored" - dnl at the first function definition in every compilation unit, and we - dnl don't want to use the option in this case. - if test $gl_cv_cc_vis_werror = yes; then - CFLAGS="$CFLAGS -Werror" - fi - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; - extern __attribute__((__visibility__("default"))) int exportedvar; - extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); - extern __attribute__((__visibility__("default"))) int exportedfunc (void); - void dummyfunc (void) {} - ]], - [[]])], - [gl_cv_cc_visibility=yes], - [gl_cv_cc_visibility=no]) - CFLAGS="$gl_save_CFLAGS"]) - AC_MSG_RESULT([$gl_cv_cc_visibility]) - if test $gl_cv_cc_visibility = yes; then - CFLAG_VISIBILITY="-fvisibility=hidden" - HAVE_VISIBILITY=1 - fi - fi - AC_SUBST([CFLAG_VISIBILITY]) - AC_SUBST([HAVE_VISIBILITY]) - AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], - [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) -]) diff --git a/m4/vsnprintf.m4 b/m4/vsnprintf.m4 deleted file mode 100644 index 4900764ee..000000000 --- a/m4/vsnprintf.m4 +++ /dev/null @@ -1,54 +0,0 @@ -# vsnprintf.m4 serial 6 -dnl Copyright (C) 2002-2004, 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Libintl 0.17 will replace vsnprintf only if it does not support %1$s, -dnl but defers to any gnulib vsnprintf replacements. Therefore, gnulib -dnl must guarantee that the decision for replacing vsnprintf is a superset -dnl of the reasons checked by libintl. -AC_DEFUN([gl_FUNC_VSNPRINTF], -[ - AC_REQUIRE([gl_STDIO_H_DEFAULTS]) - gl_cv_func_vsnprintf_usable=no - AC_CHECK_FUNCS([vsnprintf]) - if test $ac_cv_func_vsnprintf = yes; then - gl_SNPRINTF_SIZE1 - case "$gl_cv_func_snprintf_size1" in - *yes) - gl_SNPRINTF_RETVAL_C99 - case "$gl_cv_func_snprintf_retval_c99" in - *yes) - gl_PRINTF_POSITIONS - case "$gl_cv_func_printf_positions" in - *yes) - gl_cv_func_vsnprintf_usable=yes - ;; - esac - ;; - esac - ;; - esac - fi - if test $gl_cv_func_vsnprintf_usable = no; then - gl_REPLACE_VSNPRINTF - fi - AC_CHECK_DECLS_ONCE([vsnprintf]) - if test $ac_cv_have_decl_vsnprintf = no; then - HAVE_DECL_VSNPRINTF=0 - fi -]) - -AC_DEFUN([gl_REPLACE_VSNPRINTF], -[ - AC_REQUIRE([gl_STDIO_H_DEFAULTS]) - AC_LIBOBJ([vsnprintf]) - if test $ac_cv_func_vsnprintf = yes; then - REPLACE_VSNPRINTF=1 - fi - gl_PREREQ_VSNPRINTF -]) - -# Prerequisites of lib/vsnprintf.c. -AC_DEFUN([gl_PREREQ_VSNPRINTF], [:]) diff --git a/m4/warn-on-use.m4 b/m4/warn-on-use.m4 deleted file mode 100644 index e43beebd9..000000000 --- a/m4/warn-on-use.m4 +++ /dev/null @@ -1,47 +0,0 @@ -# warn-on-use.m4 serial 5 -dnl Copyright (C) 2010-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -# gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES) -# --------------------------------------- -# For each whitespace-separated element in the list of NAMES, define -# HAVE_RAW_DECL_name if the function has a declaration among INCLUDES -# even after being undefined as a macro. -# -# See warn-on-use.h for some hints on how to poison function names, as -# well as ideas on poisoning global variables and macros. NAMES may -# include global variables, but remember that only functions work with -# _GL_WARN_ON_USE. Typically, INCLUDES only needs to list a single -# header, but if the replacement header pulls in other headers because -# some systems declare functions in the wrong header, then INCLUDES -# should do likewise. -# -# It is generally safe to assume declarations for functions declared -# in the intersection of C89 and C11 (such as printf) without -# needing gl_WARN_ON_USE_PREPARE. -AC_DEFUN([gl_WARN_ON_USE_PREPARE], -[ - m4_foreach_w([gl_decl], [$2], - [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])), - [Define to 1 if ]m4_defn([gl_decl])[ is declared even after - undefining macros.])])dnl -dnl FIXME: gl_Symbol must be used unquoted until we can assume -dnl autoconf 2.64 or newer. - for gl_func in m4_flatten([$2]); do - AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl - AC_CACHE_CHECK([whether $gl_func is declared without a macro], - gl_Symbol, - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1], -[@%:@undef $gl_func - (void) $gl_func;])], - [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])]) - AS_VAR_IF(gl_Symbol, [yes], - [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) - dnl shortcut - if the raw declaration exists, then set a cache - dnl variable to allow skipping any later AC_CHECK_DECL efforts - eval ac_cv_have_decl_$gl_func=yes]) - AS_VAR_POPDEF([gl_Symbol])dnl - done -]) diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4 deleted file mode 100644 index bedb15a44..000000000 --- a/m4/wchar_h.m4 +++ /dev/null @@ -1,225 +0,0 @@ -dnl A placeholder for ISO C99 , for platforms that have issues. - -dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Written by Eric Blake. - -# wchar_h.m4 serial 39 - -AC_DEFUN([gl_WCHAR_H], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - AC_REQUIRE([gl_WCHAR_H_INLINE_OK]) - dnl Prepare for creating substitute . - dnl Check for (missing in Linux uClibc when built without wide - dnl character support). - dnl is always overridden, because of GNULIB_POSIXCHECK. - gl_CHECK_NEXT_HEADERS([wchar.h]) - if test $ac_cv_header_wchar_h = yes; then - HAVE_WCHAR_H=1 - else - HAVE_WCHAR_H=0 - fi - AC_SUBST([HAVE_WCHAR_H]) - - AC_REQUIRE([gl_FEATURES_H]) - - AC_REQUIRE([gt_TYPE_WINT_T]) - if test $gt_cv_c_wint_t = yes; then - HAVE_WINT_T=1 - else - HAVE_WINT_T=0 - fi - AC_SUBST([HAVE_WINT_T]) - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#if !(defined __GLIBC__ && !defined __UCLIBC__) -# include -# include -# include -#endif -#include - ]], - [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb - wcsrtombs wcsnrtombs wcwidth wmemchr wmemcmp wmemcpy wmemmove wmemset - wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat wcscmp - wcsncmp wcscasecmp wcsncasecmp wcscoll wcsxfrm wcsdup wcschr wcsrchr - wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth - ]) -]) - -dnl Check whether is usable at all. -AC_DEFUN([gl_WCHAR_H_INLINE_OK], -[ - dnl Test whether suffers due to the transition from '__inline' to - dnl 'gnu_inline'. See - dnl and . In summary, - dnl glibc version 2.5 or older, together with gcc version 4.3 or newer and - dnl the option -std=c99 or -std=gnu99, leads to a broken . - AC_CACHE_CHECK([whether uses 'inline' correctly], - [gl_cv_header_wchar_h_correct_inline], - [gl_cv_header_wchar_h_correct_inline=yes - AC_LANG_CONFTEST([ - AC_LANG_SOURCE([[#define wcstod renamed_wcstod -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -extern int zero (void); -int main () { return zero(); } -]])]) - if AC_TRY_EVAL([ac_compile]); then - mv conftest.$ac_objext conftest1.$ac_objext - AC_LANG_CONFTEST([ - AC_LANG_SOURCE([[#define wcstod renamed_wcstod -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int zero (void) { return 0; } -]])]) - if AC_TRY_EVAL([ac_compile]); then - mv conftest.$ac_objext conftest2.$ac_objext - if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then - : - else - gl_cv_header_wchar_h_correct_inline=no - fi - fi - fi - rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext - ]) - if test $gl_cv_header_wchar_h_correct_inline = no; then - AC_MSG_ERROR([ cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS). -This is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in -C99 mode. You have four options: - - Add the flag -fgnu89-inline to CC and reconfigure, or - - Fix your include files, using parts of - , or - - Use a gcc version older than 4.3, or - - Don't use the flags -std=c99 or -std=gnu99. -Configuration aborted.]) - fi -]) - -AC_DEFUN([gl_WCHAR_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_WCHAR_H_DEFAULTS], -[ - GNULIB_BTOWC=0; AC_SUBST([GNULIB_BTOWC]) - GNULIB_WCTOB=0; AC_SUBST([GNULIB_WCTOB]) - GNULIB_MBSINIT=0; AC_SUBST([GNULIB_MBSINIT]) - GNULIB_MBRTOWC=0; AC_SUBST([GNULIB_MBRTOWC]) - GNULIB_MBRLEN=0; AC_SUBST([GNULIB_MBRLEN]) - GNULIB_MBSRTOWCS=0; AC_SUBST([GNULIB_MBSRTOWCS]) - GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS]) - GNULIB_WCRTOMB=0; AC_SUBST([GNULIB_WCRTOMB]) - GNULIB_WCSRTOMBS=0; AC_SUBST([GNULIB_WCSRTOMBS]) - GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS]) - GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH]) - GNULIB_WMEMCHR=0; AC_SUBST([GNULIB_WMEMCHR]) - GNULIB_WMEMCMP=0; AC_SUBST([GNULIB_WMEMCMP]) - GNULIB_WMEMCPY=0; AC_SUBST([GNULIB_WMEMCPY]) - GNULIB_WMEMMOVE=0; AC_SUBST([GNULIB_WMEMMOVE]) - GNULIB_WMEMSET=0; AC_SUBST([GNULIB_WMEMSET]) - GNULIB_WCSLEN=0; AC_SUBST([GNULIB_WCSLEN]) - GNULIB_WCSNLEN=0; AC_SUBST([GNULIB_WCSNLEN]) - GNULIB_WCSCPY=0; AC_SUBST([GNULIB_WCSCPY]) - GNULIB_WCPCPY=0; AC_SUBST([GNULIB_WCPCPY]) - GNULIB_WCSNCPY=0; AC_SUBST([GNULIB_WCSNCPY]) - GNULIB_WCPNCPY=0; AC_SUBST([GNULIB_WCPNCPY]) - GNULIB_WCSCAT=0; AC_SUBST([GNULIB_WCSCAT]) - GNULIB_WCSNCAT=0; AC_SUBST([GNULIB_WCSNCAT]) - GNULIB_WCSCMP=0; AC_SUBST([GNULIB_WCSCMP]) - GNULIB_WCSNCMP=0; AC_SUBST([GNULIB_WCSNCMP]) - GNULIB_WCSCASECMP=0; AC_SUBST([GNULIB_WCSCASECMP]) - GNULIB_WCSNCASECMP=0; AC_SUBST([GNULIB_WCSNCASECMP]) - GNULIB_WCSCOLL=0; AC_SUBST([GNULIB_WCSCOLL]) - GNULIB_WCSXFRM=0; AC_SUBST([GNULIB_WCSXFRM]) - GNULIB_WCSDUP=0; AC_SUBST([GNULIB_WCSDUP]) - GNULIB_WCSCHR=0; AC_SUBST([GNULIB_WCSCHR]) - GNULIB_WCSRCHR=0; AC_SUBST([GNULIB_WCSRCHR]) - GNULIB_WCSCSPN=0; AC_SUBST([GNULIB_WCSCSPN]) - GNULIB_WCSSPN=0; AC_SUBST([GNULIB_WCSSPN]) - GNULIB_WCSPBRK=0; AC_SUBST([GNULIB_WCSPBRK]) - GNULIB_WCSSTR=0; AC_SUBST([GNULIB_WCSSTR]) - GNULIB_WCSTOK=0; AC_SUBST([GNULIB_WCSTOK]) - GNULIB_WCSWIDTH=0; AC_SUBST([GNULIB_WCSWIDTH]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) - HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) - HAVE_MBRTOWC=1; AC_SUBST([HAVE_MBRTOWC]) - HAVE_MBRLEN=1; AC_SUBST([HAVE_MBRLEN]) - HAVE_MBSRTOWCS=1; AC_SUBST([HAVE_MBSRTOWCS]) - HAVE_MBSNRTOWCS=1; AC_SUBST([HAVE_MBSNRTOWCS]) - HAVE_WCRTOMB=1; AC_SUBST([HAVE_WCRTOMB]) - HAVE_WCSRTOMBS=1; AC_SUBST([HAVE_WCSRTOMBS]) - HAVE_WCSNRTOMBS=1; AC_SUBST([HAVE_WCSNRTOMBS]) - HAVE_WMEMCHR=1; AC_SUBST([HAVE_WMEMCHR]) - HAVE_WMEMCMP=1; AC_SUBST([HAVE_WMEMCMP]) - HAVE_WMEMCPY=1; AC_SUBST([HAVE_WMEMCPY]) - HAVE_WMEMMOVE=1; AC_SUBST([HAVE_WMEMMOVE]) - HAVE_WMEMSET=1; AC_SUBST([HAVE_WMEMSET]) - HAVE_WCSLEN=1; AC_SUBST([HAVE_WCSLEN]) - HAVE_WCSNLEN=1; AC_SUBST([HAVE_WCSNLEN]) - HAVE_WCSCPY=1; AC_SUBST([HAVE_WCSCPY]) - HAVE_WCPCPY=1; AC_SUBST([HAVE_WCPCPY]) - HAVE_WCSNCPY=1; AC_SUBST([HAVE_WCSNCPY]) - HAVE_WCPNCPY=1; AC_SUBST([HAVE_WCPNCPY]) - HAVE_WCSCAT=1; AC_SUBST([HAVE_WCSCAT]) - HAVE_WCSNCAT=1; AC_SUBST([HAVE_WCSNCAT]) - HAVE_WCSCMP=1; AC_SUBST([HAVE_WCSCMP]) - HAVE_WCSNCMP=1; AC_SUBST([HAVE_WCSNCMP]) - HAVE_WCSCASECMP=1; AC_SUBST([HAVE_WCSCASECMP]) - HAVE_WCSNCASECMP=1; AC_SUBST([HAVE_WCSNCASECMP]) - HAVE_WCSCOLL=1; AC_SUBST([HAVE_WCSCOLL]) - HAVE_WCSXFRM=1; AC_SUBST([HAVE_WCSXFRM]) - HAVE_WCSDUP=1; AC_SUBST([HAVE_WCSDUP]) - HAVE_WCSCHR=1; AC_SUBST([HAVE_WCSCHR]) - HAVE_WCSRCHR=1; AC_SUBST([HAVE_WCSRCHR]) - HAVE_WCSCSPN=1; AC_SUBST([HAVE_WCSCSPN]) - HAVE_WCSSPN=1; AC_SUBST([HAVE_WCSSPN]) - HAVE_WCSPBRK=1; AC_SUBST([HAVE_WCSPBRK]) - HAVE_WCSSTR=1; AC_SUBST([HAVE_WCSSTR]) - HAVE_WCSTOK=1; AC_SUBST([HAVE_WCSTOK]) - HAVE_WCSWIDTH=1; AC_SUBST([HAVE_WCSWIDTH]) - HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB]) - HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH]) - REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T]) - REPLACE_BTOWC=0; AC_SUBST([REPLACE_BTOWC]) - REPLACE_WCTOB=0; AC_SUBST([REPLACE_WCTOB]) - REPLACE_MBSINIT=0; AC_SUBST([REPLACE_MBSINIT]) - REPLACE_MBRTOWC=0; AC_SUBST([REPLACE_MBRTOWC]) - REPLACE_MBRLEN=0; AC_SUBST([REPLACE_MBRLEN]) - REPLACE_MBSRTOWCS=0; AC_SUBST([REPLACE_MBSRTOWCS]) - REPLACE_MBSNRTOWCS=0; AC_SUBST([REPLACE_MBSNRTOWCS]) - REPLACE_WCRTOMB=0; AC_SUBST([REPLACE_WCRTOMB]) - REPLACE_WCSRTOMBS=0; AC_SUBST([REPLACE_WCSRTOMBS]) - REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS]) - REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH]) - REPLACE_WCSWIDTH=0; AC_SUBST([REPLACE_WCSWIDTH]) -]) diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4 deleted file mode 100644 index e1e1e699d..000000000 --- a/m4/wchar_t.m4 +++ /dev/null @@ -1,24 +0,0 @@ -# wchar_t.m4 serial 4 (gettext-0.18.2) -dnl Copyright (C) 2002-2003, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether has the 'wchar_t' type. -dnl Prerequisite: AC_PROG_CC - -AC_DEFUN([gt_TYPE_WCHAR_T], -[ - AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[#include - wchar_t foo = (wchar_t)'\0';]], - [[]])], - [gt_cv_c_wchar_t=yes], - [gt_cv_c_wchar_t=no])]) - if test $gt_cv_c_wchar_t = yes; then - AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.]) - fi -]) diff --git a/m4/wcrtomb.m4 b/m4/wcrtomb.m4 deleted file mode 100644 index f56b5bae9..000000000 --- a/m4/wcrtomb.m4 +++ /dev/null @@ -1,112 +0,0 @@ -# wcrtomb.m4 serial 11 -dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_WCRTOMB], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - - AC_REQUIRE([AC_TYPE_MBSTATE_T]) - gl_MBSTATE_T_BROKEN - - AC_CHECK_FUNCS_ONCE([wcrtomb]) - if test $ac_cv_func_wcrtomb = no; then - HAVE_WCRTOMB=0 - AC_CHECK_DECLS([wcrtomb],,, [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -]]) - if test $ac_cv_have_decl_wcrtomb = yes; then - dnl On Minix 3.1.8, the system's declares wcrtomb() although - dnl it does not have the function. Avoid a collision with gnulib's - dnl replacement. - REPLACE_WCRTOMB=1 - fi - else - if test $REPLACE_MBSTATE_T = 1; then - REPLACE_WCRTOMB=1 - else - dnl On AIX 4.3, OSF/1 5.1 and Solaris 10, wcrtomb (NULL, 0, NULL) sometimes - dnl returns 0 instead of 1. - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([gt_LOCALE_FR]) - AC_REQUIRE([gt_LOCALE_FR_UTF8]) - AC_REQUIRE([gt_LOCALE_JA]) - AC_REQUIRE([gt_LOCALE_ZH_CN]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - AC_CACHE_CHECK([whether wcrtomb return value is correct], - [gl_cv_func_wcrtomb_retval], - [ - dnl Initial guess, used when cross-compiling or when no suitable locale - dnl is present. -changequote(,)dnl - case "$host_os" in - # Guess no on AIX 4, OSF/1 and Solaris. - aix4* | osf* | solaris*) gl_cv_func_wcrtomb_retval="guessing no" ;; - # Guess yes otherwise. - *) gl_cv_func_wcrtomb_retval="guessing yes" ;; - esac -changequote([,])dnl - if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#include -#include -#include -#include -int main () -{ - int result = 0; - if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) - { - if (wcrtomb (NULL, 0, NULL) != 1) - result |= 1; - } - if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) - { - if (wcrtomb (NULL, 0, NULL) != 1) - result |= 2; - } - if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) - { - if (wcrtomb (NULL, 0, NULL) != 1) - result |= 4; - } - if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) - { - if (wcrtomb (NULL, 0, NULL) != 1) - result |= 8; - } - return result; -}]])], - [gl_cv_func_wcrtomb_retval=yes], - [gl_cv_func_wcrtomb_retval=no], - [:]) - fi - ]) - case "$gl_cv_func_wcrtomb_retval" in - *yes) ;; - *) REPLACE_WCRTOMB=1 ;; - esac - fi - fi -]) - -# Prerequisites of lib/wcrtomb.c. -AC_DEFUN([gl_PREREQ_WCRTOMB], [ - : -]) diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4 deleted file mode 100644 index 82ada0eee..000000000 --- a/m4/wctype_h.m4 +++ /dev/null @@ -1,209 +0,0 @@ -# wctype_h.m4 serial 18 - -dnl A placeholder for ISO C99 , for platforms that lack it. - -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Written by Paul Eggert. - -AC_DEFUN([gl_WCTYPE_H], -[ - AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_CHECK_FUNCS_ONCE([iswcntrl]) - if test $ac_cv_func_iswcntrl = yes; then - HAVE_ISWCNTRL=1 - else - HAVE_ISWCNTRL=0 - fi - AC_SUBST([HAVE_ISWCNTRL]) - - AC_REQUIRE([gt_TYPE_WINT_T]) - if test $gt_cv_c_wint_t = yes; then - HAVE_WINT_T=1 - else - HAVE_WINT_T=0 - fi - AC_SUBST([HAVE_WINT_T]) - - gl_CHECK_NEXT_HEADERS([wctype.h]) - if test $ac_cv_header_wctype_h = yes; then - if test $ac_cv_func_iswcntrl = yes; then - dnl Linux libc5 has an iswprint function that returns 0 for all arguments. - dnl The other functions are likely broken in the same way. - AC_CACHE_CHECK([whether iswcntrl works], [gl_cv_func_iswcntrl_works], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ - /* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include - #include - int main () { return iswprint ('x') == 0; } - ]])], - [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include - #if __GNU_LIBRARY__ == 1 - Linux libc5 i18n is broken. - #endif]], [])], - [gl_cv_func_iswcntrl_works="guessing yes"], - [gl_cv_func_iswcntrl_works="guessing no"]) - ]) - ]) - fi - HAVE_WCTYPE_H=1 - else - HAVE_WCTYPE_H=0 - fi - AC_SUBST([HAVE_WCTYPE_H]) - - case "$gl_cv_func_iswcntrl_works" in - *yes) REPLACE_ISWCNTRL=0 ;; - *) REPLACE_ISWCNTRL=1 ;; - esac - AC_SUBST([REPLACE_ISWCNTRL]) - - if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then - dnl Redefine all of iswcntrl, ..., iswxdigit in . - : - fi - - if test $REPLACE_ISWCNTRL = 1; then - REPLACE_TOWLOWER=1 - else - AC_CHECK_FUNCS([towlower]) - if test $ac_cv_func_towlower = yes; then - REPLACE_TOWLOWER=0 - else - AC_CHECK_DECLS([towlower],,, - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include - #if HAVE_WCTYPE_H - # include - #endif - ]]) - if test $ac_cv_have_decl_towlower = yes; then - dnl On Minix 3.1.8, the system's declares towlower() and - dnl towupper() although it does not have the functions. Avoid a - dnl collision with gnulib's replacement. - REPLACE_TOWLOWER=1 - else - REPLACE_TOWLOWER=0 - fi - fi - fi - AC_SUBST([REPLACE_TOWLOWER]) - - if test $HAVE_ISWCNTRL = 0 || test $REPLACE_TOWLOWER = 1; then - dnl Redefine towlower, towupper in . - : - fi - - dnl We assume that the wctype() and iswctype() functions exist if and only - dnl if the type wctype_t is defined in or in if that - dnl exists. - dnl HP-UX 11.00 declares all these in and lacks . - AC_CACHE_CHECK([for wctype_t], [gl_cv_type_wctype_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include - #if HAVE_WCTYPE_H - # include - #endif - wctype_t a; - ]], - [[]])], - [gl_cv_type_wctype_t=yes], - [gl_cv_type_wctype_t=no]) - ]) - if test $gl_cv_type_wctype_t = no; then - HAVE_WCTYPE_T=0 - fi - - dnl We assume that the wctrans() and towctrans() functions exist if and only - dnl if the type wctrans_t is defined in . - AC_CACHE_CHECK([for wctrans_t], [gl_cv_type_wctrans_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[/* Tru64 with Desktop Toolkit C has a bug: must be - included before . - BSD/OS 4.0.1 has a bug: , and - must be included before . */ - #include - #include - #include - #include - #include - wctrans_t a; - ]], - [[]])], - [gl_cv_type_wctrans_t=yes], - [gl_cv_type_wctrans_t=no]) - ]) - if test $gl_cv_type_wctrans_t = no; then - HAVE_WCTRANS_T=0 - fi - - dnl Check for declarations of anything we want to poison if the - dnl corresponding gnulib module is not in use. - gl_WARN_ON_USE_PREPARE([[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be - included before . */ -#if !(defined __GLIBC__ && !defined __UCLIBC__) -# include -# include -# include -# include -#endif -#include - ]], - [wctype iswctype wctrans towctrans - ]) -]) - -AC_DEFUN([gl_WCTYPE_MODULE_INDICATOR], -[ - dnl Use AC_REQUIRE here, so that the default settings are expanded once only. - AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) - gl_MODULE_INDICATOR_SET_VARIABLE([$1]) - dnl Define it also as a C macro, for the benefit of the unit tests. - gl_MODULE_INDICATOR_FOR_TESTS([$1]) -]) - -AC_DEFUN([gl_WCTYPE_H_DEFAULTS], -[ - GNULIB_ISWBLANK=0; AC_SUBST([GNULIB_ISWBLANK]) - GNULIB_WCTYPE=0; AC_SUBST([GNULIB_WCTYPE]) - GNULIB_ISWCTYPE=0; AC_SUBST([GNULIB_ISWCTYPE]) - GNULIB_WCTRANS=0; AC_SUBST([GNULIB_WCTRANS]) - GNULIB_TOWCTRANS=0; AC_SUBST([GNULIB_TOWCTRANS]) - dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_ISWBLANK=1; AC_SUBST([HAVE_ISWBLANK]) - HAVE_WCTYPE_T=1; AC_SUBST([HAVE_WCTYPE_T]) - HAVE_WCTRANS_T=1; AC_SUBST([HAVE_WCTRANS_T]) - REPLACE_ISWBLANK=0; AC_SUBST([REPLACE_ISWBLANK]) -]) diff --git a/m4/wcwidth.m4 b/m4/wcwidth.m4 deleted file mode 100644 index 740f81ee1..000000000 --- a/m4/wcwidth.m4 +++ /dev/null @@ -1,101 +0,0 @@ -# wcwidth.m4 serial 23 -dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_FUNC_WCWIDTH], -[ - AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - - dnl Persuade glibc to declare wcwidth(). - AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) - - AC_REQUIRE([gt_TYPE_WCHAR_T]) - AC_REQUIRE([gt_TYPE_WINT_T]) - - AC_CHECK_HEADERS_ONCE([wchar.h]) - AC_CHECK_FUNCS_ONCE([wcwidth]) - - AC_CHECK_DECLS([wcwidth], [], [], [[ -/* AIX 3.2.5 declares wcwidth in . */ -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be included - before . */ -#include -#include -#include -#include -]]) - if test $ac_cv_have_decl_wcwidth != yes; then - HAVE_DECL_WCWIDTH=0 - fi - - if test $ac_cv_func_wcwidth = yes; then - HAVE_WCWIDTH=1 - dnl On Mac OS X 10.3, wcwidth(0x0301) (COMBINING ACUTE ACCENT) returns 1. - dnl On OpenBSD 5.0, wcwidth(0x05B0) (HEBREW POINT SHEVA) returns 1. - dnl On OSF/1 5.1, wcwidth(0x200B) (ZERO WIDTH SPACE) returns 1. - dnl This leads to bugs in 'ls' (coreutils). - AC_CACHE_CHECK([whether wcwidth works reasonably in UTF-8 locales], - [gl_cv_func_wcwidth_works], - [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -/* AIX 3.2.5 declares wcwidth in . */ -#include -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be included - before . */ -#include -#include -#include -#include -#if !HAVE_DECL_WCWIDTH -extern -# ifdef __cplusplus -"C" -# endif -int wcwidth (int); -#endif -int main () -{ - int result = 0; - if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL) - { - if (wcwidth (0x0301) > 0) - result |= 1; - if (wcwidth (0x05B0) > 0) - result |= 2; - if (wcwidth (0x200B) > 0) - result |= 4; - } - return result; -}]])], - [gl_cv_func_wcwidth_works=yes], - [gl_cv_func_wcwidth_works=no], - [ -changequote(,)dnl - case "$host_os" in - # Guess yes on glibc and AIX 7 systems. - *-gnu* | aix[7-9]*) gl_cv_func_wcwidth_works="guessing yes";; - *) gl_cv_func_wcwidth_works="guessing no";; - esac -changequote([,])dnl - ]) - ]) - case "$gl_cv_func_wcwidth_works" in - *yes) ;; - *no) REPLACE_WCWIDTH=1 ;; - esac - else - HAVE_WCWIDTH=0 - fi - dnl We don't substitute HAVE_WCWIDTH. We assume that if the system does not - dnl have the wcwidth function, then it does not declare it. -]) diff --git a/m4/wint_t.m4 b/m4/wint_t.m4 deleted file mode 100644 index d7cd3db93..000000000 --- a/m4/wint_t.m4 +++ /dev/null @@ -1,32 +0,0 @@ -# wint_t.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. -dnl Test whether has the 'wint_t' type. -dnl Prerequisite: AC_PROG_CC - -AC_DEFUN([gt_TYPE_WINT_T], -[ - AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.0.1 has a bug: , and must be included - before . */ -#include -#include -#include -#include - wint_t foo = (wchar_t)'\0';]], - [[]])], - [gt_cv_c_wint_t=yes], - [gt_cv_c_wint_t=no])]) - if test $gt_cv_c_wint_t = yes; then - AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.]) - fi -]) diff --git a/m4/xsize.m4 b/m4/xsize.m4 deleted file mode 100644 index 8ea9f2cd3..000000000 --- a/m4/xsize.m4 +++ /dev/null @@ -1,12 +0,0 @@ -# xsize.m4 serial 5 -dnl Copyright (C) 2003-2004, 2008-2013 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -AC_DEFUN([gl_XSIZE], -[ - dnl Prerequisites of lib/xsize.h. - AC_REQUIRE([gl_SIZE_MAX]) - AC_CHECK_HEADERS([stdint.h]) -]) diff --git a/po/Makefile.in.in b/po/Makefile.in.in deleted file mode 100644 index 3619458e8..000000000 --- a/po/Makefile.in.in +++ /dev/null @@ -1,469 +0,0 @@ -# Makefile for PO directory in any package using GNU gettext. -# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper -# -# This file can be copied and used freely without restrictions. It can -# be used in projects which are not available under the GNU General Public -# License but which still want to provide support for the GNU gettext -# functionality. -# Please note that the actual code of GNU gettext is covered by the GNU -# General Public License and is *not* in the public domain. -# -# Origin: gettext-0.18 -GETTEXT_MACRO_VERSION = 0.18 - -PACKAGE = @PACKAGE@ -VERSION = @VERSION@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ - -SHELL = /bin/sh -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -datarootdir = @datarootdir@ -datadir = @datadir@ -localedir = @localedir@ -gettextsrcdir = $(datadir)/gettext/po - -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ - -# We use $(mkdir_p). -# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as -# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, -# @install_sh@ does not start with $(SHELL), so we add it. -# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined -# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake -# versions, $(mkinstalldirs) and $(install_sh) are unused. -mkinstalldirs = $(SHELL) @install_sh@ -d -install_sh = $(SHELL) @install_sh@ -MKDIR_P = @MKDIR_P@ -mkdir_p = @mkdir_p@ - -GMSGFMT_ = @GMSGFMT@ -GMSGFMT_no = @GMSGFMT@ -GMSGFMT_yes = @GMSGFMT_015@ -GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) -MSGFMT_ = @MSGFMT@ -MSGFMT_no = @MSGFMT@ -MSGFMT_yes = @MSGFMT_015@ -MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) -XGETTEXT_ = @XGETTEXT@ -XGETTEXT_no = @XGETTEXT@ -XGETTEXT_yes = @XGETTEXT_015@ -XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) -MSGMERGE = msgmerge -MSGMERGE_UPDATE = @MSGMERGE@ --update -MSGINIT = msginit -MSGCONV = msgconv -MSGFILTER = msgfilter - -POFILES = @POFILES@ -GMOFILES = @GMOFILES@ -UPDATEPOFILES = @UPDATEPOFILES@ -DUMMYPOFILES = @DUMMYPOFILES@ -DISTFILES.common = Makefile.in.in remove-potcdate.sin \ -$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) \ -$(DISTFILES.common.extra3) $(DISTFILES.common.extra4) $(DISTFILES.common.extra5) -DISTFILES = $(DISTFILES.common) Makevars POTFILES.in POTFILES-shell.in \ -$(POFILES) $(GMOFILES) \ -$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) $(DISTFILES.extra4) $(DISTFILES.extra5) grub.d.sed README - -POTFILES = \ - -CATALOGS = @CATALOGS@ - -# Makevars gets inserted here. (Don't remove this line!) - -.SUFFIXES: -.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update - -.po.mo: - @echo "$(MSGFMT) -c -o $@ $<"; \ - $(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) --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-$@ - mv t-$@ $@ - - -all: check-macro-version all-@USE_NLS@ - -all-yes: stamp-po -all-no: - -# Ensure that the gettext macros and this Makefile.in.in are in sync. -check-macro-version: - @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ - || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ - exit 1; \ - } - -# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no -# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because -# we don't want to bother translators with empty POT files). We assume that -# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. -# In this case, stamp-po is a nop (i.e. a phony target). - -# stamp-po is a timestamp denoting the last time at which the CATALOGS have -# been loosely updated. Its purpose is that when a developer or translator -# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, -# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent -# invocations of "make" will do nothing. This timestamp would not be necessary -# if updating the $(CATALOGS) would always touch them; however, the rule for -# $(POFILES) has been designed to not touch files that don't need to be -# changed. -stamp-po: $(srcdir)/$(DOMAIN).pot - test ! -f $(srcdir)/$(DOMAIN).pot || \ - test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) - @test ! -f $(srcdir)/$(DOMAIN).pot || { \ - echo "touch stamp-po" && \ - echo timestamp > stamp-poT && \ - mv stamp-poT stamp-po; \ - } - -# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', -# otherwise packages like GCC can not be built if only parts of the source -# have been downloaded. - -# This target rebuilds $(DOMAIN).pot; it is an expensive operation. -# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. -$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell.in remove-potcdate.sed - if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \ - package_gnu='GNU '; \ - else \ - package_gnu=''; \ - fi; \ - if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ - msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ - else \ - msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ - fi; \ - 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_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ - --files-from=$(srcdir)/POTFILES.in \ - --copyright-holder='$(COPYRIGHT_HOLDER)' \ - --msgid-bugs-address="$$msgid_bugs_address" \ - ;; \ - *) \ - $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ - --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ - --files-from=$(srcdir)/POTFILES.in \ - --copyright-holder='$(COPYRIGHT_HOLDER)' \ - --package-name="$${package_gnu}@PACKAGE@" \ - --package-version='@VERSION@' \ - --msgid-bugs-address="$$msgid_bugs_address" \ - ;; \ - 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 --keyword=gettext_printf \ - ;; \ - *) \ - $(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 --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 && \ - if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ - rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ - else \ - rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ - mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ - fi; \ - else \ - mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ - fi; \ - } - -# This rule has no dependencies: we don't need to update $(DOMAIN).pot at -# every "make" invocation, only create it when it is missing. -# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. -$(srcdir)/$(DOMAIN).pot: - $(MAKE) $(DOMAIN).pot-update - -# This target rebuilds a PO file if $(DOMAIN).pot has changed. -# Note that a PO file is not touched if it doesn't need to be changed. -$(POFILES): $(srcdir)/$(DOMAIN).pot - @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ - if test -f "$(srcdir)/$${lang}.po"; then \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ - cd $(srcdir) \ - && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ - $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ - *) \ - $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ - esac; \ - }; \ - else \ - $(MAKE) $${lang}.po-create; \ - fi - - -install: install-exec install-data -install-exec: -install-data: install-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ - for file in $(DISTFILES.common) Makevars.template; do \ - $(INSTALL_DATA) $(srcdir)/$$file \ - $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - for file in Makevars; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi -install-data-no: all -install-data-yes: all - @catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - dir=$(localedir)/$$lang/LC_MESSAGES; \ - $(mkdir_p) $(DESTDIR)$$dir; \ - if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ - $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ - echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ - for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ - if test -n "$$lc"; then \ - if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ - link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ - mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ - for file in *; do \ - if test -f $$file; then \ - ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ - fi; \ - done); \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - else \ - if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ - :; \ - else \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - fi; \ - fi; \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ - ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ - cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ - fi; \ - done; \ - done - -install-strip: install - -installdirs: installdirs-exec installdirs-data -installdirs-exec: -installdirs-data: installdirs-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ - else \ - : ; \ - fi -installdirs-data-no: -installdirs-data-yes: - @catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - dir=$(localedir)/$$lang/LC_MESSAGES; \ - $(mkdir_p) $(DESTDIR)$$dir; \ - for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ - if test -n "$$lc"; then \ - if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ - link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ - mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ - for file in *; do \ - if test -f $$file; then \ - ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ - fi; \ - done); \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ - else \ - if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ - :; \ - else \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ - mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ - fi; \ - fi; \ - fi; \ - done; \ - done - -# Define this as empty until I found a useful application. -installcheck: - -uninstall: uninstall-exec uninstall-data -uninstall-exec: -uninstall-data: uninstall-data-@USE_NLS@ - if test "$(PACKAGE)" = "gettext-tools"; then \ - for file in $(DISTFILES.common) Makevars.template; do \ - rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ - done; \ - else \ - : ; \ - fi -uninstall-data-no: -uninstall-data-yes: - catalogs='$(CATALOGS)'; \ - for cat in $$catalogs; do \ - cat=`basename $$cat`; \ - lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ - for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ - rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ - done; \ - done - -check: all - -info dvi ps pdf html tags TAGS ctags CTAGS ID: - -mostlyclean: - rm -f remove-potcdate.sed - rm -f stamp-poT - rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po - rm -fr *.o - -clean: mostlyclean - -distclean: clean - rm -f Makefile Makefile.in POTFILES *.mo - -maintainer-clean: distclean - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - rm -f stamp-po $(GMOFILES) - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) -dist distdir: - $(MAKE) update-po - @$(MAKE) dist2 -# This is a separate target because 'update-po' must be executed before. -dist2: stamp-po $(DISTFILES) - dists="$(DISTFILES)"; \ - if test "$(PACKAGE)" = "gettext-tools"; then \ - dists="$$dists Makevars.template"; \ - fi; \ - if test -f $(srcdir)/$(DOMAIN).pot; then \ - dists="$$dists $(DOMAIN).pot stamp-po"; \ - fi; \ - if test -f $(srcdir)/ChangeLog; then \ - dists="$$dists ChangeLog"; \ - fi; \ - for i in 0 1 2 3 4 5 6 7 8 9; do \ - if test -f $(srcdir)/ChangeLog.$$i; then \ - dists="$$dists ChangeLog.$$i"; \ - fi; \ - done; \ - if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ - for file in $$dists; do \ - if test -f $$file; then \ - cp -p $$file $(distdir) || exit 1; \ - else \ - cp -p $(srcdir)/$$file $(distdir) || exit 1; \ - fi; \ - done - -update-po: Makefile - $(MAKE) $(DOMAIN).pot-update - test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) - $(MAKE) update-gmo - -# General rule for creating PO files. - -.nop.po-create: - @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ - echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ - exit 1 - -# General rule for updating PO files. - -.nop.po-update: - @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ - if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ - tmpdir=`pwd`; \ - echo "$$lang:"; \ - test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ - echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ - cd $(srcdir); \ - if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ - $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ - *) \ - $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ - esac; \ - }; then \ - if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "msgmerge for $$lang.po failed!" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi - -$(DUMMYPOFILES): - -update-gmo: Makefile $(GMOFILES) - @: - -# Recreate Makefile by invoking config.status. Explicitly invoke the shell, -# because execution permission bits may not work on the current file system. -# Use @SHELL@, which is the shell determined by autoconf for the use by its -# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. -Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ - cd $(top_builddir) \ - && @SHELL@ ./config.status $(subdir)/$@.in po-directories - -force: - -# Tell versions [3.59,3.63) of GNU make not to export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/po/Makevars b/po/Makevars deleted file mode 100644 index 44857b1b8..000000000 --- a/po/Makevars +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile variables for PO directory in any package using GNU gettext. - -# Usually the message domain is the same as the package name. -DOMAIN = $(PACKAGE) - -# These two variables depend on the location of this directory. -subdir = po -top_builddir = .. - -# These options get passed to xgettext. -XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ - -# This is the copyright holder that gets inserted into the header of the -# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding -# package. (Note that the msgstr strings, extracted from the package's -# sources, belong to the copyright holder of the package.) Translators are -# expected to transfer the copyright for their translations to this person -# or entity, or to disclaim their copyright. The empty string stands for -# the public domain; in this case the translators are expected to disclaim -# their copyright. -COPYRIGHT_HOLDER = Free Software Foundation, Inc. - -# This is the email address or URL to which the translators shall report -# bugs in the untranslated strings: -# - Strings which are not entire sentences, see the maintainer guidelines -# in the GNU gettext documentation, section 'Preparing Strings'. -# - Strings which use unclear terms or require additional context to be -# understood. -# - Strings which make invalid assumptions about notation of date, time or -# money. -# - Pluralisation problems. -# - Incorrect English spelling. -# - Incorrect formatting. -# It can be your email address, or a mailing list address where translators -# can write to without being subscribed, or the URL of a web page through -# which the translators can contact you. -MSGID_BUGS_ADDRESS = bug-grub@gnu.org - -# This is the list of locale categories, beyond LC_MESSAGES, for which the -# message catalogs shall be used. It is usually empty. -EXTRA_LOCALE_CATEGORIES = diff --git a/po/Rules-quot b/po/Rules-quot deleted file mode 100644 index af5248792..000000000 --- a/po/Rules-quot +++ /dev/null @@ -1,47 +0,0 @@ -# Special Makefile rules for English message catalogs with quotation marks. - -DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot - -.SUFFIXES: .insert-header .po-update-en - -en@quot.po-create: - $(MAKE) en@quot.po-update -en@boldquot.po-create: - $(MAKE) en@boldquot.po-update - -en@quot.po-update: en@quot.po-update-en -en@boldquot.po-update: en@boldquot.po-update-en - -.insert-header.po-update-en: - @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ - if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ - tmpdir=`pwd`; \ - echo "$$lang:"; \ - ll=`echo $$lang | sed -e 's/@.*//'`; \ - LC_ALL=C; export LC_ALL; \ - cd $(srcdir); \ - if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ - if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ - rm -f $$tmpdir/$$lang.new.po; \ - else \ - if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ - :; \ - else \ - echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ - exit 1; \ - fi; \ - fi; \ - else \ - echo "creation of $$lang.po failed!" 1>&2; \ - rm -f $$tmpdir/$$lang.new.po; \ - fi - -en@quot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header - -en@boldquot.insert-header: insert-header.sin - sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header - -mostlyclean: mostlyclean-quot -mostlyclean-quot: - rm -f *.insert-header 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/exclude.pot b/po/exclude.pot index 0a9b215ea..816089c30 100644 --- a/po/exclude.pot +++ b/po/exclude.pot @@ -1214,6 +1214,7 @@ msgstr "" #: grub-core/commands/xnu_uuid.c:75 grub-core/fs/jfs.c:924 #: grub-core/fs/nilfs2.c:1135 +#: grub-core/fs/f2fs.c:1259 #, c-format msgid "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" msgstr "" 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 1d01d1f59..70646a24e 100644 --- a/tests/ahci_test.in +++ b/tests/ahci_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 c55d9477f..0d098c9a2 100644 --- a/tests/btrfs_test.in +++ b/tests/btrfs_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -7,17 +7,18 @@ 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 "@builddir@/grub-fs-tester" btrfs_zlib "@builddir@/grub-fs-tester" btrfs_lzo +"@builddir@/grub-fs-tester" btrfs_zstd "@builddir@/grub-fs-tester" btrfs_raid0 "@builddir@/grub-fs-tester" btrfs_raid1 "@builddir@/grub-fs-tester" btrfs_single diff --git a/tests/cdboot_test.in b/tests/cdboot_test.in index 1cc901977..f00cdec58 100644 --- a/tests/cdboot_test.in +++ b/tests/cdboot_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 1003587cc..24a811418 100644 --- a/tests/core_compress_test.in +++ b/tests/core_compress_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 0b09db549..e2e668cf6 100644 --- a/tests/cpio_test.in +++ b/tests/cpio_test.in @@ -1,10 +1,10 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ 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 7dd8d3e8f..bf823a5de 100644 --- a/tests/ehci_test.in +++ b/tests/ehci_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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/example_scripted_test.in b/tests/example_scripted_test.in index 09633e893..783b7f138 100644 --- a/tests/example_scripted_test.in +++ b/tests/example_scripted_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e true diff --git a/tests/exfat_test.in b/tests/exfat_test.in index fc1a0fe5e..7939f25d2 100644 --- a/tests/exfat_test.in +++ b/tests/exfat_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.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 c986960a8..4df696710 100644 --- a/tests/ext234_test.in +++ b/tests/ext234_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -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 @@ -30,3 +30,4 @@ fi "@builddir@/grub-fs-tester" ext3 "@builddir@/grub-fs-tester" ext4 "@builddir@/grub-fs-tester" ext4_metabg +"@builddir@/grub-fs-tester" ext4_encrypt diff --git a/tests/f2fs_test.in b/tests/f2fs_test.in new file mode 100644 index 000000000..85f8cc8bc --- /dev/null +++ b/tests/f2fs_test.in @@ -0,0 +1,19 @@ +#!@BUILD_SHEBANG@ + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 99 +fi + +if ! which mkfs.f2fs >/dev/null 2>&1; then + echo "mkfs.f2fs not installed; cannot test f2fs." + exit 99 +fi + + +"@builddir@/grub-fs-tester" f2fs diff --git a/tests/fat_test.in b/tests/fat_test.in index 1d132b517..8a2b37c5c 100644 --- a/tests/fat_test.in +++ b/tests/fat_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.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 a59645b7f..6ef49efcb 100644 --- a/tests/fddboot_test.in +++ b/tests/fddboot_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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/file_filter_test.in b/tests/file_filter_test.in index 8909e4021..ed6abcb5a 100644 --- a/tests/file_filter_test.in +++ b/tests/file_filter_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2014 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -19,7 +19,7 @@ grubshell=@builddir@/grub-shell . "@builddir@/grub-core/modinfo.sh" -filters="gzio xzio lzopio verify" +filters="gzio xzio lzopio pgp" modules="cat mpi" for mod in $(cut -d ' ' -f 2 "@builddir@/grub-core/crypto.lst" | sort -u); do diff --git a/tests/gettext_strings_test.in b/tests/gettext_strings_test.in index 5c305e75b..1c37fe41b 100644 --- a/tests/gettext_strings_test.in +++ b/tests/gettext_strings_test.in @@ -1,8 +1,8 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ 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 a459353e8..4903ad6cc 100644 --- a/tests/grub_cmd_date.in +++ b/tests/grub_cmd_date.in @@ -1,15 +1,16 @@ -#! /bin/bash +#! @BUILD_SHEBANG@ set -e . "@builddir@/grub-core/modinfo.sh" # 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` +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_regexp.in b/tests/grub_cmd_regexp.in index e7e625701..6520bd6d7 100644 --- a/tests/grub_cmd_regexp.in +++ b/tests/grub_cmd_regexp.in @@ -1,4 +1,4 @@ -#! /bin/bash +#! @BUILD_SHEBANG@ set -e # Run GRUB script in a Qemu instance diff --git a/tests/grub_cmd_set_date.in b/tests/grub_cmd_set_date.in index c594ae3fc..17673cd8a 100644 --- a/tests/grub_cmd_set_date.in +++ b/tests/grub_cmd_set_date.in @@ -1,4 +1,4 @@ -#! /bin/bash +#! @BUILD_SHEBANG@ set -e . "@builddir@/grub-core/modinfo.sh" @@ -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_dollar.in b/tests/grub_script_dollar.in index 2e076427a..392fe2e7a 100644 --- a/tests/grub_script_dollar.in +++ b/tests/grub_script_dollar.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ set -e @builddir@/grub-script-check << EOF 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 e46401c4c..98d5a9068 100644 --- a/tests/grub_script_expansion.in +++ b/tests/grub_script_expansion.in @@ -1,4 +1,4 @@ -#! /bin/bash +#! @BUILD_SHEBANG@ set -e # Run GRUB script in a Qemu instance @@ -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/grub_script_final_semicolon.in b/tests/grub_script_final_semicolon.in index 3ac26540b..f17a9bf95 100644 --- a/tests/grub_script_final_semicolon.in +++ b/tests/grub_script_final_semicolon.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ set -e @builddir@/grub-script-check </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 c229716a6..764e0da1c 100644 --- a/tests/hddboot_test.in +++ b/tests/hddboot_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 e780924ef..9c8ca52c8 100644 --- a/tests/help_test.in +++ b/tests/help_test.in @@ -1,4 +1,4 @@ -#! /bin/bash +#! @BUILD_SHEBANG@ set -e . "@builddir@/grub-core/modinfo.sh" @@ -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 e3e88f190..960f1cbd0 100644 --- a/tests/hfs_test.in +++ b/tests/hfs_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -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 f947c4a44..f727cf0e2 100644 --- a/tests/hfsplus_test.in +++ b/tests/hfsplus_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.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 fdcc9e124..a1f752adf 100644 --- a/tests/iso9660_test.in +++ b/tests/iso9660_test.in @@ -1,10 +1,10 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ 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 c2e5ecedd..d13780e23 100644 --- a/tests/jfs_test.in +++ b/tests/jfs_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.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 41984c254..915f74bd9 100644 --- a/tests/lzocompress_test.in +++ b/tests/lzocompress_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 1784b1261..c62f56c8b 100644 --- a/tests/minixfs_test.in +++ b/tests/minixfs_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -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 c757023d9..510c9c34b 100644 --- a/tests/netboot_test.in +++ b/tests/netboot_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 780b60ec1..8cc93754c 100644 --- a/tests/nilfs2_test.in +++ b/tests/nilfs2_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.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 e25c6384a..c2b08d27f 100644 --- a/tests/ntfs_test.in +++ b/tests/ntfs_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -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 7fede6f26..a40d3bc0a 100644 --- a/tests/ohci_test.in +++ b/tests/ohci_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 f8dc456fb..4138e88fe 100644 --- a/tests/partmap_test.in +++ b/tests/partmap_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ set -e # Copyright (C) 2010 Free Software Foundation, Inc. @@ -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 c1d0f63ea..4d0e7d573 100644 --- a/tests/pata_test.in +++ b/tests/pata_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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/printf_unit_test.c b/tests/printf_unit_test.c index d7b12c6db..098c29fd9 100644 --- a/tests/printf_unit_test.c +++ b/tests/printf_unit_test.c @@ -23,6 +23,10 @@ #define MSG "printf test failed: %s, %s", real, expected +#if defined(__GNUC__) && __GNUC__ >= 7 +#pragma GCC diagnostic ignored "-Wformat-truncation=" +#endif + static void printf_test (void) { diff --git a/tests/pseries_test.in b/tests/pseries_test.in index 226494593..9b4090cf5 100644 --- a/tests/pseries_test.in +++ b/tests/pseries_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 678efe7b3..37226c01b 100644 --- a/tests/reiserfs_test.in +++ b/tests/reiserfs_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -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 83e09315a..f968e9b7d 100644 --- a/tests/romfs_test.in +++ b/tests/romfs_test.in @@ -1,10 +1,10 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ 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 ec34e0108..15e70218f 100644 --- a/tests/squashfs_test.in +++ b/tests/squashfs_test.in @@ -1,10 +1,10 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ 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/ubuntu10.04_grub.cfg.in b/tests/syslinux/ubuntu10.04_grub.cfg.in index 846e4acf0..441dec045 100644 --- a/tests/syslinux/ubuntu10.04_grub.cfg.in +++ b/tests/syslinux/ubuntu10.04_grub.cfg.in @@ -41,7 +41,7 @@ menuentry 'Test memory' --hotkey 'm' --id 'memtest' { linux$linux_suffix '/'/'/install/mt86plus' } menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' { -# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/gtk.cfg not found +# File (host)/@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/gtk.cfg not found # UNSUPPORTED command 'menu begin advanced' # UNSUPPORTED command 'menu title Advanced options' # UNSUPPORTED command 'menu color title * #FFFFFFFF *' @@ -63,14 +63,14 @@ menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' { } menuentry 'Back..' --hotkey 'b' --id 'mainmenu' { # UNSUPPORTED command 'menu exit' -# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/adgtk.cfg not found +# File (host)/@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/adgtk.cfg not found # UNSUPPORTED command 'menu end' # UNSUPPORTED entry type 0 true; } menuentry 'Help' --hotkey 'h' --id 'help' { # UNSUPPORTED command 'ui gfxboot bootlogo' -#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux'/'prompt.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg: +#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux'/'prompt.cfg' (host)@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg: background_image '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'splash.png' # UNSUPPORTED command 'display f1.txt' # UNSUPPORTED command 'menu hshift 13' @@ -114,7 +114,7 @@ menuentry 'Test memory' --hotkey 'm' --id 'memtest' { linux$linux_suffix '/'/'/install/mt86plus' } menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' { -# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//gtk.cfg not found +# File (host)/@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//gtk.cfg not found # UNSUPPORTED command 'menu begin advanced' # UNSUPPORTED command 'menu title Advanced options' # UNSUPPORTED command 'menu color title * #FFFFFFFF *' @@ -136,13 +136,13 @@ menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' { } menuentry 'Back..' --hotkey 'b' --id 'mainmenu' { # UNSUPPORTED command 'menu exit' -# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//adgtk.cfg not found +# File (host)/@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//adgtk.cfg not found # UNSUPPORTED command 'menu end' # UNSUPPORTED entry type 0 true; } menuentry 'Help' --hotkey 'h' --id 'help' { -#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'prompt.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg: +#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'prompt.cfg' (host)@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg: syslinux_configfile -r '/'/'/' -c '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'' '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'prompt.cfg' } menuentry 'menu' --id 'menu' { @@ -156,7 +156,7 @@ menuentry 'menu' --id 'menu' { # UNSUPPORTED command 'f8 f8.txt' # UNSUPPORTED command 'f9 f9.txt' # UNSUPPORTED command 'f0 f10.txt' -#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'isolinux.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/isolinux.cfg: +#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/'/'isolinux.cfg' (host)@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/isolinux.cfg: background_image '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'splash.png' # D-I config version 2.0 # UNSUPPORTED command 'menu hshift 13' @@ -200,7 +200,7 @@ menuentry 'Test memory' --hotkey 'm' --id 'memtest' { linux$linux_suffix '/'/'/install/mt86plus' } menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' { -# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux///gtk.cfg not found +# File (host)/@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux///gtk.cfg not found # UNSUPPORTED command 'menu begin advanced' # UNSUPPORTED command 'menu title Advanced options' # UNSUPPORTED command 'menu color title * #FFFFFFFF *' @@ -222,14 +222,14 @@ menuentry 'Boot from first hard disk' --hotkey 'b' --id 'hd' { } menuentry 'Back..' --hotkey 'b' --id 'mainmenu' { # UNSUPPORTED command 'menu exit' -# File (host)/@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux///adgtk.cfg not found +# File (host)/@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux///adgtk.cfg not found # UNSUPPORTED command 'menu end' # UNSUPPORTED entry type 0 true; } menuentry 'Help' --hotkey 'h' --id 'help' { # UNSUPPORTED command 'ui gfxboot bootlogo' -#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'prompt.cfg' (host)@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg: +#'@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'prompt.cfg' (host)@simplified_abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux/prompt.cfg: syslinux_configfile -r '/'/'/' -c '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'' '@abs_top_srcdir@/tests/syslinux/ubuntu10.04/isolinux//'/'prompt.cfg' } } diff --git a/tests/syslinux_test.in b/tests/syslinux_test.in index fc4edd8ef..44d3cdf7a 100644 --- a/tests/syslinux_test.in +++ b/tests/syslinux_test.in @@ -1,8 +1,8 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ 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 46ba3bce2..97944b243 100644 --- a/tests/tar_test.in +++ b/tests/tar_test.in @@ -1,10 +1,10 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ 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 d5ef7f9ea..b2bd89609 100644 --- a/tests/test_sha512sum.in +++ b/tests/test_sha512sum.in @@ -1,7 +1,8 @@ -#! /bin/bash +#! @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 fe244e2bd..302b28ab2 100644 --- a/tests/udf_test.in +++ b/tests/udf_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 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 89e2c1805..de199a281 100644 --- a/tests/uhci_test.in +++ b/tests/uhci_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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="-usb -usbdevice disk:$imgfile" | 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 2337771a1..cac58dafa 100644 --- a/tests/util/grub-fs-tester.in +++ b/tests/util/grub-fs-tester.in @@ -1,20 +1,92 @@ -#!/bin/bash +#!@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 () { LC_ALL=C "$GRUBFSTEST" "$@" } +range() { + range_counter="$1" + while test "$range_counter" -le "$2"; do + echo "$range_counter" + range_counter="$((range_counter + $3))" + done +} + +powrange() { + range_counter="$1" + while test "$range_counter" -le "$2"; do + echo "$range_counter" + range_counter="$((range_counter * 2))" + done +} + run_grubfstest () { - run_it -c $NEED_IMAGES_N "${NEED_IMAGES[@]}" "$@" + need_images= + for i in $(range 0 $((NEED_IMAGES_N-1)) 1); do + need_images="$need_images $FSIMAGEP${i}.img"; + done + + 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 @@ -22,36 +94,38 @@ 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 -for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 1)); do +for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do SECSIZE="$((1 << LOGSECSIZE))" MINBLKSIZE=512 MAXBLKSIZE=512 @@ -71,7 +145,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + ;; 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) @@ -100,41 +174,49 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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 + ;; xext*) MINBLKSIZE=1024 if [ $MINBLKSIZE -lt $SECSIZE ]; then @@ -145,9 +227,13 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + xsquash*) MINBLKSIZE=4096 MAXBLKSIZE=1048576;; - xxfs) + 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 @@ -161,15 +247,20 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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 - for ((BLKSIZE=MINBLKSIZE;BLKSIZE<=MAXBLKSIZE;BLKSIZE=BLKSTEP?BLKSIZE+BLKSTEP:2*BLKSIZE)); do + if test "$BLKSTEP" -eq 0; then + blksizes="$(powrange "$MINBLKSIZE" "$MAXBLKSIZE")" + else + blksizes="$(range "$MINBLKSIZE" "$MAXBLKSIZE" "$BLKSTEP")" + fi + for BLKSIZE in $blksizes; do MAXDEVICES=1 MINDEVICES=1 export fs @@ -199,38 +290,32 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + MAXDEVICES=7;; esac - for ((NDEVICES=MINDEVICES; NDEVICES <= MAXDEVICES; NDEVICES++)); do + for NDEVICES in $(range "$MINDEVICES" "$MAXDEVICES" 1); do export NDEVICES - unset FSIMAGES - for ((i=0; i < NDEVICES; i++)); do - FSIMAGES[i]="${tempdir}/${fs}_${SECSIZE}_${BLKSIZE}_${NDEVICES}_$i.img" - done - export FSIMAGES + unset FSIMAGEP + FSIMAGEP="${tempdir}/${fs}_${SECSIZE}_${BLKSIZE}_${NDEVICES}_" + export FSIMAGEP 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));; *) NEED_IMAGES_N=$NDEVICES;; esac - for ((i=0;i < NEED_IMAGES_N; i++)); do - NEED_IMAGES[i]="${FSIMAGES[i]}"; - done export NEED_IMAGES_N - export NEED_IMAGES MNTPOINTRO="${tempdir}/${fs}_ro" MNTPOINTRW="${tempdir}/${fs}_rw" @@ -238,86 +323,97 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + MOUNTFS="$fs" MASTER="${tempdir}/master" FSLABEL="grub_;/testé莭莽茝😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfew" - CFILESN=1 - if test -f /usr/share/dict/american-english; then - CFILESSRC[0]="/usr/share/dict/american-english" - else - CFILESSRC[0]="/usr/share/dict/linux.words" + CFILESRC= + for cand in /usr/share/dict/american-english /usr/share/dict/linux.words /data/data/com.termux/files/usr/share/hunspell/en_US.dic; do + if test -f "$cand" ; then + CFILESRC="$cand" + break + fi + done + if test "$CFILESRC" = "" ; then + echo "Couldn't find compressible file" >&2 + exit 99 fi case x"$fs" in - # FS LIMITATION: 8.3 names + # FS LIMITATION: 8.3 names xmsdos*) - CFILES[0]="american.eng";; + CFILE="american.eng";; xiso9660) - CFILES[0]="american_english";; + CFILE="american_english";; *) - CFILES[0]="american-english";; + 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: exfat is at most 15 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 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 @@ -327,7 +423,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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) @@ -363,7 +459,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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 @@ -388,16 +484,16 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + ;; x"vfat16" | xmsdos16) BIGBLOCKCNT=$((25000 * BLKSIZE)) - if [ $BIGBLOCKCNT -gt $((16#ffffffff)) ]; then - BIGBLOCKCNT=$((16#ffffffff)) + if [ $BIGBLOCKCNT -gt 4294967295 ]; then + BIGBLOCKCNT=4294967295 fi ;; x"minix") 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 @@ -405,50 +501,50 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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=$((16#ffffffff));; + 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`";; @@ -462,78 +558,84 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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"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 @@ -542,19 +644,19 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + PDIR="" - # OS LIMITATION: Limited by PATH_MAX (usually 1024) - for ((i=0;i /dev/null - LODEVICES[i]=`losetup -f` - losetup "${LODEVICES[i]}" "${FSIMAGES[i]}" + 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") || exit 99 + LODEVICES="$LODEVICES $LODEVICE" + if test "$i" = 0; then + MOUNTDEVICE="$LODEVICE" + fi done ;; esac - MOUNTDEVICE="${LODEVICES[0]}" case x"$fs" in x"afs") ;; x"btrfs") - "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${LODEVICES[0]}" ;; - x"btrfs_zlib" | x"btrfs_lzo") - "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${LODEVICES[0]}" + "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}" ;; + x"btrfs_zlib" | x"btrfs_lzo" | x"btrfs_zstd") + "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}" MOUNTOPTS="compress=${fs/btrfs_/}," MOUNTFS="btrfs" ;; x"btrfs_raid0") - "mkfs.btrfs" -s $SECSIZE -d raid0 -m raid0 -L "$FSLABEL" "${LODEVICES[@]}" + "mkfs.btrfs" -s $SECSIZE -d raid0 -m raid0 -L "$FSLABEL" $LODEVICES MOUNTFS="btrfs" ;; x"btrfs_raid1") - "mkfs.btrfs" -s $SECSIZE -d raid1 -m raid1 -L "$FSLABEL" "${LODEVICES[@]}" + "mkfs.btrfs" -s $SECSIZE -d raid1 -m raid1 -L "$FSLABEL" $LODEVICES MOUNTFS="btrfs" ;; x"btrfs_raid10") - "mkfs.btrfs" -s $SECSIZE -d raid10 -m raid10 -L "$FSLABEL" "${LODEVICES[@]}" + "mkfs.btrfs" -s $SECSIZE -d raid10 -m raid10 -L "$FSLABEL" $LODEVICES MOUNTFS="btrfs" ;; x"btrfs_single") - "mkfs.btrfs" -s $SECSIZE -d single -L "$FSLABEL" "${LODEVICES[@]}" + "mkfs.btrfs" -s $SECSIZE -d single -L "$FSLABEL" $LODEVICES MOUNTFS="btrfs" ;; x"exfat") - "mkfs.$fs" -s $((BLKSIZE/512)) -n "$FSLABEL" "${LODEVICES[0]}" + "mkfs.$fs" -c $SECSIZE -L "$FSLABEL" "${MOUNTDEVICE}" MOUNTOPTS="iocharset=utf8," MOUNTFS="exfat-fuse";; x"minix") - "mkfs.minix" "${LODEVICES[0]}" + "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" "${LODEVICES[0]}" - dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#468)) conv=notrunc count=8 ;; + "mkfs.hfsplus" -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}" + dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x468)) conv=notrunc count=8 ;; x"hfsplus_wrap") - "mkfs.hfsplus" -w -b $BLKSIZE -v "$FSLABEL" "${LODEVICES[0]}" - dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#468)) conv=notrunc count=8 + "mkfs.hfsplus" -w -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}" + 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" "${LODEVICES[0]}" - dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#468)) conv=notrunc count=8 + "mkfs.hfsplus" -s -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}" + 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 "${LODEVICES[0]}" - dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#474)) conv=notrunc count=8 + "mkfs.hfs" -b $BLKSIZE -v "`echo $FSLABEL |recode utf8..macroman`" -h "${MOUNTDEVICE}" + dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x474)) conv=notrunc count=8 MOUNTOPTS="iocharset=utf8,codepage=macroman," ;; x"vfat"*|xmsdos*) @@ -643,98 +747,98 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else A= fi - "mkfs.vfat" -a $A -S $SECSIZE -s $((BLKSIZE/SECSIZE)) -F "${BITS:0:2}" -n "$FSLABEL" "${FSIMAGES[0]}" + "mkfs.vfat" -a $A -S $SECSIZE -s $((BLKSIZE/SECSIZE)) -F "${BITS:0:2}" -n "$FSLABEL" "${MOUNTDEVICE}" MOUNTOPTS="iocharset=utf8,codepage=437," MOUNTFS="$(echo "$fs"|sed 's,[0-9]*a\?$,,')";; x"minix2") - "mkfs.minix" -v "${LODEVICES[0]}" + "mkfs.minix" -v "${MOUNTDEVICE}" MOUNTFS="minix";; x"minix3") - "mkfs.minix" -B $BLKSIZE -3 "${LODEVICES[0]}" + "mkfs.minix" -3 "${MOUNTDEVICE}" MOUNTFS="minix";; x"ntfs"*) - "mkfs.ntfs" -s "$SECSIZE" -c "$BLKSIZE" -L "$FSLABEL" -Q -q "${LODEVICES[0]}" + "mkfs.ntfs" -s "$SECSIZE" -c "$BLKSIZE" -L "$FSLABEL" -Q -q "${MOUNTDEVICE}" MOUNTOPTS="iocharset=utf8,compression," MOUNTFS="ntfs-3g";; x"udf") - "mkudffs" --utf8 -b $BLKSIZE --lvid="$FSLABEL" "${LODEVICES[0]}" + "mkudffs" --utf8 -b $BLKSIZE --lvid="$FSLABEL" "${MOUNTDEVICE}" MOUNTOPTS="iocharset=utf8,bs=$BLKSIZE,";; x"ufs2") - "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 2 "${LODEVICES[0]}" + "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 2 "${MOUNTDEVICE}" MOUNTOPTS="ufstype=ufs2," MOUNTFS="ufs";; x"ufs1") - "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${LODEVICES[0]}" + "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${MOUNTDEVICE}" MOUNTOPTS="ufstype=44bsd," MOUNTFS="ufs";; x"ufs1_sun") - "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${LODEVICES[0]}" + "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${MOUNTDEVICE}" MOUNTOPTS="ufstype=sun," MOUNTFS="ufs";; x"zfs") - "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[0]}" + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}" sleep 1 "zfs" create "$FSLABEL"/"grub fs" sleep 1;; x"zfs_caseins") - "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[0]}" + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${MOUNTDEVICE}" sleep 1 "zfs" create -o casesensitivity=insensitive "$FSLABEL"/"grub fs" sleep 1;; - x"zfs_lzjb" | xzfs_gzip | xzfs_zle) - "zpool" create -O compression=${fs/zfs_/} -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[0]}" + 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" sleep 1;; x"zfs_raidz") - "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz1 "${LODEVICES[@]}" + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz1 $LODEVICES sleep 1 "zfs" create "$FSLABEL"/"grub fs" sleep 1;; x"zfs_raidz2") - "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz2 "${LODEVICES[@]}" + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz2 $LODEVICES sleep 1 "zfs" create "$FSLABEL"/"grub fs" sleep 1;; x"zfs_raidz3") - "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz3 "${LODEVICES[@]}" + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz3 $LODEVICES sleep 1 "zfs" create "$FSLABEL"/"grub fs" sleep 1;; x"zfs_mirror") - "zpool" create -R "$MNTPOINTRW" "$FSLABEL" mirror "${LODEVICES[@]}" + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" mirror $LODEVICES sleep 1 "zfs" create "$FSLABEL"/"grub fs" sleep 1;; x"zfs_stripe") - "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[@]}" + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" $LODEVICES 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 "${LODEVICES[0]}" ;; + "mkfs.reiserfs" --format=3.6 -b $BLKSIZE -l "$FSLABEL" -q "${MOUNTDEVICE}" ;; x"reiserfs_old") - "mkfs.reiserfs" --format=3.5 -b $BLKSIZE -l "$FSLABEL" -q "${LODEVICES[0]}" + "mkfs.reiserfs" --format=3.5 -b $BLKSIZE -l "$FSLABEL" -q "${MOUNTDEVICE}" MOUNTFS=reiserfs;; x"jfs") - "mkfs.jfs" -L "$FSLABEL" -q "${LODEVICES[0]}" + "mkfs.jfs" -L "$FSLABEL" -q "${MOUNTDEVICE}" MOUNTOPTS="iocharset=utf8,";; x"jfs_caseins") - "mkfs.jfs" -O -L "$FSLABEL" -q "${LODEVICES[0]}" + "mkfs.jfs" -O -L "$FSLABEL" -q "${MOUNTDEVICE}" MOUNTFS=jfs MOUNTOPTS="iocharset=utf8,";; x"mdraid"*) - mdadm -C --chunk=$((BLKSIZE/1024)) --force -e "${fs:6:1}.${fs:7:1}" "/dev/md/${fs}_${NDEVICES}" --level="${fs:13}" --raid-devices="$NDEVICES" "${LODEVICES[@]}" + mdadm -C --chunk=$((BLKSIZE/1024)) --force -e "${fs:6:1}.${fs:7:1}" "/dev/md/${fs}_${NDEVICES}" --level="${fs:13}" --raid-devices="$NDEVICES" $LODEVICES MOUNTDEVICE="/dev/md/${fs}_${NDEVICES}" MOUNTFS=ext2 "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; x"lvm"*) - for ((i=0;i^{_}[]\`|~." 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="Ελκάкиéà😁öäëñ" @@ -821,21 +937,21 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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" ;; @@ -862,35 +978,51 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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 echo "MOUNT FAILED." - for ((i=0; i < NDEVICES; i++)); do - while ! losetup -d "${LODEVICES[i]}"; do + for lodev in $LODEVICES; do + while ! losetup -d "$lodev"; do sleep 1 done - rm "${FSIMAGES[i]}" 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) @@ -915,36 +1047,28 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + esac # Make sure file is not exact multiple of block size. This helps to force # tail packing in case of squash4. - : $((BLOCKCNT--)) + BLOCKCNT="$((BLOCKCNT-1))" case x"$fs" in 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 "${CFILESSRC[0]}" "$MNTPOINTRW/$OSDIR/${CFILES[0]}" &> /dev/null; - else - for ((i=0;i<$CFILESN;i++)); do - cp "${CFILESSRC[i]}" "$MNTPOINTRW/$OSDIR/${CFILES[i]}"; - done + "$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" @@ -968,49 +1092,80 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + sleep 2 ;; x"tarfs") - (cd "$MASTER"; tar cf "${FSIMAGES[0]}" .) ;; + (cd "$MASTER"; tar cf "${FSIMAGEP}0.img" .) ;; x"cpio_"*) - (cd "$MASTER"; find . | cpio -o -H "${fs/cpio_/}" > "${FSIMAGES[0]}" ) ;; + (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 "${FSIMAGES[0]}" -- -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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" /="$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 "${FSIMAGES[0]}" -d "$MASTER" ;; + genromfs -V "$FSLABEL" -f "${FSIMAGEP}0.img" -d "$MASTER" ;; xsquash4_*) - echo mksquashfs "$MASTER" "${FSIMAGES[0]}" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE - mksquashfs "$MASTER" "${FSIMAGES[0]}" -always-use-fragments -comp "${fs/squash4_/}" -b $BLKSIZE ;; + 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=0;try < 20; try++)); do + for try in $(range 0 20 1); do if umount "$MNTPOINTRW" ; then + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" break; fi sleep 1; @@ -1019,10 +1174,20 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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=0;try < 20; try++)); do + for try in $(range 0 20 1); do if umount "$MNTPOINTRW" ; then + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" break; fi sleep 1; @@ -1033,8 +1198,9 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + ;; *) sleep 1 - for ((try=0;try < 20; try++)); do + for try in $(range 0 20 1); do if umount "$MNTPOINTRW" ; then + MOUNTS="$(echo ${MOUNTS} | sed "s|$MNTPOINTRW||g;")" break; fi sleep 1; @@ -1061,16 +1227,29 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + ;; 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[@]}" + 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 @@ -1085,7 +1264,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo LIST FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + TZ=UTC ls -l "$MNTPOINTRO" exit 1 fi @@ -1094,7 +1273,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo NLIST FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -lA "$MNTPOINTRO" + TZ=UTC ls -lA "$MNTPOINTRO" exit 1 fi @@ -1103,7 +1282,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo ILIST FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + TZ=UTC ls -l "$MNTPOINTRO" exit 1 fi @@ -1112,28 +1291,28 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo LONG LIST FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + TZ=UTC ls -l "$MNTPOINTRO" exit 1 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 echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + TZ=UTC ls -l "$MNTPOINTRO" 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 echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + TZ=UTC ls -l "$MNTPOINTRO" exit 1 fi fi @@ -1149,7 +1328,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo DOT IN ROOTDIR FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + TZ=UTC ls -l "$MNTPOINTRO" exit 1 fi @@ -1163,7 +1342,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo DOTDOT IN ROOTDIR FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + TZ=UTC ls -l "$MNTPOINTRO" exit 1 fi ;; @@ -1180,7 +1359,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo SLIST FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/sdir" + TZ=UTC ls -l "$MNTPOINTRO/sdir" exit 1 fi @@ -1195,7 +1374,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo PLIST FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/$PDIR" + TZ=UTC ls -l "$MNTPOINTRO/$PDIR" exit 1 fi @@ -1210,7 +1389,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo DOT IN SUBDIR FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/$OSDIR/sdir" + TZ=UTC ls -l "$MNTPOINTRO/$OSDIR/sdir" exit 1 fi @@ -1225,7 +1404,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + else echo DOTDOT IN SUBDIR FAIL echo "$LSROUT" - TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/$OSDIR/ssdir" + TZ=UTC ls -l "$MNTPOINTRO/$OSDIR/ssdir" exit 1 fi @@ -1241,12 +1420,12 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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"*) - for ((i=0;i /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 - : - else - echo FSTIME FAIL - echo "$FSTIME" - echo "$LSOUT" - exit 1 + 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 + echo "$FSTIME" + echo "$LSOUT" + exit 1 + fi fi if [ x$NOHARDLINK != xy ]; then @@ -1383,7 +1569,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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 @@ -1410,11 +1596,9 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + exit 1 fi ok=true - for ((i=0;i<$CFILESN;i++)); do - if ! run_grubfstest cmp "$GRUBDIR/${CFILES[i]}" "$MNTPOINTRO/$OSDIR/${CFILES[i]}" ; then - ok=false; - fi - done + if ! run_grubfstest cmp "$GRUBDIR/${CFILE}" "$MNTPOINTRO/$OSDIR/${CFILE}" ; then + ok=false; + fi if test x$ok = xtrue; then : else @@ -1482,7 +1666,7 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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" @@ -1491,6 +1675,8 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 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 @@ -1502,16 +1688,21 @@ for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + vgchange -a n grub_test sleep 1 ;; + xluks*) + cryptsetup close --disable-locks "$DMNAME" + ;; esac - for ((i=0; i < NDEVICES; i++)); do - 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) ;; - *) - while ! losetup -d "${LODEVICES[i]}"; do + 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"erofs_"*) ;; + *) + for lodev in $LODEVICES; do + while ! losetup -d "$lodev"; do sleep 1 - done;; - esac - rm "${FSIMAGES[i]}" + done + done;; + esac + for i in $(range 0 $((NDEVICES-1)) 1); do + rm "$FSIMAGEP${i}.img" done if [ x"$fs" = x"zfs" ]; then rmdir "$MNTPOINTRW"/"grub fs" || true 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-tester.in b/tests/util/grub-shell-tester.in index 5adce0a47..8a87109b1 100644 --- a/tests/util/grub-shell-tester.in +++ b/tests/util/grub-shell-tester.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ set -e # Compares GRUB script output with BASH output. diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 814f36c6b..8baa3667a 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ set -e # Run GRUB script in a Qemu instance @@ -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,28 +509,48 @@ 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 if test -z "$debug"; then qemuopts="${qemuopts} -nographic -monitor file:/dev/null" + # SeaBIOS 1.11.0 added support for VGA emulation over a serial port. If + # this is configured in SeaBIOS, then -nographic causes some extra junk to + # end up on the serial console, which interferes with our tests. This + # 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. + # + # 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 @@ -393,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 @@ -426,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}" @@ -445,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 @@ -468,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 3807e2e5c..5e029c182 100644 --- a/tests/xfs_test.in +++ b/tests/xfs_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.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 b2bd999ec..6ef73e41e 100644 --- a/tests/xzcompress_test.in +++ b/tests/xzcompress_test.in @@ -1,4 +1,4 @@ -#! /bin/sh +#! @BUILD_SHEBANG@ # Copyright (C) 2013 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify @@ -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 047120e47..0d0a57f7d 100644 --- a/tests/zfs_test.in +++ b/tests/zfs_test.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!@BUILD_SHEBANG@ set -e @@ -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 c6f8d2298..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,20 +54,82 @@ 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, strerror (errno)); - grub_util_file_sync (fp); + if (grub_util_file_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), namenew, strerror (errno)); 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 92c0d709b..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 @@ -99,7 +99,7 @@ grub_util_pull_device (const char *os_dev) { case GRUB_DEV_ABSTRACTION_LVM: grub_util_pull_lvm_by_command (os_dev); - /* Fallthrough in case that lvm-tools are unavailable. */ + /* Fallthrough - in case that lvm-tools are unavailable. */ case GRUB_DEV_ABSTRACTION_LUKS: grub_util_pull_devmapper (os_dev); return; @@ -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 118e89fe5..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, @@ -197,7 +203,8 @@ write_envblk (const char *name, grub_envblk_t envblk) grub_util_error (_("cannot write to `%s': %s"), name, strerror (errno)); - grub_util_file_sync (fp); + if (grub_util_file_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), name, strerror (errno)); fclose (fp); } 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 a358ae471..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 @@ -120,9 +121,9 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len, void return; } - if (uncompress == 0) - grub_file_filter_disable_compression (); - file = grub_file_open (pathname); + file = grub_file_open (pathname, ((uncompress == 0) + ? GRUB_FILE_TYPE_NO_DECOMPRESS : GRUB_FILE_TYPE_NONE) + | GRUB_FILE_TYPE_FSTEST); if (!file) { grub_util_error (_("cannot open `%s': %s"), pathname, @@ -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; @@ -470,9 +480,9 @@ fstest (int n) fs = grub_fs_probe (dev); if (!fs) grub_util_error ("%s", grub_errmsg); - if (!fs->uuid) + if (!fs->fs_uuid) grub_util_error ("%s", _("couldn't retrieve UUID")); - if (fs->uuid (dev, &uuid)) + if (fs->fs_uuid (dev, &uuid)) grub_util_error ("%s", grub_errmsg); if (!uuid) grub_util_error ("%s", _("couldn't retrieve UUID")); @@ -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 452b230da..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: @@ -73,13 +73,14 @@ grub_install_help_filter (int key, const char *text, static int (*compress_func) (const char *src, const char *dest) = NULL; char *grub_install_copy_buffer; +static char *dtb; int 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); @@ -105,17 +106,22 @@ 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); if (r <= 0) break; - grub_util_fd_write (out, grub_install_copy_buffer, r); + r = grub_util_fd_write (out, grub_install_copy_buffer, r); + if (r <= 0) + break; } - grub_util_fd_sync (out); - grub_util_fd_close (in); - grub_util_fd_close (out); + if (grub_util_fd_sync (out) < 0) + r = -1; + if (grub_util_fd_close (in) < 0) + r = -1; + if (grub_util_fd_close (out) < 0) + r = -1; if (r < 0) grub_util_error (_("cannot copy `%s' to `%s': %s"), @@ -167,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; @@ -228,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) { @@ -280,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++) { @@ -301,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 @@ -331,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++; @@ -364,6 +541,11 @@ grub_install_parse (int key, char *arg) case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: handle_install_list (&install_fonts, arg, 0); return 1; + case GRUB_INSTALL_OPTIONS_DTB: + if (dtb) + free (dtb); + dtb = xstrdup (arg); + return 1; case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS: if (strcmp (arg, "no") == 0 || strcmp (arg, "none") == 0) @@ -426,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", @@ -439,57 +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' " - "--format '%s' --compression '%s' %s %s\n", - dir, prefix, - outname, 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); @@ -499,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); + note, compression, dtb, sbat, + disable_shim_lock, disable_cli); while (dc--) grub_install_pop_module (); } @@ -519,7 +719,8 @@ grub_install_make_image_wrap (const char *dir, const char *prefix, grub_install_make_image_wrap_file (dir, prefix, fp, outname, memdisk_path, config_path, mkimage_target, note); - grub_util_file_sync (fp); + if (grub_util_file_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), outname, strerror (errno)); fclose (fp); } @@ -576,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); @@ -585,6 +789,7 @@ copy_all (const char *srcd, grub_util_fd_closedir (d); } +#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) static const char * get_localedir (void) { @@ -639,6 +844,59 @@ copy_locales (const char *dstd) } grub_util_fd_closedir (d); } +#endif + +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) + char *dst_locale; + + dst_locale = grub_util_path_concat (2, dst, "locale"); + grub_install_mkdir_p (dst_locale); + clean_grub_dir (dst_locale); + + if (install_locales.is_default) + { + char *srcd = grub_util_path_concat (2, src, "po"); + copy_by_ext (srcd, dst_locale, ".mo", 0); + copy_locales (dst_locale); + free (srcd); + } + else + { + size_t i; + const char *locale_dir = get_localedir (); + + for (i = 0; i < install_locales.n_entries; i++) + { + char *srcf = grub_util_path_concat_ext (3, src, "po", + install_locales.entries[i], + ".mo"); + char *dstf = grub_util_path_concat_ext (2, dst_locale, + install_locales.entries[i], + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + free (srcf); + srcf = grub_util_path_concat_ext (4, locale_dir, + install_locales.entries[i], + "LC_MESSAGES", PACKAGE, ".mo"); + if (grub_install_compress_file (srcf, dstf, 0) == 0) + grub_util_error (_("cannot find locale `%s'"), + install_locales.entries[i]); + free (srcf); + free (dstf); + } + } + free (dst_locale); +#endif +} static struct { @@ -646,27 +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_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_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) @@ -694,7 +957,7 @@ grub_install_get_platforms_string (void) } ptr[-2] = 0; free (arr); - + return platforms_string; } @@ -723,7 +986,7 @@ grub_install_copy_files (const char *src, const char *dst, enum grub_install_plat platid) { - char *dst_platform, *dst_locale, *dst_fonts; + char *dst_platform, *dst_fonts; const char *pkgdatadir = grub_util_get_pkgdatadir (); char *themes_dir; @@ -734,13 +997,12 @@ grub_install_copy_files (const char *src, dst_platform = grub_util_path_concat (2, dst, platform); free (platform); } - dst_locale = grub_util_path_concat (2, dst, "locale"); dst_fonts = grub_util_path_concat (2, dst, "fonts"); grub_install_mkdir_p (dst_platform); - grub_install_mkdir_p (dst_locale); clean_grub_dir (dst); clean_grub_dir (dst_platform); - clean_grub_dir (dst_locale); + + grub_install_copy_nls(src, dst); if (install_modules.is_default) copy_by_ext (src, dst_platform, ".mod", 1); @@ -789,50 +1051,6 @@ grub_install_copy_files (const char *src, free (dstf); } - if (install_locales.is_default) - { - char *srcd = grub_util_path_concat (2, src, "po"); - copy_by_ext (srcd, dst_locale, ".mo", 0); - copy_locales (dst_locale); - free (srcd); - } - else - { - const char *locale_dir = get_localedir (); - - for (i = 0; i < install_locales.n_entries; i++) - { - char *srcf = grub_util_path_concat_ext (3, src, - "po", - install_locales.entries[i], - ".mo"); - char *dstf = grub_util_path_concat_ext (2, dst_locale, - install_locales.entries[i], - ".mo"); - if (grub_install_compress_file (srcf, dstf, 0)) - { - free (srcf); - free (dstf); - continue; - } - free (srcf); - srcf = grub_util_path_concat_ext (4, - locale_dir, - install_locales.entries[i], - "LC_MESSAGES", - PACKAGE, - ".mo"); - if (grub_install_compress_file (srcf, dstf, 0)) - { - free (srcf); - free (dstf); - continue; - } - grub_util_error (_("cannot find locale `%s'"), - install_locales.entries[i]); - } - } - if (install_themes.is_default) { install_themes.is_default = 0; @@ -895,7 +1113,6 @@ grub_install_copy_files (const char *src, } free (dst_platform); - free (dst_locale); free (dst_fonts); } @@ -911,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 6c89c2b0c..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)) @@ -319,11 +319,21 @@ get_default_platform (void) #elif defined (__ia64__) return "ia64-efi"; #elif defined (__arm__) - return "arm-uboot"; + return grub_install_get_default_arm_platform (); #elif defined (__aarch64__) 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 }; @@ -446,17 +456,17 @@ probe_mods (grub_disk_t disk) if (raid_level >= 0) { grub_install_push_module ("diskfilter"); - if (disk->dev->raidname) - grub_install_push_module (disk->dev->raidname (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"); /* In case of LVM/RAID, check the member devices as well. */ - if (disk->dev->memberlist) - list = disk->dev->memberlist (disk); + if (disk->dev->disk_memberlist) + list = disk->dev->disk_memberlist (disk); while (list) { probe_mods (list->disk); @@ -477,6 +487,9 @@ 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: case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: @@ -486,6 +499,7 @@ have_bootdev (enum grub_install_plat pl) case GRUB_INSTALL_PLATFORM_I386_QEMU: case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: @@ -495,6 +509,7 @@ have_bootdev (enum grub_install_plat pl) case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: return 0; /* pacify warning. */ @@ -510,9 +525,9 @@ probe_cryptodisk_uuid (grub_disk_t disk) grub_disk_memberlist_t list = NULL, tmp; /* In case of LVM/RAID, check the member devices as well. */ - if (disk->dev->memberlist) + if (disk->dev->disk_memberlist) { - list = disk->dev->memberlist (disk); + list = disk->dev->disk_memberlist (disk); } while (list) { @@ -622,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)) { @@ -684,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, @@ -713,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_type_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), @@ -736,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) { @@ -815,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[]) { @@ -870,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); @@ -898,6 +926,9 @@ 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: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: @@ -907,10 +938,12 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: break; case GRUB_INSTALL_PLATFORM_I386_QEMU: case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: @@ -941,17 +974,22 @@ 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: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_QEMU: case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: free (install_device); install_device = NULL; break; @@ -992,6 +1030,9 @@ 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: is_efi = 1; break; @@ -1004,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) @@ -1049,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"), @@ -1070,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 @@ -1105,6 +1165,15 @@ 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; + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + efi_file = "BOOTRISCV64.EFI"; + break; default: grub_util_error ("%s", _("You've found a bug")); break; @@ -1132,6 +1201,15 @@ 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; + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + efi_file = "grubriscv64.efi"; + break; default: efi_file = "grub.efi"; break; @@ -1185,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); @@ -1213,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. */ @@ -1234,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++) @@ -1295,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; @@ -1341,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) @@ -1352,8 +1432,8 @@ main (int argc, char *argv[]) { char *uuid = NULL; /* generic method (used on coreboot and ata mod). */ - if (!force_file_id && grub_fs->uuid && grub_fs->uuid (grub_dev, - &uuid)) + if (!force_file_id + && grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid)) { grub_print_error (); grub_errno = 0; @@ -1434,6 +1514,9 @@ 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: g = grub_util_guess_efi_drive (*curdev); break; @@ -1448,6 +1531,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: case GRUB_INSTALL_PLATFORM_I386_QEMU: case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: @@ -1458,6 +1542,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance")); break; /* pacify warning. */ @@ -1468,6 +1553,7 @@ main (int argc, char *argv[]) { grub_util_fprint_full_disk_name (load_cfg_f, g, dev); fprintf (load_cfg_f, " "); + free (g); } if (dev != grub_dev) grub_device_close (dev); @@ -1524,6 +1610,9 @@ 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: core_name = "core.efi"; snprintf (mkimage_target, sizeof (mkimage_target), @@ -1542,11 +1631,13 @@ main (int argc, char *argv[]) break; case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: core_name = "core.elf"; snprintf (mkimage_target, sizeof (mkimage_target), "%s-%s", @@ -1625,10 +1716,14 @@ 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: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_I386_PC: case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: @@ -1638,6 +1733,7 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: break; /* pacify warning. */ case GRUB_INSTALL_PLATFORM_MAX: @@ -1650,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, @@ -1669,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, @@ -1695,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; } @@ -1728,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)); @@ -1736,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); @@ -1770,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 { @@ -1828,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)); @@ -1836,14 +1948,20 @@ 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) { /* Try to make this image bootable using the EFI Boot Manager, if available. */ - grub_install_register_efi (efidir_grub_dev, - "\\System\\Library\\CoreServices", - efi_distributor); + int ret; + ret = grub_install_register_efi (efidir_grub_dev, + "\\System\\Library\\CoreServices", + efi_distributor); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); } grub_device_close (ins_dev); @@ -1851,18 +1969,26 @@ main (int argc, char *argv[]) free (mach_kernel); break; } + /* 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) { char * efifile_path; char * part; + int ret; /* Try to make this image bootable using the EFI Boot Manager, if available. */ if (!efi_distributor || efi_distributor[0] == '\0') @@ -1879,8 +2005,11 @@ main (int argc, char *argv[]) efidir_grub_dev->disk->name, (part ? ",": ""), (part ? : "")); grub_free (part); - grub_install_register_efi (efidir_grub_dev, - efifile_path, efi_distributor); + ret = grub_install_register_efi (efidir_grub_dev, + efifile_path, efi_distributor); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); } break; @@ -1888,12 +2017,14 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_QEMU: case GRUB_INSTALL_PLATFORM_I386_XEN: case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: grub_util_warn ("%s", _("WARNING: no platform-specific install was performed")); break; @@ -1902,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 f8496d28b..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 } @@ -134,23 +134,42 @@ fi # Device containing our userland. Typically used for root= parameter. GRUB_DEVICE="`${grub_probe} --target=device /`" GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true +GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true # Device containing our /boot partition. Usually the same as GRUB_DEVICE. 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`" if [ x"$GRUB_FS" = xunknown ]; then - GRUB_FS="$(stat -f --printf=%T / || echo unknown)" + GRUB_FS="$(stat -f -c %T / || echo unknown)" +fi + +# Provide a default set of stock linux early initrd images. +# Define here so the list can be modified in the sourced config file. +if [ "x${GRUB_EARLY_INITRD_LINUX_STOCK}" = "x" ]; then + GRUB_EARLY_INITRD_LINUX_STOCK="intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode.cpio" fi 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}" @@ -182,8 +201,10 @@ if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub # override them. export GRUB_DEVICE \ GRUB_DEVICE_UUID \ + GRUB_DEVICE_PARTUUID \ GRUB_DEVICE_BOOT \ GRUB_DEVICE_BOOT_UUID \ + GRUB_DISABLE_OS_PROBER \ GRUB_FS \ GRUB_FONT \ GRUB_PRELOAD_MODULES \ @@ -204,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 \ @@ -211,17 +233,23 @@ 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 \ GRUB_VIDEO_BACKEND \ GRUB_GFXMODE \ GRUB_BACKGROUND \ GRUB_THEME \ GRUB_GFXPAYLOAD_LINUX \ - GRUB_DISABLE_OS_PROBER \ GRUB_INIT_TUNE \ GRUB_SAVEDEFAULT \ GRUB_ENABLE_CRYPTODISK \ @@ -276,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 60b31cadd..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' @@ -188,6 +192,7 @@ grub_file_is_not_garbage () *.dpkg-*) return 1 ;; # debian dpkg *.rpmsave|*.rpmnew) return 1 ;; README*|*/README*) return 1 ;; # documentation + *.sig) return 1 ;; # signatures esac else return 1 @@ -199,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 aba19d21b..547f7310f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -71,6 +71,7 @@ static struct argp_option options[] = { N_("embed FILE as a memdisk image\n" "Implies `-p (memdisk)/boot/grub' and overrides any prefix supplied previously," " but the prefix itself can be overridden by later options"), 0}, + {"dtb", 'D', N_("FILE"), 0, N_("embed FILE as a device tree (DTB)\n"), 0}, /* TRANSLATORS: "embed" is a verb (command description). "*/ {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0}, /* TRANSLATORS: "embed" is a verb (command description). "*/ @@ -80,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 } }; @@ -117,11 +121,15 @@ struct arguments char *dir; char *prefix; char *memdisk; + char *dtb; char **pubkeys; 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; }; @@ -176,6 +184,13 @@ argp_parser (int key, char *arg, struct argp_state *state) arguments->prefix = xstrdup ("(memdisk)/boot/grub"); break; + case 'D': + if (arguments->dtb) + free (arguments->dtb); + + arguments->dtb = xstrdup (arg); + break; + case 'k': arguments->pubkeys = xrealloc (arguments->pubkeys, sizeof (arguments->pubkeys[0]) @@ -215,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; @@ -300,10 +330,16 @@ main (int argc, char *argv[]) arguments.memdisk, arguments.pubkeys, arguments.npubkeys, arguments.config, arguments.image_target, arguments.note, - arguments.comp); + arguments.comp, arguments.dtb, + arguments.sbat, arguments.disable_shim_lock, + arguments.disable_cli); - grub_util_file_sync (fp); - fclose (fp); + if (grub_util_file_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout", + strerror (errno)); + if (fclose (fp) == EOF) + grub_util_error (_("cannot close `%s': %s"), arguments.output ? : "stdout", + strerror (errno)); for (i = 0; i < arguments.nmodules; i++) free (arguments.modules[i]); @@ -315,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-mkimage32.c b/util/grub-mkimage32.c index 9b31397bc..026a2dd59 100644 --- a/util/grub-mkimage32.c +++ b/util/grub-mkimage32.c @@ -17,6 +17,10 @@ # define ELF_R_SYM(val) ELF32_R_SYM(val) # define ELF_R_TYPE(val) ELF32_R_TYPE(val) # define ELF_ST_TYPE(val) ELF32_ST_TYPE(val) -#define XEN_NOTE_SIZE 132 +#define XEN_NOTE_SIZE 132 +#define XEN_PVH_NOTE_SIZE 20 + +#ifndef GRUB_MKIMAGEXX #include "grub-mkimagexx.c" +#endif diff --git a/util/grub-mkimage64.c b/util/grub-mkimage64.c index d83345924..170defb40 100644 --- a/util/grub-mkimage64.c +++ b/util/grub-mkimage64.c @@ -17,6 +17,10 @@ # define ELF_R_SYM(val) ELF64_R_SYM(val) # define ELF_R_TYPE(val) ELF64_R_TYPE(val) # define ELF_ST_TYPE(val) ELF64_ST_TYPE(val) -#define XEN_NOTE_SIZE 120 +#define XEN_NOTE_SIZE 120 +#define XEN_PVH_NOTE_SIZE 24 + +#ifndef GRUB_MKIMAGEXX #include "grub-mkimagexx.c" +#endif diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index f8faae878..448862b2e 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -44,12 +44,24 @@ #include #include #include +#include #include #include #include +#include + #pragma GCC diagnostic ignored "-Wcast-align" +#define GRUB_MKIMAGEXX +#if !defined(MKIMAGE_ELF32) && !defined(MKIMAGE_ELF64) +#if __SIZEOF_POINTER__ == 8 +#include "grub-mkimage64.c" +#else +#include "grub-mkimage32.c" +#endif +#endif + /* These structures are defined according to the CHRP binding to IEEE1275, "Client Program Format" section. */ @@ -84,10 +96,30 @@ struct fixup_block_list #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) +struct section_metadata +{ + Elf_Half num_sections; + Elf_Shdr *sections; + Elf_Addr *addrs; + Elf_Addr *vaddrs; + Elf_Half section_entsize; + Elf_Shdr *symtab; + 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) { - return image_target->id == IMAGE_EFI || image_target->id == IMAGE_UBOOT; + return image_target->id == IMAGE_EFI || image_target->id == IMAGE_UBOOT + || (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM); } #ifdef MKIMAGE_ELF32 @@ -184,19 +216,26 @@ 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, - Elf_Addr target_addr, grub_size_t align, - size_t kernel_size, size_t bss_size) + int note, char *sbat, char **core_img, size_t *core_size, + Elf_Addr target_addr, + struct grub_mkimage_layout *layout) { char *elf_img; size_t program_size; 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; @@ -206,15 +245,15 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc phnum++; footer_size += sizeof (struct grub_ieee1275_note); } - if (image_target->id == IMAGE_XEN) + if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) { phnum++; shnum++; string_size += sizeof (".xen"); - footer_size += XEN_NOTE_SIZE; + footer_size += (image_target->id == IMAGE_XEN) ? XEN_NOTE_SIZE : XEN_PVH_NOTE_SIZE; } header_size = ALIGN_UP (sizeof (*ehdr) + phnum * sizeof (*phdr) - + shnum * sizeof (*shdr) + string_size, align); + + shnum * sizeof (*shdr) + string_size, layout->align); program_size = ALIGN_ADDR (*core_size); @@ -224,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) @@ -258,9 +298,10 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (align > image_target->link_align ? align : image_target->link_align); + 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; @@ -272,27 +313,34 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc else { grub_uint32_t target_addr_mods; - phdr->p_filesz = grub_host_to_target32 (kernel_size); - phdr->p_memsz = grub_host_to_target32 (kernel_size + bss_size); + phdr->p_filesz = grub_host_to_target32 (layout->kernel_size); + if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM) + phdr->p_memsz = grub_host_to_target32 (layout->kernel_size); + else + phdr->p_memsz = grub_host_to_target32 (layout->kernel_size + layout->bss_size); phdr++; phdr->p_type = grub_host_to_target32 (PT_GNU_STACK); - phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size); phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0; phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); phdr->p_align = grub_host_to_target32 (image_target->link_align); phdr++; phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size); phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); phdr->p_filesz = phdr->p_memsz - = grub_host_to_target32 (*core_size - kernel_size); + = grub_host_to_target32 (*core_size - layout->kernel_size); - if (image_target->id == IMAGE_COREBOOT) + if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_386) target_addr_mods = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; + else if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM) + target_addr_mods = ALIGN_UP (target_addr + layout->end + + image_target->mod_gap, + image_target->mod_align); else - target_addr_mods = ALIGN_UP (target_addr + kernel_size + bss_size + target_addr_mods = ALIGN_UP (target_addr + layout->kernel_size + layout->bss_size + image_target->mod_gap, image_target->mod_align); phdr->p_vaddr = grub_host_to_target_addr (target_addr_mods); @@ -312,7 +360,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc note_ptr = (Elf_Nhdr *) ptr; note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); note_ptr->n_descsz = grub_host_to_target32 (sizeof (PACKAGE_NAME)); - note_ptr->n_type = grub_host_to_target32 (6); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS); ptr += sizeof (Elf_Nhdr); memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); @@ -323,7 +371,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc note_ptr = (Elf_Nhdr *) ptr; note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); note_ptr->n_descsz = grub_host_to_target32 (sizeof ("generic")); - note_ptr->n_type = grub_host_to_target32 (8); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_LOADER); ptr += sizeof (Elf_Nhdr); memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); @@ -334,7 +382,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc note_ptr = (Elf_Nhdr *) ptr; note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); note_ptr->n_descsz = grub_host_to_target32 (sizeof ("xen-3.0")); - note_ptr->n_type = grub_host_to_target32 (5); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION); ptr += sizeof (Elf_Nhdr); memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); @@ -345,7 +393,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc note_ptr = (Elf_Nhdr *) ptr; note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); - note_ptr->n_type = grub_host_to_target32 (1); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_ENTRY); ptr += sizeof (Elf_Nhdr); memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); @@ -356,7 +404,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc note_ptr = (Elf_Nhdr *) ptr; note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); - note_ptr->n_type = grub_host_to_target32 (3); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE); ptr += sizeof (Elf_Nhdr); memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); @@ -369,7 +417,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc note_ptr = (Elf_Nhdr *) ptr; note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); note_ptr->n_descsz = grub_host_to_target32 (sizeof ("yes,bimodal")); - note_ptr->n_type = grub_host_to_target32 (9); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE); ptr += sizeof (Elf_Nhdr); memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); @@ -388,18 +436,55 @@ 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) + { + char *note_start = (elf_img + program_size + header_size); + Elf_Nhdr *note_ptr; + char *ptr = (char *) note_start; + + grub_util_info ("adding XEN NOTE segment"); + + /* Phys32 Entry. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memset (ptr, 0, image_target->voidp_sizeof); + *(grub_uint32_t *) ptr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR; + ptr += image_target->voidp_sizeof; + + assert (XEN_PVH_NOTE_SIZE == (ptr - note_start)); + + 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 (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); @@ -418,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); } { @@ -434,7 +543,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc shdr->sh_size = grub_host_to_target32 (string_size); shdr->sh_link = grub_host_to_target32 (0); shdr->sh_info = grub_host_to_target32 (0); - shdr->sh_addralign = grub_host_to_target32 (align); + shdr->sh_addralign = grub_host_to_target32 (layout->align); shdr->sh_entsize = grub_host_to_target32 (0); shdr++; @@ -445,10 +554,10 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); shdr->sh_addr = grub_host_to_target_addr (target_addr); shdr->sh_offset = grub_host_to_target_addr (header_size); - shdr->sh_size = grub_host_to_target32 (kernel_size); + shdr->sh_size = grub_host_to_target32 (layout->kernel_size); shdr->sh_link = grub_host_to_target32 (0); shdr->sh_info = grub_host_to_target32 (0); - shdr->sh_addralign = grub_host_to_target32 (align); + shdr->sh_addralign = grub_host_to_target32 (layout->align); shdr->sh_entsize = grub_host_to_target32 (0); shdr++; @@ -456,24 +565,27 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc shdr->sh_name = grub_host_to_target32 (ptr - str_start); ptr += sizeof ("mods"); shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); - shdr->sh_addr = grub_host_to_target_addr (target_addr + kernel_size); - shdr->sh_offset = grub_host_to_target_addr (header_size + kernel_size); - shdr->sh_size = grub_host_to_target32 (*core_size - kernel_size); + shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size); + shdr->sh_offset = grub_host_to_target_addr (header_size + layout->kernel_size); + shdr->sh_size = grub_host_to_target32 (*core_size - layout->kernel_size); shdr->sh_link = grub_host_to_target32 (0); shdr->sh_info = grub_host_to_target32 (0); shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof); shdr->sh_entsize = grub_host_to_target32 (0); shdr++; - if (image_target->id == IMAGE_XEN) + if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) { memcpy (ptr, ".xen", sizeof (".xen")); shdr->sh_name = grub_host_to_target32 (ptr - str_start); ptr += sizeof (".xen"); shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); - shdr->sh_addr = grub_host_to_target_addr (target_addr + kernel_size); + shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size); shdr->sh_offset = grub_host_to_target_addr (program_size + header_size); - shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE); + if (image_target->id == IMAGE_XEN) + shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE); + else + shdr->sh_size = grub_host_to_target32 (XEN_PVH_NOTE_SIZE); shdr->sh_link = grub_host_to_target32 (0); shdr->sh_info = grub_host_to_target32 (0); shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof); @@ -490,9 +602,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc /* Relocate symbols; note that this function overwrites the symbol table. Return the address of a start symbol. */ static Elf_Addr -SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, +SUFFIX (relocate_symbols) (Elf_Ehdr *e, struct section_metadata *smd, void *jumpers, Elf_Addr jumpers_addr, Elf_Addr bss_start, Elf_Addr end, const struct grub_install_image_target_desc *image_target) @@ -502,19 +612,18 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr start_address = (Elf_Addr) -1; Elf_Sym *sym; Elf_Word i; - Elf_Shdr *strtab_section; - const char *strtab; + Elf_Shdr *symtab_section; + const char *symtab; grub_uint64_t *jptr = jumpers; - strtab_section - = (Elf_Shdr *) ((char *) sections - + (grub_target_to_host32 (symtab_section->sh_link) - * section_entsize)); - strtab = (char *) e + grub_target_to_host (strtab_section->sh_offset); + symtab_section = (Elf_Shdr *) ((char *) smd->sections + + grub_target_to_host32 (smd->symtab->sh_link) + * smd->section_entsize); + symtab = (char *) e + grub_target_to_host (symtab_section->sh_offset); - symtab_size = grub_target_to_host (symtab_section->sh_size); - sym_size = grub_target_to_host (symtab_section->sh_entsize); - symtab_offset = grub_target_to_host (symtab_section->sh_offset); + symtab_size = grub_target_to_host (smd->symtab->sh_size); + sym_size = grub_target_to_host (smd->symtab->sh_entsize); + symtab_offset = grub_target_to_host (smd->symtab->sh_offset); num_syms = symtab_size / sym_size; for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); @@ -524,7 +633,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Section cur_index; const char *name; - name = strtab + grub_target_to_host32 (sym->st_name); + name = symtab + grub_target_to_host32 (sym->st_name); cur_index = grub_target_to_host16 (sym->st_shndx); if (cur_index == STN_ABS) @@ -542,12 +651,12 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, else continue; } - else if (cur_index >= num_sections) + else if (cur_index >= smd->num_sections) grub_util_error ("section %d does not exist", cur_index); else { sym->st_value = (grub_target_to_host (sym->st_value) - + section_addresses[cur_index]); + + smd->vaddrs[cur_index]); } if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info) @@ -562,7 +671,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG " (0x%" GRUB_HOST_PRIxLONG_LONG ")", name, (unsigned long long) sym->st_value, - (unsigned long long) section_addresses[cur_index]); + (unsigned long long) smd->vaddrs[cur_index]); if (start_address == (Elf_Addr)-1) if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) @@ -699,17 +808,19 @@ arm_get_trampoline_size (Elf_Ehdr *e, } #endif +static int +SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target); +static int +SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target, + struct section_metadata *smd); + /* Deal with relocation information. This function relocates addresses within the virtual address space starting from 0. So only relative addresses can be fully resolved. Absolute addresses must be relocated again by a PE32 relocator when loaded. */ static void -SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, - char *pe_target, Elf_Addr tramp_off, - Elf_Addr got_off, +SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, + char *pe_target, Elf_Addr tramp_off, Elf_Addr got_off, const struct grub_install_image_target_desc *image_target) { Elf_Half i; @@ -718,38 +829,44 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, 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); #endif - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || (s->sh_type == grub_host_to_target32 (SHT_RELA))) { Elf_Rela *r; Elf_Word rtab_size, r_size, num_rs; Elf_Off rtab_offset; - Elf_Shdr *symtab_section; Elf_Word target_section_index; Elf_Addr target_section_addr; Elf_Shdr *target_section; Elf_Word j; - symtab_section = (Elf_Shdr *) ((char *) sections - + (grub_target_to_host32 (s->sh_link) - * section_entsize)); + if (!SUFFIX (is_kept_section) (s, image_target) && + !SUFFIX (is_kept_reloc_section) (s, image_target, smd)) + { + grub_util_info ("not translating relocations for omitted section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + continue; + } + target_section_index = grub_target_to_host32 (s->sh_info); - target_section_addr = section_addresses[target_section_index]; - target_section = (Elf_Shdr *) ((char *) sections + target_section_addr = smd->addrs[target_section_index]; + target_section = (Elf_Shdr *) ((char *) smd->sections + (target_section_index - * section_entsize)); + * smd->section_entsize)); grub_util_info ("dealing with the relocation section %s for %s", - strtab + grub_target_to_host32 (s->sh_name), - strtab + grub_target_to_host32 (target_section->sh_name)); + smd->strtab + grub_target_to_host32 (s->sh_name), + smd->strtab + grub_target_to_host32 (target_section->sh_name)); rtab_size = grub_target_to_host (s->sh_size); r_size = grub_target_to_host (s->sh_entsize); @@ -770,7 +887,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, target = SUFFIX (get_target_address) (e, target_section, offset, image_target); info = grub_target_to_host (r->r_info); - sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + sym_addr = SUFFIX (get_symbol_address) (e, smd->symtab, ELF_R_SYM (info), image_target); addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? @@ -832,6 +949,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, break; case R_X86_64_PC32: + case R_X86_64_PLT32: { grub_uint32_t *t32 = (grub_uint32_t *) target; *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) @@ -900,13 +1018,14 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Sym *sym; sym = (Elf_Sym *) ((char *) e - + grub_target_to_host (symtab_section->sh_offset) - + ELF_R_SYM (info) * grub_target_to_host (symtab_section->sh_entsize)); + + grub_target_to_host (smd->symtab->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize)); if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target + sym->st_value - image_target->vaddr_offset)); } + /* FALLTHROUGH */ case R_IA64_LTOFF_FPTR22: *gpptr = grub_host_to_target64 (addend + sym_addr); grub_ia64_add_value_to_slot_21 ((grub_addr_t) target, @@ -1051,6 +1170,71 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, } 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: @@ -1065,7 +1249,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, (int) sym_addr, (int) sym_addr); /* Data will be naturally aligned */ if (image_target->id == IMAGE_EFI) - sym_addr += 0x400; + sym_addr += GRUB_PE32_SECTION_ALIGNMENT; *target = grub_host_to_target32 (grub_target_to_host32 (*target) + sym_addr); } break; @@ -1085,8 +1269,8 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, - (char *) e), sym_addr); sym = (Elf_Sym *) ((char *) e - + grub_target_to_host (symtab_section->sh_offset) - + ELF_R_SYM (info) * grub_target_to_host (symtab_section->sh_entsize)); + + grub_target_to_host (smd->symtab->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize)); if (ELF_ST_TYPE (sym->st_info) != STT_FUNC) sym_addr |= 1; if (!(sym_addr & 1)) @@ -1154,6 +1338,197 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, break; } #endif /* MKIMAGE_ELF32 */ + case EM_RISCV: + { + grub_uint64_t *t64 = (grub_uint64_t *) target; + 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; + + /* + * Instructions and instruction encoding are documented in the RISC-V + * specification. This file is based on version 2.2: + * + * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf + */ + + sym_addr += addend; + off = sym_addr - target_section_addr - offset - image_target->vaddr_offset; + + switch (ELF_R_TYPE (info)) + { + case R_RISCV_ADD8: + *t8 = *t8 + sym_addr; + break; + case R_RISCV_ADD16: + *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) + sym_addr); + break; + case R_RISCV_32: + case R_RISCV_ADD32: + *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) + sym_addr); + break; + case R_RISCV_64: + case R_RISCV_ADD64: + *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + sym_addr); + break; + + case R_RISCV_SUB8: + *t8 = sym_addr - *t8; + break; + case R_RISCV_SUB16: + *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) - sym_addr); + break; + case R_RISCV_SUB32: + *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) - sym_addr); + break; + case R_RISCV_SUB64: + *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) - sym_addr); + break; + case R_RISCV_BRANCH: + { + grub_uint32_t imm12 = (off & 0x1000) << (31 - 12); + grub_uint32_t imm11 = (off & 0x800) >> (11 - 7); + grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10); + grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) + | imm12 | imm11 | imm10_5 | imm4_1); + } + break; + case R_RISCV_JAL: + { + grub_uint32_t imm20 = (off & 0x100000) << (31 - 20); + grub_uint32_t imm19_12 = (off & 0xff000); + grub_uint32_t imm11 = (off & 0x800) << (20 - 11); + grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) + | imm20 | imm19_12 | imm11 | imm10_1); + } + break; + case R_RISCV_CALL: + case R_RISCV_CALL_PLT: + { + grub_uint32_t hi20, lo12; + + if (off != (grub_int32_t)off) + grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e)); + + hi20 = (off + 0x800) & 0xfffff000; + lo12 = (off - hi20) & 0xfff; + t32[0] = grub_host_to_target32 ((grub_target_to_host32 (t32[0]) & 0xfff) | hi20); + t32[1] = grub_host_to_target32 ((grub_target_to_host32 (t32[1]) & 0xfffff) | (lo12 << 20)); + } + break; + case R_RISCV_RVC_BRANCH: + { + grub_uint16_t imm8 = (off & 0x100) << (12 - 8); + grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5); + grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10); + *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe383) + | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1); + } + break; + case R_RISCV_RVC_JUMP: + { + grub_uint16_t imm11 = (off & 0x800) << (12 - 11); + grub_uint16_t imm10 = (off & 0x400) >> (10 - 8); + grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11); + grub_uint16_t imm7 = (off & 0x80) >> (7 - 6); + grub_uint16_t imm6 = (off & 0x40) << (12 - 11); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4 = (off & 0x10) << (12 - 5); + grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10); + *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe003) + | imm11 | imm10 | imm9_8 | imm7 | imm6 + | imm5 | imm4 | imm3_1); + } + break; + case R_RISCV_PCREL_HI20: + { + grub_int32_t hi20; + + if (off != (grub_int32_t)off) + grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e)); + + hi20 = (off + 0x800) & 0xfffff000; + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | hi20); + } + break; + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: + { + Elf_Rela *rel2; + Elf_Word k; + /* Search backwards for matching HI20 reloc. */ + for (k = j, rel2 = (Elf_Rela *) ((char *) r - r_size); + k > 0; + k--, rel2 = (Elf_Rela *) ((char *) rel2 - r_size)) + { + Elf_Addr rel2_info; + Elf_Addr rel2_offset; + Elf_Addr rel2_sym_addr; + Elf_Addr rel2_addend; + Elf_Addr rel2_loc; + grub_int64_t rel2_off; + + rel2_offset = grub_target_to_host (rel2->r_offset); + rel2_info = grub_target_to_host (rel2->r_info); + rel2_loc = target_section_addr + rel2_offset + image_target->vaddr_offset; + + if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20 + && rel2_loc == sym_addr) + { + rel2_sym_addr = SUFFIX (get_symbol_address) + (e, smd->symtab, ELF_R_SYM (rel2_info), + image_target); + rel2_addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (rel2->r_addend) : 0; + rel2_off = rel2_sym_addr + rel2_addend - rel2_loc; + off = rel2_off - ((rel2_off + 0x800) & 0xfffff000); + + if (ELF_R_TYPE (info) == R_RISCV_PCREL_LO12_I) + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | (off & 0xfff) << 20); + else + { + grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0); + } + break; + } + } + if (k == 0) + grub_util_error ("cannot find matching HI20 relocation"); + } + break; + case R_RISCV_HI20: + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | (((grub_int32_t) sym_addr + 0x800) & 0xfffff000)); + break; + case R_RISCV_LO12_I: + { + grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | ((lo12 & 0xfff) << 20)); + } + break; + case R_RISCV_LO12_S: + { + grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0); + } + break; + case R_RISCV_RELAX: + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } default: grub_util_error ("unknown architecture type %d", image_target->elf_target); @@ -1369,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: @@ -1404,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: @@ -1438,6 +1872,76 @@ translate_relocation_pe (struct translate_context *ctx, } break; #endif /* defined(MKIMAGE_ELF32) */ + case EM_RISCV: + switch (ELF_R_TYPE (info)) + { + case R_RISCV_32: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + /* Relative relocations do not require fixup entries. */ + 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: + case R_RISCV_RVC_BRANCH: + case R_RISCV_RVC_JUMP: + case R_RISCV_ADD32: + case R_RISCV_SUB32: + grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address); + break; + case R_RISCV_HI20: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_HI20, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_LO12_I: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_LOW12I, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_LO12_S: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_LOW12S, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_RELAX: + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; default: grub_util_error ("unknown machine type 0x%x", image_target->elf_target); } @@ -1624,9 +2128,7 @@ create_u64_fixups (struct translate_context *ctx, /* Make a .reloc section. */ static void make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, - Elf_Addr *section_addresses, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, + struct section_metadata *smd, const struct grub_install_image_target_desc *image_target) { unsigned i; @@ -1635,8 +2137,8 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, translate_reloc_start (&ctx, image_target); - for (i = 0, s = sections; i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + for (i = 0, s = smd->sections; i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) if ((grub_target_to_host32 (s->sh_type) == SHT_REL) || (grub_target_to_host32 (s->sh_type) == SHT_RELA)) { @@ -1646,15 +2148,22 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, Elf_Addr section_address; Elf_Word j; + if (!SUFFIX (is_kept_reloc_section) (s, image_target, smd)) + { + grub_util_info ("not translating the skipped relocation section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + continue; + } + grub_util_info ("translating the relocation section %s", - strtab + grub_le_to_cpu32 (s->sh_name)); + smd->strtab + grub_le_to_cpu32 (s->sh_name)); rtab_size = grub_target_to_host (s->sh_size); r_size = grub_target_to_host (s->sh_entsize); rtab_offset = grub_target_to_host (s->sh_offset); num_rs = rtab_size / r_size; - section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; + section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)]; for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); j < num_rs; @@ -1705,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)) @@ -1721,6 +2230,56 @@ SUFFIX (is_bss_section) (Elf_Shdr *s, const struct grub_install_image_target_des == SHF_ALLOC) && (grub_target_to_host32 (s->sh_type) == SHT_NOBITS); } +/* Determine if a section is going to be in the final output */ +static int +SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + /* We keep .text and .data */ + if (SUFFIX (is_text_section) (s, image_target) + || SUFFIX (is_data_section) (s, image_target)) + return 1; + + /* + * And we keep .bss if we're producing PE binaries or the target doesn't + * have a relocating loader. Platforms other than EFI and U-boot shouldn't + * have .bss in their binaries as we build with -Wl,-Ttext. + */ + if (SUFFIX (is_bss_section) (s, image_target) + && (image_target->id == IMAGE_EFI || !is_relocatable (image_target))) + return 1; + + /* Otherwise this is not a section we're keeping in the final output. */ + return 0; +} + +static int +SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target, + struct section_metadata *smd) +{ + int i; + int r = 0; + const char *name = smd->strtab + grub_host_to_target32 (s->sh_name); + + if (!strncmp (name, ".rela.", 6)) + name += 5; + else if (!strncmp (name, ".rel.", 5)) + name += 4; + else + return 1; + + for (i = 0, s = smd->sections; i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + { + const char *sname = smd->strtab + grub_host_to_target32 (s->sh_name); + if (strcmp (sname, name)) + continue; + + return SUFFIX (is_kept_section) (s, image_target); + } + + return r; +} + /* Return if the ELF header is valid. */ static int SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, const struct grub_install_image_target_desc *image_target) @@ -1741,12 +2300,11 @@ SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, const struct grub_install_i static Elf_Addr SUFFIX (put_section) (Elf_Shdr *s, int i, Elf_Addr current_address, - Elf_Addr *section_addresses, - const char *strtab, + struct section_metadata *smd, const struct grub_install_image_target_desc *image_target) { Elf_Word align = grub_host_to_target_addr (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); + const char *name = smd->strtab + grub_host_to_target32 (s->sh_name); if (align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, @@ -1758,24 +2316,23 @@ SUFFIX (put_section) (Elf_Shdr *s, int i, name, (unsigned long long) current_address); if (!is_relocatable (image_target)) current_address = grub_host_to_target_addr (s->sh_addr) - - image_target->link_addr; - section_addresses[i] = current_address; + - image_target->link_addr; + smd->addrs[i] = current_address; current_address += grub_host_to_target_addr (s->sh_size); return current_address; } -/* Locate section addresses by merging code sections and data sections - into .text and .data, respectively. Return the array of section - addresses. */ -static Elf_Addr * +/* + * Locate section addresses by merging code sections and data sections + * into .text and .data, respectively. + */ +static void SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path, - Elf_Shdr *sections, Elf_Half section_entsize, - Elf_Half num_sections, const char *strtab, + struct section_metadata *smd, struct grub_mkimage_layout *layout, const struct grub_install_image_target_desc *image_target) { int i; - Elf_Addr *section_addresses; Elf_Shdr *s; layout->align = 1; @@ -1783,30 +2340,23 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path, if (image_target->elf_target == EM_AARCH64) layout->align = 4096; - section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); - memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); - layout->kernel_size = 0; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) && grub_host_to_target32 (s->sh_addralign) > layout->align) layout->align = grub_host_to_target32 (s->sh_addralign); - /* .text */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) if (SUFFIX (is_text_section) (s, image_target)) { - layout->kernel_size = SUFFIX (put_section) (s, i, - layout->kernel_size, - section_addresses, - strtab, - image_target); + layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, + smd, image_target); if (!is_relocatable (image_target) && grub_host_to_target_addr (s->sh_addr) != image_target->link_addr) { @@ -1820,52 +2370,50 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path, } } - layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset, - image_target->section_align) - - image_target->vaddr_offset; - layout->exec_size = layout->kernel_size; - - /* .data */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (SUFFIX (is_data_section) (s, image_target)) - layout->kernel_size = SUFFIX (put_section) (s, i, - layout->kernel_size, - section_addresses, - strtab, - image_target); - #ifdef MKIMAGE_ELF32 if (image_target->elf_target == EM_ARM) { grub_size_t tramp; - layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset, - image_target->section_align) - image_target->vaddr_offset; layout->kernel_size = ALIGN_UP (layout->kernel_size, 16); - tramp = arm_get_trampoline_size (e, sections, section_entsize, - num_sections, image_target); + tramp = arm_get_trampoline_size (e, smd->sections, smd->section_entsize, + smd->num_sections, image_target); layout->tramp_off = layout->kernel_size; layout->kernel_size += ALIGN_UP (tramp, 16); } #endif + layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + layout->exec_size = layout->kernel_size; + + /* .data */ + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if (SUFFIX (is_data_section) (s, image_target)) + layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, smd, + image_target); + layout->bss_start = layout->kernel_size; layout->end = layout->kernel_size; - + /* .bss */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (SUFFIX (is_bss_section) (s, image_target)) - layout->end = SUFFIX (put_section) (s, i, - layout->end, - section_addresses, - strtab, - image_target); + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + { + if (SUFFIX (is_bss_section) (s, image_target)) + layout->end = SUFFIX (put_section) (s, i, layout->end, smd, image_target); + + /* + * This must to be in the last time this function passes through the loop. + */ + smd->vaddrs[i] = smd->addrs[i] + image_target->vaddr_offset; + } layout->end = ALIGN_UP (layout->end + image_target->vaddr_offset, image_target->section_align) - image_target->vaddr_offset; @@ -1874,10 +2422,8 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path, Platforms other than EFI and U-boot shouldn't have .bss in their binaries as we build with -Wl,-Ttext. */ - if (image_target->id != IMAGE_UBOOT) + if (image_target->id == IMAGE_EFI || !is_relocatable (image_target)) layout->kernel_size = layout->end; - - return section_addresses; } char * @@ -1887,18 +2433,12 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, const struct grub_install_image_target_desc *image_target) { char *kernel_img, *out_img; - const char *strtab; + struct section_metadata smd = { 0, 0, 0, 0, 0, 0, 0 }; Elf_Ehdr *e; - Elf_Shdr *sections; - Elf_Addr *section_addresses; - Elf_Addr *section_vaddresses; int i; Elf_Shdr *s; - Elf_Half num_sections; Elf_Off section_offset; - Elf_Half section_entsize; grub_size_t kernel_size; - Elf_Shdr *symtab_section = 0; grub_memset (layout, 0, sizeof (*layout)); @@ -1913,48 +2453,45 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, grub_util_error ("invalid ELF header"); section_offset = grub_target_to_host (e->e_shoff); - section_entsize = grub_target_to_host16 (e->e_shentsize); - num_sections = grub_target_to_host16 (e->e_shnum); + smd.section_entsize = grub_target_to_host16 (e->e_shentsize); + smd.num_sections = grub_target_to_host16 (e->e_shnum); - if (kernel_size < section_offset + (grub_uint32_t) section_entsize * num_sections) + if (kernel_size < section_offset + + (grub_uint32_t) smd.section_entsize * smd.num_sections) grub_util_error (_("premature end of file %s"), kernel_path); - sections = (Elf_Shdr *) (kernel_img + section_offset); + smd.sections = (Elf_Shdr *) (kernel_img + section_offset); /* Relocate sections then symbols in the virtual address space. */ - s = (Elf_Shdr *) ((char *) sections - + grub_host_to_target16 (e->e_shstrndx) * section_entsize); - strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); + s = (Elf_Shdr *) ((char *) smd.sections + + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize); + smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); - section_addresses = SUFFIX (locate_sections) (e, kernel_path, - sections, section_entsize, - num_sections, strtab, - layout, - image_target); + smd.addrs = xcalloc (smd.num_sections, sizeof (*smd.addrs)); + smd.vaddrs = xcalloc (smd.num_sections, sizeof (*smd.vaddrs)); - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + 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 = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) { Elf_Word sec_align = grub_host_to_target_addr (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); + const char *name = smd.strtab + grub_host_to_target32 (s->sh_name); if (sec_align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, sec_align) - image_target->vaddr_offset; - + grub_util_info ("locating the section %s at 0x%" GRUB_HOST_PRIxLONG_LONG, name, (unsigned long long) current_address); @@ -1962,13 +2499,29 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, current_address = grub_host_to_target_addr (s->sh_addr) - image_target->link_addr; - section_vaddresses[i] = current_address + 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); } 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 @@ -1977,21 +2530,22 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, if (image_target->id == IMAGE_SPARC64_AOUT || image_target->id == IMAGE_SPARC64_RAW || image_target->id == IMAGE_UBOOT + || image_target->id == IMAGE_COREBOOT || image_target->id == IMAGE_SPARC64_CDCORE) layout->kernel_size = ALIGN_UP (layout->kernel_size, image_target->mod_align); if (is_relocatable (image_target)) { - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + smd.symtab = NULL; + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) { - symtab_section = s; + smd.symtab = s; break; } - if (! symtab_section) + if (! smd.symtab) grub_util_error ("%s", _("no symbol table")); #ifdef MKIMAGE_ELF64 if (image_target->elf_target == EM_IA_64) @@ -2006,7 +2560,7 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, layout->kernel_size += ALIGN_UP (tramp, 16); layout->ia64jmp_off = layout->kernel_size; - layout->ia64jmpnum = SUFFIX (count_funcs) (e, symtab_section, + layout->ia64jmpnum = SUFFIX (count_funcs) (e, smd.symtab, image_target); layout->kernel_size += 16 * layout->ia64jmpnum; @@ -2025,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 { @@ -2037,31 +2595,19 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, if (is_relocatable (image_target)) { - layout->start_address = SUFFIX (relocate_symbols) (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections, - (char *) out_img + layout->ia64jmp_off, - layout->ia64jmp_off - + image_target->vaddr_offset, - layout->bss_start, - layout->end, - image_target); + layout->start_address = SUFFIX (relocate_symbols) (e, &smd, + (char *) out_img + layout->ia64jmp_off, + layout->ia64jmp_off + image_target->vaddr_offset, + layout->bss_start, layout->end, image_target); + if (layout->start_address == (Elf_Addr) -1) grub_util_error ("start symbol is not defined"); - /* Resolve addresses in the virtual address space. */ - SUFFIX (relocate_addresses) (e, sections, section_addresses, - section_entsize, - num_sections, strtab, - out_img, layout->tramp_off, - layout->got_off, - image_target); + /* Resolve addrs in the virtual address space. */ + SUFFIX (relocate_addrs) (e, &smd, out_img, layout->tramp_off, + layout->got_off, image_target); - make_reloc_section (e, layout, - section_vaddresses, sections, - section_entsize, num_sections, - strtab, - image_target); + make_reloc_section (e, layout, &smd, image_target); if (image_target->id != IMAGE_EFI) { out_img = xrealloc (out_img, layout->kernel_size + total_module_size @@ -2073,30 +2619,25 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, } } - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (SUFFIX (is_data_section) (s, image_target) - /* Explicitly initialize BSS - when producing PE32 to avoid a bug in EFI implementations. - Platforms other than EFI and U-boot shouldn't have .bss in - their binaries as we build with -Wl,-Ttext. - */ - || (SUFFIX (is_bss_section) (s, image_target) && (image_target->id != IMAGE_UBOOT)) - || SUFFIX (is_text_section) (s, image_target)) + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) + if (SUFFIX (is_kept_section) (s, image_target)) { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - memset (out_img + section_addresses[i], 0, + memset (out_img + smd.addrs[i], 0, grub_host_to_target_addr (s->sh_size)); else - memcpy (out_img + section_addresses[i], + memcpy (out_img + smd.addrs[i], kernel_img + grub_host_to_target_addr (s->sh_offset), grub_host_to_target_addr (s->sh_size)); } free (kernel_img); - free (section_vaddresses); - free (section_addresses); + free (smd.vaddrs); + smd.vaddrs = NULL; + free (smd.addrs); + smd.addrs = NULL; return out_img; } 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 82073d5cc..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 }; @@ -107,7 +107,10 @@ static const struct [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" }, [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_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" }, }; static void @@ -157,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 238d4840e..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]); @@ -323,6 +343,7 @@ check_xorriso (const char *val) char *buf = NULL; size_t len = 0; int ret = 0; + int wstatus = 0; argv[0] = xorriso; argv[1] = "-as"; @@ -347,8 +368,10 @@ check_xorriso (const char *val) } close (fd); - waitpid (pid, NULL, 0); + waitpid (pid, &wstatus, 0); free (buf); + if (!WIFEXITED (wstatus) || WEXITSTATUS(wstatus) != 0) + return 0; return ret; } @@ -426,6 +449,7 @@ main (int argc, char *argv[]) char **argp_argv; int xorriso_tail_argc; char **xorriso_tail_argv; + int rv; grub_util_host_init (&argc, &argv); grub_util_disable_fd_syncs (); @@ -437,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 */ @@ -453,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]; @@ -461,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: @@ -478,6 +506,10 @@ main (int argc, char *argv[]) if (!output_image) grub_util_error ("%s", _("output file must be specified")); + if (!check_xorriso ("graft-points")) { + grub_util_error ("%s", _("xorriso not found")); + } + grub_init_all (); grub_hostfs_init (); grub_host_init (); @@ -486,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"); @@ -522,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] @@ -530,6 +565,9 @@ 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]) system_area = SYS_AREA_COMMON; else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]) @@ -625,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, @@ -634,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.")); @@ -727,17 +765,34 @@ main (int argc, char *argv[]) || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] || 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_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); @@ -745,23 +800,36 @@ 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_abs (GRUB_INSTALL_PLATFORM_RISCV32_EFI, "riscv32-efi", imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv64.efi"); + make_image_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi", imgname); + free (imgname); + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) { imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi"); @@ -787,23 +855,23 @@ main (int argc, char *argv[]) free (efidir_efi_boot); efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img"); - int rv; rv = grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i", efiimgfat, "::", NULL }); if (rv != 0) grub_util_error ("`%s` invocation failed\n", "mformat"); rv = grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL }); if (rv != 0) - grub_util_error ("`%s` invocation failed\n", "mformat"); + grub_util_error ("`%s` invocation failed\n", "mcopy"); xorriso_push ("--efi-boot"); xorriso_push ("efi.img"); 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 (); } @@ -960,7 +1028,9 @@ main (int argc, char *argv[]) xorriso_argv[xorriso_argc] = NULL; - grub_util_exec ((const char *const *)xorriso_argv); + rv = grub_util_exec ((const char *const *)xorriso_argv); + if (rv != 0) + grub_util_error ("`%s` invocation failed\n", "xorriso"); grub_util_unlink_recursive (iso9660_dir); 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 9179285a5..91d9e8f88 100644 --- a/util/grub-module-verifier.c +++ b/util/grub-module-verifier.c @@ -19,6 +19,7 @@ struct grub_module_verifier_arch archs[] = { -1 }, (int[]){ R_X86_64_PC32, + R_X86_64_PLT32, -1 } }, @@ -28,6 +29,7 @@ struct grub_module_verifier_arch archs[] = { GRUB_ELF_R_PPC_ADDR16_HA, GRUB_ELF_R_PPC_ADDR32, GRUB_ELF_R_PPC_REL32, + GRUB_ELF_R_PPC_PLTREL24, -1 } }, { "sparc64", 8, 1, EM_SPARCV9, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ @@ -116,6 +118,95 @@ struct grub_module_verifier_arch archs[] = { R_AARCH64_LDST64_ABS_LO12_NC, 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, + R_RISCV_ADD8, + R_RISCV_ADD16, + R_RISCV_ADD32, + R_RISCV_ADD64, + R_RISCV_SUB8, + R_RISCV_SUB16, + R_RISCV_SUB32, + R_RISCV_SUB64, + R_RISCV_ALIGN, + R_RISCV_BRANCH, + R_RISCV_CALL, + R_RISCV_CALL_PLT, + R_RISCV_GOT_HI20, + R_RISCV_HI20, + R_RISCV_JAL, + R_RISCV_LO12_I, + R_RISCV_LO12_S, + R_RISCV_PCREL_HI20, + R_RISCV_PCREL_LO12_I, + R_RISCV_PCREL_LO12_S, + R_RISCV_RELAX, + R_RISCV_RVC_BRANCH, + R_RISCV_RVC_JUMP, + -1 + } }, + { "riscv64", 8, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_RISCV_32, + R_RISCV_64, + R_RISCV_ADD8, + R_RISCV_ADD16, + R_RISCV_ADD32, + R_RISCV_ADD64, + R_RISCV_SUB8, + R_RISCV_SUB16, + R_RISCV_SUB32, + R_RISCV_SUB64, + R_RISCV_ALIGN, + R_RISCV_BRANCH, + R_RISCV_CALL, + R_RISCV_CALL_PLT, + R_RISCV_GOT_HI20, + R_RISCV_HI20, + R_RISCV_JAL, + R_RISCV_LO12_I, + R_RISCV_LO12_S, + R_RISCV_PCREL_HI20, + R_RISCV_PCREL_LO12_I, + R_RISCV_PCREL_LO12_S, + R_RISCV_RELAX, + R_RISCV_RVC_BRANCH, + R_RISCV_RVC_JUMP, + -1 } }, }; @@ -128,6 +219,7 @@ struct platform_whitelist { static struct platform_whitelist whitelists[] = { {"i386", "xen", (const char *[]) {"all_video", 0}}, + {"i386", "xen_pvh", (const char *[]) {"all_video", 0}}, {"x86_64", "xen", (const char *[]) {"all_video", 0}}, {"sparc64", "ieee1275", (const char *[]) {"all_video", 0}}, @@ -156,7 +248,7 @@ main (int argc, char **argv) if (strcmp(archs[arch].name, argv[2]) == 0) break; if (arch == ARRAY_SIZE(archs)) - grub_util_error("unknown arch: %s", argv[2]); + grub_util_error("%s: unknown arch: %s", argv[1], argv[2]); for (whitelist = 0; whitelist < ARRAY_SIZE(whitelists); whitelist++) if (strcmp(whitelists[whitelist].arch, argv[2]) == 0 @@ -168,8 +260,8 @@ main (int argc, char **argv) module_size = grub_util_get_image_size (argv[1]); module_img = grub_util_read_image (argv[1]); if (archs[arch].voidp_sizeof == 8) - grub_module_verify64(module_img, module_size, &archs[arch], whitelist_empty); + grub_module_verify64(argv[1], module_img, module_size, &archs[arch], whitelist_empty); else - grub_module_verify32(module_img, module_size, &archs[arch], whitelist_empty); + grub_module_verify32(argv[1], module_img, module_size, &archs[arch], whitelist_empty); return 0; } 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 1feaafc9b..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,51 +142,121 @@ 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 struct grub_module_verifier_arch *arch, Elf_Ehdr *e) +check_license (const char * const filename, + 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)) return; - grub_util_error ("incompatible license"); + grub_util_error ("%s: incompatible license", 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)); @@ -201,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; @@ -209,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; @@ -221,13 +302,13 @@ 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 ("no symbol table and no .moddeps section"); + grub_util_error ("%s: no symbol table and no .moddeps section", modname); if (!s->sh_size) - grub_util_error ("no symbol table and empty .moddeps section"); + grub_util_error ("%s: no symbol table and empty .moddeps section", modname); return; } @@ -248,7 +329,7 @@ check_symbols (const struct grub_module_verifier_arch *arch, break; default: - return grub_util_error ("unknown symbol type `%d'", (int) type); + return grub_util_error ("%s: unknown symbol type `%d'", modname, (int) type); } } } @@ -274,16 +355,17 @@ is_symbol_local(Elf_Sym *sym) } static void -section_check_relocations (const struct grub_module_verifier_arch *arch, void *ehdr, - Elf_Shdr *s, size_t target_seg_size) +section_check_relocations (const char * const modname, + const struct grub_module_verifier_arch *arch, void *ehdr, + 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 ("relocation without symbol table"); + grub_util_error ("%s: relocation without symbol table", modname); for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)), max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size)); @@ -294,7 +376,7 @@ section_check_relocations (const struct grub_module_verifier_arch *arch, void *e unsigned i; if (target_seg_size < grub_target_to_host (rel->r_offset)) - grub_util_error ("reloc offset is out of the segment"); + grub_util_error ("%s: reloc offset is out of the segment", modname); grub_uint32_t type = ELF_R_TYPE (grub_target_to_host (rel->r_info)); @@ -307,17 +389,17 @@ section_check_relocations (const struct grub_module_verifier_arch *arch, void *e if (arch->supported_relocations[i] != -1) continue; if (!arch->short_relocations) - grub_util_error ("unsupported relocation 0x%x", type); + grub_util_error ("%s: unsupported relocation 0x%x", modname, type); for (i = 0; arch->short_relocations[i] != -1; i++) if (type == arch->short_relocations[i]) break; if (arch->short_relocations[i] == -1) - grub_util_error ("unsupported relocation 0x%x", type); + grub_util_error ("%s: unsupported relocation 0x%x", modname, type); sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM (grub_target_to_host (rel->r_info))); if (is_symbol_local (sym)) continue; - grub_util_error ("relocation 0x%x is not module-local", type); + grub_util_error ("%s: relocation 0x%x is not module-local", modname, type); } #if defined(MODULEVERIFIER_ELF64) if (arch->machine == EM_AARCH64) @@ -342,11 +424,11 @@ section_check_relocations (const struct grub_module_verifier_arch *arch, void *e && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC) break; if (rel2 >= (Elf_Rela *) max) - grub_util_error ("ADR_GOT_PAGE without matching LD64_GOT_LO12_NC"); + grub_util_error ("%s: ADR_GOT_PAGE without matching LD64_GOT_LO12_NC", modname); break; case R_AARCH64_LD64_GOT_LO12_NC: if (unmatched_adr_got_page == 0) - grub_util_error ("LD64_GOT_LO12_NC without matching ADR_GOT_PAGE"); + grub_util_error ("%s: LD64_GOT_LO12_NC without matching ADR_GOT_PAGE", modname); unmatched_adr_got_page--; break; } @@ -356,34 +438,38 @@ section_check_relocations (const struct grub_module_verifier_arch *arch, void *e } static void -check_relocations (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) +check_relocations (const char * const modname, + 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 ("unsupported SHT_REL"); - if (grub_target_to_host32 (s->sh_type) == SHT_RELA && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_RELA)) - grub_util_error ("unsupported SHT_RELA"); + 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 ("orphaned reloc section"); - 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 (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 -SUFFIX(grub_module_verify) (void *module_img, size_t size, +SUFFIX(grub_module_verify) (const char * const filename, + void *module_img, size_t size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty) { @@ -391,7 +477,7 @@ SUFFIX(grub_module_verify) (void *module_img, size_t size, /* Check the header size. */ if (size < sizeof (Elf_Ehdr)) - grub_util_error ("ELF header smaller than expected"); + grub_util_error ("%s: ELF header smaller than expected", filename); /* Check the magic numbers. */ if (e->e_ident[EI_MAG0] != ELFMAG0 @@ -400,36 +486,36 @@ SUFFIX(grub_module_verify) (void *module_img, size_t size, || e->e_ident[EI_MAG3] != ELFMAG3 || e->e_ident[EI_VERSION] != EV_CURRENT || grub_target_to_host32 (e->e_version) != EV_CURRENT) - grub_util_error ("invalid arch-independent ELF magic"); + grub_util_error ("%s: invalid arch-independent ELF magic", filename); if (e->e_ident[EI_CLASS] != ELFCLASSXX || e->e_ident[EI_DATA] != (arch->bigendian ? ELFDATA2MSB : ELFDATA2LSB) || grub_target_to_host16 (e->e_machine) != arch->machine) - grub_util_error ("invalid arch-dependent ELF magic"); + grub_util_error ("%s: invalid arch-dependent ELF magic", filename); if (grub_target_to_host16 (e->e_type) != ET_REL) { - grub_util_error ("this ELF file is not of the right type"); + grub_util_error ("%s: this ELF file is not of the right type", 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 ("ELF sections outside core"); + grub_util_error ("%s: ELF sections outside core", filename); } - check_license (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 ("no module name found"); + 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(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 aca5f82e3..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; @@ -190,9 +195,10 @@ fuse_getattr (const char *path, struct stat *st) } /* It's the whole device. */ - (fs->dir) (dev, path2, fuse_getattr_find_file, &ctx); + (fs->fs_dir) (dev, path2, fuse_getattr_find_file, &ctx); grub_free (path2); + free (pathname); if (!ctx.file_exists) { grub_errno = GRUB_ERR_NONE; @@ -208,7 +214,7 @@ fuse_getattr (const char *path, struct stat *st) if (!ctx.file_info.dir) { grub_file_t file; - file = grub_file_open (path); + file = grub_file_open (path, GRUB_FILE_TYPE_GET_SIZE); if (! file && grub_errno == GRUB_ERR_BAD_FILE_TYPE) { 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,11 +246,14 @@ 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); + file = grub_file_open (path, GRUB_FILE_TYPE_MOUNT); if (! file) return translate_error (); files[first_fd++] = 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]); @@ -308,7 +317,7 @@ fuse_readdir_call_fill (const char *filename, grub_file_t file; char *tmp; tmp = xasprintf ("%s/%s", ctx->path, filename); - file = grub_file_open (tmp); + file = grub_file_open (tmp, GRUB_FILE_TYPE_GET_SIZE); free (tmp); /* Symlink to directory. */ if (! file && grub_errno == GRUB_ERR_BAD_FILE_TYPE) @@ -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,13 +366,13 @@ fuse_readdir (const char *path, void *buf, char *pathname; pathname = xstrdup (path); - + /* Remove trailing '/'. */ while (pathname [0] && pathname[1] && pathname[grub_strlen (pathname) - 1] == '/') pathname[grub_strlen (pathname) - 1] = 0; - (fs->dir) (dev, pathname, fuse_readdir_call_fill, &ctx); + (fs->fs_dir) (dev, pathname, fuse_readdir_call_fill, &ctx); free (pathname); grub_errno = GRUB_ERR_NONE; return 0; @@ -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)) { @@ -530,6 +550,7 @@ argp_parser (int key, char *arg, struct argp_state *state) if (arg[0] != '-') break; + /* FALLTHROUGH */ default: if (!arg) return 0; @@ -542,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; @@ -549,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 }; @@ -569,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 8ac527d2f..65c1ca3f8 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,7 @@ enum { PRINT_DRIVE, PRINT_DEVICE, PRINT_PARTMAP, + PRINT_PARTUUID, PRINT_ABSTRACTION, PRINT_CRYPTODISK_UUID, PRINT_HINT_STR, @@ -85,6 +87,7 @@ static const char *targets[] = [PRINT_DRIVE] = "drive", [PRINT_DEVICE] = "device", [PRINT_PARTMAP] = "partmap", + [PRINT_PARTUUID] = "partuuid", [PRINT_ABSTRACTION] = "abstraction", [PRINT_CRYPTODISK_UUID] = "cryptodisk_uuid", [PRINT_HINT_STR] = "hints_string", @@ -129,6 +132,20 @@ get_targets_string (void) return str; } +static int +print_gpt_guid (grub_guid_t 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); + + return grub_printf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid.data1, guid.data2, guid.data3, guid.data4[0], + guid.data4[1], guid.data4[2], guid.data4[3], + guid.data4[4], guid.data4[5], guid.data4[6], + guid.data4[7]); +} + static void do_print (const char *x, void *data) { @@ -154,9 +171,9 @@ probe_partmap (grub_disk_t disk, char delim) grub_diskfilter_get_partmap (disk, do_print, &delim); /* In case of LVM/RAID, check the member devices as well. */ - if (disk->dev->memberlist) + if (disk->dev->disk_memberlist) { - list = disk->dev->memberlist (disk); + list = disk->dev->disk_memberlist (disk); } while (list) { @@ -167,15 +184,54 @@ probe_partmap (grub_disk_t disk, char delim) } } +static void +probe_partuuid (grub_disk_t disk, char delim) +{ + grub_partition_t p = disk->partition; + + /* + * Nested partitions not supported for now. + * Non-nested partitions must have disk->partition->parent == NULL + */ + if (p && p->parent == NULL) + { + disk->partition = p->parent; + + if (strcmp(p->partmap->name, "msdos") == 0) + { + /* + * The partition GUID for MSDOS is the partition number (starting + * with 1) prepended with the NT disk signature. + */ + 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_printf ("%08x-%02x", + grub_le_to_cpu32(nt_disk_sig), 1 + p->number); + } + else if (strcmp(p->partmap->name, "gpt") == 0) + { + struct grub_gpt_partentry gptdata; + + if (grub_disk_read (disk, p->offset, p->index, + sizeof(gptdata), &gptdata) == 0) + print_gpt_guid(gptdata.guid); + } + + disk->partition = p; + } +} + static void probe_cryptodisk_uuid (grub_disk_t disk, char delim) { grub_disk_memberlist_t list = NULL, tmp; /* In case of LVM/RAID, check the member devices as well. */ - if (disk->dev->memberlist) + if (disk->dev->disk_memberlist) { - list = disk->dev->memberlist (disk); + list = disk->dev->disk_memberlist (disk); } while (list) { @@ -216,8 +272,8 @@ probe_abstraction (grub_disk_t disk, char delim) grub_disk_memberlist_t list = NULL, tmp; int raid_level; - if (disk->dev->memberlist) - list = disk->dev->memberlist (disk); + if (disk->dev->disk_memberlist) + list = disk->dev->disk_memberlist (disk); while (list) { probe_abstraction (list->disk, delim); @@ -243,8 +299,8 @@ probe_abstraction (grub_disk_t disk, char delim) if (raid_level >= 0) { printf ("diskfilter%c", delim); - if (disk->dev->raidname) - printf ("%s%c", disk->dev->raidname (disk), delim); + if (disk->dev->disk_raidname) + printf ("%s%c", disk->dev->disk_raidname (disk), delim); } if (raid_level == 5) printf ("raid5rec%c", delim); @@ -305,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++) @@ -342,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) { @@ -377,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); @@ -390,10 +446,10 @@ probe (const char *path, char **device_names, char delim) else if (print == PRINT_FS_UUID) { char *uuid; - if (! fs->uuid) + if (! fs->fs_uuid) grub_util_error (_("%s does not support UUIDs"), fs->name); - if (fs->uuid (dev, &uuid) != GRUB_ERR_NONE) + if (fs->fs_uuid (dev, &uuid) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); printf ("%s", uuid); @@ -402,11 +458,11 @@ probe (const char *path, char **device_names, char delim) else if (print == PRINT_FS_LABEL) { char *label; - if (! fs->label) + if (! fs->fs_label) grub_util_error (_("filesystem `%s' does not support labels"), fs->name); - if (fs->label (dev, &label) != GRUB_ERR_NONE) + if (fs->fs_label (dev, &label) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); printf ("%s", label); @@ -487,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) @@ -621,6 +677,12 @@ probe (const char *path, char **device_names, char delim) /* Check if dev->disk itself is contained in a partmap. */ probe_partmap (dev->disk, delim); + else if (print == PRINT_PARTUUID) + { + probe_partuuid (dev->disk, delim); + putchar (delim); + } + else if (print == PRINT_MSDOS_PARTTYPE) { if (dev->disk->partition @@ -641,21 +703,7 @@ probe (const char *path, char **device_names, char delim) if (grub_disk_read (dev->disk, p->offset, p->index, sizeof (gptdata), &gptdata) == 0) - { - grub_gpt_part_type_t gpttype; - gpttype.data1 = grub_le_to_cpu32 (gptdata.type.data1); - gpttype.data2 = grub_le_to_cpu16 (gptdata.type.data2); - gpttype.data3 = grub_le_to_cpu16 (gptdata.type.data3); - grub_memcpy (gpttype.data4, gptdata.type.data4, 8); - - grub_printf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - gpttype.data1, gpttype.data2, - gpttype.data3, gpttype.data4[0], - gpttype.data4[1], gpttype.data4[2], - gpttype.data4[3], gpttype.data4[4], - gpttype.data4[5], gpttype.data4[6], - gpttype.data4[7]); - } + print_gpt_guid(gptdata.type); dev->disk->partition = p; } putchar (delim); @@ -684,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-reboot.in b/util/grub-reboot.in index 4d4f75704..ef3b5c049 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -20,6 +20,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ +sbindir=@sbindir@ sysconfdir="@sysconfdir@" PACKAGE_NAME=@PACKAGE_NAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ @@ -32,6 +33,7 @@ fi self=`basename $0` grub_editenv=${bindir}/@grub_editenv@ +grub_probe=${sbindir}/@grub_probe@ rootdir= bootdir= grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` @@ -56,6 +58,8 @@ submenus or sub-submenus require specifying the submenu components and then the menu item component. The titles should be separated using the greater-than character (>) with no extra spaces. Depending on your shell some characters including > may need escaping. More information about this is available in the GRUB Manual in the section about the 'default' command. "; echo + echo + gettext "NOTE: In cases where GRUB cannot write to the environment block, such as when it is stored on an MDRAID or LVM device, the chosen boot menu entry will remain the default even after reboot. "; echo echo gettext "Report bugs to ."; echo } @@ -131,6 +135,18 @@ fi grubdir=`echo "${bootdir}/@grubdirname@" | sed 's,//*,/,g'` +abstractions=`$grub_probe --target=abstraction ${grubdir}/grubenv` +for abstraction in $abstractions; do + case "$abstraction" in + diskfilter | lvm) + gettext_printf "\nWARNING: Detected GRUB environment block on $abstraction device\n" + gettext_printf "%s will remain the default boot entry until manually cleared with:\n" "${entry}" + gettext_printf " grub-editenv ${grubdir}/grubenv unset next_entry\n\n" + break + ;; + esac +done + # Restore saved_entry if it was set by previous version prev_saved_entry=`$grub_editenv ${grubdir}/grubenv list | sed -n 's/^prev_saved_entry=//p'` if [ "$prev_saved_entry" ]; then 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 993b02068..1783224dd 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -69,7 +69,7 @@ #define DEFAULT_CORE_FILE "core.img" /* Non-printable "keys" for arguments with no short form. - * See grub-core/gnulib/argp.h for details. */ + * See grub-core/lib/gnulib/argp.h for details. */ enum { NO_RS_CODES_KEY = 0x100, }; @@ -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 de9044c7f..cc393be7e 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -43,12 +43,24 @@ 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=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. -if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ - || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ +if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \ + || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ + && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \ + || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ + && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \ || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then LINUX_ROOT_DEVICE=${GRUB_DEVICE} +elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \ + || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then + LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID} else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} fi @@ -63,7 +75,7 @@ case x"$GRUB_FS" in xzfs) rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true` bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`" - LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}" + LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}" ;; esac @@ -136,9 +148,13 @@ EOF if test -n "${initrd}" ; then # TRANSLATORS: ramdisk isn't identifier. Should be translated. 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 echo '$(echo "$message" | grub_quote)' - initrd ${rel_dirname}/${initrd} + initrd $(echo $initrd_path) EOF fi sed "s/^/$submenu_indentation/" << EOF @@ -177,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` @@ -188,9 +214,19 @@ while [ "x$list" != "x" ] ; do alt_version=`echo $version | sed -e "s,\.old$,,g"` linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" - initrd= - for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \ - "initrd-${version}" "initramfs-${version}.img" \ + initrd_early= + for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \ + ${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do + if test -e "${dirname}/${i}" ; then + initrd_early="${initrd_early} ${i}" + fi + done + + initrd_real= + 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}" \ @@ -198,11 +234,22 @@ while [ "x$list" != "x" ] ; do "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \ "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do if test -e "${dirname}/${i}" ; then - initrd="$i" + initrd_real="${i}" break fi done + initrd= + if test -n "${initrd_early}" || test -n "${initrd_real}"; then + initrd="${initrd_early} ${initrd_real}" + + initrd_display= + for i in ${initrd}; do + initrd_display="${initrd_display} ${dirname}/${i}" + done + gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 + fi + config= for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do if test -e "${i}" ; then @@ -216,15 +263,27 @@ while [ "x$list" != "x" ] ; do initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"` fi - if test -n "${initrd}" ; then - gettext_printf "Found initrd image: %s\n" "${dirname}/${initrd}" >&2 - elif test -z "${initramfs}" ; then + if test -z "${initramfs}" && test -z "${initrd_real}" ; then # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs. Since there's # no initrd or builtin initramfs, it can't work here. - linux_root_device_thisversion=${GRUB_DEVICE} + if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \ + || [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then + + linux_root_device_thisversion=${GRUB_DEVICE} + else + linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID} + 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}" @@ -242,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 c48af948d..94dd8be13 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -43,12 +43,24 @@ 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=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. -if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ - || ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ +if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \ + || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \ + && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \ + || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \ + && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \ || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then LINUX_ROOT_DEVICE=${GRUB_DEVICE} +elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \ + || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then + LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID} else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} fi @@ -71,31 +83,49 @@ case x"$GRUB_FS" in xzfs) rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true` bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`" - LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}" + LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}" ;; 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")" @@ -113,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)' @@ -122,16 +152,27 @@ linux_entry () else xen_rm_opts="no-real-mode edd=off" fi - multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} + ${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} echo '$(echo "$lmessage" | grub_quote)' - module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} + ${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} EOF if test -n "${initrd}" ; then # TRANSLATORS: ramdisk isn't identifier. Should be translated. message="$(gettext_printf "Loading initial ramdisk ...")" + initrd_path= + for i in ${initrd}; do + 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 --nounzip ${rel_dirname}/${initrd} + ${module_loader} ${rel_dirname}/${xenpolicy} EOF fi sed "s/^/$submenu_indentation/" << EOF @@ -159,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 @@ -170,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= @@ -191,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` @@ -206,8 +264,28 @@ while [ "x${xen_list}" != "x" ] ; do if [ "x$is_top_level" != xtrue ]; then echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {" fi - while [ "x$list" != "x" ] ; do - linux=`version_find_latest $list` + if ($grub_file --is-arm64-efi $current_xen); then + xen_loader="xen_hypervisor" + module_loader="xen_module" + else + if ($grub_file --is-x86-multiboot2 $current_xen); then + xen_loader="multiboot2" + module_loader="module2" + else + xen_loader="multiboot" + module_loader="module" + fi + fi + + initrd_early= + for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \ + ${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do + if test -e "${xen_dirname}/${i}" ; then + initrd_early="${initrd_early} ${i}" + fi + done + + for linux in ${reverse_sorted_linux_list}; do gettext_printf "Found linux image: %s\n" "$linux" >&2 basename=`basename $linux` dirname=`dirname $linux` @@ -216,9 +294,11 @@ while [ "x${xen_list}" != "x" ] ; do alt_version=`echo $version | sed -e "s,\.old$,,g"` linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" - initrd= - for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \ - "initrd-${version}" "initramfs-${version}.img" \ + initrd_real= + 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}" \ @@ -226,18 +306,45 @@ while [ "x${xen_list}" != "x" ] ; do "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \ "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}" ; do if test -e "${dirname}/${i}" ; then - initrd="$i" + initrd_real="$i" break fi done - if test -n "${initrd}" ; then - gettext_printf "Found initrd image: %s\n" "${dirname}/${initrd}" >&2 - else - # "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here. - linux_root_device_thisversion=${GRUB_DEVICE} + + initrd= + if test -n "${initrd_early}" || test -n "${initrd_real}"; then + # 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 + initrd_display="${initrd_display} ${dirname}/${i}" + done + gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + if test -z "${initrd_real}"; then + # "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here. + if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \ + || [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then + + linux_root_device_thisversion=${GRUB_DEVICE} + else + linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID} + fi + fi + + # 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}" @@ -256,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 < @@ -732,19 +832,67 @@ grub_install_get_image_targets_string (void) return formats; } +/* + * The image_target parameter is used by the grub_host_to_target32() macro. + */ +static struct grub_pe32_section_table * +init_pe_section(const struct grub_install_image_target_desc *image_target, + struct grub_pe32_section_table *section, + const char * const name, + grub_uint32_t *vma, grub_uint32_t vsz, grub_uint32_t valign, + grub_uint32_t *rda, grub_uint32_t rsz, + grub_uint32_t characteristics) +{ + size_t len = strlen (name); + + if (len > 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) + 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; + 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; @@ -789,6 +937,21 @@ grub_install_generate_image (const char *dir, const char *prefix, total_module_size += memdisk_size + sizeof (struct grub_module_header); } + if (dtb_path) + { + dtb_size = ALIGN_ADDR(grub_util_get_image_size (dtb_path)); + 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); @@ -816,7 +979,8 @@ grub_install_generate_image (const char *dir, const char *prefix, else kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size, &layout, image_target); - if (image_target->id == IMAGE_XEN && layout.align < 4096) + if ((image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) && + layout.align < 4096) layout.align = 4096; if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) @@ -911,6 +1075,39 @@ grub_install_generate_image (const char *dir, const char *prefix, offset += memdisk_size; } + if (dtb_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_DTB); + header->size = grub_host_to_target32 (dtb_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (dtb_path, kernel_img + offset); + 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; @@ -947,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); @@ -973,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); @@ -1033,7 +1230,7 @@ grub_install_generate_image (const char *dir, const char *prefix, /* fallthrough */ case IMAGE_COREBOOT: case IMAGE_QEMU: - if (layout.kernel_size + layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000) + if (image_target->elf_target != EM_ARM && layout.kernel_size + layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000) grub_util_error (_("kernel image is too big (0x%x > 0x%x)"), (unsigned) layout.kernel_size + (unsigned) layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR, @@ -1046,6 +1243,7 @@ grub_install_generate_image (const char *dir, const char *prefix, case IMAGE_MIPS_ARC: case IMAGE_QEMU_MIPS_FLASH: case IMAGE_XEN: + case IMAGE_XEN_PVH: break; case IMAGE_SPARC64_AOUT: case IMAGE_SPARC64_RAW: @@ -1072,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); @@ -1099,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); @@ -1138,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, - image_target->section_align); + vma = raw_data = header_size; - pe_size = ALIGN_UP (reloc_addr + layout.reloc_size, - image_target->section_align); - 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); @@ -1176,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 @@ -1189,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 (image_target->section_align); - 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 (image_target->section_align); - 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; @@ -1419,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, @@ -1430,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, @@ -1443,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; @@ -1472,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); @@ -1498,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); @@ -1604,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)); @@ -1622,10 +1809,19 @@ grub_install_generate_image (const char *dir, const char *prefix, case IMAGE_LOONGSON_ELF: case IMAGE_PPC: case IMAGE_XEN: + case IMAGE_XEN_PVH: case IMAGE_COREBOOT: 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) @@ -1637,11 +1833,11 @@ 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, - target_addr, layout.align, layout.kernel_size, layout.bss_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, - target_addr, layout.align, layout.kernel_size, layout.bss_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 8aa5a39a7..87a889ff7 100644 --- a/util/setup.c +++ b/util/setup.c @@ -137,6 +137,9 @@ struct blocklists struct grub_boot_blocklist *first_block, *block; #ifdef GRUB_SETUP_BIOS grub_uint16_t current_segment; +#endif +#ifdef GRUB_SETUP_SPARC64 + grub_uint64_t gpt_offset; #endif grub_uint16_t last_length; grub_disk_addr_t first_sector; @@ -151,6 +154,10 @@ save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length, struct grub_boot_blocklist *prev = bl->block + 1; grub_uint64_t seclen; +#ifdef GRUB_SETUP_SPARC64 + sector -= bl->gpt_offset; +#endif + grub_util_info ("saving <%" GRUB_HOST_PRIuLONG_LONG ",%u,%u>", (unsigned long long) sector, offset, length); @@ -198,7 +205,6 @@ save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length, #endif } -#ifdef GRUB_SETUP_BIOS /* Context for setup/identify_partmap. */ struct identify_partmap_ctx { @@ -234,7 +240,6 @@ identify_partmap (grub_disk_t disk __attribute__ ((unused)), ctx->multiple_partmaps = 1; return 1; } -#endif #ifdef GRUB_SETUP_BIOS #define SETUP grub_util_bios_setup @@ -249,15 +254,14 @@ 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; char *root = 0; size_t boot_size, core_size; -#ifdef GRUB_SETUP_BIOS grub_uint16_t core_sectors; -#endif grub_device_t root_dev = 0, dest_dev, core_dev; grub_util_fd_t fp; struct blocklists bl; @@ -267,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; @@ -281,10 +288,8 @@ SETUP (const char *dir, core_path = grub_util_get_path (dir, core_file); core_size = grub_util_get_image_size (core_path); -#ifdef GRUB_SETUP_BIOS core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); -#endif if (core_size < GRUB_DISK_SECTOR_SIZE) grub_util_error (_("the size of `%s' is too small"), core_path); #ifdef GRUB_SETUP_BIOS @@ -298,9 +303,8 @@ SETUP (const char *dir, bl.first_block = (struct grub_boot_blocklist *) (core_img + GRUB_DISK_SECTOR_SIZE - sizeof (*bl.block)); - grub_util_info ("root is `%s', dest is `%s'", root, dest); - grub_util_info ("Opening dest"); + grub_util_info ("Opening dest `%s'", dest); dest_dev = grub_device_open (dest); if (! dest_dev) grub_util_error ("%s", grub_errmsg); @@ -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) @@ -366,8 +370,8 @@ SETUP (const char *dir, if (grub_env_set ("root", root) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); -#ifdef GRUB_SETUP_BIOS { +#ifdef GRUB_SETUP_BIOS char *tmp_img; grub_uint8_t *boot_drive_check; @@ -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. */ @@ -392,6 +396,7 @@ SETUP (const char *dir, boot_drive_check[0] = 0x90; boot_drive_check[1] = 0x90; } +#endif struct identify_partmap_ctx ctx = { .dest_partmap = NULL, @@ -407,6 +412,7 @@ SETUP (const char *dir, grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx); +#ifdef GRUB_SETUP_BIOS /* Copy the partition table. */ if (ctx.dest_partmap || (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))) @@ -415,6 +421,7 @@ SETUP (const char *dir, GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC); free (tmp_img); +#endif if (ctx.container && grub_strcmp (ctx.container->partmap->name, "msdos") == 0 @@ -488,7 +495,7 @@ SETUP (const char *dir, goto unable_to_embed; } - if (fs && !fs->embed) + if (fs && !fs->fs_embed) { grub_util_warn (_("File system `%s' doesn't support embedding"), fs->name); @@ -502,27 +509,39 @@ SETUP (const char *dir, else maxsec = core_sectors; +#ifdef GRUB_SETUP_BIOS if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) >> GRUB_DISK_SECTOR_BITS)) maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) >> GRUB_DISK_SECTOR_BITS); +#endif + +#ifdef GRUB_SETUP_SPARC64 + /* + * On SPARC we need two extra. One is because we are combining the + * core.img with the boot.img. The other is because the boot sector + * starts at 1. + */ + nsec += 2; + maxsec += 2; +#endif if (is_ldm) err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, 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->embed (dest_dev, &nsec, maxsec, - GRUB_EMBED_PCBIOS, §ors); + err = fs->fs_embed (dest_dev, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); if (!err && nsec < core_sectors) { err = grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Your embedding area is unusually small. " "core.img won't fit in it.")); } - + if (err) { grub_util_warn ("%s", grub_errmsg); @@ -537,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) @@ -554,9 +573,39 @@ SETUP (const char *dir, bl.block--; bl.block->start = 0; bl.block->len = 0; +#ifdef GRUB_SETUP_BIOS bl.block->segment = 0; +#endif +#ifdef GRUB_SETUP_SPARC64 + { + /* + * On SPARC, the block-list entries need to be based off the beginning + * of the parition, not the beginning of the disk. + */ + struct grub_boot_blocklist *block; + block = bl.first_block; + + while (block->len) + { + block->start -= bl.first_sector; + block--; + } + } + + /* + * Reserve space for the boot block since it can not be in the + * Parition table on SPARC. + */ + assert (bl.first_block->len > 2); + bl.first_block->start += 2; + bl.first_block->len -= 2; + write_rootdev (root_dev, boot_img, sectors[BOOT_SECTOR + 1] - bl.first_sector); +#endif + +#ifdef GRUB_SETUP_BIOS write_rootdev (root_dev, boot_img, bl.first_sector); +#endif /* Round up to the nearest sector boundary, and zero the extra memory */ core_img = xrealloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); @@ -566,9 +615,9 @@ SETUP (const char *dir, bl.first_block = (struct grub_boot_blocklist *) (core_img + GRUB_DISK_SECTOR_SIZE - 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)); @@ -597,14 +646,34 @@ SETUP (const char *dir, grub_disk_write (dest_dev->disk, sectors[i], 0, GRUB_DISK_SECTOR_SIZE, core_img + i * GRUB_DISK_SECTOR_SIZE); +#endif +#ifdef GRUB_SETUP_SPARC64 + { + int isec = BOOT_SECTOR; + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, sectors[isec++], 0, + GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + + /* Write the core image onto the disk. */ + for (i = 0 ; isec < nsec; i++, isec++) + { + if (grub_disk_write (dest_dev->disk, sectors[isec], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE)) + grub_util_error ("%s", grub_errmsg); + } + } + +#endif grub_free (sectors); goto finish; } unable_to_embed: -#endif if (dest_dev->disk->dev->id != root_dev->disk->dev->id) grub_util_error ("%s", _("embedding is not possible, but this is required for " @@ -662,6 +731,15 @@ unable_to_embed: bl.block = bl.first_block; +#ifdef GRUB_SETUP_SPARC64 + { + grub_partition_t container = root_dev->disk->partition; + + if (grub_strstr (container->partmap->name, "gpt")) + bl.gpt_offset = grub_partition_get_start (container); + } +#endif + grub_install_get_blocklist (root_dev, core_path, core_img, core_size, save_blocklists, &bl); @@ -712,8 +790,10 @@ unable_to_embed: != GRUB_DISK_SECTOR_SIZE * 2) grub_util_error (_("cannot write to `%s': %s"), core_path, strerror (errno)); - grub_util_fd_sync (fp); - grub_util_fd_close (fp); + if (grub_util_fd_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), core_path, strerror (errno)); + if (grub_util_fd_close (fp) < 0) + grub_util_error (_("cannot close `%s': %s"), core_path, strerror (errno)); grub_util_biosdisk_flush (root_dev->disk); grub_disk_cache_invalidate_all (); @@ -721,15 +801,18 @@ unable_to_embed: { char *buf, *ptr = core_img; size_t len = core_size; - grub_uint64_t blk; + grub_uint64_t blk, offset = 0; grub_partition_t container = core_dev->disk->partition; grub_err_t err; core_dev->disk->partition = 0; +#ifdef GRUB_SETUP_SPARC64 + offset = bl.gpt_offset; +#endif buf = xmalloc (core_size); blk = bl.first_sector; - err = grub_disk_read (core_dev->disk, blk, 0, GRUB_DISK_SECTOR_SIZE, buf); + err = grub_disk_read (core_dev->disk, blk + offset, 0, GRUB_DISK_SECTOR_SIZE, buf); if (err) grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, grub_errmsg); @@ -748,7 +831,7 @@ unable_to_embed: if (cur > len) cur = len; - err = grub_disk_read (core_dev->disk, blk, 0, cur, buf); + err = grub_disk_read (core_dev->disk, blk + offset, 0, cur, buf); if (err) grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, grub_errmsg); @@ -759,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")); } @@ -778,6 +861,10 @@ unable_to_embed: 0, GRUB_DISK_SECTOR_SIZE, boot_img)) grub_util_error ("%s", grub_errmsg); +#ifdef GRUB_SETUP_SPARC64 + finish: +#endif + grub_util_biosdisk_flush (root_dev->disk); grub_util_biosdisk_flush (dest_dev->disk);