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 b8efcc4dd..f6a1bd051 100644 --- a/.gitignore +++ b/.gitignore @@ -1,238 +1,277 @@ -*~ -00_header -10_* -20_linux_xen -30_os-prober -40_custom -41_custom +# +# Ignore patterns in this directory and all subdirectories. +# *.1 *.8 -ABOUT-NLS -aclocal.m4 -ahci_test -ascii.bitmaps -ascii.h -autom4te.cache -build-aux -build-grub-gen-asciih -build-grub-gen-widthspec -build-grub-mkfont -cdboot_test -cmp_test -config.cache -config.guess -config.h -config-util.h -config-util.h.in -config.log -config.status -config.sub -configure -core_compress_test -DISTLIST -docs/*.info -docs/stamp-vti -docs/version.texi -ehci_test -example_grub_script_test -example_scripted_test -example_unit_test +*.a *.exec *.exec.exe -fddboot_test -genkernsyms.sh -gensymlist.sh -gentrigtables -gentrigtables.exe -gettext_strings_test -gpt_unit_test -/gnulib -grub-bin2h -/grub-bios-setup -/grub-bios-setup.exe -grub_cmd_date -grub_cmd_echo -grub_cmd_regexp -grub_cmd_set_date -grub_cmd_sleep -/grub-editenv -/grub-editenv.exe -grub-emu -grub-emu-lite -grub-emu.exe -grub-emu-lite.exe -grub_emu_init.c -grub_emu_init.h -/grub-file -/grub-file.exe -grub-fstest -grub-fstest.exe -grub_fstest_init.c -grub_fstest_init.h -grub_func_test -grub-install -grub-install.exe -grub-kbdcomp -/grub-macbless -/grub-macbless.exe -grub-macho2img -/grub-menulst2cfg -/grub-menulst2cfg.exe -/grub-mk* -grub-mount -/grub-ofpathname -/grub-ofpathname.exe -grub-core/build-grub-pe2elf.exe -/grub-probe -/grub-probe.exe -grub_probe_init.c -grub_probe_init.h -/grub-reboot -grub_script_blanklines -grub_script_blockarg -grub_script_break -grub-script-check -grub-script-check.exe -grub_script_check_init.c -grub_script_check_init.h -grub_script_comments -grub_script_continue -grub_script_dollar -grub_script_echo1 -grub_script_echo_keywords -grub_script_escape_comma -grub_script_eval -grub_script_expansion -grub_script_final_semicolon -grub_script_for1 -grub_script_functions -grub_script_gettext -grub_script_if -grub_script_leading_whitespace -grub_script_no_commands -grub_script_not -grub_script_return -grub_script_setparams -grub_script_shift -grub_script_strcmp -grub_script_test -grub_script_vars1 -grub_script_while1 -grub_script.tab.c -grub_script.tab.h -grub_script.yy.c -grub_script.yy.h -grub-set-default -grub_setup_init.c -grub_setup_init.h -grub-shell -grub-shell-tester -grub-sparc64-setup -grub-sparc64-setup.exe -/grub-syslinux2cfg -/grub-syslinux2cfg.exe -gzcompress_test -hddboot_test -help_test -*.img *.image *.image.exe -include/grub/cpu -include/grub/machine -INSTALL.grub -install-sh -lib/libgcrypt-grub -libgrub_a_init.c +*.img *.log *.lst -lzocompress_test *.marker -Makefile -/m4 *.mod -mod-*.c -missing -netboot_test *.o -*.a -ohci_test -partmap_test -pata_test *.pf2 *.pp -po/*.mo -po/grub.pot -po/Makefile.in.in -po/Makevars -po/Makevars.template -po/POTFILES -po/Rules-quot -po/stamp-po -printf_test -priority_queue_unit_test -pseries_test -stamp-h -stamp-h1 -stamp-h.in -symlist.c -symlist.h -trigtables.c *.trs -uhci_test -update-grub_lib -unidata.c -xzcompress_test -Makefile.in +*~ +.deps-core/ +.deps-util/ +.deps/ +.dirstamp +DISTLIST GPATH GRTAGS GSYMS GTAGS -compile -depcomp +Makefile +Makefile.in +ascii.bitmaps +genkernsyms.sh +gensymlist.sh +grub-bin2h +grub-emu +grub-emu-lite +grub-emu-lite.exe +grub-emu.exe +grub-macho2img +grub_emu_init.c +grub_emu_init.h +grub_probe_init.c +grub_probe_init.h +grub_script.tab.c +grub_script.tab.h +grub_script.yy.c +grub_script.yy.h +grub_script_check_init.c +grub_script_check_init.h +grub_setup_init.c +grub_setup_init.h mdate-sh -texinfo.tex -grub-core/lib/libgcrypt-grub -.deps -.deps-util -.deps-core -.dirstamp -Makefile.util.am -contrib -grub-core/bootinfo.txt -grub-core/Makefile.core.am -grub-core/Makefile.gcry.def -grub-core/contrib -grub-core/gdb_grub -grub-core/genmod.sh -grub-core/gensyminfo.sh -grub-core/gmodule.pl -grub-core/grub.chrp -grub-core/modinfo.sh -grub-core/*.module -grub-core/*.module.exe -grub-core/*.pp -grub-core/kernel.img.bin -util/bash-completion.d/grub -grub-core/lib/gnulib -grub-core/rs_decoder.h +mod-*.c +update-grub_lib widthspec.bin -widthspec.h -docs/stamp-1 -docs/version-dev.texi -Makefile.utilgcry.def -po/*.po -po/*.gmo -po/LINGUAS -po/remove-potcdate.sed -include/grub/gcrypt/gcrypt.h -include/grub/gcrypt/g10lib.h -po/POTFILES.in -po/POTFILES-shell.in -/grub-glue-efi -/grub-render-label -/grub-glue-efi.exe -/grub-render-label.exe + +# +# Ignore patterns relative to this .gitignore file's directory. +# +/00_header +/10_* +/20_linux_xen +/30_os-prober +/30_uefi-firmware +/40_custom +/41_custom +/ABOUT-NLS +/ChangeLog +/INSTALL.grub +/Makefile.util.am +/Makefile.utilgcry.def +/aclocal.m4 +/ahci_test +/ascii.h +/autom4te.cache/ +/btrfs_test +/build-aux/ +/build-grub-gen-asciih +/build-grub-gen-widthspec +/build-grub-mkfont +/cdboot_test +/cmp_test +/compile +/config-util.h +/config-util.h.in +/config.cache +/config.guess +/config.h +/config.log +/config.status +/config.sub +/configure +/contrib +/core_compress_test +/cpio_test +/date_test +/depcomp +/docs/*.info +/docs/*.info-[0-9]* +/docs/stamp-1 +/docs/stamp-vti +/docs/version-dev.texi +/docs/version.texi +/ehci_test +/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/modinfo.sh +/grub-core/rs_decoder.h +/grub-core/symlist.c +/grub-core/symlist.h +/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-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 +/m4/ +/minixfs_test +/missing +/netboot_test +/nilfs2_test +/ntfs_test +/ohci_test +/partmap_test +/pata_test +/po/*.gmo +/po/*.mo +/po/*.po +/po/LINGUAS +/po/Makefile.in.in +/po/Makevars +/po/Makevars.template +/po/POTFILES +/po/POTFILES-shell.in +/po/POTFILES.in +/po/Rules-quot +/po/grub.pot +/po/remove-potcdate.sed +/po/stamp-po +/printf_test +/priority_queue_unit_test +/pseries_test +/reiserfs_test +/romfs_test +/squashfs_test +/stamp-h +/stamp-h.in +/stamp-h1 +/syslinux_test +/tar_test +/test_sha512sum +/test_unset +/tests/syslinux/ubuntu10.04_grub.cfg +/texinfo.tex +/udf_test +/uhci_test +/util/bash-completion.d/grub +/widthspec.h +/xfs_test +/xzcompress_test +/zfs_test diff --git a/.travis.yml b/.travis.yml index 81de20fa3..4bd05a30a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ language: c addons: apt: packages: + - autopoint - libsdl1.2-dev - lzop - ovmf @@ -35,7 +36,7 @@ before_script: script: # Comments must be outside the command strings below, or the Travis parser # will get confused. - - ./autogen.sh + - ./bootstrap # Build all selected GRUB targets. - for target in $GRUB_TARGETS; do diff --git a/INSTALL b/INSTALL index 8acb40902..79a0af7d9 100644 --- a/INSTALL +++ b/INSTALL @@ -11,27 +11,9 @@ 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 3.8.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 @@ -160,12 +142,20 @@ For this example the configure line might look like (more details below) (some options are optional and included here for completeness but some rarely used options are omitted): -./configure BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config --host=amd64-linux-gnu -CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" PKG_CONFIG=amd64-linux-gnu-pkg-config ---target=arm --with-platform=uboot TARGET_CC=arm-elf-gcc -TARGET_CFLAGS="-Os -march=armv6" TARGET_CCASFLAGS="-march=armv6" -TARGET_OBJCOPY="arm-elf-objcopy" TARGET_STRIP="arm-elf-strip" -TARGET_NM=arm-elf-nm TARGET_RANLIB=arm-elf-ranlib LEX=gflex + ./configure --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 + +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 @@ -182,20 +172,23 @@ corresponding platform are not needed for the platform in question. - For host 1. --host= to autoconf name of host. - 2. CC= for gcc able to compile for host - 3. HOST_CFLAGS= for C options for host. - 4. HOST_CPPFLAGS= for C preprocessor options for host. - 5. HOST_LDFLAGS= for linker options for host. - 6. PKG_CONFIG= for pkg-config for host (optional). - 7. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional). - 8. Libfuse if any must be in standard linker folders (-lfuse) (optional). - 9. Libzfs if any must be in standard linker folders (-lzfs) (optional). - 10. Liblzma if any must be in standard linker folders (-llzma) (optional). + 2. CC= for gcc able to compile for host. + 3. CFLAGS= for C options for host. + 4. HOST_CC= for gcc able to compile for host. + 5. HOST_CFLAGS= for C options for host. + 6. HOST_CPPFLAGS= for C preprocessor options for host. + 7. HOST_LDFLAGS= for linker options for host. + 8. PKG_CONFIG= for pkg-config for host (optional). + 9. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional). + 10. Libfuse if any must be in standard linker folders (-lfuse) (optional). + 11. Libzfs if any must be in standard linker folders (-lzfs) (optional). + 12. Liblzma if any must be in standard linker folders (-llzma) (optional). + Note: The HOST_* variables override not prefixed variables. - For target 1. --target= to autoconf cpu name of target. 2. --with-platform to choose firmware. - 3. TARGET_CC= for gcc able to compile for target + 3. TARGET_CC= for gcc able to compile for target. 4. TARGET_CFLAGS= for C options for target. 5. TARGET_CPPFLAGS= for C preprocessor options for target. 6. TARGET_CCASFLAGS= for assembler options for target. @@ -204,6 +197,10 @@ 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) diff --git a/Makefile.am b/Makefile.am index 1f4bb9b8c..bf9c1ba64 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,7 +37,7 @@ 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 diff --git a/Makefile.util.def b/Makefile.util.def index 65cbfc081..d9e2bd84d 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,7 +36,9 @@ 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/cryptodisk.c; common = grub-core/disk/AFSplitter.c; @@ -139,7 +141,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; @@ -240,8 +242,19 @@ program = { common = util/grub-editenv.c; common = util/editenv.c; + common = util/grub-install-common.c; common = grub-core/osdep/init.c; + common = grub-core/osdep/compress.c; + extra_dist = grub-core/osdep/unix/compress.c; + extra_dist = grub-core/osdep/basic/compress.c; + common = util/mkimage.c; + common = util/grub-mkimage32.c; + common = util/grub-mkimage64.c; + common = grub-core/osdep/config.c; + common = util/config.c; + common = util/resolve.c; + ldadd = '$(LIBLZMA)'; ldadd = libgrubmods.a; ldadd = libgrubgcry.a; ldadd = libgrubkern.a; @@ -502,6 +515,12 @@ script = { 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; @@ -1175,18 +1194,6 @@ script = { common = tests/grub_cmd_tr.in; }; -script = { - testcase; - name = gptrepair_test; - common = tests/gptrepair_test.in; -}; - -script = { - testcase; - name = gptprio_test; - common = tests/gptprio_test.in; -}; - script = { testcase; name = file_filter_test; @@ -1282,25 +1289,6 @@ program = { ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; }; -program = { - testcase; - name = gpt_unit_test; - common = tests/gpt_unit_test.c; - common = tests/lib/unit_test.c; - common = grub-core/commands/search_part_label.c; - common = grub-core/commands/search_part_uuid.c; - common = grub-core/commands/search_disk_uuid.c; - common = grub-core/disk/host.c; - common = grub-core/kern/emu/hostfs.c; - common = grub-core/lib/gpt.c; - common = grub-core/tests/lib/test.c; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/gnulib/libgnu.a; - ldadd = '$(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; -}; - program = { name = grub-menulst2cfg; mansection = 1; diff --git a/autogen.sh b/autogen.sh index ef43270fc..31b0ced7e 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,7 +13,7 @@ fi export LC_COLLATE=C unset LC_ALL -find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' ! -ipath './gnulib/*' ! -iname './grub-core/lib/gnulib/*' |sort > po/POTFILES.in +find . -iname '*.[ch]' ! -ipath './grub-core/lib/libgcrypt-grub/*' ! -ipath './build-aux/*' ! -ipath './grub-core/lib/libgcrypt/src/misc.c' ! -ipath './grub-core/lib/libgcrypt/src/global.c' ! -ipath './grub-core/lib/libgcrypt/src/secmem.c' ! -ipath './util/grub-gen-widthspec.c' ! -ipath './util/grub-gen-asciih.c' ! -ipath './gnulib/*' ! -ipath './grub-core/lib/gnulib/*' |sort > po/POTFILES.in find util -iname '*.in' ! -name Makefile.in |sort > po/POTFILES-shell.in echo "Importing unicode..." diff --git a/bootstrap.conf b/bootstrap.conf index 988dda099..6d383240e 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -23,6 +23,7 @@ GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263 # directly. gnulib_modules=" argp + base64 error fnmatch getdelim @@ -78,10 +79,18 @@ cp -a INSTALL INSTALL.grub bootstrap_post_import_hook () { set -e - for patchname in fix-null-deref fix-width no-abort; do + for patchname in fix-base64 fix-null-deref fix-width no-abort; do patch -d grub-core/lib/gnulib -p2 \ < "grub-core/lib/gnulib-patches/$patchname.patch" done + for patchname in \ + 0001-Support-POTFILES-shell \ + 0002-Handle-gettext_printf-shell-function \ + 0003-Make-msgfmt-output-in-little-endian \ + 0004-Use-SHELL-rather-than-bin-sh; do + patch -d po -p3 \ + < "po/gettext-patches/$patchname.patch" + done FROM_BOOTSTRAP=1 ./autogen.sh set +e # bootstrap expects this } diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 46c4e95e2..37dc3aa10 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -28,6 +28,7 @@ EXTRA_DIST += grub-core/gensymlist.sh EXTRA_DIST += grub-core/genemuinit.sh EXTRA_DIST += grub-core/genemuinitheader.sh +EXTRA_DIST += grub-core/lib/gnulib-patches/fix-base64.patch EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-deref.patch EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch @@ -110,6 +111,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/configure.ac b/configure.ac index 7656f2434..7c10a4db7 100644 --- a/configure.ac +++ b/configure.ac @@ -26,12 +26,15 @@ dnl This is necessary because the target type in autoconf does not dnl describe such a system very well. dnl dnl The current strategy is to use variables with no prefix (such as -dnl CC, CFLAGS, etc.) for the host type, variables with prefix "BUILD_" -dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables -dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are -dnl used for the target type. See INSTALL for full list of variables. +dnl CC, CFLAGS, etc.) for the host and target type, variables with +dnl prefix "BUILD_" (such as BUILD_CC, BUILD_CFLAGS, etc.) for the +dnl build type, variables with prefix "HOST_" (such as HOST_CC, +dnl HOST_CFLAGS, etc.) for the host type and variables with the prefix +dnl "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for +dnl the target type. See INSTALL for full list of variables and +dnl description of the relationships between them. -AC_INIT([GRUB],[2.04],[bug-grub@gnu.org]) +AC_INIT([GRUB],[2.05],[bug-grub@gnu.org]) AC_CONFIG_AUX_DIR([build-aux]) @@ -77,9 +80,15 @@ grub_TRANSFORM([grub-file]) # 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 $BUILD_CFLAGS" +HOST_CFLAGS="-std=gnu99 $HOST_CFLAGS" +TARGET_CFLAGS="-std=gnu99 $TARGET_CFLAGS" + # Default HOST_CPPFLAGS HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W" HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1" @@ -562,6 +571,24 @@ CPPFLAGS="$TARGET_CPPFLAGS" LDFLAGS="$TARGET_LDFLAGS" LIBS="" +if test "x$target_m32" = x1; then + # Force 32-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" + TARGET_MODULE_FORMAT="elf32" +fi + +if test "x$target_m64" = x1; then + # Force 64-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m64" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" + TARGET_MODULE_FORMAT="elf64" +fi + # debug flags. TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations" TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g" @@ -750,24 +777,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 @@ -854,6 +863,11 @@ if test x"$platform" != xemu ; then 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 @@ -999,6 +1013,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" @@ -1198,7 +1223,8 @@ if test "x$target_cpu" = xarm; then AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [ grub_cv_target_cc_mno_movt=no for cand in "-mno-movt" \ - "-mllvm -arm-use-movt=0"; do + "-mllvm -arm-use-movt=0" \ + "-mword-relocations"; do if test x"$grub_cv_target_cc_mno_movt" != xno ; then break fi @@ -1251,6 +1277,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 @@ -1358,7 +1385,7 @@ 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) +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 @@ -1435,9 +1462,11 @@ 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 + AC_DEFINE([MM_DEBUG], [1], + [Define to 1 if you enable memory manager debugging.]) +fi AC_ARG_ENABLE([cache-stats], AS_HELP_STRING([--enable-cache-stats], diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi index ee389fd83..24d17b8ec 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -490,6 +490,8 @@ to update it. @menu * Gnulib:: +* jsmn:: +* minilzo:: @end menu @node Gnulib @@ -545,6 +547,41 @@ AC_SYS_LARGEFILE @end example +It will also be necessary to adjust the patches in +@file{po/gettext-patches/} to apply to an older version of gettext. + +@node jsmn +@section jsmn + +jsmn is a minimalistic JSON parser which is implemented in a single header file +@file{jsmn.h}. To import a different version of the jsmn parser, you may simply +download the @file{jsmn.h} header from the desired tag or commit to the target +directory: + +@example +curl -L https://raw.githubusercontent.com/zserge/jsmn/v1.1.0/jsmn.h \ + -o grub-core/lib/json/jsmn.h +@end example + +@node minilzo +@section minilzo + +miniLZO is a very lightweight subset of the LZO library intended for easy +inclusion in other projects. It is generated automatically from the LZO +source code and contains the most important LZO functions. + +To upgrade to a new version of the miniLZO library, download the release +tarball and copy the files into the target directory: + +@example +curl -L -O http://www.oberhumer.com/opensource/lzo/download/minilzo-2.08.tar.gz +tar -zxf minilzo-2.08.tar.gz +rm minilzo-2.08/testmini.c +rm -r grub-core/lib/minilzo/* +cp minilzo-2.08/*.[hc] grub-core/lib/minilzo +rm -r minilzo-2.08* +@end example + @node Porting @chapter Porting diff --git a/docs/grub.texi b/docs/grub.texi index 54b0e17ae..37f7ce7da 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -894,6 +894,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 @@ -991,6 +992,26 @@ way. Please consider alternative boot methods like copying all files from the image to actual partition. Consult your OS documentation for more details +@node LVM cache booting +@section Booting from LVM cache logical volume + +The LVM cache logical volume is the logical volume consisting of the original +and the cache pool logical volume. The original is usually on a larger and +slower storage device while the cache pool is on a smaller and faster one. The +performance of the original volume can be improved by storing the frequently +used data on the cache pool to utilize the greater performance of faster +device. + +GRUB boots from LVM cache logical volume merely by reading it's original +logical volume so that dirty data in cache pool volume is disregarded. This is +not a problem for "writethrough" cache mode as it ensures that any data written +will be stored both on the cache and the origin LV. For the other cache mode +"writeback", which delays writing from the cache pool back to the origin LV to +boost performance, GRUB may fail to boot in the wake of accidental power outage +due to it's inability to assemble the cache device for reading the required +dirty data left behind. The situation will be improved after adding full +support to the LVM cache logical volume in the future. + @node OS-specific notes @section Some caveats on OS-specific issues @@ -1093,12 +1114,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 @@ -1309,12 +1324,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 @@ -1441,6 +1456,15 @@ enable the use of partition UUIDs, set this option to @samp{false}. If this option is set to @samp{true}, disable the generation of recovery mode menu entries. +@item GRUB_DISABLE_UUID +Normally, @command{grub-mkconfig} will generate menu entries that use +universally-unique identifiers (UUIDs) to identify various filesystems to +search for files. This is usually more reliable, but in some cases it may +not be appropriate. To disable this use of UUIDs, set this option to +@samp{true}. Setting this option to @samp{true}, will also set the options +@samp{GRUB_DISABLE_LINUX_UUID} and @samp{GRUB_DISABLE_LINUX_PARTUUID} to +@samp{true}, unless they have been explicilty 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, @@ -1495,7 +1519,7 @@ Normally, @command{grub-mkconfig} will generate top level menu entry for the kernel with highest version number and put all other found kernels or alternative menu entries for recovery mode in submenu. For entries returned by @command{os-prober} first entry will be put on top level and all others -in submenu. If this option is set to @samp{y}, flat menu with all entries +in submenu. If this option is set to @samp{true}, flat menu with all entries on top level will be generated instead. Changing this option will require changing existing values of @samp{GRUB_DEFAULT}, @samp{fallback} (@pxref{fallback}) and @samp{default} (@pxref{default}) environment variables as well as saved @@ -1529,16 +1553,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 @@ -2486,6 +2510,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-@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 loouk 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-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. @@ -3930,7 +4005,6 @@ you forget a command, you can run the command @command{help} * password_pbkdf2:: Set a hashed password * 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 @@ -3950,7 +4024,6 @@ you forget a command, you can run the command @command{help} * 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 @@ -4202,8 +4275,9 @@ is requested interactively. Option @var{device} configures specific grub 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. +GRUB suports 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. @end deffn @@ -4221,13 +4295,12 @@ 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}. @end deffn @node distrust @@ -4424,22 +4497,22 @@ about each of the commands whose names begin with those @var{patterns}. @node initrd @subsection initrd -@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}. +@deffn Command initrd file [file @dots{}] +Load, in order, all initial ramdisks 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 @node initrd16 @subsection initrd16 -@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}. +@deffn Command initrd16 file [file @dots{}] +Load, in order, all initial ramdisks 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 @@ -4647,7 +4720,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. @@ -4772,19 +4845,11 @@ a rest. @node probe @subsection probe -@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label} device +@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label}|@option{--part-uuid} device Retrieve device information. If option @option{--set} is given, assign result to variable @var{var}, otherwise print information on the screen. -@end deffn - -@node pxe_unload -@subsection pxe_unload - -@deffn Command pxe_unload -Unload the PXE environment (@pxref{Network}). - -This command is only available on PC BIOS systems. +The option @option{--part-uuid} is currently only implemented for MSDOS and GPT formatted disks. @end deffn @@ -5078,9 +5143,10 @@ 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 @@ -5122,21 +5188,27 @@ return. Only one of these options may be specified at a time. @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, @@ -5268,12 +5340,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 @@ -5357,10 +5423,11 @@ This command is only available on AArch64 systems. * 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 @@ -5407,8 +5474,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 @@ -5435,35 +5538,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 @@ -5681,7 +5766,8 @@ 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. 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 diff --git a/gentpl.py b/gentpl.py index 387588c05..c86550d4f 100644 --- a/gentpl.py +++ b/gentpl.py @@ -766,7 +766,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 $< $@; \ fi """) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5dc520bd4..3ea8e7ff4 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -92,7 +92,6 @@ 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/mm_private.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/tpm.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h if COND_i386_pc diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 6ca83ec39..b5f47fc41 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -140,7 +140,6 @@ kernel = { common = kern/rescue_parser.c; common = kern/rescue_reader.c; common = kern/term.c; - common = kern/tpm.c; noemu = kern/compiler-rt.c; noemu = kern/mm.c; @@ -204,7 +203,6 @@ kernel = { efi = term/efi/console.c; efi = kern/acpi.c; efi = kern/efi/acpi.c; - efi = kern/efi/tpm.c; i386_coreboot = kern/i386/pc/acpi.c; i386_multiboot = kern/i386/pc/acpi.c; i386_coreboot = kern/acpi.c; @@ -264,7 +262,6 @@ kernel = { i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/mmap.c; - i386_pc = kern/i386/pc/tpm.c; i386_pc = term/i386/pc/console.c; i386_qemu = bus/pci.c; @@ -891,32 +888,11 @@ module = { enable = x86_64_efi; }; -module = { - name = getenv; - common = commands/efi/getenv.c; - enable = efi; -}; - module = { name = gptsync; common = commands/gptsync.c; }; -module = { - name = gptrepair; - common = commands/gptrepair.c; -}; - -module = { - name = gptprio; - common = commands/gptprio.c; -}; - -module = { - name = gpt; - common = lib/gpt.c; -}; - module = { name = halt; nopc = commands/halt.c; @@ -974,7 +950,7 @@ module = { module = { name = shim_lock; common = commands/efi/shim_lock.c; - enable = x86_64_efi; + enable = efi; }; module = { @@ -1104,21 +1080,6 @@ module = { common = commands/search_label.c; }; -module = { - name = search_part_uuid; - common = commands/search_part_uuid.c; -}; - -module = { - name = search_part_label; - common = commands/search_part_label.c; -}; - -module = { - name = search_disk_uuid; - common = commands/search_disk_uuid.c; -}; - module = { name = setpci; common = commands/setpci.c; @@ -1215,10 +1176,27 @@ module = { common = disk/cryptodisk.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 = { @@ -1709,6 +1687,7 @@ module = { module = { name = datetime; + common = lib/datetime.c; cmos = lib/cmos_datetime.c; efi = lib/efi/datetime.c; uboot = lib/dummy/datetime.c; @@ -1721,7 +1700,6 @@ module = { i386_xen_pvh = lib/xen/datetime.c; mips_arc = lib/arc/datetime.c; - enable = noemu; }; module = { @@ -1903,14 +1881,6 @@ module = { enable = x86_64_efi; }; -module = { - name = linuxefi; - efi = loader/i386/efi/linux.c; - efi = lib/cmdline.c; - enable = i386_efi; - enable = x86_64_efi; -}; - module = { name = chain; efi = loader/efi/chainloader.c; @@ -1956,7 +1926,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; @@ -2531,7 +2500,7 @@ module = { name = tpm; common = commands/tpm.c; efi = commands/efi/tpm.c; - enable = x86_64_efi; + enable = efi; }; module = { @@ -2565,8 +2534,3 @@ module = { common = commands/i386/wrmsr.c; enable = x86; }; -module = { - name = fwconfig; - common = commands/fwconfig.c; - enable = x86; -}; diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index 47a461ed5..2bd0b2d28 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -24,14 +24,11 @@ * defines for the code go here */ -#define TPM 1 - /* Print message string */ #define MSG(x) movw $x, %si; call LOCAL(message) #define ERR(x) movw $x, %si; jmp LOCAL(error_message) .macro floppy -#ifndef TPM part_start: LOCAL(probe_values): @@ -88,7 +85,6 @@ fd_probe_error_string: .asciz "Floppy" movb MACRO_DOLLAR(79), %ch jmp LOCAL(final_init) -#endif .endm .macro scratch @@ -259,7 +255,6 @@ real_start: /* set %si to the disk address packet */ movw $disk_address_packet, %si -#ifndef TPM /* check if LBA is supported */ movb $0x41, %ah movw $0x55aa, %bx @@ -279,7 +274,6 @@ real_start: andw $1, %cx jz LOCAL(chs_mode) -#endif LOCAL(lba_mode): xorw %ax, %ax @@ -323,9 +317,6 @@ LOCAL(lba_mode): jmp LOCAL(copy_buffer) LOCAL(chs_mode): -#ifdef TPM - jmp LOCAL(general_error) -#else /* * Determine the hard disk geometry from the BIOS! * We do this first, so that LS-120 IDE floppies work correctly. @@ -437,7 +428,7 @@ setup_sectors: jc LOCAL(read_error) movw %es, %bx -#endif /* TPM */ + LOCAL(copy_buffer): /* * We need to save %cx and %si because the startup code in @@ -460,25 +451,6 @@ LOCAL(copy_buffer): popw %ds popa -#ifdef TPM - pusha - - movw $0xBB00, %ax /* TCG_StatusCheck */ - int $0x1A - test %eax, %eax - jnz boot /* No TPM or TPM deactivated */ - - movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */ - movw $GRUB_BOOT_MACHINE_KERNEL_ADDR, %di - xorl %esi, %esi - movl $0x41504354, %ebx /* TCPA */ - movl $0x200, %ecx /* Measure 512 bytes */ - movl $0x8, %edx /* PCR 8 */ - int $0x1A - -boot: - popa -#endif /* boot kernel */ jmp *(LOCAL(kernel_address)) diff --git a/grub-core/boot/i386/pc/diskboot.S b/grub-core/boot/i386/pc/diskboot.S index 5d413d50d..c1addc0df 100644 --- a/grub-core/boot/i386/pc/diskboot.S +++ b/grub-core/boot/i386/pc/diskboot.S @@ -19,8 +19,6 @@ #include #include -#define TPM 1 - /* * defines for the code go here */ @@ -60,21 +58,6 @@ _start: /* this sets up for the first run through "bootloop" */ movw $LOCAL(firstlist), %di -#ifdef TPM - /* clear EAX to remove potential garbage */ - xorl %eax, %eax - /* 8(%di) = number of sectors to read */ - movw 8(%di), %ax - - /* Multiply number of sectors to read with 512 bytes. EAX is 32bit - * which is large enough to hold values of up to 4GB. I doubt there - * will ever be a core.img larger than that. ;-) */ - shll $9, %eax - - /* write result to bytes_to_measure var */ - movl %eax, bytes_to_measure -#endif - /* save the sector number of the second sector in %ebp */ movl (%di), %ebp @@ -312,29 +295,6 @@ LOCAL(copy_buffer): /* END OF MAIN LOOP */ LOCAL(bootit): -#ifdef TPM - pusha - movw $0xBB07, %ax /* TCG_CompactHashLogExtendEvent */ - - movw $0x0, %bx - movw %bx, %es - - /* We've already measured the first 512 bytes, now measure the rest */ - xorl %edi, %edi - movw $(GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200), %di - - movl $0x41504354, %ebx /* EBX = "TCPA" */ - - /* %ecx = The length, in bytes, of the buffer to measure */ - movl $bytes_to_measure, %esi - movl (%esi), %ecx - xorl %esi, %esi - movl $0x9, %edx /* PCR 9 */ - - int $0x1A - - popa -#endif /* print a newline */ MSG(notification_done) popw %dx /* this makes sure %dl is our "boot" drive */ @@ -369,10 +329,6 @@ geometry_error_string: .asciz "Geom" read_error_string: .asciz "Read" general_error_string: .asciz " Error" -#ifdef TPM -bytes_to_measure: .long 0 -#endif - /* * message: write the string pointed to by %si * diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c index 34a7ff1b5..a06cce302 100644 --- a/grub-core/bus/usb/usbhub.c +++ b/grub-core/bus/usb/usbhub.c @@ -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); 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/efi/getenv.c b/grub-core/commands/efi/getenv.c deleted file mode 100644 index 7eb2c4506..000000000 --- a/grub-core/commands/efi/getenv.c +++ /dev/null @@ -1,153 +0,0 @@ -/* getenv.c - retrieve EFI variables. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * Copyright (C) 2014 CoreOS, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const struct grub_arg_option options_getenv[] = { - {"var-name", 'e', 0, - N_("Environment variable to query"), - N_("VARNAME"), ARG_TYPE_STRING}, - {"var-guid", 'g', 0, - N_("GUID of environment variable to query"), - N_("GUID"), ARG_TYPE_STRING}, - {"binary", 'b', 0, - N_("Read binary data and represent it as hex"), - 0, ARG_TYPE_NONE}, - {0, 0, 0, 0, 0, 0} -}; - -enum options_getenv -{ - GETENV_VAR_NAME, - GETENV_VAR_GUID, - GETENV_BINARY, -}; - -static grub_err_t -grub_cmd_getenv (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - char *envvar = NULL, *guid = NULL, *bindata = NULL, *data = NULL; - grub_size_t datasize; - grub_efi_guid_t efi_var_guid; - grub_efi_boolean_t binary = state[GETENV_BINARY].set; - unsigned int i; - - if (!state[GETENV_VAR_NAME].set || !state[GETENV_VAR_GUID].set) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("-e and -g are required")); - goto done; - } - - if (argc != 1) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments")); - goto done; - } - - envvar = state[GETENV_VAR_NAME].arg; - guid = state[GETENV_VAR_GUID].arg; - - if (grub_strlen(guid) != 36 || - guid[8] != '-' || - guid[13] != '-' || - guid[18] != '-' || - guid[23] != '-') - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid GUID")); - goto done; - } - - /* Forgive me father for I have sinned */ - guid[8] = 0; - efi_var_guid.data1 = grub_strtoul(guid, NULL, 16); - guid[13] = 0; - efi_var_guid.data2 = grub_strtoul(guid + 9, NULL, 16); - guid[18] = 0; - efi_var_guid.data3 = grub_strtoul(guid + 14, NULL, 16); - efi_var_guid.data4[7] = grub_strtoul(guid + 34, NULL, 16); - guid[34] = 0; - efi_var_guid.data4[6] = grub_strtoul(guid + 32, NULL, 16); - guid[32] = 0; - efi_var_guid.data4[5] = grub_strtoul(guid + 30, NULL, 16); - guid[30] = 0; - efi_var_guid.data4[4] = grub_strtoul(guid + 28, NULL, 16); - guid[28] = 0; - efi_var_guid.data4[3] = grub_strtoul(guid + 26, NULL, 16); - guid[26] = 0; - efi_var_guid.data4[2] = grub_strtoul(guid + 24, NULL, 16); - guid[23] = 0; - efi_var_guid.data4[1] = grub_strtoul(guid + 21, NULL, 16); - guid[21] = 0; - efi_var_guid.data4[0] = grub_strtoul(guid + 19, NULL, 16); - - data = grub_efi_get_variable(envvar, &efi_var_guid, &datasize); - - if (!data || !datasize) - { - grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("No such variable")); - goto done; - } - - if (binary) - { - bindata = grub_zalloc(datasize * 2 + 1); - for (i=0; inum_table_entries; i++) { grub_efi_packed_guid_t *guid = @@ -129,11 +127,6 @@ fake_bios_data (int use_rom) smbios = grub_efi_system_table->configuration_table[i].vendor_table; grub_dprintf ("efi", "SMBIOS: %p\n", smbios); } - else if (! grub_memcmp (guid, &smbios3_guid, sizeof (grub_efi_guid_t))) - { - smbios3 = grub_efi_system_table->configuration_table[i].vendor_table; - grub_dprintf ("efi", "SMBIOS3: %p\n", smbios3); - } } *ebda_seg_ptr = FAKE_EBDA_SEG; @@ -144,13 +137,8 @@ fake_bios_data (int use_rom) if (acpi) grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16); - if (use_rom) - { - if (smbios) - grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios, 31); - if (smbios3) - grub_memcpy ((char *) SBIOS_ADDR + 32, (char *) smbios3, 24); - } + if ((use_rom) && (smbios)) + grub_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16); } static grub_err_t diff --git a/grub-core/commands/efi/lsefisystab.c b/grub-core/commands/efi/lsefisystab.c index 7c039c509..d29188efa 100644 --- a/grub-core/commands/efi/lsefisystab.c +++ b/grub-core/commands/efi/lsefisystab.c @@ -40,6 +40,7 @@ static const struct guid_mapping guid_mappings[] = { 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"}, @@ -72,7 +73,8 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)), 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, diff --git a/grub-core/commands/efi/smbios.c b/grub-core/commands/efi/smbios.c index 927702209..75202d5aa 100644 --- a/grub-core/commands/efi/smbios.c +++ b/grub-core/commands/efi/smbios.c @@ -1,7 +1,7 @@ /* smbios.c - get smbios tables. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 Free Software Foundation, Inc. + * 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 @@ -37,6 +37,7 @@ grub_machine_smbios_get_eps (void) return (struct grub_smbios_eps *) grub_efi_system_table->configuration_table[i].vendor_table; } + return 0; } @@ -55,5 +56,6 @@ grub_machine_smbios_get_eps3 (void) return (struct grub_smbios_eps3 *) grub_efi_system_table->configuration_table[i].vendor_table; } + return 0; } diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c index 32909c192..b03b6b296 100644 --- a/grub-core/commands/efi/tpm.c +++ b/grub-core/commands/efi/tpm.c @@ -119,103 +119,6 @@ grub_tpm_handle_find (grub_efi_handle_t *tpm_handle, return 0; } -static grub_err_t -grub_tpm1_execute (grub_efi_handle_t tpm_handle, - PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_status_t status; - grub_efi_tpm_protocol_t *tpm; - grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn); - grub_uint32_t outhdrsize = - sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut); - - tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm1_present (tpm)) - return 0; - - /* UEFI TPM protocol takes the raw operand block, no param block header. */ - status = efi_call_5 (tpm->pass_through_to_tpm, tpm, - inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, - outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); - - switch (status) - { - case GRUB_EFI_SUCCESS: - return 0; - case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("Command failed")); - case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); - case GRUB_EFI_BUFFER_TOO_SMALL: - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("Output buffer too small")); - case GRUB_EFI_NOT_FOUND: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); - default: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } -} - -static grub_err_t -grub_tpm2_execute (grub_efi_handle_t tpm_handle, - PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_status_t status; - grub_efi_tpm2_protocol_t *tpm; - grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn); - grub_uint32_t outhdrsize = - sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut); - - tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm2_present (tpm)) - return 0; - - /* UEFI TPM protocol takes the raw operand block, no param block header. */ - status = efi_call_5 (tpm->submit_command, tpm, - inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, - outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); - - switch (status) - { - case GRUB_EFI_SUCCESS: - return 0; - case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("Command failed")); - case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); - case GRUB_EFI_BUFFER_TOO_SMALL: - return grub_error (GRUB_ERR_BAD_ARGUMENT, - N_("Output buffer too small")); - case GRUB_EFI_NOT_FOUND: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); - default: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } -} - -grub_err_t -grub_tpm_execute (PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_handle_t tpm_handle; - grub_uint8_t protocol_version; - - /* Absence of a TPM isn't a failure. */ - if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) - return 0; - - if (protocol_version == 1) - return grub_tpm1_execute (tpm_handle, inbuf, outbuf); - else - return grub_tpm2_execute (tpm_handle, inbuf, outbuf); -} - static grub_err_t grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, grub_size_t size, grub_uint8_t pcr, @@ -247,6 +150,7 @@ grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, algorithm = TCG_ALG_SHA; status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size, algorithm, event, &eventnum, &lastevent); + grub_free (event); switch (status) { @@ -297,6 +201,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf, (grub_uint64_t) size, event); + grub_free (event); switch (status) { @@ -317,7 +222,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, } grub_err_t -grub_tpm_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, +grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description) { grub_efi_handle_t tpm_handle; diff --git a/grub-core/commands/fwconfig.c b/grub-core/commands/fwconfig.c deleted file mode 100644 index 3abe59f2b..000000000 --- a/grub-core/commands/fwconfig.c +++ /dev/null @@ -1,122 +0,0 @@ -/* fwconfig.c - command to read config from qemu fwconfig */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 CoreOS, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -#define SELECTOR 0x510 -#define DATA 0x511 - -#define SIGNATURE_INDEX 0x00 -#define DIRECTORY_INDEX 0x19 - -static grub_extcmd_t cmd_read_fwconfig; - -struct grub_qemu_fwcfgfile { - grub_uint32_t size; - grub_uint16_t select; - grub_uint16_t reserved; - char name[56]; -}; - -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_fwconfig (grub_extcmd_context_t ctxt __attribute__ ((unused)), - int argc, char **argv) -{ - grub_uint32_t i, j, value = 0; - struct grub_qemu_fwcfgfile file; - char fwsig[4], signature[4] = { 'Q', 'E', 'M', 'U' }; - - if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - - /* Verify that we have meaningful hardware here */ - grub_outw(SIGNATURE_INDEX, SELECTOR); - for (i=0; i. - */ - -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static const struct grub_arg_option options_next[] = { - {"set-device", 'd', 0, - N_("Set a variable to the name of selected partition."), - N_("VARNAME"), ARG_TYPE_STRING}, - {"set-uuid", 'u', 0, - N_("Set a variable to the GPT UUID of selected partition."), - N_("VARNAME"), ARG_TYPE_STRING}, - {0, 0, 0, 0, 0, 0} -}; - -enum options_next -{ - NEXT_SET_DEVICE, - NEXT_SET_UUID, -}; - -static unsigned int -grub_gptprio_priority (struct grub_gpt_partentry *entry) -{ - return (unsigned int) grub_gpt_entry_attribute - (entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_PRIORITY, 4); -} - -static unsigned int -grub_gptprio_tries_left (struct grub_gpt_partentry *entry) -{ - return (unsigned int) grub_gpt_entry_attribute - (entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4); -} - -static void -grub_gptprio_set_tries_left (struct grub_gpt_partentry *entry, - unsigned int tries_left) -{ - grub_gpt_entry_set_attribute - (entry, tries_left, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4); -} - -static unsigned int -grub_gptprio_successful (struct grub_gpt_partentry *entry) -{ - return (unsigned int) grub_gpt_entry_attribute - (entry, GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_SUCCESSFUL, 1); -} - -static grub_err_t -grub_find_next (const char *disk_name, - const grub_gpt_part_guid_t *part_type, - char **part_name, char **part_guid) -{ - struct grub_gpt_partentry *part, *part_found = NULL; - grub_device_t dev = NULL; - grub_gpt_t gpt = NULL; - grub_uint32_t i, part_index; - - dev = grub_device_open (disk_name); - if (!dev) - goto done; - - gpt = grub_gpt_read (dev->disk); - if (!gpt) - goto done; - - if (grub_gpt_repair (dev->disk, gpt)) - goto done; - - for (i = 0; (part = grub_gpt_get_partentry (gpt, i)) != NULL; i++) - { - if (grub_memcmp (part_type, &part->type, sizeof (*part_type)) == 0) - { - unsigned int priority, tries_left, successful, old_priority = 0; - - priority = grub_gptprio_priority (part); - tries_left = grub_gptprio_tries_left (part); - successful = grub_gptprio_successful (part); - - if (part_found) - old_priority = grub_gptprio_priority (part_found); - - if ((tries_left || successful) && priority > old_priority) - { - part_index = i; - part_found = part; - } - } - } - - if (!part_found) - { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such partition")); - goto done; - } - - if (grub_gptprio_tries_left (part_found)) - { - unsigned int tries_left = grub_gptprio_tries_left (part_found); - - grub_gptprio_set_tries_left (part_found, tries_left - 1); - - if (grub_gpt_update (gpt)) - goto done; - - if (grub_gpt_write (dev->disk, gpt)) - goto done; - } - - *part_name = grub_xasprintf ("%s,gpt%u", disk_name, part_index + 1); - if (!*part_name) - goto done; - - *part_guid = grub_gpt_guid_to_str (&part_found->guid); - if (!*part_guid) - goto done; - - grub_errno = GRUB_ERR_NONE; - -done: - grub_gpt_free (gpt); - - if (dev) - grub_device_close (dev); - - return grub_errno; -} - - - -static grub_err_t -grub_cmd_next (grub_extcmd_context_t ctxt, int argc, char **args) -{ - struct grub_arg_list *state = ctxt->state; - char *p, *root = NULL, *part_name = NULL, *part_guid = NULL; - - /* TODO: Add a uuid parser and a command line flag for providing type. */ - grub_gpt_part_guid_t part_type = GRUB_GPT_PARTITION_TYPE_USR_X86_64; - - if (!state[NEXT_SET_DEVICE].set || !state[NEXT_SET_UUID].set) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("-d and -u are required")); - goto done; - } - - if (argc == 0) - root = grub_strdup (grub_env_get ("root")); - else if (argc == 1) - root = grub_strdup (args[0]); - else - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected arguments")); - goto done; - } - - if (!root) - goto done; - - /* To make using $root practical strip off the partition name. */ - p = grub_strchr (root, ','); - if (p) - *p = '\0'; - - if (grub_find_next (root, &part_type, &part_name, &part_guid)) - goto done; - - if (grub_env_set (state[NEXT_SET_DEVICE].arg, part_name)) - goto done; - - if (grub_env_set (state[NEXT_SET_UUID].arg, part_guid)) - goto done; - - grub_errno = GRUB_ERR_NONE; - -done: - grub_free (root); - grub_free (part_name); - grub_free (part_guid); - - return grub_errno; -} - -static grub_extcmd_t cmd_next; - -GRUB_MOD_INIT(gptprio) -{ - cmd_next = grub_register_extcmd ("gptprio.next", grub_cmd_next, 0, - N_("-d VARNAME -u VARNAME [DEVICE]"), - N_("Select next partition to boot."), - options_next); -} - -GRUB_MOD_FINI(gptprio) -{ - grub_unregister_extcmd (cmd_next); -} diff --git a/grub-core/commands/gptrepair.c b/grub-core/commands/gptrepair.c deleted file mode 100644 index c17c7346c..000000000 --- a/grub-core/commands/gptrepair.c +++ /dev/null @@ -1,110 +0,0 @@ -/* gptrepair.c - verify and restore GPT info from alternate location. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * Copyright (C) 2014 CoreOS, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static char * -trim_dev_name (char *name) -{ - grub_size_t len = grub_strlen (name); - if (len && name[0] == '(' && name[len - 1] == ')') - { - name[len - 1] = '\0'; - name = name + 1; - } - return name; -} - -static grub_err_t -grub_cmd_gptrepair (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - grub_device_t dev = NULL; - grub_gpt_t gpt = NULL; - char *dev_name; - - if (argc != 1 || !grub_strlen(args[0])) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); - - dev_name = trim_dev_name (args[0]); - dev = grub_device_open (dev_name); - if (!dev) - goto done; - - if (!dev->disk) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk"); - goto done; - } - - gpt = grub_gpt_read (dev->disk); - if (!gpt) - goto done; - - if (grub_gpt_both_valid (gpt)) - { - grub_printf_ (N_("GPT already valid, %s unmodified.\n"), dev_name); - goto done; - } - - if (!grub_gpt_primary_valid (gpt)) - grub_printf_ (N_("Found invalid primary GPT on %s\n"), dev_name); - - if (!grub_gpt_backup_valid (gpt)) - grub_printf_ (N_("Found invalid backup GPT on %s\n"), dev_name); - - if (grub_gpt_repair (dev->disk, gpt)) - goto done; - - if (grub_gpt_write (dev->disk, gpt)) - goto done; - - grub_printf_ (N_("Repaired GPT on %s\n"), dev_name); - -done: - if (gpt) - grub_gpt_free (gpt); - - if (dev) - grub_device_close (dev); - - return grub_errno; -} - -static grub_command_t cmd; - -GRUB_MOD_INIT(gptrepair) -{ - cmd = grub_register_command ("gptrepair", grub_cmd_gptrepair, - N_("DEVICE"), - N_("Verify and repair GPT on drive DEVICE.")); -} - -GRUB_MOD_FINI(gptrepair) -{ - grub_unregister_command (cmd); -} diff --git a/grub-core/commands/i386/cmostest.c b/grub-core/commands/i386/cmostest.c index c839b704d..9f6b56a2f 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"); diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c index c81813105..a980e4688 100644 --- a/grub-core/commands/i386/pc/play.c +++ b/grub-core/commands/i386/pc/play.c @@ -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/smbios.c b/grub-core/commands/i386/pc/smbios.c index 3bdf3d766..069d66367 100644 --- a/grub-core/commands/i386/pc/smbios.c +++ b/grub-core/commands/i386/pc/smbios.c @@ -1,7 +1,7 @@ /* smbios.c - get smbios tables. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 Free Software Foundation, Inc. + * 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 @@ -27,11 +27,12 @@ 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) + + 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; } @@ -41,10 +42,11 @@ 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) + + for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000; ptr += 16) if (grub_memcmp (ptr, "_SM3_", 5) == 0 && grub_byte_checksum (ptr, sizeof (struct grub_smbios_eps3)) == 0) return (struct grub_smbios_eps3 *) ptr; + return 0; } diff --git a/grub-core/commands/i386/rdmsr.c b/grub-core/commands/i386/rdmsr.c index 15b9adfca..46c4346da 100644 --- a/grub-core/commands/i386/rdmsr.c +++ b/grub-core/commands/i386/rdmsr.c @@ -44,7 +44,7 @@ grub_cmd_msr_read (grub_extcmd_context_t ctxt, int argc, char **argv) { grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr; grub_uint64_t value; - char *ptr; + const char *ptr; char buf[sizeof("1122334455667788")]; /* diff --git a/grub-core/commands/i386/wrmsr.c b/grub-core/commands/i386/wrmsr.c index 9c5e510eb..fa76f5aed 100644 --- a/grub-core/commands/i386/wrmsr.c +++ b/grub-core/commands/i386/wrmsr.c @@ -37,7 +37,7 @@ grub_cmd_msr_write (grub_command_t cmd __attribute__ ((unused)), int argc, char { grub_uint32_t manufacturer[3], max_cpuid, a, b, c, features, addr; grub_uint64_t value; - char *ptr; + const char *ptr; /* * The CPUID instruction should be used to determine whether MSRs diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c index 460cf4e7e..ff3f58781 100644 --- a/grub-core/commands/keystatus.c +++ b/grub-core/commands/keystatus.c @@ -35,24 +35,6 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -static int -grub_getkeystatus (void) -{ - int status = 0; - grub_term_input_t term; - - if (grub_term_poll_usb) - grub_term_poll_usb (0); - - FOR_ACTIVE_TERM_INPUTS(term) - { - if (term->getkeystatus) - status |= term->getkeystatus (term); - } - - return status; -} - static grub_err_t grub_cmd_keystatus (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c index db7a8f002..cc5971f4d 100644 --- a/grub-core/commands/legacycfg.c +++ b/grub-core/commands/legacycfg.c @@ -32,6 +32,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -104,13 +105,22 @@ legacy_file (const char *filename) if (newsuffix) { char *t; - + grub_size_t sz; + + if (grub_add (grub_strlen (suffix), grub_strlen (newsuffix), &sz) || + grub_add (sz, 1, &sz)) + { + grub_errno = GRUB_ERR_OUT_OF_RANGE; + goto fail_0; + } + t = suffix; - suffix = grub_realloc (suffix, grub_strlen (suffix) - + grub_strlen (newsuffix) + 1); + suffix = grub_realloc (suffix, sz); if (!suffix) { grub_free (t); + + fail_0: grub_free (entrysrc); grub_free (parsed); grub_free (newsuffix); @@ -154,13 +164,22 @@ legacy_file (const char *filename) else { char *t; + grub_size_t sz; + + if (grub_add (grub_strlen (entrysrc), grub_strlen (parsed), &sz) || + grub_add (sz, 1, &sz)) + { + grub_errno = GRUB_ERR_OUT_OF_RANGE; + goto fail_1; + } t = entrysrc; - entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc) - + grub_strlen (parsed) + 1); + entrysrc = grub_realloc (entrysrc, sz); if (!entrysrc) { grub_free (t); + + fail_1: grub_free (parsed); grub_free (suffix); return grub_errno; @@ -314,7 +333,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; @@ -436,7 +455,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 +578,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])); diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c index 2c5363da7..9164df744 100644 --- a/grub-core/commands/menuentry.c +++ b/grub-core/commands/menuentry.c @@ -154,7 +154,7 @@ grub_normal_add_menu_entry (int argc, const char **args, goto fail; /* Save argc, args to pass as parameters to block arg later. */ - menu_args = grub_malloc (sizeof (char*) * (argc + 1)); + menu_args = grub_calloc (argc + 1, sizeof (char *)); if (! menu_args) goto fail; diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c index 699447d11..7c8f97f6a 100644 --- a/grub-core/commands/nativedisk.c +++ b/grub-core/commands/nativedisk.c @@ -195,7 +195,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)), else path_prefix = prefix; - mods = grub_malloc (argc * sizeof (mods[0])); + mods = grub_calloc (argc, sizeof (mods[0])); if (!mods) return grub_errno; diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c index 22b46b187..051e31320 100644 --- a/grub-core/commands/parttool.c +++ b/grub-core/commands/parttool.c @@ -59,7 +59,13 @@ grub_parttool_register(const char *part_name, for (nargs = 0; args[nargs].name != 0; nargs++); cur->nargs = nargs; cur->args = (struct grub_parttool_argdesc *) - grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc)); + grub_calloc (nargs + 1, sizeof (struct grub_parttool_argdesc)); + if (!cur->args) + { + grub_free (cur); + curhandle--; + return -1; + } grub_memcpy (cur->args, args, (nargs + 1) * sizeof (struct grub_parttool_argdesc)); @@ -257,7 +263,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), return err; } - parsed = (int *) grub_zalloc (argc * sizeof (int)); + parsed = (int *) grub_calloc (argc, sizeof (int)); for (i = 1; i < argc; i++) if (! parsed[i]) @@ -290,7 +296,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } ptool = cur; pargs = (struct grub_parttool_args *) - grub_zalloc (ptool->nargs * sizeof (struct grub_parttool_args)); + grub_calloc (ptool->nargs, sizeof (struct grub_parttool_args)); for (j = i; j < argc; j++) if (! parsed[j]) { diff --git a/grub-core/commands/password_pbkdf2.c b/grub-core/commands/password_pbkdf2.c index da636e621..ab845d25e 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; diff --git a/grub-core/commands/pcidump.c b/grub-core/commands/pcidump.c index f99ad4a21..f72628fce 100644 --- a/grub-core/commands/pcidump.c +++ b/grub-core/commands/pcidump.c @@ -95,7 +95,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (ctxt->state[0].set) { ptr = ctxt->state[0].arg; - ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff); + ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -108,8 +108,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (*ptr != ':') return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); ptr++; - ctx.pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff) - << 16; + ctx.pciid_check_value |= (grub_strtoul (ptr, &ptr, 16) & 0xffff) << 16; if (grub_errno == GRUB_ERR_BAD_NUMBER) grub_errno = GRUB_ERR_NONE; else @@ -121,10 +120,10 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (ctxt->state[1].set) { const char *optr; - + ptr = ctxt->state[1].arg; optr = ptr; - ctx.bus = grub_strtoul (ptr, (char **) &ptr, 16); + ctx.bus = grub_strtoul (ptr, &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -138,7 +137,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); ptr++; optr = ptr; - ctx.device = grub_strtoul (ptr, (char **) &ptr, 16); + ctx.device = grub_strtoul (ptr, &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; @@ -149,7 +148,7 @@ grub_cmd_pcidump (grub_extcmd_context_t ctxt, if (*ptr == '.') { ptr++; - ctx.function = grub_strtoul (ptr, (char **) &ptr, 16); + ctx.function = grub_strtoul (ptr, &ptr, 16); if (grub_errno) return grub_errno; ctx.check_function = 1; diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c index 91a1c7c90..bbf6871fe 100644 --- a/grub-core/commands/pgp.c +++ b/grub-core/commands/pgp.c @@ -759,78 +759,6 @@ grub_cmd_trust (grub_extcmd_context_t ctxt, return GRUB_ERR_NONE; } -static grub_ssize_t -pseudo_read (struct grub_file *file, char *buf, grub_size_t len) -{ - grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len); - return len; -} - -/* Filesystem descriptor. */ -struct grub_fs pseudo_fs = - { - .name = "pseudo", - .fs_read = pseudo_read - }; - -static grub_err_t -grub_cmd_trust_var (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) -{ - struct grub_file pseudo_file; - const char *var; - char *data; - struct grub_public_key *pk = NULL; - unsigned int i, idx0, idx1; - - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); - - var = grub_env_get (args[0]); - if (!var) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unknown variable")); - - data = grub_zalloc (grub_strlen (var) / 2); - if (!data) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate memory for key")); - - /* For the want of sscanf() */ - for (i = 0; i < grub_strlen (var); i += 2) - { - if (var[i] < 0x40) - idx0 = var[i] - 0x30; - else - idx0 = var[i] - 0x57; - - if (var[i+1] < 0x40) - idx1 = var[i+1] - 0x30; - else - idx1 = var[i+1] - 0x57; - - data[i/2] = ((idx0 << 4) & 0xf0) | (idx1 & 0x0f); - } - - grub_memset (&pseudo_file, 0, sizeof (pseudo_file)); - - pseudo_file.fs = &pseudo_fs; - pseudo_file.size = grub_strlen (var) / 2; - pseudo_file.data = data; - - pk = grub_load_public_key (&pseudo_file); - if (!pk) - { - grub_free(data); - return grub_errno; - } - - pk->next = grub_pk_trusted; - grub_pk_trusted = pk; - - grub_free(data); - return GRUB_ERR_NONE; - -} - static grub_err_t grub_cmd_list (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), @@ -994,6 +922,21 @@ grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)), return grub_strdup (sec ? "enforce" : "no"); } +static grub_ssize_t +pseudo_read (struct grub_file *file, char *buf, grub_size_t len) +{ + grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len); + return len; +} + + +/* Filesystem descriptor. */ +struct grub_fs pseudo_fs = + { + .name = "pseudo", + .fs_read = pseudo_read + }; + struct grub_file_verifier grub_pubkey_verifier = { .name = "pgp", @@ -1004,7 +947,7 @@ struct grub_file_verifier grub_pubkey_verifier = }; static grub_extcmd_t cmd, cmd_trust; -static grub_command_t cmd_trust_var, cmd_distrust, cmd_list; +static grub_command_t cmd_distrust, cmd_list; GRUB_MOD_INIT(pgp) { @@ -1055,9 +998,6 @@ GRUB_MOD_INIT(pgp) N_("[-s|--skip-sig] PUBKEY_FILE"), N_("Add PUBKEY_FILE to trusted keys."), options); - cmd_trust_var = grub_register_command ("trust_var", grub_cmd_trust_var, - N_("PUBKEY_VAR"), - N_("Add the contents of PUBKEY_VAR to trusted keys.")); cmd_list = grub_register_command ("list_trusted", grub_cmd_list, 0, N_("Show the list of trusted keys.")); @@ -1073,7 +1013,6 @@ GRUB_MOD_FINI(pgp) grub_verifier_unregister (&grub_pubkey_verifier); grub_unregister_extcmd (cmd); grub_unregister_extcmd (cmd_trust); - grub_unregister_command (cmd_trust_var); grub_unregister_command (cmd_list); grub_unregister_command (cmd_distrust); } diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index 95d272287..573bdf603 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,6 +101,52 @@ 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) + return grub_errno; + if (grub_strcmp(dev->disk->partition->partmap->name, "gpt") == 0) + { + struct grub_gpt_partentry entry; + grub_gpt_part_guid_t *guid; + + if (grub_disk_read(disk, p->offset, p->index, sizeof(entry), &entry)) + return grub_errno; + guid = &entry.guid; + grub_snprintf (val, sizeof(val), + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + grub_le_to_cpu32 (guid->data1), + grub_le_to_cpu16 (guid->data2), + grub_le_to_cpu16 (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]); + } + 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; diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c index f00b184c8..612003f94 100644 --- a/grub-core/commands/regexp.c +++ b/grub-core/commands/regexp.c @@ -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 fd411ce3e..ed090b3af 100644 --- a/grub-core/commands/search.c +++ b/grub-core/commands/search.c @@ -30,10 +30,6 @@ #include #include #include -#if defined(DO_SEARCH_PART_UUID) || defined(DO_SEARCH_PART_LABEL) || \ - defined(DO_SEARCH_DISK_UUID) -#include -#endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -70,7 +66,7 @@ iterate_device (const char *name, void *data) name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') return 1; -#if defined(DO_SEARCH_FS_UUID) || defined(DO_SEARCH_DISK_UUID) +#ifdef DO_SEARCH_FS_UUID #define compare_fn grub_strcasecmp #else #define compare_fn grub_strcmp @@ -94,63 +90,6 @@ iterate_device (const char *name, void *data) } grub_free (buf); } -#elif defined(DO_SEARCH_PART_UUID) - { - grub_device_t dev; - char *quid; - - dev = grub_device_open (name); - if (dev) - { - if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE) - { - if (grub_strcasecmp (quid, ctx->key) == 0) - found = 1; - - grub_free (quid); - } - - grub_device_close (dev); - } - } -#elif defined(DO_SEARCH_PART_LABEL) - { - grub_device_t dev; - char *quid; - - dev = grub_device_open (name); - if (dev) - { - if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE) - { - if (grub_strcmp (quid, ctx->key) == 0) - found = 1; - - grub_free (quid); - } - - grub_device_close (dev); - } - } -#elif defined(DO_SEARCH_DISK_UUID) - { - grub_device_t dev; - char *quid; - - dev = grub_device_open (name); - if (dev) - { - if (grub_gpt_disk_uuid (dev, &quid) == GRUB_ERR_NONE) - { - if (grub_strcmp (quid, ctx->key) == 0) - found = 1; - - grub_free (quid); - } - - grub_device_close (dev); - } - } #else { /* SEARCH_FS_UUID or SEARCH_LABEL */ @@ -374,14 +313,8 @@ static grub_command_t cmd; #ifdef DO_SEARCH_FILE GRUB_MOD_INIT(search_fs_file) -#elif defined(DO_SEARCH_PART_UUID) -GRUB_MOD_INIT(search_part_uuid) -#elif defined(DO_SEARCH_PART_LABEL) -GRUB_MOD_INIT(search_part_label) #elif defined (DO_SEARCH_FS_UUID) GRUB_MOD_INIT(search_fs_uuid) -#elif defined (DO_SEARCH_DISK_UUID) -GRUB_MOD_INIT(search_disk_uuid) #else GRUB_MOD_INIT(search_label) #endif @@ -394,14 +327,8 @@ GRUB_MOD_INIT(search_label) #ifdef DO_SEARCH_FILE GRUB_MOD_FINI(search_fs_file) -#elif defined(DO_SEARCH_PART_UUID) -GRUB_MOD_FINI(search_part_uuid) -#elif defined(DO_SEARCH_PART_LABEL) -GRUB_MOD_FINI(search_part_label) #elif defined (DO_SEARCH_FS_UUID) GRUB_MOD_FINI(search_fs_uuid) -#elif defined (DO_SEARCH_DISK_UUID) -GRUB_MOD_FINI(search_disk_uuid) #else GRUB_MOD_FINI(search_label) #endif diff --git a/grub-core/commands/search_disk_uuid.c b/grub-core/commands/search_disk_uuid.c deleted file mode 100644 index fba96f6b8..000000000 --- a/grub-core/commands/search_disk_uuid.c +++ /dev/null @@ -1,5 +0,0 @@ -#define DO_SEARCH_DISK_UUID 1 -#define FUNC_NAME grub_search_disk_uuid -#define COMMAND_NAME "search.disk_uuid" -#define HELP_MESSAGE N_("Search devices by disk UUID. If VARIABLE is specified, the first device found is set to a variable.") -#include "search.c" diff --git a/grub-core/commands/search_part_label.c b/grub-core/commands/search_part_label.c deleted file mode 100644 index ca906cbd9..000000000 --- a/grub-core/commands/search_part_label.c +++ /dev/null @@ -1,5 +0,0 @@ -#define DO_SEARCH_PART_LABEL 1 -#define FUNC_NAME grub_search_part_label -#define COMMAND_NAME "search.part_label" -#define HELP_MESSAGE N_("Search devices by partition label. If VARIABLE is specified, the first device found is set to a variable.") -#include "search.c" diff --git a/grub-core/commands/search_part_uuid.c b/grub-core/commands/search_part_uuid.c deleted file mode 100644 index 2d1d3d0d7..000000000 --- a/grub-core/commands/search_part_uuid.c +++ /dev/null @@ -1,5 +0,0 @@ -#define DO_SEARCH_PART_UUID 1 -#define FUNC_NAME grub_search_part_uuid -#define COMMAND_NAME "search.part_uuid" -#define HELP_MESSAGE N_("Search devices by partition UUID. If VARIABLE is specified, the first device found is set to a variable.") -#include "search.c" diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index d931c56c5..47fc8eb99 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -36,12 +36,6 @@ static const struct grub_arg_option options[] = 0, 0}, {"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."), 0, 0}, - {"part-label", 'L', 0, N_("Search devices by a partition label."), - 0, 0}, - {"part-uuid", 'U', 0, N_("Search devices by a partition UUID."), - 0, 0}, - {"disk-uuid", 'U', 0, N_("Search devices by a disk UUID."), - 0, 0}, {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("Set a variable to the first device found."), N_("VARNAME"), ARG_TYPE_STRING}, @@ -77,9 +71,6 @@ enum options SEARCH_FILE, SEARCH_LABEL, SEARCH_FS_UUID, - SEARCH_PART_LABEL, - SEARCH_PART_UUID, - SEARCH_DISK_UUID, SEARCH_SET, SEARCH_NO_FLOPPY, SEARCH_HINT, @@ -131,7 +122,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; @@ -195,15 +186,6 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) else if (state[SEARCH_FS_UUID].set) grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set, hints, nhints); - else if (state[SEARCH_PART_LABEL].set) - grub_search_part_label (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); - else if (state[SEARCH_PART_UUID].set) - grub_search_part_uuid (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); - else if (state[SEARCH_DISK_UUID].set) - grub_search_disk_uuid (id, var, state[SEARCH_NO_FLOPPY].set, - hints, nhints); else if (state[SEARCH_FILE].set) grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set, hints, nhints); diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index d5bc97d60..e966af080 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,14 +301,14 @@ 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; 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 index 82186319a..1a9086ddd 100644 --- a/grub-core/commands/smbios.c +++ b/grub-core/commands/smbios.c @@ -1,7 +1,7 @@ /* smbios.c - retrieve smbios information. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2013,2014,2015 Free Software Foundation, Inc. + * 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 @@ -27,86 +27,111 @@ 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. */ -struct grub_smbios_eps3 * +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; } -/* 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 = {0, 0, 0}; +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. The given buffer stores the - * newly formatted string if needed. When the requested data is successfully - * retrieved and formatted, the pointer to the string is returned; otherwise, - * NULL is returned on failure. + * 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 (char *buffer, grub_size_t size, - const grub_uint8_t *structure, grub_uint8_t offset) +grub_smbios_format_byte (const grub_uint8_t *structure, grub_uint8_t offset) { - grub_snprintf (buffer, size, "%u", structure[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 (char *buffer, grub_size_t size, - const grub_uint8_t *structure, grub_uint8_t offset) +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, size, "%u", value); + grub_snprintf (buffer, sizeof (buffer), "%u", value); + return (const char *)buffer; } static const char * -grub_smbios_format_dword (char *buffer, grub_size_t size, - const grub_uint8_t *structure, grub_uint8_t offset) +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, size, "%" PRIuGRUB_UINT32_T, value); + grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT32_T, value); + return (const char *)buffer; } static const char * -grub_smbios_format_qword (char *buffer, grub_size_t size, - const grub_uint8_t *structure, grub_uint8_t offset) +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, size, "%" PRIuGRUB_UINT64_T, value); + grub_snprintf (buffer, sizeof (buffer), "%" PRIuGRUB_UINT64_T, value); + return (const char *)buffer; } -/* The matching string pointer is returned directly to avoid extra copying. */ static const char * -grub_smbios_get_string (char *buffer __attribute__ ((unused)), - grub_size_t size __attribute__ ((unused)), - const grub_uint8_t *structure, grub_uint8_t offset) +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; @@ -135,25 +160,24 @@ grub_smbios_get_string (char *buffer __attribute__ ((unused)), } static const char * -grub_smbios_format_uuid (char *buffer, grub_size_t size, - const grub_uint8_t *structure, grub_uint8_t offset) +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, size, + + 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. */ -#define MAXIMUM_FORMAT_LENGTH (sizeof ("ffffffff-ffff-ffff-ffff-ffffffffffff")) static const struct { - const char *(*format) (char *buffer, grub_size_t size, - const grub_uint8_t *structure, grub_uint8_t offset); + const char *(*format) (const grub_uint8_t *structure, grub_uint8_t offset); grub_uint8_t field_length; } field_extractors[] = { {grub_smbios_format_byte, 1}, @@ -167,10 +191,12 @@ static const struct { /* 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 entries with the given type."), + {"type", 't', 0, N_("Match structures with the given type."), N_("type"), ARG_TYPE_INT}, - {"handle", 'h', 0, N_("Match entries with the given handle."), + {"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}, @@ -188,10 +214,11 @@ static const struct grub_arg_option options[] = { 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. * @@ -225,7 +252,6 @@ grub_smbios_match_structure (const grub_int16_t type, && (type < 0 || type == structure_type) && (match == 0 || match == ++matches)) return ptr; - else { ptr += ptr[1]; @@ -239,7 +265,6 @@ grub_smbios_match_structure (const grub_int16_t type, return NULL; } - static grub_err_t grub_cmd_smbios (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), @@ -254,7 +279,7 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt, const grub_uint8_t *structure; const char *value; - char buffer[MAXIMUM_FORMAT_LENGTH]; + char *modified_value = NULL; grub_int32_t option; grub_int8_t field_type = -1; grub_uint8_t i; @@ -283,7 +308,7 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt, if (state[2].set) { option = grub_strtol (state[2].arg, NULL, 0); - if (option <= 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; @@ -323,24 +348,25 @@ grub_cmd_smbios (grub_extcmd_context_t ctxt, N_("the field ends outside the structure")); /* Format the requested structure field into a readable string. */ - value = field_extractors[field_type].format (buffer, sizeof (buffer), - structure, offset); + 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; } - -static grub_extcmd_t cmd; - GRUB_MOD_INIT(smbios) { struct grub_smbios_eps3 *eps3; diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c index 4e929e045..62d3fb398 100644 --- a/grub-core/commands/test.c +++ b/grub-core/commands/test.c @@ -31,7 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); /* 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); diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c index 1441c494d..2052c36ea 100644 --- a/grub-core/commands/tpm.c +++ b/grub-core/commands/tpm.c @@ -29,13 +29,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); -grub_err_t -grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - return grub_tpm_log_event (buf, size, pcr, description); -} - static grub_err_t grub_tpm_verify_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)), diff --git a/grub-core/commands/verifiers.c b/grub-core/commands/verifiers.c index 0dde48182..aae4d84bb 100644 --- a/grub-core/commands/verifiers.c +++ b/grub-core/commands/verifiers.c @@ -196,7 +196,8 @@ grub_verifiers_open (grub_file_t io, enum grub_file_type type) return ret; fail: - ver->close (context); + if (ver->close) + ver->close (context); fail_noclose: verified_free (verified); grub_free (ret); @@ -207,6 +208,9 @@ grub_err_t grub_verify_string (char *str, enum grub_verify_string_type type) { struct grub_file_verifier *ver; + + grub_dprintf ("verify", "string: %s, type: %d\n", str, type); + FOR_LIST_ELEMENTS(ver, grub_file_verifiers) { grub_err_t err; diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c index 4be8107d5..016a4d818 100644 --- a/grub-core/commands/videoinfo.c +++ b/grub-core/commands/videoinfo.c @@ -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) diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index 4a106ca04..cc3290311 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; } 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/cryptodisk.c b/grub-core/disk/cryptodisk.c index 5037768fc..13af84dd1 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 @@ -404,6 +404,167 @@ grub_cryptodisk_decrypt (struct grub_cryptodisk *dev, return grub_cryptodisk_endecrypt (dev, data, len, sector, 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: %d", + 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: %d", + 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: %d", + 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, "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) + { + const char *hash_str = cipheriv + 6; + + mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV; + + /* Configure the hash and cipher used for ESSIV. */ + essiv_hash = grub_crypto_lookup_md_by_name (hash_str); + if (!essiv_hash) + { + ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, + "Couldn't load %s hash", hash_str); + goto err; + } + essiv_cipher = grub_crypto_cipher_open (ciph); + if (!essiv_cipher) + { + ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, + "Couldn't load %s cipher", ciphername); + goto err; + } + } + else + { + ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s", + cipheriv); + goto err; + } + + crypt->cipher = cipher; + crypt->benbi_log = benbi_log; + crypt->mode = mode; + crypt->mode_iv = mode_iv; + crypt->secondary_cipher = secondary_cipher; + crypt->essiv_cipher = essiv_cipher; + crypt->essiv_hash = essiv_hash; + +err: + if (ret) + { + grub_crypto_cipher_close (cipher); + grub_crypto_cipher_close (secondary_cipher); + } + return ret; +} + gcry_err_code_t grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize) { @@ -596,9 +757,8 @@ grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector, size, sector, dev->offset); 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), + 0, size << disk->log_sector_size, buf); if (err) { grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err); @@ -655,12 +815,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; 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"); @@ -1150,5 +1308,6 @@ GRUB_MOD_FINI (cryptodisk) { grub_disk_dev_unregister (&grub_cryptodisk_dev); cryptodisk_cleanup (); + grub_unregister_extcmd (cmd); grub_procfs_unregister (&luks_script); } diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c index c3b578acf..86557f923 100644 --- a/grub-core/disk/diskfilter.c +++ b/grub-core/disk/diskfilter.c @@ -969,7 +969,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) @@ -1134,7 +1135,7 @@ 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])); array->lvs->segments->stripe_size = stripe_size; for (i = 0; i < nmemb; i++) { @@ -1226,7 +1227,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); diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 3d3033547..8ca250c77 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -278,14 +278,10 @@ grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data, char name[10]; if (cd_drive && drive == cd_drive) - { - grub_dprintf ("biosdisk", "iterating cd\n"); - return hook ("cd", hook_data); - } + return hook ("cd", hook_data); grub_snprintf (name, sizeof (name), (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); - grub_dprintf ("biosdisk", "iterating %s\n", name); return hook (name, hook_data); } @@ -305,7 +301,7 @@ grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1, GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0) { - grub_dprintf ("biosdisk", "Read error when probing drive 0x%2x\n", drive); + grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive); break; } @@ -340,8 +336,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) int drive; struct grub_biosdisk_data *data; - grub_dprintf ("biosdisk", "opening %s\n", name); - drive = grub_biosdisk_get_drive (name); if (drive < 0) return grub_errno; @@ -399,11 +393,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) (1 << disk->log_sector_size) < drp->bytes_per_sector; disk->log_sector_size++); } - - grub_dprintf ("biosdisk", - "LBA total = 0x%llx block size = 0x%lx\n", - (unsigned long long) total_sectors, - 1L << disk->log_sector_size); } } } @@ -439,9 +428,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) if (! total_sectors) total_sectors = ((grub_uint64_t) data->cylinders) * data->heads * data->sectors; - - grub_dprintf ("biosdisk", "C/H/S %lu/%lu/%lu\n", - data->cylinders, data->heads, data->sectors); } disk->total_sectors = total_sectors; @@ -454,15 +440,12 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) disk->data = data; - grub_dprintf ("biosdisk", "opening %s succeeded\n", name); - return GRUB_ERR_NONE; } static void grub_biosdisk_close (grub_disk_t disk) { - grub_dprintf ("biosdisk", "closing %s\n", disk->name); grub_free (disk->data); } @@ -594,9 +577,6 @@ static grub_err_t grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) { - grub_dprintf ("biosdisk", "reading 0x%lx sectors at 0x%llx from %s\n", - (unsigned long) size, (unsigned long long) sector, disk->name); - while (size) { grub_size_t len; @@ -627,9 +607,6 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, { struct grub_biosdisk_data *data = disk->data; - grub_dprintf ("biosdisk", "writing 0x%lx sectors at 0x%llx to %s\n", - (unsigned long) size, (unsigned long long) sector, disk->name); - if (data->flags & GRUB_BIOSDISK_FLAG_CDROM) return grub_error (GRUB_ERR_IO, N_("cannot write to CD-ROM")); diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index f73257e66..03674cb47 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -297,7 +297,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) { diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c index 2a22d2d6c..58f8a53e1 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 @@ -289,6 +290,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) @@ -323,8 +325,8 @@ make_vg (grub_disk_t disk, 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; ptr = vblk[i].dynamic; @@ -350,7 +352,13 @@ make_vg (grub_disk_t disk, grub_free (lv); goto fail2; } - lv->name = grub_malloc (*ptr + 1); + if (grub_add (*ptr, 1, &sz)) + { + grub_free (lv->internal_id); + grub_free (lv); + goto fail2; + } + lv->name = grub_malloc (sz); if (!lv->name) { grub_free (lv->internal_id); @@ -543,8 +551,8 @@ 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; } @@ -590,8 +598,8 @@ make_vg (grub_disk_t disk, } 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); + comp->segments->nodes = grub_calloc (comp->segments->node_alloc, + sizeof (*comp->segments->nodes)); if (!lv->segments->nodes) goto fail2; } @@ -599,10 +607,13 @@ make_vg (grub_disk_t disk, 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); + grub_size_t sz; + + if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || + grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) + goto fail2; + + t = grub_realloc (lv->segments->nodes, sz); if (!t) goto fail2; lv->segments->nodes = t; @@ -723,10 +734,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; @@ -1017,7 +1031,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/luks.c b/grub-core/disk/luks.c index 86c50c612..59702067a 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 @@ -75,15 +75,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, 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) @@ -103,6 +95,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, || grub_be_to_cpu16 (header.version) != 1) return NULL; + grub_memset (uuid, 0, sizeof (uuid)); optr = uuid; for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)]; iptr++) @@ -126,183 +119,33 @@ 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 = grub_be_to_cpu32 (header.payloadOffset); + newdev->source_disk = NULL; + newdev->log_sector_size = 9; + newdev->total_length = grub_disk_get_size (disk) - newdev->offset; + grub_memcpy (newdev->uuid, uuid, sizeof (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)); return newdev; } @@ -336,7 +179,7 @@ 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; diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c new file mode 100644 index 000000000..31d7166fc --- /dev/null +++ b/grub-core/disk/luks2.c @@ -0,0 +1,687 @@ +/* + * 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 + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define LUKS_MAGIC_1ST "LUKS\xBA\xBE" +#define LUKS_MAGIC_2ND "SKUL\xBA\xBE" + +#define MAX_PASSPHRASE 256 + +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 +{ + 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 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 +{ + /* 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", type); + + 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", type); + + 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", type); + + 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 i) +{ + grub_json_t keyslots, keyslot, digests, digest, segments, segment; + grub_size_t j, size; + grub_uint64_t idx; + + /* Get nth keyslot */ + if (grub_json_getvalue (&keyslots, root, "keyslots") || + grub_json_getchild (&keyslot, &keyslots, i) || + grub_json_getuint64 (&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 %"PRIuGRUB_SIZE, i); + + /* 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 (j = 0; j < size; j++) + { + if (grub_json_getchild (&digest, &digests, i) || + grub_json_getchild (&digest, &digest, 0) || + luks2_parse_digest (d, &digest)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Could not parse digest %"PRIuGRUB_SIZE, i); + + if ((d->keyslots & (1 << idx))) + break; + } + if (j == size) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No digest for keyslot %"PRIuGRUB_SIZE); + + /* 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 (j = 0; j < size; j++) + { + if (grub_json_getchild (&segment, &segments, i) || + grub_json_getuint64 (&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 %"PRIuGRUB_SIZE, i); + + if ((d->segments & (1 << idx))) + break; + } + if (j == size) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "No segment for digest %"PRIuGRUB_SIZE); + + 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, const char *check_uuid, int check_boot) +{ + grub_cryptodisk_t cryptodisk; + grub_luks2_header_t header; + char uuid[sizeof (header.uuid) + 1]; + grub_size_t i, j; + + if (check_boot) + return NULL; + + if (luks2_read_header (disk, &header)) + { + grub_errno = GRUB_ERR_NONE; + return NULL; + } + + for (i = 0, j = 0; i < sizeof (header.uuid); i++) + if (header.uuid[i] != '-') + uuid[j++] = header.uuid[i]; + uuid[j] = '\0'; + + if (check_uuid && grub_strcasecmp (check_uuid, uuid) != 0) + return NULL; + + cryptodisk = grub_zalloc (sizeof (*cryptodisk)); + if (!cryptodisk) + return NULL; + + COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (uuid)); + grub_memcpy (cryptodisk->uuid, uuid, sizeof (uuid)); + + cryptodisk->modname = "luks2"; + return cryptodisk; +} + +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]; + grub_size_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 (!base64_decode (d->digest, grub_strlen (d->digest), (char *)digest, &digestlen)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid digest"); + if (!base64_decode (d->salt, grub_strlen (d->salt), (char *)salt, &saltlen)) + 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 disk, 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; + grub_size_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 (!base64_decode (k->kdf.salt, grub_strlen (k->kdf.salt), + (char *)salt, &saltlen)) + { + 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 (disk, 0, k->area.offset, k->area.size, split_key); + if (ret) + { + grub_error (GRUB_ERR_IO, "Read error: %s\n", grub_errmsg); + goto err; + } + + gcry_ret = grub_cryptodisk_decrypt (crypt, split_key, k->area.size, 0); + 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 disk, + grub_cryptodisk_t crypt) +{ + grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; + char passphrase[MAX_PASSPHRASE], cipher[32]; + char *json_header = NULL, *part = NULL, *ptr; + grub_size_t candidate_key_len = 0, i, 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; + + ret = luks2_read_header (disk, &header); + if (ret) + return ret; + + json_header = grub_zalloc (grub_be_to_cpu64 (header.hdr_size) - sizeof (header)); + if (!json_header) + return GRUB_ERR_OUT_OF_MEMORY; + + /* Read the JSON area. */ + ret = grub_disk_read (disk, 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; + } + + /* Get the passphrase from the user. */ + if (disk->partition) + part = grub_partition_get_name (disk->partition); + grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), disk->name, + disk->partition ? "," : "", part ? : "", + crypt->uuid); + if (!grub_password_get (passphrase, MAX_PASSPHRASE)) + { + ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied"); + 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; + } + + /* Try all keyslot */ + for (i = 0; i < size; i++) + { + ret = luks2_get_keyslot (&keyslot, &digest, &segment, json, i); + if (ret) + goto err; + + if (keyslot.priority == 0) + { + grub_dprintf ("luks2", "Ignoring keyslot %"PRIuGRUB_SIZE" due to priority\n", i); + continue; + } + + grub_dprintf ("luks2", "Trying keyslot %"PRIuGRUB_SIZE"\n", i); + + /* Set up disk according to keyslot's segment. */ + crypt->offset = grub_divmod64 (segment.offset, segment.sector_size, NULL); + crypt->log_sector_size = sizeof (unsigned int) * 8 + - __builtin_clz ((unsigned int) segment.sector_size) - 1; + if (grub_strcmp (segment.size, "dynamic") == 0) + crypt->total_length = grub_disk_get_size (disk) - crypt->offset; + else + crypt->total_length = grub_strtoull (segment.size, NULL, 10); + + ret = luks2_decrypt_key (candidate_key, disk, crypt, &keyslot, + (const grub_uint8_t *) passphrase, grub_strlen (passphrase)); + if (ret) + { + grub_dprintf ("luks2", "Decryption with keyslot %"PRIuGRUB_SIZE" failed: %s\n", + i, grub_errmsg); + continue; + } + + ret = luks2_verify_key (&digest, candidate_key, keyslot.key_size); + if (ret) + { + grub_dprintf ("luks2", "Could not open keyslot %"PRIuGRUB_SIZE": %s\n", + i, grub_errmsg); + continue; + } + + /* + * TRANSLATORS: It's a cryptographic key slot: one element of an array + * where each element is either empty or holds a key. + */ + grub_printf_ (N_("Slot %"PRIuGRUB_SIZE" opened\n"), i); + + 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 (part); + 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..753545146 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,20 @@ GRUB_MOD_LICENSE ("GPLv3+"); +struct cache_lv +{ + struct grub_diskfilter_lv *lv; + char *cache_pool; + char *origin; + struct cache_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 +72,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,6 +104,34 @@ grub_lvm_check_flag (char *p, const char *str, const char *flag) } } +static void +grub_lvm_free_cache_lvs (struct cache_lv *cache_lvs) +{ + struct cache_lv *cache; + + while ((cache = cache_lvs)) + { + cache_lvs = cache_lvs->next; + + if (cache->lv) + { + unsigned int i; + + for (i = 0; i < cache->lv->segment_count; ++i) + if (cache->lv->segments) + grub_free (cache->lv->segments[i].nodes); + grub_free (cache->lv->segments); + grub_free (cache->lv->fullname); + grub_free (cache->lv->idname); + grub_free (cache->lv->name); + } + grub_free (cache->lv); + grub_free (cache->origin); + grub_free (cache->cache_pool); + grub_free (cache); + } +} + static struct grub_diskfilter_vg * grub_lvm_detect (grub_disk_t disk, struct grub_diskfilter_pv_id *id, @@ -102,10 +139,12 @@ grub_lvm_detect (grub_disk_t disk, { 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; @@ -173,7 +212,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; @@ -205,19 +244,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 ((grub_size_t)metadatabuf, (grub_size_t)mda_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 +293,8 @@ grub_lvm_detect (grub_disk_t disk, if (! vg) { + struct cache_lv *cache_lvs = NULL; + /* First time we see this volume group. We've to create the whole volume group structure. */ vg = grub_malloc (sizeof (*vg)); @@ -367,8 +420,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 +497,7 @@ 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)); seg = lv->segments; for (i = 0; i < lv->segment_count; i++) @@ -483,8 +554,8 @@ grub_lvm_detect (grub_disk_t disk, if (seg->node_count != 1) seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = "); - seg->nodes = grub_zalloc (sizeof (*stripe) - * seg->node_count); + seg->nodes = grub_calloc (seg->node_count, + sizeof (*stripe)); stripe = seg->nodes; p = grub_strstr (p, "stripes = ["); @@ -671,6 +742,106 @@ grub_lvm_detect (grub_disk_t disk, seg->nodes[seg->node_count - 1].name = tmp; } } + else if (grub_memcmp (p, "cache\"", + sizeof ("cache\"") - 1) == 0) + { + struct cache_lv *cache = NULL; + + char *p2, *p3; + grub_size_t sz; + + cache = grub_zalloc (sizeof (*cache)); + if (!cache) + goto cache_lv_fail; + cache->lv = grub_zalloc (sizeof (*cache->lv)); + if (!cache->lv) + goto cache_lv_fail; + grub_memcpy (cache->lv, lv, sizeof (*cache->lv)); + + if (lv->fullname) + { + cache->lv->fullname = grub_strdup (lv->fullname); + if (!cache->lv->fullname) + goto cache_lv_fail; + } + if (lv->idname) + { + cache->lv->idname = grub_strdup (lv->idname); + if (!cache->lv->idname) + goto cache_lv_fail; + } + if (lv->name) + { + cache->lv->name = grub_strdup (lv->name); + if (!cache->lv->name) + goto cache_lv_fail; + } + + skip_lv = 1; + + p2 = grub_strstr (p, "cache_pool = \""); + if (!p2) + goto cache_lv_fail; + + p2 = grub_strchr (p2, '"'); + if (!p2) + goto cache_lv_fail; + + p3 = ++p2; + p3 = grub_strchr (p3, '"'); + if (!p3) + goto cache_lv_fail; + + sz = p3 - p2; + + cache->cache_pool = grub_malloc (sz + 1); + if (!cache->cache_pool) + goto cache_lv_fail; + grub_memcpy (cache->cache_pool, p2, sz); + cache->cache_pool[sz] = '\0'; + + p2 = grub_strstr (p, "origin = \""); + if (!p2) + goto cache_lv_fail; + + p2 = grub_strchr (p2, '"'); + if (!p2) + goto cache_lv_fail; + + p3 = ++p2; + p3 = grub_strchr (p3, '"'); + if (!p3) + goto cache_lv_fail; + + sz = p3 - p2; + + cache->origin = grub_malloc (sz + 1); + if (!cache->origin) + goto cache_lv_fail; + grub_memcpy (cache->origin, p2, sz); + cache->origin[sz] = '\0'; + + cache->next = cache_lvs; + cache_lvs = cache; + break; + + cache_lv_fail: + if (cache) + { + grub_free (cache->origin); + grub_free (cache->cache_pool); + if (cache->lv) + { + grub_free (cache->lv->fullname); + grub_free (cache->lv->idname); + grub_free (cache->lv->name); + } + grub_free (cache->lv); + grub_free (cache); + } + grub_lvm_free_cache_lvs (cache_lvs); + goto fail4; + } else { #ifdef GRUB_UTIL @@ -747,6 +918,58 @@ grub_lvm_detect (grub_disk_t disk, } } + + { + struct cache_lv *cache; + + for (cache = cache_lvs; cache; cache = cache->next) + { + struct grub_diskfilter_lv *lv; + + for (lv = vg->lvs; lv; lv = lv->next) + if (grub_strcmp (lv->name, cache->origin) == 0) + break; + if (lv) + { + cache->lv->segments = grub_calloc (lv->segment_count, sizeof (*lv->segments)); + if (!cache->lv->segments) + { + grub_lvm_free_cache_lvs (cache_lvs); + goto fail4; + } + grub_memcpy (cache->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; + + cache->lv->segments[i].nodes = grub_calloc (node_count, sizeof (*nodes)); + if (!cache->lv->segments[i].nodes) + { + for (j = 0; j < i; ++j) + grub_free (cache->lv->segments[j].nodes); + grub_free (cache->lv->segments); + cache->lv->segments = NULL; + grub_lvm_free_cache_lvs (cache_lvs); + goto fail4; + } + grub_memcpy (cache->lv->segments[i].nodes, nodes, node_count * sizeof (*nodes)); + } + + if (cache->lv->segments) + { + cache->lv->segment_count = lv->segment_count; + cache->lv->vg = vg; + cache->lv->next = vg->lvs; + vg->lvs = cache->lv; + cache->lv = NULL; + } + } + } + } + + grub_lvm_free_cache_lvs (cache_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..c980feba4 100644 --- a/grub-core/disk/mdraid1x_linux.c +++ b/grub-core/disk/mdraid1x_linux.c @@ -178,7 +178,7 @@ grub_mdraid_detect (grub_disk_t disk, return NULL; if (grub_disk_read (disk, sector, - (char *) &sb.dev_roles[grub_le_to_cpu32 (sb.dev_number)] + (char *) (sb.dev_roles + grub_le_to_cpu32 (sb.dev_number)) - (char *) &sb, sizeof (role), &role)) return NULL; diff --git a/grub-core/disk/xen/xendisk.c b/grub-core/disk/xen/xendisk.c index 48476cbbf..d6612eebd 100644 --- a/grub-core/disk/xen/xendisk.c +++ b/grub-core/disk/xen/xendisk.c @@ -426,7 +426,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/pc/cfgtables.c b/grub-core/efiemu/i386/pc/cfgtables.c index 1d8833115..e5fffb7d4 100644 --- a/grub-core/efiemu/i386/pc/cfgtables.c +++ b/grub-core/efiemu/i386/pc/cfgtables.c @@ -30,14 +30,10 @@ grub_machine_efiemu_init_tables (void) void *table; grub_err_t err; grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID; - grub_efi_guid_t smbios3 = GRUB_EFI_SMBIOS3_TABLE_GUID; grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID; grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID; err = grub_efiemu_unregister_configuration_table (smbios); - if (err) - return err; - err = grub_efiemu_unregister_configuration_table (smbios3); if (err) return err; err = grub_efiemu_unregister_configuration_table (acpi); @@ -47,20 +43,6 @@ grub_machine_efiemu_init_tables (void) if (err) return err; - table = grub_smbios_get_eps (); - if (table) - { - err = grub_efiemu_register_configuration_table (smbios, 0, 0, table); - if (err) - return err; - } - table = grub_smbios_get_eps3 (); - if (table) - { - err = grub_efiemu_register_configuration_table (smbios3, 0, 0, table); - if (err) - return err; - } table = grub_acpi_get_rsdpv1 (); if (table) { @@ -75,6 +57,13 @@ grub_machine_efiemu_init_tables (void) if (err) return err; } + table = grub_smbios_get_eps (); + if (table) + { + err = grub_efiemu_register_configuration_table (smbios, 0, 0, table); + if (err) + return err; + } return GRUB_ERR_NONE; } 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/mm.c b/grub-core/efiemu/mm.c index 52a032f7b..9b8e0d0ad 100644 --- a/grub-core/efiemu/mm.c +++ b/grub-core/efiemu/mm.c @@ -554,11 +554,11 @@ grub_efiemu_mmap_sort_and_uniq (void) /* Initialize variables*/ grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE); scanline_events = (struct grub_efiemu_mmap_scan *) - grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num); + grub_calloc (mmap_num, sizeof (struct grub_efiemu_mmap_scan) * 2); /* Number of chunks can't increase more than by factor of 2 */ result = (grub_efi_memory_descriptor_t *) - grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num); + grub_calloc (mmap_num, sizeof (grub_efi_memory_descriptor_t) * 2); if (!result || !scanline_events) { grub_free (result); @@ -660,7 +660,7 @@ grub_efiemu_mm_do_alloc (void) /* Preallocate mmap */ efiemu_mmap = (grub_efi_memory_descriptor_t *) - grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t)); + grub_calloc (mmap_reserved_size, sizeof (grub_efi_memory_descriptor_t)); if (!efiemu_mmap) { grub_efiemu_unload (); diff --git a/grub-core/efiemu/pnvram.c b/grub-core/efiemu/pnvram.c index c5c3d4bd3..dd42bc691 100644 --- a/grub-core/efiemu/pnvram.c +++ b/grub-core/efiemu/pnvram.c @@ -39,7 +39,7 @@ static grub_size_t nvramsize; /* Parse signed value */ static int -grub_strtosl (const char *arg, char **end, int base) +grub_strtosl (const char *arg, const char ** const end, int base) { if (arg[0] == '-') return -grub_strtoul (arg + 1, end, base); @@ -120,7 +120,8 @@ nvram_set (void * data __attribute__ ((unused))) grub_memset (nvram, 0, nvramsize); FOR_SORTED_ENV (var) { - char *guid, *attr, *name, *varname; + const char *guid; + char *attr, *name, *varname; struct efi_variable *efivar; int len = 0; int i; diff --git a/grub-core/font/font.c b/grub-core/font/font.c index 85a292557..d09bb38d8 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+"); @@ -293,8 +294,7 @@ 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)); @@ -361,9 +361,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; @@ -528,6 +532,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; diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c index 6b6a2bc91..220b3712f 100644 --- a/grub-core/fs/affs.c +++ b/grub-core/fs/affs.c @@ -301,7 +301,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); @@ -422,7 +422,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, return 1; } - hashtable = grub_zalloc (data->htsize * sizeof (*hashtable)); + hashtable = grub_calloc (data->htsize, sizeof (*hashtable)); if (!hashtable) return 1; @@ -628,7 +628,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'; } diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c index 48bd3d04a..27339bdb3 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c @@ -40,6 +40,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -136,6 +137,8 @@ struct grub_btrfs_chunk_item #define GRUB_BTRFS_CHUNK_TYPE_RAID10 0x40 #define GRUB_BTRFS_CHUNK_TYPE_RAID5 0x80 #define GRUB_BTRFS_CHUNK_TYPE_RAID6 0x100 +#define GRUB_BTRFS_CHUNK_TYPE_RAID1C3 0x200 +#define GRUB_BTRFS_CHUNK_TYPE_RAID1C4 0x400 grub_uint8_t dummy2[0xc]; grub_uint16_t nstripes; grub_uint16_t nsubstripes; @@ -329,9 +332,13 @@ save_ref (struct grub_btrfs_leaf_descriptor *desc, if (desc->allocated < desc->depth) { void *newdata; - desc->allocated *= 2; - newdata = grub_realloc (desc->data, sizeof (desc->data[0]) - * desc->allocated); + grub_size_t sz; + + if (grub_mul (desc->allocated, 2, &desc->allocated) || + grub_mul (desc->allocated, sizeof (desc->data[0]), &sz)) + return GRUB_ERR_OUT_OF_RANGE; + + newdata = grub_realloc (desc->data, sz); if (!newdata) return grub_errno; desc->data = newdata; @@ -413,7 +420,7 @@ lower_bound (struct grub_btrfs_data *data, { desc->allocated = 16; desc->depth = 0; - desc->data = grub_malloc (sizeof (desc->data[0]) * desc->allocated); + desc->data = grub_calloc (desc->allocated, sizeof (desc->data[0])); if (!desc->data) return grub_errno; } @@ -622,16 +629,21 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id) if (data->n_devices_attached > data->n_devices_allocated) { void *tmp; - data->n_devices_allocated = 2 * data->n_devices_attached + 1; - data->devices_attached - = grub_realloc (tmp = data->devices_attached, - data->n_devices_allocated - * sizeof (data->devices_attached[0])); + grub_size_t sz; + + if (grub_mul (data->n_devices_attached, 2, &data->n_devices_allocated) || + grub_add (data->n_devices_allocated, 1, &data->n_devices_allocated) || + grub_mul (data->n_devices_allocated, sizeof (data->devices_attached[0]), &sz)) + goto fail; + + data->devices_attached = grub_realloc (tmp = data->devices_attached, sz); if (!data->devices_attached) { + data->devices_attached = tmp; + + fail: if (ctx.dev_found) grub_device_close (ctx.dev_found); - data->devices_attached = tmp; return NULL; } } @@ -752,7 +764,7 @@ raid56_read_retry (struct grub_btrfs_data *data, grub_err_t ret = GRUB_ERR_OUT_OF_MEMORY; grub_uint64_t i, failed_devices; - buffers = grub_zalloc (sizeof(*buffers) * nstripes); + buffers = grub_calloc (nstripes, sizeof (*buffers)); if (!buffers) goto cleanup; @@ -964,14 +976,19 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, 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; break; } case GRUB_BTRFS_CHUNK_TYPE_RAID0: @@ -2160,7 +2177,7 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), *nsectors = 64 * 2 - 1; 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/fs/ext2.c b/grub-core/fs/ext2.c index 9b389802a..ac33bcd68 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+"); @@ -703,6 +704,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) { char *symlink; struct grub_fshelp_node *diro = node; + grub_size_t sz; if (! diro->inode_read) { @@ -717,7 +719,13 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) } } - symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); + if (grub_add (grub_le_to_cpu32 (diro->inode.size), 1, &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + return NULL; + } + + symlink = grub_malloc (sz); if (! symlink) return 0; diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c index d544e0af1..7f775a170 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 @@ -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++) { @@ -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_int32_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_int32_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,10 +1017,19 @@ 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 (info.mtimeset == 0) + grub_error (GRUB_ERR_OUT_OF_RANGE, + "invalid modification timestamp for %s", path); if (hook (ctxt.filename, &info, hook_data)) break; diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index ac0a40990..3fe842b4d 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -1360,7 +1360,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); diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 54786bb1c..9c4e4c88c 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -31,6 +31,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -475,8 +476,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; @@ -715,12 +720,12 @@ list_nodes (void *record, void *hook_arg) if (type == GRUB_FSHELP_UNKNOWN) return 0; - filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) - * GRUB_MAX_UTF8_PER_UTF16 + 1); + filename = grub_calloc (grub_be_to_cpu16 (catkey->namelen), + GRUB_MAX_UTF8_PER_UTF16 + 1); if (! filename) return 0; - keyname = grub_malloc (grub_be_to_cpu16 (catkey->namelen) * sizeof (*keyname)); + keyname = grub_calloc (grub_be_to_cpu16 (catkey->namelen), sizeof (*keyname)); if (!keyname) { grub_free (filename); @@ -1007,7 +1012,7 @@ grub_hfsplus_label (grub_device_t device, char **label) grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr); label_len = grub_be_to_cpu16 (catkey->namelen); - label_name = grub_malloc (label_len * sizeof (*label_name)); + label_name = grub_calloc (label_len, sizeof (*label_name)); if (!label_name) { grub_free (node); @@ -1029,7 +1034,7 @@ grub_hfsplus_label (grub_device_t device, char **label) } } - *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1); + *label = grub_calloc (label_len, GRUB_MAX_UTF8_PER_UTF16 + 1); if (! *label) { grub_free (label_name); diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c index 49c0c632b..5ec4433b8 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+"); @@ -331,7 +332,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; @@ -531,11 +532,22 @@ 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; } @@ -560,17 +572,24 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, { 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) { @@ -621,7 +640,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 +664,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; @@ -776,14 +805,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, 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 +832,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); diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index fc4e1f678..2f34f76da 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -556,8 +556,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); diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c index 50c1fe72f..de2b107a4 100644 --- a/grub-core/fs/sfs.c +++ b/grub-core/fs/sfs.c @@ -26,6 +26,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -266,7 +267,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 +308,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; @@ -477,10 +483,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 +736,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, diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c index 95d5c1e1f..a5f35c10e 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" @@ -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_size_t sz; + + if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + 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), @@ -557,6 +576,7 @@ 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; err = read_chunk (dir->data, &di, sizeof (di), grub_le_to_cpu64 (dir->data->sb.diroffset) @@ -589,13 +609,16 @@ 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 (grub_add (dir->stsize, 1, &sz) || + grub_mul (sz, 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 - sizeof(dir->stack[0])); node->ino = ino; node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); @@ -746,7 +769,7 @@ 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; diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c index 7d63e0c99..c551ed6b5 100644 --- a/grub-core/fs/tar.c +++ b/grub-core/fs/tar.c @@ -120,7 +120,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, if (data->linkname_alloc < linksize + 1) { char *n; - n = grub_malloc (2 * (linksize + 1)); + n = grub_calloc (2, linksize + 1); if (!n) return grub_errno; grub_free (data->linkname); diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c index dc8b6e2d1..2ac5c1d00 100644 --- a/grub-core/fs/udf.c +++ b/grub-core/fs/udf.c @@ -28,6 +28,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -873,7 +874,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) { unsigned i; utf16len = sz - 1; - utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + utf16 = grub_calloc (utf16len, sizeof (utf16[0])); if (!utf16) return NULL; for (i = 0; i < utf16len; i++) @@ -883,16 +884,26 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) { unsigned i; utf16len = (sz - 1) / 2; - utf16 = grub_malloc (utf16len * sizeof (utf16[0])); + utf16 = grub_calloc (utf16len, sizeof (utf16[0])); if (!utf16) return NULL; for (i = 0; i < utf16len; i++) utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; } if (!outbuf) - outbuf = grub_malloc (utf16len * GRUB_MAX_UTF8_PER_UTF16 + 1); + { + grub_size_t size; + + if (grub_mul (utf16len, GRUB_MAX_UTF8_PER_UTF16, &size) || + grub_add (size, 1, &size)) + goto fail; + + outbuf = grub_malloc (size); + } if (outbuf) *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0'; + + fail: grub_free (utf16); return outbuf; } @@ -954,8 +965,10 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, return 0; if (grub_udf_read_icb (dir->data, &dirent.icb, child)) - return 0; - + { + grub_free (child); + return 0; + } if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) { /* This is the parent directory. */ @@ -977,11 +990,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)) { @@ -1005,7 +1025,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node) grub_size_t sz = U64 (node->block.fe.file_size); grub_uint8_t *raw; const grub_uint8_t *ptr; - char *out, *optr; + char *out = NULL, *optr; if (sz < 4) return NULL; @@ -1013,14 +1033,16 @@ 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); + if (grub_mul (sz, 2, &sz) || + grub_add (sz, 1, &sz)) + goto fail_0; + + out = grub_malloc (sz); if (!out) { + fail_0: grub_free (raw); return NULL; } @@ -1031,17 +1053,17 @@ grub_udf_read_symlink (grub_fshelp_node_t node) { grub_size_t s; if ((grub_size_t) (ptr - raw + 4) > sz) - goto fail; + goto fail_1; if (!(ptr[2] == 0 && ptr[3] == 0)) - goto fail; + goto fail_1; s = 4 + ptr[1]; if ((grub_size_t) (ptr - raw + s) > sz) - goto fail; + goto fail_1; switch (*ptr) { case 1: if (ptr[1]) - goto fail; + goto fail_1; /* Fallthrough. */ case 2: /* in 4 bytes. out: 1 byte. */ @@ -1066,11 +1088,11 @@ grub_udf_read_symlink (grub_fshelp_node_t node) if (optr != out) *optr++ = '/'; if (!read_string (ptr + 4, s - 4, optr)) - goto fail; + goto fail_1; optr += grub_strlen (optr); break; default: - goto fail; + goto fail_1; } ptr += s; } @@ -1078,7 +1100,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"); diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 96ffecbfc..ea6590290 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -25,6 +25,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -899,6 +900,7 @@ 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) @@ -913,10 +915,11 @@ 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_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; diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c index 2f72e42bf..41ef0ff57 100644 --- a/grub-core/fs/zfs/zfs.c +++ b/grub-core/fs/zfs/zfs.c @@ -55,6 +55,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -141,7 +142,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]; } @@ -773,11 +777,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; @@ -3325,7 +3332,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); @@ -3468,14 +3475,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)); @@ -4336,7 +4347,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++) diff --git a/grub-core/fs/zfs/zfscrypt.c b/grub-core/fs/zfs/zfscrypt.c index 1402e0bc2..de3b015f5 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 @@ -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; diff --git a/grub-core/gfxmenu/gui_circular_progress.c b/grub-core/gfxmenu/gui_circular_progress.c index 354dd7b73..7578bfbec 100644 --- a/grub-core/gfxmenu/gui_circular_progress.c +++ b/grub-core/gfxmenu/gui_circular_progress.c @@ -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..6b2e976f1 100644 --- a/grub-core/gfxmenu/gui_image.c +++ b/grub-core/gfxmenu/gui_image.c @@ -195,7 +195,10 @@ load_image (grub_gui_image_t self, const char *path) return grub_errno; if (self->bitmap && (self->bitmap != self->raw_bitmap)) - grub_video_bitmap_destroy (self->bitmap); + { + grub_video_bitmap_destroy (self->bitmap); + self->bitmap = 0; + } if (self->raw_bitmap) grub_video_bitmap_destroy (self->raw_bitmap); diff --git a/grub-core/gfxmenu/gui_string_util.c b/grub-core/gfxmenu/gui_string_util.c index a9a415e31..ba1e1eab3 100644 --- a/grub-core/gfxmenu/gui_string_util.c +++ b/grub-core/gfxmenu/gui_string_util.c @@ -55,7 +55,7 @@ canonicalize_path (const char *path) if (*p == '/') components++; - char **path_array = grub_malloc (components * sizeof (*path_array)); + char **path_array = grub_calloc (components, sizeof (*path_array)); if (! path_array) return 0; diff --git a/grub-core/gfxmenu/theme_loader.c b/grub-core/gfxmenu/theme_loader.c index d6829bb5e..eae83086b 100644 --- a/grub-core/gfxmenu/theme_loader.c +++ b/grub-core/gfxmenu/theme_loader.c @@ -484,7 +484,7 @@ parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *pr ptr++; } - num = grub_strtoul (ptr, (char **) &ptr, 0); + num = grub_strtoul (ptr, &ptr, 0); if (grub_errno) return grub_errno; if (sig) diff --git a/grub-core/gfxmenu/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/io/gzio.c b/grub-core/io/gzio.c index 6208a9763..43d98a7bd 100644 --- a/grub-core/io/gzio.c +++ b/grub-core/io/gzio.c @@ -554,7 +554,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) diff --git a/grub-core/kern/arm/cache.c b/grub-core/kern/arm/cache.c index af1c4bbf5..6c75193e4 100644 --- a/grub-core/kern/arm/cache.c +++ b/grub-core/kern/arm/cache.c @@ -93,13 +93,16 @@ probe_caches (void) grub_arch_cache_ilinesz = 8 << (cache_type & 3); type = ARCH_ARMV6; break; - case 0x80 ... 0x8f: + default: + /* + * The CTR register is pretty much unchanged from v7 onwards, + * and is guaranteed to be backward compatible (the IDC/DIC bits + * allow certain CMOs to be elided, but performing them is never + * wrong), hence handling it like its AArch64 equivalent. + */ grub_arch_cache_dlinesz = 4 << ((cache_type >> 16) & 0xf); grub_arch_cache_ilinesz = 4 << (cache_type & 0xf); type = ARCH_ARMV7; - break; - default: - grub_fatal ("Unsupported cache type 0x%x", cache_type); } if (grub_arch_cache_dlinesz > grub_arch_cache_ilinesz) grub_arch_cache_max_linesz = grub_arch_cache_dlinesz; diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c index 06df60e2f..40c3b467f 100644 --- a/grub-core/kern/arm/efi/init.c +++ b/grub-core/kern/arm/efi/init.c @@ -71,4 +71,7 @@ grub_machine_fini (int flags) efi_call_1 (b->close_event, tmr_evt); grub_efi_fini (); + + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) + grub_efi_memory_fini (); } diff --git a/grub-core/kern/arm64/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/dl.c b/grub-core/kern/dl.c index 24d506512..48eb5e7b6 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -32,21 +32,12 @@ #include #include #include -#include /* Platforms where modules are in a readonly area of memory. */ #if defined(GRUB_MACHINE_QEMU) #define GRUB_MODULES_MACHINE_READONLY #endif -#ifdef GRUB_MACHINE_EMU -#include -#endif - -#ifdef GRUB_MACHINE_EFI -#include -#endif - #pragma GCC diagnostic ignored "-Wcast-align" @@ -695,15 +686,6 @@ grub_dl_load_file (const char *filename) void *core = 0; grub_dl_t mod = 0; -#ifdef GRUB_MACHINE_EFI - if (grub_efi_secure_boot ()) - { - grub_error (GRUB_ERR_ACCESS_DENIED, - "Secure Boot forbids loading module from %s", filename); - return 0; - } -#endif - grub_boot_time ("Loading module %s", filename); file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); @@ -730,9 +712,6 @@ grub_dl_load_file (const char *filename) opens of the same device. */ grub_file_close (file); - grub_tpm_measure(core, size, GRUB_BINARY_PCR, filename); - grub_print_error(); - mod = grub_dl_load_core (core, size); grub_free (core); if (! mod) diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index a0faa40ec..e0165e74c 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -157,7 +157,8 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle) void grub_reboot (void) { - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); efi_call_4 (grub_efi_system_table->runtime_services->reset_system, GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); for (;;) ; @@ -202,7 +203,7 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, len = grub_strlen (var); len16 = len * GRUB_MAX_UTF16_PER_UTF8; - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); + var16 = grub_calloc (len16 + 1, sizeof (var16[0])); if (!var16) return grub_errno; len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); @@ -237,7 +238,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, len = grub_strlen (var); len16 = len * GRUB_MAX_UTF16_PER_UTF8; - var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); + var16 = grub_calloc (len16 + 1, sizeof (var16[0])); if (!var16) return NULL; len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); @@ -273,34 +274,6 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, return NULL; } -grub_efi_boolean_t -grub_efi_secure_boot (void) -{ - grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; - grub_size_t datasize; - char *secure_boot = NULL; - char *setup_mode = NULL; - grub_efi_boolean_t ret = 0; - - secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); - - if (datasize != 1 || !secure_boot) - goto out; - - setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); - - if (datasize != 1 || !setup_mode) - goto out; - - if (*secure_boot && !*setup_mode) - ret = 1; - - out: - grub_free (secure_boot); - grub_free (setup_mode); - return ret; -} - #pragma GCC diagnostic ignored "-Wcast-align" /* Search the mods section from the PE32/PE32+ image. This code uses @@ -336,13 +309,23 @@ grub_efi_modules_addr (void) } 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; } @@ -360,7 +343,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) dp = dp0; - while (1) + while (dp) { grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); @@ -370,9 +353,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; } @@ -388,7 +377,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); @@ -404,14 +393,21 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0) *p++ = '/'; - len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4) - / sizeof (grub_efi_char16_t)); + len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); + if (len < 4) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, + "malformed EFI Device Path node has length=%d", len); + return NULL; + } + + len = (len - 4) / sizeof (grub_efi_char16_t); fp = (grub_efi_file_path_device_path_t *) dp; /* According to EFI spec Path Name is NULL terminated */ while (len > 0 && fp->path_name[len - 1] == 0) len--; - dup_name = grub_malloc (len * sizeof (*dup_name)); + dup_name = grub_calloc (len, sizeof (*dup_name)); if (!dup_name) { grub_free (name); @@ -480,7 +476,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=%d", len); + return NULL; + } + + total_size += len; if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p)) break; } @@ -525,7 +540,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); @@ -937,7 +952,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; @@ -973,5 +991,14 @@ 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; } diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index 3dfdf2d22..2c31847bf 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -80,5 +80,4 @@ grub_efi_fini (void) { grub_efidisk_fini (); grub_console_fini (); - grub_efi_memory_fini (); } diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index 671b1bf4d..457772d57 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -49,38 +49,6 @@ static grub_efi_uintn_t finish_desc_size; static grub_efi_uint32_t finish_desc_version; int grub_efi_is_finished = 0; -/* Allocate pages below a specified address */ -void * -grub_efi_allocate_pages_max (grub_efi_physical_address_t max, - grub_efi_uintn_t pages) -{ - grub_efi_status_t status; - grub_efi_boot_services_t *b; - grub_efi_physical_address_t address = max; - - if (max > 0xffffffff) - return 0; - - b = grub_efi_system_table->boot_services; - status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); - - if (status != GRUB_EFI_SUCCESS) - return 0; - - if (address == 0) - { - /* Uggh, the address 0 was allocated... This is too annoying, - so reallocate another one. */ - address = max; - status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); - grub_efi_free_pages (0, pages); - if (status != GRUB_EFI_SUCCESS) - return 0; - } - - return (void *) ((grub_addr_t) address); -} - /* * We need to roll back EFI allocations on exit. Remember allocations that * we'll free on exit. @@ -157,12 +125,20 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, /* Limit the memory access to less than 4GB for 32-bit platforms. */ if (address > GRUB_EFI_MAX_USABLE_ADDRESS) - return 0; + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("invalid memory address (0x%llx > 0x%llx)"), + address, GRUB_EFI_MAX_USABLE_ADDRESS); + return NULL; + } b = grub_efi_system_table->boot_services; status = efi_call_4 (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) { @@ -172,7 +148,10 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); grub_efi_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); diff --git a/grub-core/kern/efi/tpm.c b/grub-core/kern/efi/tpm.c deleted file mode 100644 index 532e534e4..000000000 --- a/grub-core/kern/efi/tpm.c +++ /dev/null @@ -1,273 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -static grub_efi_guid_t tpm_guid = EFI_TPM_GUID; -static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID; - -static grub_efi_boolean_t grub_tpm_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; - - caps.Size = (grub_uint8_t)sizeof(caps); - - status = efi_call_5(tpm->status_check, tpm, &caps, &flags, &eventlog, - &lastevent); - - if (status != GRUB_EFI_SUCCESS || caps.TPMDeactivatedFlag - || !caps.TPMPresentFlag) - return 0; - - return 1; -} - -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); - - status = efi_call_2(tpm->get_capability, tpm, &caps); - - if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) - return 0; - - return 1; -} - -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; - - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm_guid, NULL, - &num_handles); - if (handles && num_handles > 0) { - *tpm_handle = handles[0]; - *protocol_version = 1; - return 1; - } - - handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, - &num_handles); - if (handles && num_handles > 0) { - *tpm_handle = handles[0]; - *protocol_version = 2; - return 1; - } - - return 0; -} - -static grub_err_t -grub_tpm1_execute(grub_efi_handle_t tpm_handle, - PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_status_t status; - grub_efi_tpm_protocol_t *tpm; - grub_uint32_t inhdrsize = sizeof(*inbuf) - sizeof(inbuf->TPMOperandIn); - grub_uint32_t outhdrsize = sizeof(*outbuf) - sizeof(outbuf->TPMOperandOut); - - tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm_present(tpm)) - return 0; - - /* UEFI TPM protocol takes the raw operand block, no param block header */ - status = efi_call_5 (tpm->pass_through_to_tpm, tpm, - inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, - outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); - - switch (status) { - case GRUB_EFI_SUCCESS: - return 0; - case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("Command failed")); - case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); - case GRUB_EFI_BUFFER_TOO_SMALL: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); - case GRUB_EFI_NOT_FOUND: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); - default: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } -} - -static grub_err_t -grub_tpm2_execute(grub_efi_handle_t tpm_handle, - PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_status_t status; - grub_efi_tpm2_protocol_t *tpm; - grub_uint32_t inhdrsize = sizeof(*inbuf) - sizeof(inbuf->TPMOperandIn); - grub_uint32_t outhdrsize = sizeof(*outbuf) - sizeof(outbuf->TPMOperandOut); - - tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (!grub_tpm2_present(tpm)) - return 0; - - /* UEFI TPM protocol takes the raw operand block, no param block header */ - status = efi_call_5 (tpm->submit_command, tpm, - inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, - outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); - - switch (status) { - case GRUB_EFI_SUCCESS: - return 0; - case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("Command failed")); - case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); - case GRUB_EFI_BUFFER_TOO_SMALL: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); - case GRUB_EFI_NOT_FOUND: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); - default: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } -} - -grub_err_t -grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - grub_efi_handle_t tpm_handle; - grub_uint8_t protocol_version; - - /* It's not a hard failure for there to be no TPM */ - if (!grub_tpm_handle_find(&tpm_handle, &protocol_version)) - return 0; - - if (protocol_version == 1) { - return grub_tpm1_execute(tpm_handle, inbuf, outbuf); - } else { - return grub_tpm2_execute(tpm_handle, inbuf, outbuf); - } -} - -static grub_err_t -grub_tpm1_log_event(grub_efi_handle_t tpm_handle, unsigned char *buf, - grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - TCG_PCR_EVENT *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_tpm_present(tpm)) - return 0; - - event = grub_zalloc(sizeof (TCG_PCR_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_memcpy(event->Event, description, event->EventSize); - - algorithm = TCG_ALG_SHA; - status = efi_call_7 (tpm->log_extend_event, tpm, (grub_efi_physical_address_t)buf, (grub_uint64_t) size, - algorithm, event, &eventnum, &lastevent); - - switch (status) { - case GRUB_EFI_SUCCESS: - return 0; - case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("Command failed")); - case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); - case GRUB_EFI_BUFFER_TOO_SMALL: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); - case GRUB_EFI_NOT_FOUND: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); - default: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } -} - -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_memcpy(event->Event, description, grub_strlen(description) + 1); - - status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_efi_physical_address_t)buf, - (grub_uint64_t) size, event); - - switch (status) { - case GRUB_EFI_SUCCESS: - return 0; - case GRUB_EFI_DEVICE_ERROR: - return grub_error (GRUB_ERR_IO, N_("Command failed")); - case GRUB_EFI_INVALID_PARAMETER: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); - case GRUB_EFI_BUFFER_TOO_SMALL: - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); - case GRUB_EFI_NOT_FOUND: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); - default: - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); - } -} - -grub_err_t -grub_tpm_log_event(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; - - if (!grub_tpm_handle_find(&tpm_handle, &protocol_version)) - return 0; - - 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); - } -} diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index e9ec680cd..d975265b2 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.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/misc.c b/grub-core/kern/emu/misc.c index 65db79baa..dfd8a8ec4 100644 --- a/grub-core/kern/emu/misc.c +++ b/grub-core/kern/emu/misc.c @@ -85,6 +85,18 @@ grub_util_error (const char *fmt, ...) exit (1); } +void * +xcalloc (grub_size_t nmemb, grub_size_t size) +{ + void *p; + + p = calloc (nmemb, size); + if (!p) + grub_util_error ("%s", _("out of memory")); + + return p; +} + void * xmalloc (grub_size_t size) { 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/fs.c b/grub-core/kern/fs.c index 2b85f4950..fb30da9f4 100644 --- a/grub-core/kern/fs.c +++ b/grub-core/kern/fs.c @@ -134,7 +134,7 @@ struct grub_fs_block 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; @@ -151,7 +151,7 @@ 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; diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c index da499aba0..46476e27e 100644 --- a/grub-core/kern/i386/efi/init.c +++ b/grub-core/kern/i386/efi/init.c @@ -27,7 +27,6 @@ #include #include #include -#include void grub_machine_init (void) @@ -39,6 +38,11 @@ grub_machine_init (void) void grub_machine_fini (int flags) { - if (flags & GRUB_LOADER_FLAG_NORETURN) - grub_efi_fini (); + if (!(flags & GRUB_LOADER_FLAG_NORETURN)) + return; + + grub_efi_fini (); + + if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY)) + grub_efi_memory_fini (); } diff --git a/grub-core/kern/i386/pc/tpm.c b/grub-core/kern/i386/pc/tpm.c deleted file mode 100644 index f6f264aff..000000000 --- a/grub-core/kern/i386/pc/tpm.c +++ /dev/null @@ -1,145 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#define TCPA_MAGIC 0x41504354 - -static int tpm_presence = -1; - -int tpm_present(void); - -int tpm_present(void) -{ - struct grub_bios_int_registers regs; - - if (tpm_presence != -1) - return tpm_presence; - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - regs.eax = 0xbb00; - regs.ebx = TCPA_MAGIC; - grub_bios_interrupt (0x1a, ®s); - - if (regs.eax == 0) - tpm_presence = 1; - else - tpm_presence = 0; - - return tpm_presence; -} - -grub_err_t -grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf) -{ - struct grub_bios_int_registers regs; - grub_addr_t inaddr, outaddr; - - if (!tpm_present()) - return 0; - - inaddr = (grub_addr_t) inbuf; - outaddr = (grub_addr_t) outbuf; - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - regs.eax = 0xbb02; - regs.ebx = TCPA_MAGIC; - regs.ecx = 0; - regs.edx = 0; - regs.es = (inaddr & 0xffff0000) >> 4; - regs.edi = inaddr & 0xffff; - regs.ds = outaddr >> 4; - regs.esi = outaddr & 0xf; - - grub_bios_interrupt (0x1a, ®s); - - if (regs.eax) - { - tpm_presence = 0; - return grub_error (GRUB_ERR_IO, N_("TPM error %x, disabling TPM"), regs.eax); - } - - return 0; -} - -typedef struct { - grub_uint32_t pcrindex; - grub_uint32_t eventtype; - grub_uint8_t digest[20]; - grub_uint32_t eventdatasize; - grub_uint8_t event[0]; -} GRUB_PACKED Event; - -typedef struct { - grub_uint16_t ipblength; - grub_uint16_t reserved; - grub_uint32_t hashdataptr; - grub_uint32_t hashdatalen; - grub_uint32_t pcr; - grub_uint32_t reserved2; - grub_uint32_t logdataptr; - grub_uint32_t logdatalen; -} GRUB_PACKED EventIncoming; - -typedef struct { - grub_uint16_t opblength; - grub_uint16_t reserved; - grub_uint32_t eventnum; - grub_uint8_t hashvalue[20]; -} GRUB_PACKED EventOutgoing; - -grub_err_t -grub_tpm_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - struct grub_bios_int_registers regs; - EventIncoming incoming; - EventOutgoing outgoing; - Event *event; - grub_uint32_t datalength; - - if (!tpm_present()) - return 0; - - datalength = grub_strlen(description); - event = grub_zalloc(datalength + sizeof(Event)); - if (!event) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - N_("cannot allocate TPM event buffer")); - - event->pcrindex = pcr; - event->eventtype = 0x0d; - event->eventdatasize = grub_strlen(description); - grub_memcpy(event->event, description, datalength); - - incoming.ipblength = sizeof(incoming); - incoming.hashdataptr = (grub_uint32_t)buf; - incoming.hashdatalen = size; - incoming.pcr = pcr; - incoming.logdataptr = (grub_uint32_t)event; - incoming.logdatalen = datalength + sizeof(Event); - - regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; - regs.eax = 0xbb01; - regs.ebx = TCPA_MAGIC; - regs.ecx = 0; - regs.edx = 0; - regs.es = (((grub_addr_t) &incoming) & 0xffff0000) >> 4; - regs.edi = ((grub_addr_t) &incoming) & 0xffff; - regs.ds = (((grub_addr_t) &outgoing) & 0xffff0000) >> 4; - regs.esi = ((grub_addr_t) &outgoing) & 0xffff; - - grub_bios_interrupt (0x1a, ®s); - - grub_free(event); - - if (regs.eax) - { - tpm_presence = 0; - return grub_error (GRUB_ERR_IO, N_("TPM error %x, disabling TPM"), regs.eax); - } - - return 0; -} diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c index b5ecbd091..f1965571b 100644 --- a/grub-core/kern/ia64/efi/init.c +++ b/grub-core/kern/ia64/efi/init.c @@ -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/main.c b/grub-core/kern/main.c index 682d598f1..9cad0c448 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -131,9 +131,6 @@ grub_set_prefix_and_root (void) { char *cmdpath; - grub_env_set ("cmddevice", fwdevice); - grub_env_export ("cmddevice"); - cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); if (cmdpath) { 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/misc.c b/grub-core/kern/misc.c index 3b633d51f..a278e069b 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -158,17 +158,28 @@ int grub_err_printf (const char *fmt, ...) __attribute__ ((alias("grub_printf"))); #endif +int +grub_debug_enabled (const char * condition) +{ + const char *debug; + + debug = grub_env_get ("debug"); + if (!debug) + return 0; + + if (grub_strword (debug, "all") || grub_strword (debug, condition)) + return 1; + + return 0; +} + 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); va_start (args, fmt); @@ -340,7 +351,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 +369,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; @@ -588,7 +601,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 : 10; char *p; if ((long long) n < 0 && c == 'd') @@ -603,7 +616,7 @@ 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 @@ -676,6 +689,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, { case 'p': case 'x': + case 'X': case 'u': case 'd': case 'c': @@ -690,7 +704,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, 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) { grub_errno = GRUB_ERR_NONE; @@ -762,6 +776,7 @@ parse_printf_args (const char *fmt0, struct printf_args *args, switch (c) { case 'x': + case 'X': case 'u': args->ptr[curn].type = UNSIGNED_INT + longfmt; break; @@ -853,14 +868,14 @@ 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 == '$') { @@ -900,6 +915,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, c = 'x'; /* Fall through. */ case 'x': + case 'X': case 'u': case 'd': { diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c index ee88ff611..f2822a836 100644 --- a/grub-core/kern/mm.c +++ b/grub-core/kern/mm.c @@ -67,8 +67,10 @@ #include #include #include +#include #ifdef MM_DEBUG +# undef grub_calloc # undef grub_malloc # undef grub_zalloc # undef grub_realloc @@ -375,6 +377,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) @@ -561,6 +587,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, 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) { diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c index 78175aac2..619db3122 100644 --- a/grub-core/kern/parser.c +++ b/grub-core/kern/parser.c @@ -213,7 +213,7 @@ grub_parser_split_cmdline (const char *cmdline, 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); diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c index e499147cb..2c401b866 100644 --- a/grub-core/kern/partition.c +++ b/grub-core/kern/partition.c @@ -126,7 +126,7 @@ grub_partition_probe (struct grub_disk *disk, const char *str) while (*ptr && grub_isalpha (*ptr)) ptr++; partname_end = ptr; - num = grub_strtoul (ptr, (char **) &ptr, 0) - 1; + num = grub_strtoul (ptr, &ptr, 0) - 1; curpart = 0; /* Use the first partition map type found. */ diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c index 7eb1969d0..38795fe67 100644 --- a/grub-core/kern/riscv/efi/init.c +++ b/grub-core/kern/riscv/efi/init.c @@ -73,4 +73,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/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/tpm.c b/grub-core/kern/tpm.c deleted file mode 100644 index 9841d8d38..000000000 --- a/grub-core/kern/tpm.c +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include -#include -#include -#include - -grub_err_t -grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, - const char *description) -{ - return grub_tpm_log_event (buf, size, pcr, description); -} - diff --git a/grub-core/kern/uboot/uboot.c b/grub-core/kern/uboot/uboot.c index be4816fe6..aac8f9ae1 100644 --- a/grub-core/kern/uboot/uboot.c +++ b/grub-core/kern/uboot/uboot.c @@ -133,7 +133,7 @@ grub_uboot_dev_enum (void) return num_devices; max_devices = 2; - enum_devices = grub_malloc (sizeof(struct device_info) * max_devices); + enum_devices = grub_calloc (max_devices, sizeof(struct device_info)); if (!enum_devices) return 0; diff --git a/grub-core/lib/LzmaEnc.c b/grub-core/lib/LzmaEnc.c index f2ec04a8c..753e56a95 100644 --- a/grub-core/lib/LzmaEnc.c +++ b/grub-core/lib/LzmaEnc.c @@ -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..8439a0062 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); @@ -375,7 +382,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 +438,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 +451,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 ecfbe3409..ed0b149dc 100644 --- a/grub-core/lib/cmdline.c +++ b/grub-core/lib/cmdline.c @@ -19,7 +19,6 @@ #include #include -#include static unsigned int check_arg (char *c, int *has_space) { diff --git a/grub-core/normal/datetime.c b/grub-core/lib/datetime.c similarity index 100% rename from grub-core/normal/datetime.c rename to grub-core/lib/datetime.c diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c index 5859f0498..29d413641 100644 --- a/grub-core/lib/efi/halt.c +++ b/grub-core/lib/efi/halt.c @@ -28,7 +28,8 @@ void grub_halt (void) { - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN | + GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY); #if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \ !defined(__riscv) grub_acpi_halt (); 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/gnulib-patches/fix-base64.patch b/grub-core/lib/gnulib-patches/fix-base64.patch new file mode 100644 index 000000000..985db1279 --- /dev/null +++ b/grub-core/lib/gnulib-patches/fix-base64.patch @@ -0,0 +1,21 @@ +diff --git a/lib/base64.h b/lib/base64.h +index 9cd0183b8..185a2afa1 100644 +--- a/lib/base64.h ++++ b/lib/base64.h +@@ -21,8 +21,14 @@ + /* Get size_t. */ + # include + +-/* Get bool. */ +-# include ++#ifndef GRUB_POSIX_BOOL_DEFINED ++typedef enum { false = 0, true = 1 } bool; ++#define GRUB_POSIX_BOOL_DEFINED 1 ++#endif ++ ++#ifndef _GL_ATTRIBUTE_CONST ++# define _GL_ATTRIBUTE_CONST /* empty */ ++#endif + + # ifdef __cplusplus + extern "C" { diff --git a/grub-core/lib/gpt.c b/grub-core/lib/gpt.c deleted file mode 100644 index 80bca2e4e..000000000 --- a/grub-core/lib/gpt.c +++ /dev/null @@ -1,777 +0,0 @@ -/* gpt.c - Read/Verify/Write GUID Partition Tables (GPT). */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2005,2006,2007,2008 Free Software Foundation, Inc. - * Copyright (C) 2014 CoreOS, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_uint8_t grub_gpt_magic[] = GRUB_GPT_HEADER_MAGIC; - -static grub_err_t -grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt, - struct grub_gpt_header *header, - void **ret_entries, - grub_size_t *ret_entries_size); - -char * -grub_gpt_guid_to_str (grub_gpt_part_guid_t *guid) -{ - return grub_xasprintf ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - grub_le_to_cpu32 (guid->data1), - grub_le_to_cpu16 (guid->data2), - grub_le_to_cpu16 (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 grub_err_t -grub_gpt_device_partentry (grub_device_t device, - struct grub_gpt_partentry *entry) -{ - grub_disk_t disk = device->disk; - grub_partition_t p; - grub_err_t err; - - if (!disk || !disk->partition) - return grub_error (GRUB_ERR_BUG, "not a partition"); - - if (grub_strcmp (disk->partition->partmap->name, "gpt")) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a GPT partition"); - - p = disk->partition; - disk->partition = p->parent; - err = grub_disk_read (disk, p->offset, p->index, sizeof (*entry), entry); - disk->partition = p; - - return err; -} - -grub_err_t -grub_gpt_part_label (grub_device_t device, char **label) -{ - struct grub_gpt_partentry entry; - const grub_size_t name_len = ARRAY_SIZE (entry.name); - const grub_size_t label_len = name_len * GRUB_MAX_UTF8_PER_UTF16 + 1; - grub_size_t i; - grub_uint8_t *end; - - if (grub_gpt_device_partentry (device, &entry)) - return grub_errno; - - *label = grub_malloc (label_len); - if (!*label) - return grub_errno; - - for (i = 0; i < name_len; i++) - entry.name[i] = grub_le_to_cpu16 (entry.name[i]); - - end = grub_utf16_to_utf8 ((grub_uint8_t *) *label, entry.name, name_len); - *end = '\0'; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_gpt_part_uuid (grub_device_t device, char **uuid) -{ - struct grub_gpt_partentry entry; - - if (grub_gpt_device_partentry (device, &entry)) - return grub_errno; - - *uuid = grub_gpt_guid_to_str (&entry.guid); - if (!*uuid) - return grub_errno; - - return GRUB_ERR_NONE; -} - -static struct grub_gpt_header * -grub_gpt_get_header (grub_gpt_t gpt) -{ - if (gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) - return &gpt->primary; - else if (gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) - return &gpt->backup; - - grub_error (GRUB_ERR_BUG, "No valid GPT header"); - return NULL; -} - -grub_err_t -grub_gpt_disk_uuid (grub_device_t device, char **uuid) -{ - struct grub_gpt_header *header; - - grub_gpt_t gpt = grub_gpt_read (device->disk); - if (!gpt) - goto done; - - header = grub_gpt_get_header (gpt); - if (!header) - goto done; - - *uuid = grub_gpt_guid_to_str (&header->guid); - -done: - grub_gpt_free (gpt); - return grub_errno; -} - -static grub_uint64_t -grub_gpt_size_to_sectors (grub_gpt_t gpt, grub_size_t size) -{ - unsigned int sector_size; - grub_uint64_t sectors; - - sector_size = 1U << gpt->log_sector_size; - sectors = size / sector_size; - if (size % sector_size) - sectors++; - - return sectors; -} - -/* Copied from grub-core/kern/disk_common.c grub_disk_adjust_range so we can - * avoid attempting to use disk->total_sectors when GRUB won't let us. - * TODO: Why is disk->total_sectors not set to GRUB_DISK_SIZE_UNKNOWN? */ -static int -grub_gpt_disk_size_valid (grub_disk_t disk) -{ - grub_disk_addr_t total_sectors; - - /* 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)) - return 0; - - return 1; -} - -static void -grub_gpt_lecrc32 (grub_uint32_t *crc, const void *data, grub_size_t len) -{ - grub_uint32_t crc32_val; - - grub_crypto_hash (GRUB_MD_CRC32, &crc32_val, data, len); - - /* GRUB_MD_CRC32 always uses big endian, gpt is always little. */ - *crc = grub_swap_bytes32 (crc32_val); -} - -static void -grub_gpt_header_lecrc32 (grub_uint32_t *crc, struct grub_gpt_header *header) -{ - grub_uint32_t old, new; - - /* crc32 must be computed with the field cleared. */ - old = header->crc32; - header->crc32 = 0; - grub_gpt_lecrc32 (&new, header, sizeof (*header)); - header->crc32 = old; - - *crc = new; -} - -/* Make sure the MBR is a protective MBR and not a normal MBR. */ -grub_err_t -grub_gpt_pmbr_check (struct grub_msdos_partition_mbr *mbr) -{ - unsigned int i; - - if (mbr->signature != - grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid MBR signature"); - - for (i = 0; i < sizeof (mbr->entries); i++) - if (mbr->entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK) - return GRUB_ERR_NONE; - - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid protective MBR"); -} - -static grub_uint64_t -grub_gpt_entries_size (struct grub_gpt_header *gpt) -{ - return (grub_uint64_t) grub_le_to_cpu32 (gpt->maxpart) * - (grub_uint64_t) grub_le_to_cpu32 (gpt->partentry_size); -} - -static grub_uint64_t -grub_gpt_entries_sectors (struct grub_gpt_header *gpt, - unsigned int log_sector_size) -{ - grub_uint64_t sector_bytes, entries_bytes; - - sector_bytes = 1ULL << log_sector_size; - entries_bytes = grub_gpt_entries_size (gpt); - return grub_divmod64(entries_bytes + sector_bytes - 1, sector_bytes, NULL); -} - -static int -is_pow2 (grub_uint32_t n) -{ - return (n & (n - 1)) == 0; -} - -grub_err_t -grub_gpt_header_check (struct grub_gpt_header *gpt, - unsigned int log_sector_size) -{ - grub_uint32_t crc = 0, size; - grub_uint64_t start, end; - - if (grub_memcmp (gpt->magic, grub_gpt_magic, sizeof (grub_gpt_magic)) != 0) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT signature"); - - if (gpt->version != GRUB_GPT_HEADER_VERSION) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "unknown GPT version"); - - grub_gpt_header_lecrc32 (&crc, gpt); - if (gpt->crc32 != crc) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT header crc32"); - - /* The header size "must be greater than or equal to 92 and must be less - * than or equal to the logical block size." */ - size = grub_le_to_cpu32 (gpt->headersize); - if (size < 92U || size > (1U << log_sector_size)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT header size"); - - /* The partition entry size must be "a value of 128*(2^n) where n is an - * integer greater than or equal to zero (e.g., 128, 256, 512, etc.)." */ - size = grub_le_to_cpu32 (gpt->partentry_size); - if (size < 128U || size % 128U || !is_pow2 (size / 128U)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT entry size"); - - /* The minimum entries table size is specified in terms of bytes, - * regardless of how large the individual entry size is. */ - if (grub_gpt_entries_size (gpt) < GRUB_GPT_DEFAULT_ENTRIES_SIZE) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT entry table size"); - - /* And of course there better be some space for partitions! */ - start = grub_le_to_cpu64 (gpt->start); - end = grub_le_to_cpu64 (gpt->end); - if (start > end) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid usable sectors"); - - return GRUB_ERR_NONE; -} - -static int -grub_gpt_headers_equal (grub_gpt_t gpt) -{ - /* Assume headers passed grub_gpt_header_check so skip magic and version. - * Individual fields must be checked instead of just using memcmp because - * crc32, header, alternate, and partitions will all normally differ. */ - - if (gpt->primary.headersize != gpt->backup.headersize || - gpt->primary.header_lba != gpt->backup.alternate_lba || - gpt->primary.alternate_lba != gpt->backup.header_lba || - gpt->primary.start != gpt->backup.start || - gpt->primary.end != gpt->backup.end || - gpt->primary.maxpart != gpt->backup.maxpart || - gpt->primary.partentry_size != gpt->backup.partentry_size || - gpt->primary.partentry_crc32 != gpt->backup.partentry_crc32) - return 0; - - return grub_memcmp(&gpt->primary.guid, &gpt->backup.guid, - sizeof(grub_gpt_part_guid_t)) == 0; -} - -static grub_err_t -grub_gpt_check_primary (grub_gpt_t gpt) -{ - grub_uint64_t backup, primary, entries, entries_len, start, end; - - primary = grub_le_to_cpu64 (gpt->primary.header_lba); - backup = grub_le_to_cpu64 (gpt->primary.alternate_lba); - entries = grub_le_to_cpu64 (gpt->primary.partitions); - entries_len = grub_gpt_entries_sectors(&gpt->primary, gpt->log_sector_size); - start = grub_le_to_cpu64 (gpt->primary.start); - end = grub_le_to_cpu64 (gpt->primary.end); - - grub_dprintf ("gpt", "Primary GPT layout:\n" - "primary header = 0x%llx backup header = 0x%llx\n" - "entries location = 0x%llx length = 0x%llx\n" - "first usable = 0x%llx last usable = 0x%llx\n", - (unsigned long long) primary, - (unsigned long long) backup, - (unsigned long long) entries, - (unsigned long long) entries_len, - (unsigned long long) start, - (unsigned long long) end); - - if (grub_gpt_header_check (&gpt->primary, gpt->log_sector_size)) - return grub_errno; - if (primary != 1) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid primary GPT LBA"); - if (entries <= 1 || entries+entries_len > start) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid entries location"); - if (backup <= end) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid backup GPT LBA"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_gpt_check_backup (grub_gpt_t gpt) -{ - grub_uint64_t backup, primary, entries, entries_len, start, end; - - backup = grub_le_to_cpu64 (gpt->backup.header_lba); - primary = grub_le_to_cpu64 (gpt->backup.alternate_lba); - entries = grub_le_to_cpu64 (gpt->backup.partitions); - entries_len = grub_gpt_entries_sectors(&gpt->backup, gpt->log_sector_size); - start = grub_le_to_cpu64 (gpt->backup.start); - end = grub_le_to_cpu64 (gpt->backup.end); - - grub_dprintf ("gpt", "Backup GPT layout:\n" - "primary header = 0x%llx backup header = 0x%llx\n" - "entries location = 0x%llx length = 0x%llx\n" - "first usable = 0x%llx last usable = 0x%llx\n", - (unsigned long long) primary, - (unsigned long long) backup, - (unsigned long long) entries, - (unsigned long long) entries_len, - (unsigned long long) start, - (unsigned long long) end); - - if (grub_gpt_header_check (&gpt->backup, gpt->log_sector_size)) - return grub_errno; - if (primary != 1) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid primary GPT LBA"); - if (entries <= end || entries+entries_len > backup) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid entries location"); - if (backup <= end) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid backup GPT LBA"); - - /* If both primary and backup are valid but differ prefer the primary. */ - if ((gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) && - !grub_gpt_headers_equal (gpt)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "backup GPT out of sync"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_gpt_read_primary (grub_disk_t disk, grub_gpt_t gpt) -{ - grub_disk_addr_t addr; - - /* TODO: The gpt partmap module searches for the primary header instead - * of relying on the disk's sector size. For now trust the disk driver - * but eventually this code should match the existing behavior. */ - gpt->log_sector_size = disk->log_sector_size; - - grub_dprintf ("gpt", "reading primary GPT from sector 0x1\n"); - - addr = grub_gpt_sector_to_addr (gpt, 1); - if (grub_disk_read (disk, addr, 0, sizeof (gpt->primary), &gpt->primary)) - return grub_errno; - - if (grub_gpt_check_primary (gpt)) - return grub_errno; - - gpt->status |= GRUB_GPT_PRIMARY_HEADER_VALID; - - if (grub_gpt_read_entries (disk, gpt, &gpt->primary, - &gpt->entries, &gpt->entries_size)) - return grub_errno; - - gpt->status |= GRUB_GPT_PRIMARY_ENTRIES_VALID; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_gpt_read_backup (grub_disk_t disk, grub_gpt_t gpt) -{ - void *entries = NULL; - grub_size_t entries_size; - grub_uint64_t sector; - grub_disk_addr_t addr; - - /* Assumes gpt->log_sector_size == disk->log_sector_size */ - if (gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) - { - sector = grub_le_to_cpu64 (gpt->primary.alternate_lba); - if (grub_gpt_disk_size_valid (disk) && sector >= disk->total_sectors) - return grub_error (GRUB_ERR_OUT_OF_RANGE, - "backup GPT located at 0x%llx, " - "beyond last disk sector at 0x%llx", - (unsigned long long) sector, - (unsigned long long) disk->total_sectors - 1); - } - else if (grub_gpt_disk_size_valid (disk)) - sector = disk->total_sectors - 1; - else - return grub_error (GRUB_ERR_OUT_OF_RANGE, - "size of disk unknown, cannot locate backup GPT"); - - grub_dprintf ("gpt", "reading backup GPT from sector 0x%llx\n", - (unsigned long long) sector); - - addr = grub_gpt_sector_to_addr (gpt, sector); - if (grub_disk_read (disk, addr, 0, sizeof (gpt->backup), &gpt->backup)) - return grub_errno; - - if (grub_gpt_check_backup (gpt)) - return grub_errno; - - /* Ensure the backup header thinks it is located where we found it. */ - if (grub_le_to_cpu64 (gpt->backup.header_lba) != sector) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid backup GPT LBA"); - - gpt->status |= GRUB_GPT_BACKUP_HEADER_VALID; - - if (grub_gpt_read_entries (disk, gpt, &gpt->backup, - &entries, &entries_size)) - return grub_errno; - - if (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID) - { - if (entries_size != gpt->entries_size || - grub_memcmp (entries, gpt->entries, entries_size) != 0) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "backup GPT out of sync"); - - grub_free (entries); - } - else - { - gpt->entries = entries; - gpt->entries_size = entries_size; - } - - gpt->status |= GRUB_GPT_BACKUP_ENTRIES_VALID; - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_gpt_read_entries (grub_disk_t disk, grub_gpt_t gpt, - struct grub_gpt_header *header, - void **ret_entries, - grub_size_t *ret_entries_size) -{ - void *entries = NULL; - grub_uint32_t count, size, crc; - grub_uint64_t sector; - grub_disk_addr_t addr; - grub_size_t entries_size; - - /* Grub doesn't include calloc, hence the manual overflow check. */ - count = grub_le_to_cpu32 (header->maxpart); - size = grub_le_to_cpu32 (header->partentry_size); - entries_size = count *size; - if (size && entries_size / size != count) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - goto fail; - } - - /* Double check that the header was validated properly. */ - if (entries_size < GRUB_GPT_DEFAULT_ENTRIES_SIZE) - return grub_error (GRUB_ERR_BUG, "invalid GPT entries table size"); - - entries = grub_malloc (entries_size); - if (!entries) - goto fail; - - sector = grub_le_to_cpu64 (header->partitions); - grub_dprintf ("gpt", "reading GPT %lu entries from sector 0x%llx\n", - (unsigned long) count, - (unsigned long long) sector); - - addr = grub_gpt_sector_to_addr (gpt, sector); - if (grub_disk_read (disk, addr, 0, entries_size, entries)) - goto fail; - - grub_gpt_lecrc32 (&crc, entries, entries_size); - if (crc != header->partentry_crc32) - { - grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid GPT entry crc32"); - goto fail; - } - - *ret_entries = entries; - *ret_entries_size = entries_size; - return GRUB_ERR_NONE; - -fail: - grub_free (entries); - return grub_errno; -} - -grub_gpt_t -grub_gpt_read (grub_disk_t disk) -{ - grub_gpt_t gpt; - - grub_dprintf ("gpt", "reading GPT from %s\n", disk->name); - - gpt = grub_zalloc (sizeof (*gpt)); - if (!gpt) - goto fail; - - if (grub_disk_read (disk, 0, 0, sizeof (gpt->mbr), &gpt->mbr)) - goto fail; - - /* Check the MBR but errors aren't reported beyond the status bit. */ - if (grub_gpt_pmbr_check (&gpt->mbr)) - grub_errno = GRUB_ERR_NONE; - else - gpt->status |= GRUB_GPT_PROTECTIVE_MBR; - - /* If both the primary and backup fail report the primary's error. */ - if (grub_gpt_read_primary (disk, gpt)) - { - grub_error_push (); - grub_gpt_read_backup (disk, gpt); - grub_error_pop (); - } - else - grub_gpt_read_backup (disk, gpt); - - /* If either succeeded clear any possible error from the other. */ - if (grub_gpt_primary_valid (gpt) || grub_gpt_backup_valid (gpt)) - grub_errno = GRUB_ERR_NONE; - else - goto fail; - - return gpt; - -fail: - grub_gpt_free (gpt); - return NULL; -} - -struct grub_gpt_partentry * -grub_gpt_get_partentry (grub_gpt_t gpt, grub_uint32_t n) -{ - struct grub_gpt_header *header; - grub_size_t offset; - - header = grub_gpt_get_header (gpt); - if (!header) - return NULL; - - if (n >= grub_le_to_cpu32 (header->maxpart)) - return NULL; - - offset = (grub_size_t) grub_le_to_cpu32 (header->partentry_size) * n; - return (struct grub_gpt_partentry *) ((char *) gpt->entries + offset); -} - -grub_err_t -grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt) -{ - /* Skip if there is nothing to do. */ - if (grub_gpt_both_valid (gpt)) - return GRUB_ERR_NONE; - - grub_dprintf ("gpt", "repairing GPT for %s\n", disk->name); - - if (disk->log_sector_size != gpt->log_sector_size) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "GPT sector size must match disk sector size"); - - if (grub_gpt_primary_valid (gpt)) - { - grub_uint64_t backup_header; - - grub_dprintf ("gpt", "primary GPT is valid\n"); - - /* Relocate backup to end if disk if the disk has grown. */ - backup_header = grub_le_to_cpu64 (gpt->primary.alternate_lba); - if (grub_gpt_disk_size_valid (disk) && - disk->total_sectors - 1 > backup_header) - { - backup_header = disk->total_sectors - 1; - grub_dprintf ("gpt", "backup GPT header relocated to 0x%llx\n", - (unsigned long long) backup_header); - - gpt->primary.alternate_lba = grub_cpu_to_le64 (backup_header); - } - - grub_memcpy (&gpt->backup, &gpt->primary, sizeof (gpt->backup)); - gpt->backup.header_lba = gpt->primary.alternate_lba; - gpt->backup.alternate_lba = gpt->primary.header_lba; - gpt->backup.partitions = grub_cpu_to_le64 (backup_header - - grub_gpt_size_to_sectors (gpt, gpt->entries_size)); - } - else if (grub_gpt_backup_valid (gpt)) - { - grub_dprintf ("gpt", "backup GPT is valid\n"); - - grub_memcpy (&gpt->primary, &gpt->backup, sizeof (gpt->primary)); - gpt->primary.header_lba = gpt->backup.alternate_lba; - gpt->primary.alternate_lba = gpt->backup.header_lba; - gpt->primary.partitions = grub_cpu_to_le64_compile_time (2); - } - else - return grub_error (GRUB_ERR_BUG, "No valid GPT"); - - if (grub_gpt_update (gpt)) - return grub_errno; - - grub_dprintf ("gpt", "repairing GPT for %s successful\n", disk->name); - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_gpt_update (grub_gpt_t gpt) -{ - grub_uint32_t crc; - - /* Clear status bits, require revalidation of everything. */ - gpt->status &= ~(GRUB_GPT_PRIMARY_HEADER_VALID | - GRUB_GPT_PRIMARY_ENTRIES_VALID | - GRUB_GPT_BACKUP_HEADER_VALID | - GRUB_GPT_BACKUP_ENTRIES_VALID); - - /* Writing headers larger than our header structure are unsupported. */ - gpt->primary.headersize = - grub_cpu_to_le32_compile_time (sizeof (gpt->primary)); - gpt->backup.headersize = - grub_cpu_to_le32_compile_time (sizeof (gpt->backup)); - - grub_gpt_lecrc32 (&crc, gpt->entries, gpt->entries_size); - gpt->primary.partentry_crc32 = crc; - gpt->backup.partentry_crc32 = crc; - - grub_gpt_header_lecrc32 (&gpt->primary.crc32, &gpt->primary); - grub_gpt_header_lecrc32 (&gpt->backup.crc32, &gpt->backup); - - if (grub_gpt_check_primary (gpt)) - { - grub_error_push (); - return grub_error (GRUB_ERR_BUG, "Generated invalid GPT primary header"); - } - - gpt->status |= (GRUB_GPT_PRIMARY_HEADER_VALID | - GRUB_GPT_PRIMARY_ENTRIES_VALID); - - if (grub_gpt_check_backup (gpt)) - { - grub_error_push (); - return grub_error (GRUB_ERR_BUG, "Generated invalid GPT backup header"); - } - - gpt->status |= (GRUB_GPT_BACKUP_HEADER_VALID | - GRUB_GPT_BACKUP_ENTRIES_VALID); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_gpt_write_table (grub_disk_t disk, grub_gpt_t gpt, - struct grub_gpt_header *header) -{ - grub_disk_addr_t addr; - - if (grub_le_to_cpu32 (header->headersize) != sizeof (*header)) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Header size is %u, must be %u", - grub_le_to_cpu32 (header->headersize), - sizeof (*header)); - - addr = grub_gpt_sector_to_addr (gpt, grub_le_to_cpu64 (header->header_lba)); - if (addr == 0) - return grub_error (GRUB_ERR_BUG, - "Refusing to write GPT header to address 0x0"); - if (grub_disk_write (disk, addr, 0, sizeof (*header), header)) - return grub_errno; - - addr = grub_gpt_sector_to_addr (gpt, grub_le_to_cpu64 (header->partitions)); - if (addr < 2) - return grub_error (GRUB_ERR_BUG, - "Refusing to write GPT entries to address 0x%llx", - (unsigned long long) addr); - if (grub_disk_write (disk, addr, 0, gpt->entries_size, gpt->entries)) - return grub_errno; - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt) -{ - grub_uint64_t backup_header; - - /* TODO: update/repair protective MBRs too. */ - - if (!grub_gpt_both_valid (gpt)) - return grub_error (GRUB_ERR_BAD_PART_TABLE, "Invalid GPT data"); - - /* Write the backup GPT first so if writing fails the update is aborted - * and the primary is left intact. However if the backup location is - * inaccessible we have to just skip and hope for the best, the backup - * will need to be repaired in the OS. */ - backup_header = grub_le_to_cpu64 (gpt->backup.header_lba); - if (grub_gpt_disk_size_valid (disk) && - backup_header >= disk->total_sectors) - { - grub_printf ("warning: backup GPT located at 0x%llx, " - "beyond last disk sector at 0x%llx\n", - (unsigned long long) backup_header, - (unsigned long long) disk->total_sectors - 1); - grub_printf ("warning: only writing primary GPT, " - "the backup GPT must be repaired from the OS\n"); - } - else - { - grub_dprintf ("gpt", "writing backup GPT to %s\n", disk->name); - if (grub_gpt_write_table (disk, gpt, &gpt->backup)) - return grub_errno; - } - - grub_dprintf ("gpt", "writing primary GPT to %s\n", disk->name); - if (grub_gpt_write_table (disk, gpt, &gpt->primary)) - return grub_errno; - - return GRUB_ERR_NONE; -} - -void -grub_gpt_free (grub_gpt_t gpt) -{ - if (!gpt) - return; - - grub_free (gpt->entries); - grub_free (gpt); -} diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c index 71dd4f0ab..34cbe834f 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,13 +124,10 @@ 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; @@ -183,11 +179,9 @@ grub_relocator64_boot (struct grub_relocator *rel, void *relst; grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr, - max_addr - RELOCATOR_SIZEOF (64), - RELOCATOR_SIZEOF (64), 16, - GRUB_RELOCATOR_PREFERENCE_NONE, - 0); + err = grub_relocator_alloc_chunk_align_safe (rel, &ch, min_addr, max_addr, + RELOCATOR_SIZEOF (64), 16, + GRUB_RELOCATOR_PREFERENCE_NONE, 0); if (err) return err; diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S index 371a2ed69..e9238119b 100644 --- a/grub-core/lib/i386/relocator16.S +++ b/grub-core/lib/i386/relocator16.S @@ -38,15 +38,21 @@ VARIABLE(grub_relocator16_start) #ifdef __APPLE__ LOCAL(cs_base_bytes12_offset) = LOCAL (cs_base_bytes12) - LOCAL (base) LOCAL(cs_base_byte3_offset) = LOCAL (cs_base_byte3) - LOCAL (base) + LOCAL(ds_base_bytes12_offset) = LOCAL (ds_base_bytes12) - LOCAL (base) + LOCAL(ds_base_byte3_offset) = LOCAL (ds_base_byte3) - LOCAL (base) movl %esi, %eax movw %ax, (LOCAL(cs_base_bytes12_offset)) (RSI, 1) + movw %ax, (LOCAL(ds_base_bytes12_offset)) (RSI, 1) shrl $16, %eax movb %al, (LOCAL (cs_base_byte3_offset)) (RSI, 1) + movb %al, (LOCAL (ds_base_byte3_offset)) (RSI, 1) #else movl %esi, %eax movw %ax, (LOCAL (cs_base_bytes12) - LOCAL (base)) (RSI, 1) + movw %ax, (LOCAL (ds_base_bytes12) - LOCAL (base)) (RSI, 1) shrl $16, %eax movb %al, (LOCAL (cs_base_byte3) - LOCAL (base)) (RSI, 1) + movb %al, (LOCAL (ds_base_byte3) - LOCAL (base)) (RSI, 1) #endif RELOAD_GDT @@ -88,15 +94,15 @@ VARIABLE(grub_relocator16_start) LOCAL(segment_offset) = LOCAL (segment) - LOCAL (base) LOCAL(idt_offset) = LOCAL(relocator16_idt) - LOCAL (base) LOCAL(cont2_offset) = LOCAL (cont2) - LOCAL(base) - movw %ax, LOCAL(segment_offset) (%esi, 1) - lidt LOCAL(idt_offset) (%esi, 1) + movw %ax, (LOCAL(segment_offset)) + lidt (LOCAL(idt_offset)) /* jump to a 16 bit segment */ ljmp $PSEUDO_REAL_CSEG, $(LOCAL(cont2_offset)) #else - movw %ax, (LOCAL (segment) - LOCAL (base)) (%esi, 1) + movw %ax, (LOCAL (segment) - LOCAL (base)) - lidt (EXT_C(grub_relocator16_idt) - LOCAL (base)) (%esi, 1) + lidt (EXT_C(grub_relocator16_idt) - LOCAL (base)) /* jump to a 16 bit segment */ ljmp $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base)) @@ -311,11 +317,17 @@ LOCAL(cs_base_byte3): .byte 0x9E, 0, 0 /* -- 16 bit real mode DS -- - * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present + * base = filled by code, limit 0x0FFFF (1 B Granularity), present * type = 16 bit data read/write, DPL = 0 */ - .word 0xFFFF, 0 - .byte 0, 0x92, 0, 0 + .word 0xFFFF +LOCAL(ds_base_bytes12): + .word 0 +LOCAL(ds_base_byte3): + .byte 0 + + .byte 0x92, 0, 0 + LOCAL(gdt_end): #ifdef __APPLE__ diff --git a/grub-core/lib/i386/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/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..1c20c75ea --- /dev/null +++ b/grub-core/lib/json/json.c @@ -0,0 +1,264 @@ +/* + * 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; +} diff --git a/grub-core/lib/json/json.h b/grub-core/lib/json/json.h new file mode 100644 index 000000000..4ea2a22d8 --- /dev/null +++ b/grub-core/lib/json/json.h @@ -0,0 +1,128 @@ +/* + * 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); + +#endif diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c index ef56150ac..05719ab2c 100644 --- a/grub-core/lib/legacy_parse.c +++ b/grub-core/lib/legacy_parse.c @@ -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'; diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c index f5e946a2d..63f6fcd11 100644 --- a/grub-core/lib/libgcrypt/cipher/ac.c +++ b/grub-core/lib/libgcrypt/cipher/ac.c @@ -185,7 +185,7 @@ ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n, gcry_mpi_t mpi; char *label; - data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n); + data_mpis_new = gcry_calloc (data_mpis_n, sizeof (*data_mpis_new)); if (! data_mpis_new) { err = gcry_error_from_errno (errno); @@ -572,7 +572,7 @@ _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, } /* Add MPI list. */ - arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1)); + arg_list = gcry_calloc (data_n + 1, sizeof (*arg_list)); if (! arg_list) { err = gcry_error_from_errno (errno); @@ -1283,7 +1283,7 @@ ac_data_construct (const char *identifier, int include_flags, /* We build a list of arguments to pass to gcry_sexp_build_array(). */ data_length = _gcry_ac_data_length (data); - arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2)); + arg_list = gcry_calloc (data_length, sizeof (*arg_list) * 2); if (! arg_list) { err = gcry_error_from_errno (errno); @@ -1593,7 +1593,7 @@ _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, arg_list_n += 2; /* Allocate list. */ - arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n); + arg_list = gcry_calloc (arg_list_n, sizeof (*arg_list)); if (! arg_list) { err = gcry_error_from_errno (errno); diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c index 2788e349f..b12e79b19 100644 --- a/grub-core/lib/libgcrypt/cipher/primegen.c +++ b/grub-core/lib/libgcrypt/cipher/primegen.c @@ -383,7 +383,7 @@ prime_generate_internal (int need_q_factor, } /* Allocate an array to track pool usage. */ - pool_in_use = gcry_malloc (n * sizeof *pool_in_use); + pool_in_use = gcry_calloc (n, sizeof *pool_in_use); if (!pool_in_use) { err = gpg_err_code_from_errno (errno); @@ -765,7 +765,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel, if (nbits < 16) log_fatal ("can't generate a prime with less than %d bits\n", 16); - mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods ); + mods = gcry_xcalloc( no_of_small_prime_numbers, sizeof *mods); /* Make nbits fit into gcry_mpi_t implementation. */ val_2 = mpi_alloc_set_ui( 2 ); val_3 = mpi_alloc_set_ui( 3); diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c index 910982141..ca087ad75 100644 --- a/grub-core/lib/libgcrypt/cipher/pubkey.c +++ b/grub-core/lib/libgcrypt/cipher/pubkey.c @@ -2941,7 +2941,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey) * array to a format string, so we have to do it this way :-(. */ /* FIXME: There is now such a format specifier, so we can change the code to be more clear. */ - arg_list = malloc (nelem * sizeof *arg_list); + arg_list = calloc (nelem, sizeof *arg_list); if (!arg_list) { rc = gpg_err_code_from_syserror (); @@ -3233,7 +3233,7 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) } strcpy (p, "))"); - arg_list = malloc (nelem * sizeof *arg_list); + arg_list = calloc (nelem, sizeof *arg_list); if (!arg_list) { rc = gpg_err_code_from_syserror (); diff --git a/grub-core/lib/libgcrypt_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/minilzo/lzoconf.h b/grub-core/lib/minilzo/lzoconf.h index 1d0fe14fc..61be29c5d 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-2014 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 0x2080 +#define LZO_VERSION_STRING "2.08" +#define LZO_VERSION_DATE "Jun 29 2014" /* 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) @@ -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,31 @@ 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; # else - typedef unsigned long long lzo_uint; - typedef long long lzo_int; + typedef lzo_ullong_t lzo_uint; + typedef lzo_llong_t lzo_int; # endif +# define LZO_SIZEOF_LZO_UINT 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_UINT LZO_SIZEOF_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_UINT LZO_SIZEOF_LONG # define LZO_UINT_MAX ULONG_MAX # define LZO_INT_MAX LONG_MAX # define LZO_INT_MIN LONG_MIN @@ -141,63 +121,22 @@ 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_UINT >= 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_uint) == LZO_SIZEOF_LZO_UINT) +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 +145,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 + * like 16-bit MSDOS with __huge pointers and Cray PVP, but these + * obsolete configurations are not supported any longer. + */ +#if defined(__LZO_MMODEL_HUGE) +#error "__LZO_MMODEL_HUGE is unsupported" +#endif +#if (LZO_MM_PVP) +#error "LZO_MM_PVP 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)) /*********************************************************************** @@ -315,7 +285,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 +313,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 +329,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 +352,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 +376,30 @@ 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; + #if defined(LZO_CFG_COMPAT) #define __LZOCONF_H 1 @@ -443,4 +441,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..f4ae9487e 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-2014 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,30 @@ # define __LONG_MAX__ 9223372036854775807L # endif #endif -#if defined(__INTEL_COMPILER) && defined(__linux__) +#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 +72,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 +109,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) @@ -233,14 +246,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 +278,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))) - (o)) << 1) + (o)*!!(b)) #if 1 && defined(__cplusplus) # if !defined(__STDC_CONSTANT_MACROS) # define __STDC_CONSTANT_MACROS 1 @@ -263,9 +297,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) @@ -366,12 +404,12 @@ #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 +437,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 +483,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 +510,65 @@ # 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 +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) # if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) -# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) # else -# define LZO_CC_CLANG_CLANG 0x010000L +# 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 -# define LZO_CC_CLANG LZO_CC_CLANG_GNUC # define LZO_INFO_CC "clang" # define LZO_INFO_CCVER __VERSION__ #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 +593,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 +618,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 +642,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 +654,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 +677,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 +686,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 +712,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 +769,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__) +# 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" @@ -685,10 +788,10 @@ # 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) +# 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) +# elif defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 2) # define LZO_INFO_ARCH "arm" # else # define LZO_INFO_ARCH "arm" @@ -806,53 +909,147 @@ # 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_THUMB && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM_THUMB) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM_THUMB) +# 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)) || 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__) +# 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 +1076,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,10 +1099,10 @@ #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 @@ -937,7 +1134,7 @@ extern "C" { #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 +1148,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 +1164,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 +1180,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 +1207,156 @@ 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__ +#elif (LZO_CC_IBMC >= 600) # define __lzo_gnuc_extension__ __extension__ #else +#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) -#endif -#endif -#if defined(__lzo_alignof) -# define __lzo_HAVE_alignof 1 -#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__)) -#endif -#endif -#if defined(__lzo_constructor) -# define __lzo_HAVE_constructor 1 -#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__)) -#endif -#endif -#if defined(__lzo_destructor) -# define __lzo_HAVE_destructor 1 -#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 -#endif -#endif -#if defined(__lzo_inline) -# define __lzo_HAVE_inline 1 -#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_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__)) -#endif -#endif -#if defined(__lzo_forceinline) -# define __lzo_HAVE_forceinline 1 -#else -# define __lzo_forceinline /*empty*/ -#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) {LZO_EXTERN_C int lzo_unused__[1-2*!(sizeof(var)>0)];} # elif (LZO_CC_PACIFICC) # define LZO_UNUSED(var) ((void) sizeof(var)) # elif (LZO_CC_WATCOMC) && defined(__cplusplus) @@ -1591,18 +1377,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) {LZO_EXTERN_C int lzo_unused_func__[1-2*!(sizeof((int)func)>0)];} # 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 +1400,488 @@ 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_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_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(__lzo_static_unused_void_func) +# 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_static_unused_void_func(f) static void __attribute__((__unused__)) f(void) +# else +# define __lzo_static_unused_void_func(f) static __lzo_inline void f(void) +# endif +#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)) +# 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 +#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_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 +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) #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,6 +1945,7 @@ 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__) @@ -1719,61 +1955,615 @@ extern "C" { # endif #endif #endif +#endif +#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_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define LZO_WORDSIZE 4 +# elif 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(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_SIZEOF_VOID_P 4 +# else +# 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) +# 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(__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 && 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(__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_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 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) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 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 defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 6) && !defined(__TARGET_PROFILE_M) +# 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 +# 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 +# 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_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 +2574,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 +2617,382 @@ 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 +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +__lzo_gnuc_extension__ typedef long long lzo_llong_t__; +__lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_SIZEOF_LONG == 2) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +#elif (LZO_SIZEOF_INT == 2) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __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_SIZEOF_LONG == 4) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# 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) +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __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) && !(LZO_CFG_TYPE_PREFER___INT64) +# define LZO_CFG_TYPE_PREFER___INT64 1 +# endif +#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_SIZEOF_LZO_INT64E_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG == 8) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_TYPE_PREFER___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# 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 +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG_LONG +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __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 +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF___INT64 +#else +#endif +#endif +#if defined(lzo_int64e_t) + 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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 + typedef char* lzo_intptr_t; + typedef char* lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +#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 +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +#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 +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 +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 +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 +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 +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 +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 +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 +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..ab2be5f4f 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-2014 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,30 @@ # define __LONG_MAX__ 9223372036854775807L # endif #endif -#if defined(__INTEL_COMPILER) && defined(__linux__) +#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 +92,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 +129,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) @@ -253,14 +266,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 +298,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))) - (o)) << 1) + (o)*!!(b)) #if 1 && defined(__cplusplus) # if !defined(__STDC_CONSTANT_MACROS) # define __STDC_CONSTANT_MACROS 1 @@ -283,9 +317,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) @@ -386,12 +424,12 @@ #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 +457,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 +503,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 +530,65 @@ # 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 +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) # if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) -# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) # else -# define LZO_CC_CLANG_CLANG 0x010000L +# 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 -# define LZO_CC_CLANG LZO_CC_CLANG_GNUC # define LZO_INFO_CC "clang" # define LZO_INFO_CCVER __VERSION__ #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 +613,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 +638,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 +662,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 +674,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 +697,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 +706,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 +732,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 +789,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__) +# 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" @@ -705,10 +808,10 @@ # 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) +# 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) +# elif defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 2) # define LZO_INFO_ARCH "arm" # else # define LZO_INFO_ARCH "arm" @@ -826,53 +929,147 @@ # 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_THUMB && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM_THUMB) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM_THUMB) +# 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)) || 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__) +# 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 +1096,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,10 +1119,10 @@ #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 @@ -957,7 +1154,7 @@ extern "C" { #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 +1168,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 +1184,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 +1200,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 +1227,156 @@ 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__ +#elif (LZO_CC_IBMC >= 600) # define __lzo_gnuc_extension__ __extension__ #else +#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) -#endif -#endif -#if defined(__lzo_alignof) -# define __lzo_HAVE_alignof 1 -#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__)) -#endif -#endif -#if defined(__lzo_constructor) -# define __lzo_HAVE_constructor 1 -#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__)) -#endif -#endif -#if defined(__lzo_destructor) -# define __lzo_HAVE_destructor 1 -#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 -#endif -#endif -#if defined(__lzo_inline) -# define __lzo_HAVE_inline 1 -#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_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__)) -#endif -#endif -#if defined(__lzo_forceinline) -# define __lzo_HAVE_forceinline 1 -#else -# define __lzo_forceinline /*empty*/ -#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) {LZO_EXTERN_C int lzo_unused__[1-2*!(sizeof(var)>0)];} # elif (LZO_CC_PACIFICC) # define LZO_UNUSED(var) ((void) sizeof(var)) # elif (LZO_CC_WATCOMC) && defined(__cplusplus) @@ -1611,18 +1397,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) {LZO_EXTERN_C int lzo_unused_func__[1-2*!(sizeof((int)func)>0)];} # 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 +1420,488 @@ 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_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_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(__lzo_static_unused_void_func) +# 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_static_unused_void_func(f) static void __attribute__((__unused__)) f(void) +# else +# define __lzo_static_unused_void_func(f) static __lzo_inline void f(void) +# endif +#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)) +# 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 +#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_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 +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) #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,6 +1965,7 @@ 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__) @@ -1739,61 +1975,615 @@ extern "C" { # endif #endif #endif +#endif +#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_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define LZO_WORDSIZE 4 +# elif 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(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_SIZEOF_VOID_P 4 +# else +# 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) +# 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(__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 && 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(__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_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 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) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 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 defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 6) && !defined(__TARGET_PROFILE_M) +# 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 +# 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 +# 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_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 +2594,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 +2637,381 @@ 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 +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +__lzo_gnuc_extension__ typedef long long lzo_llong_t__; +__lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_SIZEOF_LONG == 2) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +#elif (LZO_SIZEOF_INT == 2) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __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_SIZEOF_LONG == 4) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# 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) +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __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) && !(LZO_CFG_TYPE_PREFER___INT64) +# define LZO_CFG_TYPE_PREFER___INT64 1 +# endif +#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_SIZEOF_LZO_INT64E_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG == 8) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_TYPE_PREFER___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# 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 +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG_LONG +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __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 +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF___INT64 +#else +#endif +#endif +#if defined(lzo_int64e_t) + 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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 + typedef char* lzo_intptr_t; + typedef char* lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +#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 +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +#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 +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 +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 +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 +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 +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 +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 +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 +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 +3020,7 @@ extern "C" { #undef LZO_HAVE_CONFIG_H #include "minilzo.h" -#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2050) +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2080) # error "version mismatch in miniLZO source files" #endif @@ -1886,23 +3032,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 @@ -1911,22 +3043,27 @@ extern "C" { # error "include this file first" #endif #include "lzo/lzoconf.h" +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER2) +# include LZO_CFG_EXTRA_CONFIG_HEADER2 +#endif #endif -#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED) +#if (LZO_VERSION < 0x2080) || !defined(__LZOCONF_H_INCLUDED) # 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_SUNPROC) @@ -1937,49 +3074,16 @@ extern "C" { #endif #endif -#if (__LZO_MMODEL_HUGE) && !(LZO_HAVE_MM_HUGE_PTR) -# error "this should not happen - check defines for __huge" -#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 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 +3106,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 +3133,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 +3179,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 +3220,548 @@ 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)) +#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 + +#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 +__lzo_static_forceinline void +#endif +lzo_bitops_unused_funcs(void) +{ + 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 + LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); +} + +#if defined(__lzo_alignof) && !(LZO_CFG_NO_UNALIGNED) +#ifndef __lzo_memops_tcheck +#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) +#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) +#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) +#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 + +#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 +__lzo_static_forceinline void +#endif +lzo_memops_unused_funcs(void) +{ + 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); + LZO_UNUSED_FUNC(lzo_memops_unused_funcs); +} + +#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 +3782,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 +3815,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 +3852,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 +3872,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,9 +3885,8 @@ __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; p = __lzo_ptr_linear(ptr); @@ -2342,7 +3912,7 @@ static const char __lzo_copyright[] = #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-2014 Markus Franz Xaver Johannes Oberhumer\n" "\n" "http://www.oberhumer.com $\n\n" "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" @@ -2352,11 +3922,7 @@ static const char __lzo_copyright[] = 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 } LZO_PUBLIC(unsigned) @@ -2393,16 +3959,16 @@ _lzo_version_date(void) #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 +4025,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 +4042,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 +4057,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 +4080,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 +4099,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 +4134,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 +4242,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 +4254,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 +4297,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 @@ -3088,77 +4606,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 +4614,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 +4623,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 +4653,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 +4669,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 +4715,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 +4739,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 +4769,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 +4807,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 +4861,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 +4881,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 +4893,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 +4933,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 +4944,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 +4988,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 +5009,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 +5021,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 +5048,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 +5085,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 +5127,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 +5173,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 +5193,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 +5234,7 @@ first_literal_run: #endif goto match_done; - do { + for (;;) { match: if (t >= 64) { @@ -3813,14 +5294,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 +5318,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 +5339,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 +5365,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 +5414,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 +5435,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 +5444,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 +5472,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 +5480,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 +5529,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 +5550,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 +5562,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 +5589,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 +5626,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 +5668,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 +5714,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 +5734,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 +5775,7 @@ first_literal_run: #endif goto match_done; - do { + for (;;) { match: if (t >= 64) { @@ -4339,14 +5835,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 +5859,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 +5880,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 +5906,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 +5955,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 +5976,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 +5985,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 +6013,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 +6021,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 +6051,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..793745467 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-2014 Markus Franz Xaver Johannes Oberhumer All Rights Reserved. The LZO library is free software; you can redistribute it and/or @@ -50,7 +35,7 @@ #ifndef __MINILZO_H #define __MINILZO_H 1 -#define MINILZO_VERSION 0x2050 +#define MINILZO_VERSION 0x2080 #ifdef __LZOCONF_H # error "you cannot use both LZO and miniLZO" @@ -78,7 +63,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) diff --git a/grub-core/lib/mips/relocator.c b/grub-core/lib/mips/relocator.c index 9d5f49cb9..743b213e6 100644 --- a/grub-core/lib/mips/relocator.c +++ b/grub-core/lib/mips/relocator.c @@ -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/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h index 3b46f47ff..7a8d385e9 100644 --- a/grub-core/lib/posix_wrap/stdlib.h +++ b/grub-core/lib/posix_wrap/stdlib.h @@ -21,6 +21,7 @@ #include #include +#include static inline void free (void *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 * diff --git a/grub-core/lib/powerpc/relocator.c b/grub-core/lib/powerpc/relocator.c index bdf2b111b..8ffb8b686 100644 --- a/grub-core/lib/powerpc/relocator.c +++ b/grub-core/lib/powerpc/relocator.c @@ -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..7d5e7c05a 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)); diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index ee9fa7b4f..467305b46 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 @@ -158,11 +159,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++) diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c index ea3ebc719..f2c1944c2 100644 --- a/grub-core/lib/relocator.c +++ b/grub-core/lib/relocator.c @@ -495,9 +495,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", @@ -963,7 +963,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; @@ -1386,8 +1386,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) @@ -1562,8 +1562,8 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, 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); diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c index 4afa99279..de9fda06f 100644 --- a/grub-core/lib/syslinux_parse.c +++ b/grub-core/lib/syslinux_parse.c @@ -1062,7 +1062,7 @@ write_entry (struct output_buffer *outbuf, if (ptr[0] == 'h' && ptr[1] == 'd') { is_fd = 0; - devn = grub_strtoul (ptr + 2, &ptr, 0); + devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0); continue; } if (grub_strncasecmp (ptr, "file=", 5) == 0) @@ -1086,12 +1086,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 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/zstd/fse_decompress.c b/grub-core/lib/zstd/fse_decompress.c index 72bbead5b..2227b84bc 100644 --- a/grub-core/lib/zstd/fse_decompress.c +++ b/grub-core/lib/zstd/fse_decompress.c @@ -82,7 +82,7 @@ FSE_DTable* FSE_createDTable (unsigned tableLog) { if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX; - return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); + return (FSE_DTable*)calloc( FSE_DTABLE_SIZE_U32(tableLog), sizeof (U32) ); } void FSE_freeDTable (FSE_DTable* dt) diff --git a/grub-core/loader/arm/linux.c b/grub-core/loader/arm/linux.c index 51684914c..d70c17486 100644 --- a/grub-core/loader/arm/linux.c +++ b/grub-core/loader/arm/linux.c @@ -78,7 +78,7 @@ linux_prepare_atag (void *target_atag) /* some place for cmdline, initrd and terminator. */ tmp_size = get_atag_size (atag_orig) + 20 + (arg_size) / 4; - tmp_atag = grub_malloc (tmp_size * sizeof (grub_uint32_t)); + tmp_atag = grub_calloc (tmp_size, sizeof (grub_uint32_t)); if (!tmp_atag) return grub_errno; diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c index 17bed4e15..ef3e9f944 100644 --- a/grub-core/loader/arm64/linux.c +++ b/grub-core/loader/arm64/linux.c @@ -34,8 +34,6 @@ #include #include -#include - GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; @@ -335,8 +333,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); - cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE) - + VERITY_CMDLINE_LENGTH; + cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); linux_args = grub_malloc (cmdline_size); if (!linux_args) { @@ -353,7 +350,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (grub_errno == GRUB_ERR_NONE) { - grub_pass_verity_hash (kernel_addr, linux_args, cmdline_size); grub_loader_set (grub_linux_boot, grub_linux_unload, 0); loaded = 1; } diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index cd92ea3f2..7b31c3fb9 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -106,7 +106,7 @@ grub_chainloader_boot (void) return grub_errno; } -static void +static grub_err_t copy_file_path (grub_efi_file_path_device_path_t *fp, const char *str, grub_efi_uint16_t len) { @@ -116,9 +116,9 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE; fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE; - path_name = grub_malloc (len * GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); + path_name = grub_calloc (len, GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name)); if (!path_name) - return; + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "failed to allocate path buffer"); size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8, (const grub_uint8_t *) str, len, 0); @@ -131,6 +131,7 @@ copy_file_path (grub_efi_file_path_device_path_t *fp, fp->path_name[size++] = '\0'; fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp); grub_free (path_name); + return GRUB_ERR_NONE; } static grub_efi_device_path_t * @@ -156,9 +157,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=%d", len); + return NULL; + } + + size += len; if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d))) break; d = GRUB_EFI_NEXT_DEVICE_PATH (d); @@ -180,13 +190,19 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) 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); diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index 3730ed382..f5bf7f89e 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #ifdef GRUB_MACHINE_PCBIOS #include @@ -1012,11 +1013,16 @@ grub_netbsd_add_modules (void) struct grub_netbsd_btinfo_modules *mods; unsigned i; grub_err_t err; + grub_size_t sz; for (mod = netbsd_mods; mod; mod = mod->next) modcnt++; - mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt); + if (grub_mul (modcnt, sizeof (mods->mods[0]), &sz) || + grub_add (sz, sizeof (*mods), &sz)) + return GRUB_ERR_OUT_OF_RANGE; + + mods = grub_malloc (sz); if (!mods) return grub_errno; @@ -1615,7 +1621,7 @@ 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); + unit = grub_strtoul (arg, &arg, 10); if (! (arg && *arg >= 'a' && *arg <= 'z')) return grub_error (GRUB_ERR_BAD_ARGUMENT, "only device specifications of form " @@ -1633,7 +1639,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; @@ -1735,7 +1741,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"); diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c index af6741d15..a8d8bf7da 100644 --- a/grub-core/loader/i386/bsdXX.c +++ b/grub-core/loader/i386/bsdXX.c @@ -48,7 +48,7 @@ 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); + *shdr = grub_calloc (e->e_shnum, e->e_shentsize); if (! *shdr) return grub_errno; diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c deleted file mode 100644 index fc3d949c9..000000000 --- a/grub-core/loader/i386/efi/linux.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2012 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -GRUB_MOD_LICENSE ("GPLv3+"); - -static grub_dl_t my_mod; -static int loaded; -static void *kernel_mem; -static grub_uint64_t kernel_size; -static grub_uint8_t *initrd_mem; -static grub_uint32_t handover_offset; -struct linux_kernel_params *params; -static char *linux_cmdline; - -#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) - -#define SHIM_LOCK_GUID \ - { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} } - -struct grub_efi_shim_lock -{ - grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); -}; -typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; - -static grub_efi_boolean_t -grub_linuxefi_secure_validate (void *data, grub_uint32_t size) -{ - grub_efi_guid_t guid = SHIM_LOCK_GUID; - grub_efi_shim_lock_t *shim_lock; - - shim_lock = grub_efi_locate_protocol(&guid, NULL); - - if (!shim_lock) { - if (grub_efi_secure_boot()) - return 0; - else - return 1; - } - - if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) - return 1; - - return 0; -} - -typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *); - -static grub_err_t -grub_linuxefi_boot (void) -{ - handover_func hf; - int offset = 0; - -#ifdef __x86_64__ - offset = 512; -#endif - - hf = (handover_func)((char *)kernel_mem + handover_offset + offset); - - asm volatile ("cli"); - - hf (grub_efi_image_handle, grub_efi_system_table, params); - - /* Not reached */ - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_linuxefi_unload (void) -{ - grub_dl_unref (my_mod); - loaded = 0; - if (initrd_mem) - grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); - if (linux_cmdline) - grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); - if (kernel_mem) - grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); - if (params) - grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t *files = 0; - int i, nfiles = 0; - grub_size_t size = 0; - grub_uint8_t *ptr; - - 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; - } - - files = grub_zalloc (argc * sizeof (files[0])); - if (!files) - goto fail; - - for (i = 0; i < argc; i++) - { - grub_file_filter_disable_compression (); - files[i] = grub_file_open (argv[i]); - if (! files[i]) - goto fail; - nfiles++; - size += ALIGN_UP (grub_file_size (files[i]), 4); - } - - initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); - - if (!initrd_mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); - goto fail; - } - - params->ramdisk_size = size; - params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; - - ptr = initrd_mem; - - for (i = 0; i < nfiles; i++) - { - grub_ssize_t cursize = grub_file_size (files[i]); - if (grub_file_read (files[i], ptr, cursize) != cursize) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - argv[i]); - goto fail; - } - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure (ptr, cursize, GRUB_BINARY_PCR, "Initrd"); - //grub_print_error(); - ptr += cursize; - grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); - ptr += ALIGN_UP_OVERHEAD (cursize, 4); - } - - params->ramdisk_size = size; - - fail: - for (i = 0; i < nfiles; i++) - grub_file_close (files[i]); - grub_free (files); - - if (initrd_mem && grub_errno) - grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size)); - - 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_kernel_header lh; - grub_ssize_t len, start, filelen; - void *kernel = NULL; - - 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; - - filelen = grub_file_size (file); - - kernel = grub_malloc(filelen); - - if (!kernel) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); - goto fail; - } - - if (grub_file_read (file, kernel, filelen) != filelen) - { - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); - goto fail; - } - - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure (kernel, filelen, GRUB_BINARY_PCR, "Kernel"); - //grub_print_error(); - - if (! grub_linuxefi_secure_validate (kernel, filelen)) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); - grub_free (kernel); - goto fail; - } - - params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); - - if (! params) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); - goto fail; - } - - grub_memset (params, 0, 16384); - - grub_memcpy (&lh, kernel, sizeof (lh)); - - if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) - { - grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); - goto fail; - } - - if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) - { - grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); - goto fail; - } - - if (lh.version < grub_cpu_to_le16 (0x020b)) - { - grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); - goto fail; - } - - if (!lh.handover_offset) - { - grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); - goto fail; - } - - linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, - BYTES_TO_PAGES(lh.cmdline_size + 1)); - - if (!linux_cmdline) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); - goto fail; - } - - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_cmdline + sizeof (LINUX_IMAGE) - 1, - lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); - - grub_pass_verity_hash(&lh, linux_cmdline, lh.cmdline_size); - lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; - - handover_offset = lh.handover_offset; - - start = (lh.setup_sects + 1) * 512; - len = grub_file_size(file) - start; - - kernel_mem = grub_efi_allocate_pages(lh.pref_address, - BYTES_TO_PAGES(lh.init_size)); - - if (!kernel_mem) - kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, - BYTES_TO_PAGES(lh.init_size)); - - if (!kernel_mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); - goto fail; - } - - grub_memcpy (kernel_mem, (char *)kernel + start, len); - grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); - loaded=1; - - lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; - grub_memcpy (params, &lh, 2 * 512); - - params->type_of_loader = 0x21; - - fail: - - if (file) - grub_file_close (file); - - grub_free (kernel); - - if (grub_errno != GRUB_ERR_NONE) - { - grub_dl_unref (my_mod); - loaded = 0; - } - - if (linux_cmdline && !loaded) - grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); - - if (kernel_mem && !loaded) - grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); - - if (params && !loaded) - grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); - - return grub_errno; -} - -static grub_command_t cmd_linux, cmd_initrd; - -GRUB_MOD_INIT(linuxefi) -{ - cmd_linux = - grub_register_command ("linuxefi", grub_cmd_linux, - 0, N_("Load Linux.")); - cmd_initrd = - grub_register_command ("initrdefi", grub_cmd_initrd, - 0, N_("Load initrd.")); - my_mod = mod; -} - -GRUB_MOD_FINI(linuxefi) -{ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_initrd); -} diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 98729ba0e..976af3fae 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -36,9 +36,7 @@ #include #include #include -#include - -#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -183,9 +181,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); @@ -550,9 +547,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); @@ -645,13 +646,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; struct linux_i386_kernel_header lh; grub_uint8_t setup_sects; - grub_size_t real_size, prot_size, prot_file_size, kernel_offset; + grub_size_t real_size, prot_size, prot_file_size; grub_ssize_t len; int i; grub_size_t align, min_align; int relocatable; grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; - grub_uint8_t *kernel = NULL; grub_dl_ref (my_mod); @@ -665,15 +665,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (! file) goto fail; - len = grub_file_size (file); - kernel = grub_malloc (len); - if (!kernel) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); - goto fail; - } - - if (grub_file_read (file, kernel, len) != len) + if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) { if (!grub_errno) grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), @@ -681,14 +673,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure (kernel, len, GRUB_BINARY_PCR, "Kernel"); - //grub_print_error(); - - grub_memcpy (&lh, kernel, sizeof (lh)); - - kernel_offset = sizeof (lh); - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) { grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); @@ -781,17 +765,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; grub_memset (&linux_params, 0, sizeof (linux_params)); - grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); - - linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; - linux_params.kernel_alignment = (1 << align); - linux_params.ps_mouse = linux_params.padding10 = 0; /* * The Linux 32-bit boot protocol defines the setup header end * to be at 0x202 + the byte value at 0x201. */ - len = 0x202 + *((char *) &linux_params.jump + 1); + len = 0x202 + *((char *) &lh.jump + 1); /* Verify the struct is big enough so we do not write past the end. */ if (len > (char *) &linux_params.edd_mbr_sig_buffer - (char *) &linux_params) { @@ -799,18 +778,23 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } + grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, len - 0x1F1); + /* We've already read lh so there is no need to read it second time. */ len -= sizeof(lh); - if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len) + if ((len > 0) && + (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)) { if (!grub_errno) grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); goto fail; } - kernel_offset += len; + 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; linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; /* These two are used (instead of cmd_line_ptr) by older versions of Linux, @@ -868,7 +852,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* The other parameters are filled when booting. */ - kernel_offset = real_size + GRUB_DISK_SECTOR_SIZE; + grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n", (unsigned) real_size, (unsigned) prot_size); @@ -964,7 +948,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); @@ -1021,10 +1005,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - grub_pass_verity_hash(&lh, linux_cmdline, maximal_cmdline_size); len = prot_file_size; - grub_memcpy (prot_mode_mem, kernel + kernel_offset, len); - kernel_offset += len; + if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); if (grub_errno == GRUB_ERR_NONE) { @@ -1035,8 +1019,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), fail: - grub_free (kernel); - if (file) grub_file_close (file); diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index 468349f84..a67d9d0a8 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -36,7 +36,6 @@ #include #include #include -#include #ifdef GRUB_MACHINE_EFI #include @@ -174,10 +173,6 @@ grub_multiboot_load (grub_file_t file, const char *filename) return grub_errno; } - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure((unsigned char*)buffer, len, GRUB_BINARY_PCR, filename); - //grub_print_error(); - header = find_header (buffer, len); if (header == 0) @@ -471,10 +466,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); diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c index c25e0dad1..814988ab9 100644 --- a/grub-core/loader/i386/pc/linux.c +++ b/grub-core/loader/i386/pc/linux.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -124,14 +124,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; struct linux_i386_kernel_header lh; grub_uint8_t setup_sects; - grub_size_t real_size, kernel_offset = 0; + grub_size_t real_size; grub_ssize_t len; int i; char *grub_linux_prot_chunk; int grub_linux_is_bzimage; grub_addr_t grub_linux_prot_target; grub_err_t err; - grub_uint8_t *kernel = NULL; grub_dl_ref (my_mod); @@ -145,15 +144,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (! file) goto fail; - len = grub_file_size (file); - kernel = grub_malloc (len); - if (!kernel) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); - goto fail; - } - - if (grub_file_read (file, kernel, len) != len) + if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) { if (!grub_errno) grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), @@ -161,13 +152,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure (kernel, len, GRUB_BINARY_PCR, "Kernel"); - //grub_print_error(); - - grub_memcpy (&lh, kernel, sizeof (lh)); - kernel_offset = sizeof (lh); - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) { grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); @@ -235,8 +219,12 @@ 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 @@ -276,7 +264,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); @@ -331,9 +319,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh)); len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh); - grub_memcpy (grub_linux_real_chunk + sizeof (lh), kernel + kernel_offset, - len); - kernel_offset += len; + if (grub_file_read (file, grub_linux_real_chunk + sizeof (lh), len) != len) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + goto fail; + } if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) || grub_le_to_cpu16 (lh.version) < 0x0200) @@ -383,8 +375,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), fail: - grub_free (kernel); - if (file) grub_file_close (file); @@ -463,10 +453,8 @@ 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); diff --git a/grub-core/loader/i386/xen.c b/grub-core/loader/i386/xen.c index bb9508ce9..cd24874ca 100644 --- a/grub-core/loader/i386/xen.c +++ b/grub-core/loader/i386/xen.c @@ -41,6 +41,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -636,6 +637,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")); @@ -656,9 +658,7 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), if (!file) return grub_errno; - elf = grub_xen_file_and_cmdline (file, - (char *) xen_state.next_start.cmd_line, - sizeof (xen_state.next_start.cmd_line) - 1); + elf = grub_xen_file (file); if (!elf) goto fail; @@ -705,8 +705,14 @@ grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), xen_state.max_addr = ALIGN_UP (kern_end, 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); diff --git a/grub-core/loader/i386/xen_file.c b/grub-core/loader/i386/xen_file.c index defb4fedc..9af5d66df 100644 --- a/grub-core/loader/i386/xen_file.c +++ b/grub-core/loader/i386/xen_file.c @@ -19,20 +19,11 @@ #include #include #include -#include #define XZ_MAGIC "\3757zXZ\0" grub_elf_t grub_xen_file (grub_file_t file) -{ - return grub_xen_file_and_cmdline (file, NULL, 0); -} - -grub_elf_t -grub_xen_file_and_cmdline (grub_file_t file, - char *cmdline, - grub_size_t cmdline_max_len) { grub_elf_t elf; struct linux_i386_kernel_header lh; @@ -73,9 +64,6 @@ grub_xen_file_and_cmdline (grub_file_t file, (unsigned long long) payload_offset, (unsigned long long) lh.payload_length); - if (cmdline) - grub_pass_verity_hash (&lh, cmdline, cmdline_max_len); - grub_file_seek (file, payload_offset); if (grub_file_read (file, &magic, sizeof (magic)) != sizeof (magic)) diff --git a/grub-core/loader/i386/xen_fileXX.c b/grub-core/loader/i386/xen_fileXX.c index 6329ec010..27afcaacb 100644 --- a/grub-core/loader/i386/xen_fileXX.c +++ b/grub-core/loader/i386/xen_fileXX.c @@ -25,7 +25,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi, grub_off_t off, grub_size_t sz) { char *buf; - char *ptr; + const char *ptr; int has_paddr = 0; grub_errno = GRUB_ERR_NONE; diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c index e64ed08f5..a70093607 100644 --- a/grub-core/loader/i386/xnu.c +++ b/grub-core/loader/i386/xnu.c @@ -262,20 +262,19 @@ grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev, if (!prop) return grub_errno; - prop->name = utf8; - prop->name16 = utf16; - prop->name16len = utf16len; - - prop->length = datalen; - prop->data = grub_malloc (prop->length); + prop->data = grub_malloc (datalen); if (!prop->data) { - grub_free (prop->name); - grub_free (prop->name16); grub_free (prop); return grub_errno; } - grub_memcpy (prop->data, data, prop->length); + grub_memcpy (prop->data, data, datalen); + + prop->name = utf8; + prop->name16 = utf16; + prop->name16len = utf16len; + prop->length = datalen; + grub_list_push (GRUB_AS_LIST_P (&dev->properties), GRUB_AS_LIST (prop)); return GRUB_ERR_NONE; @@ -295,7 +294,7 @@ grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *d return grub_errno; len = grub_strlen (name); - utf16 = grub_malloc (sizeof (grub_uint16_t) * len); + utf16 = grub_calloc (len, sizeof (grub_uint16_t)); if (!utf16) { grub_free (utf8); @@ -331,7 +330,7 @@ grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor * grub_uint16_t *utf16; grub_err_t err; - utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen); + utf16 = grub_calloc (namelen, sizeof (grub_uint16_t)); if (!utf16) return grub_errno; grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen); @@ -516,14 +515,15 @@ grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)), devhead = buf; buf = devhead + 1; - dpstart = buf; + dp = dpstart = buf; - do + while (GRUB_EFI_DEVICE_PATH_VALID (dp) && buf < bufend) { - dp = buf; buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp); + if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) + break; + dp = buf; } - while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend); dev = grub_xnu_devprop_add_device (dpstart, (char *) buf - (char *) dpstart); diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c index 4b185cb15..3fe390f17 100644 --- a/grub-core/loader/linux.c +++ b/grub-core/loader/linux.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include struct newc_head { @@ -99,13 +99,13 @@ 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++); @@ -131,14 +131,22 @@ insert_dir (const char *name, struct dir **root, ptr = make_header (ptr, name, ce - name, 040777, 0); } - size += ALIGN_UP ((ce - (char *) name) - + sizeof (struct newc_head), 4); + if (grub_add (*size, + ALIGN_UP ((ce - (char *) name) + + sizeof (struct newc_head), 4), + size)) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + grub_free (n->name); + grub_free (n); + return grub_errno; + } *head = n; cur = n; } root = &cur->next; } - return size; + return GRUB_ERR_NONE; } grub_err_t @@ -152,8 +160,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; @@ -174,26 +181,33 @@ grub_initrd_init (int argc, char *argv[], eptr = grub_strchr (ptr, ':'); if (eptr) { + grub_size_t dir_size, name_len; + initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); - if (!initrd_ctx->components[i].newc_name) + if (!initrd_ctx->components[i].newc_name || + insert_dir (initrd_ctx->components[i].newc_name, &root, 0, + &dir_size)) { grub_initrd_close (initrd_ctx); return grub_errno; } - initrd_ctx->size - += ALIGN_UP (sizeof (struct newc_head) - + grub_strlen (initrd_ctx->components[i].newc_name), - 4); - initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, - &root, 0); + name_len = grub_strlen (initrd_ctx->components[i].newc_name); + 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!!!") - 1, 4), + &initrd_ctx->size)) + goto overflow; free_dir (root); root = 0; newc = 0; @@ -209,19 +223,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!!!") - 1, 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 @@ -262,8 +286,16 @@ 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), 0100777, @@ -289,10 +321,6 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, grub_initrd_close (initrd_ctx); return grub_errno; } - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure (ptr, cursize, GRUB_BINARY_PCR, "Initrd"); - //grub_print_error(); - ptr += cursize; } if (newc) diff --git a/grub-core/loader/macho.c b/grub-core/loader/macho.c index 085f9c689..05710c48e 100644 --- a/grub-core/loader/macho.c +++ b/grub-core/loader/macho.c @@ -97,7 +97,7 @@ grub_macho_file (grub_file_t file, const char *filename, int is_64bit) if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header)) == (grub_off_t) -1) goto fail; - archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs); + archs = grub_calloc (narchs, sizeof (struct grub_macho_fat_arch)); if (!archs) goto fail; if (grub_file_read (macho->file, archs, diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c index 7b723bf18..e4ed95921 100644 --- a/grub-core/loader/mips/linux.c +++ b/grub-core/loader/mips/linux.c @@ -442,12 +442,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), { grub_relocator_chunk_t ch; - err = grub_relocator_alloc_chunk_align (relocator, &ch, - (target_addr & 0x1fffffff) - + linux_size + 0x10000, - (0x10000000 - size), - size, 0x10000, - GRUB_RELOCATOR_PREFERENCE_NONE, 0); + err = grub_relocator_alloc_chunk_align_safe (relocator, &ch, (target_addr & 0x1fffffff) + + linux_size + 0x10000, 0x10000000, size, + 0x10000, GRUB_RELOCATOR_PREFERENCE_NONE, 0); if (err) goto fail; diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c index c16489de9..facb13f3d 100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@ -50,7 +50,6 @@ #include #include #include -#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -404,7 +403,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, - lowest_addr, (0xffffffff - size) + 1, + lowest_addr, UP_TO_TOP32 (size), size, MULTIBOOT_MOD_ALIGN, GRUB_RELOCATOR_PREFERENCE_NONE, 1); if (err) @@ -438,9 +437,6 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), } grub_file_close (file); - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure (module, size, GRUB_BINARY_PCR, argv[0]); - //grub_print_error(); return GRUB_ERR_NONE; } diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c index 70cd1db51..f2318e0d1 100644 --- a/grub-core/loader/multiboot_elfxx.c +++ b/grub-core/loader/multiboot_elfxx.c @@ -109,10 +109,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size) return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); - err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, - mld->min_addr, mld->max_addr - load_size, - load_size, mld->align ? mld->align : 1, - mld->preference, mld->avoid_efi_boot_services); + err = grub_relocator_alloc_chunk_align_safe (GRUB_MULTIBOOT (relocator), &ch, + mld->min_addr, mld->max_addr, + load_size, mld->align ? mld->align : 1, + mld->preference, mld->avoid_efi_boot_services); if (err) { @@ -217,7 +217,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) { grub_uint8_t *shdr, *shdrptr; - shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize); + shdr = grub_calloc (ehdr->e_shnum, ehdr->e_shentsize); if (!shdr) return grub_errno; @@ -256,7 +256,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) continue; err = grub_relocator_alloc_chunk_align (GRUB_MULTIBOOT (relocator), &ch, 0, - (0xffffffff - sh->sh_size) + 1, + UP_TO_TOP32 (sh->sh_size), sh->sh_size, sh->sh_addralign, GRUB_RELOCATOR_PREFERENCE_NONE, mld->avoid_efi_boot_services); diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index ab8d99c28..9a943d7bd 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -36,7 +36,6 @@ #include #include #include -#include #if defined (GRUB_MACHINE_EFI) #include @@ -49,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; @@ -132,10 +137,6 @@ grub_multiboot2_load (grub_file_t file, const char *filename) COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0); - // TODO figure out the GRUB_VERIFY_ equivalent for this one - //grub_tpm_measure ((unsigned char *)mld.buffer, len, GRUB_BINARY_PCR, filename); - //grub_print_error(); - header = find_header (mld.buffer, len); if (header == 0) @@ -300,10 +301,10 @@ grub_multiboot2_load (grub_file_t file, const char *filename) return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size"); } - err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, - mld.min_addr, mld.max_addr - code_size, - code_size, mld.align ? mld.align : 1, - mld.preference, keep_bs); + err = grub_relocator_alloc_chunk_align_safe (grub_multiboot2_relocator, &ch, + mld.min_addr, mld.max_addr, + code_size, mld.align ? mld.align : 1, + mld.preference, keep_bs); } else err = grub_relocator_alloc_chunk_addr (grub_multiboot2_relocator, @@ -713,7 +714,7 @@ grub_multiboot2_make_mbi (grub_uint32_t *target) COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % sizeof (grub_properly_aligned_t) == 0); err = grub_relocator_alloc_chunk_align (grub_multiboot2_relocator, &ch, - 0, 0xffffffff - bufsize, + MBI_MIN_ADDR, UP_TO_TOP32 (bufsize), bufsize, MULTIBOOT_TAG_ALIGN, GRUB_RELOCATOR_PREFERENCE_NONE, 1); if (err) @@ -1075,7 +1076,11 @@ grub_multiboot2_add_module (grub_addr_t start, grub_size_t size, err = grub_create_loader_cmdline (argc, argv, newmod->cmdline, newmod->cmdline_size, GRUB_VERIFY_MODULE_CMDLINE); if (err) - return err; + { + grub_free (newmod->cmdline); + grub_free (newmod); + return err; + } if (modules_last) modules_last->next = newmod; diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index 7f74d1d6f..9ae4ceb35 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -34,6 +34,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -59,15 +60,17 @@ grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target) { grub_err_t err; grub_relocator_chunk_t ch; + 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, - grub_xnu_heap_target_start - + grub_xnu_heap_size, size); + 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; @@ -800,7 +803,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); diff --git a/grub-core/loader/xnu_resume.c b/grub-core/loader/xnu_resume.c index 8089804d4..d648ef0cd 100644 --- a/grub-core/loader/xnu_resume.c +++ b/grub-core/loader/xnu_resume.c @@ -129,7 +129,7 @@ grub_xnu_resume (char *imagename) { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_align (grub_xnu_relocator, &ch, 0, - (0xffffffff - hibhead.image_size) + 1, + UP_TO_TOP32 (hibhead.image_size), hibhead.image_size, GRUB_XNU_PAGESIZE, GRUB_RELOCATOR_PREFERENCE_NONE, 0); diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c index 6a31cbae3..64684c23d 100644 --- a/grub-core/mmap/mmap.c +++ b/grub-core/mmap/mmap.c @@ -143,9 +143,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) { @@ -423,7 +423,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 +465,7 @@ static grub_uint64_t parsemem (const char *str) { grub_uint64_t ret; - char *ptr; + const char *ptr; ret = grub_strtoul (str, &ptr, 0); diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index e81014f6f..e33be51f8 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -25,20 +25,6 @@ #include #include -#if !defined(GRUB_MACHINE_EFI) && (defined(__i386__) || defined(__x86_64__)) -#define GRUB_NET_BOOTP_ARCH 0x0000 -#elif defined(GRUB_MACHINE_EFI) && defined(__x86_64__) -#define GRUB_NET_BOOTP_ARCH 0x0007 -#elif defined(GRUB_MACHINE_EFI) && defined(__aarch64__) -#define GRUB_NET_BOOTP_ARCH 0x000B -#else -#error "unknown bootp architecture" -#endif - -static grub_uint8_t grub_userclass[] = {0x4D, 0x06, 0x05, 'G', 'R', 'U', 'B', '2'}; -static grub_uint8_t grub_dhcpdiscover[] = {0x35, 0x01, 0x01}; -static grub_uint8_t grub_dhcptime[] = {0x33, 0x04, 0x00, 0x00, 0x0e, 0x10}; - struct grub_dhcp_discover_options { grub_uint8_t magic[4]; @@ -104,6 +90,19 @@ enum /* 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) @@ -161,6 +160,9 @@ again: if (i + taglength >= size) return NULL; + grub_dprintf("net", "DHCP option %u (0x%02x) found with length %u.\n", + tagtype, tagtype, taglength); + /* FIXME RFC 3396 options concatentation */ if (tagtype == opt_code) { @@ -415,6 +417,39 @@ grub_net_configure_by_dhcp_ack (const char *name, 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) { @@ -438,7 +473,6 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) struct udphdr *udph; grub_net_network_level_address_t target; grub_net_link_level_address_t ll_target; - grub_uint8_t *offset; static struct grub_dhcp_discover_options discover_options = { @@ -498,31 +532,19 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) 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) + sizeof(grub_userclass) - + sizeof(grub_dhcpdiscover) - + sizeof(grub_dhcptime) - + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); + nb = grub_netbuff_alloc (sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); if (!nb) return grub_errno; - err = grub_netbuff_reserve (nb, sizeof (*pack) + sizeof(grub_userclass) - + sizeof(grub_dhcpdiscover) - + sizeof(grub_dhcptime) - + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); + err = grub_netbuff_reserve (nb, sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128); if (err) goto out; - err = grub_netbuff_push (nb, sizeof(grub_userclass) - + sizeof(grub_dhcpdiscover) - + sizeof(grub_dhcptime) - + GRUB_BOOTP_MAX_OPTIONS_SIZE); + err = grub_netbuff_push (nb, GRUB_BOOTP_MAX_OPTIONS_SIZE); if (err) goto out; - grub_memset (nb->data, 0, sizeof(grub_userclass) - + sizeof(grub_dhcpdiscover) - + sizeof(grub_dhcptime) - + GRUB_BOOTP_MAX_OPTIONS_SIZE); + grub_memset (nb->data, 0, GRUB_BOOTP_MAX_OPTIONS_SIZE); if (!iface->srv_id) { grub_memcpy (nb->data, &discover_options, sizeof (discover_options)); @@ -559,22 +581,6 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) pack->ident = iface->xid; grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6); - offset = (grub_uint8_t *)&pack->vendor; - grub_memcpy (offset, grub_dhcpdiscover, sizeof(grub_dhcpdiscover)); - offset += sizeof(grub_dhcpdiscover); - grub_memcpy (offset, grub_userclass, sizeof(grub_userclass)); - offset += sizeof(grub_userclass); - grub_memcpy (offset, grub_dhcptime, sizeof(grub_dhcptime)); - - /* insert Client System Architecture (option 93) */ - offset += sizeof(grub_dhcptime); - offset[0] = 93; - offset[1] = 2; - offset[2] = (GRUB_NET_BOOTP_ARCH >> 8); - offset[3] = (GRUB_NET_BOOTP_ARCH & 0xFF); - - /* option terminator */ - offset[4] = 255; grub_netbuff_push (nb, sizeof (*udph)); @@ -669,14 +675,6 @@ grub_net_process_dhcp (struct grub_net_buff *nb, } } -static char -hexdigit (grub_uint8_t val) -{ - if (val < 10) - return val + '0'; - return val + 'a' - 10; -} - static grub_err_t grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) @@ -804,7 +802,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; diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c index 5deb1efd3..906ec7d67 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; @@ -285,8 +292,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), ptr++; ptr += 4; } - *data->addresses = grub_realloc (*data->addresses, sizeof ((*data->addresses)[0]) - * (grub_be_to_cpu16 (head->ancount) + *data->naddresses)); + *data->addresses = grub_calloc (grub_be_to_cpu16 (head->ancount), + sizeof ((*data->addresses)[0])); if (!*data->addresses) { grub_errno = GRUB_ERR_NONE; @@ -406,8 +413,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) { @@ -479,7 +486,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; diff --git a/grub-core/net/http.c b/grub-core/net/http.c index 389a78ee0..b616cf40b 100644 --- a/grub-core/net/http.c +++ b/grub-core/net/http.c @@ -107,7 +107,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 +134,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; } @@ -309,7 +309,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) { http_data_t data = file->data; grub_uint8_t *ptr; - int i, port; + int i; struct grub_net_buff *nb; grub_err_t err; @@ -390,13 +390,9 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) grub_netbuff_put (nb, 2); grub_memcpy (ptr, "\r\n", 2); - if (file->device->net->port) - port = file->device->net->port; - else - port = HTTP_PORT; data->sock = grub_net_tcp_open (file->device->net->server, - port, http_receive, - http_err, http_err, + HTTP_PORT, http_receive, + http_err, NULL, file); if (!data->sock) { diff --git a/grub-core/net/net.c b/grub-core/net/net.c index c474edac3..04ad10682 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -333,8 +333,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 +406,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; @@ -453,7 +453,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; @@ -563,7 +563,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 +579,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; @@ -1261,7 +1261,7 @@ grub_net_open_real (const char *name) grub_net_app_level_t proto; const char *protname, *server; grub_size_t protnamelen; - int try, port = 0; + int try; if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) { @@ -1278,18 +1278,7 @@ grub_net_open_real (const char *name) else { const char *comma; - char *colon; comma = grub_strchr (name, ','); - if (!comma) - { - comma = grub_strchr (name, ';'); - } - colon = grub_strchr (name, ':'); - if (colon) - { - port = (int) grub_strtol(colon+1, NULL, 10); - *colon = '\0'; - } if (comma) { protnamelen = comma - name; @@ -1324,13 +1313,8 @@ grub_net_open_real (const char *name) ret->server = grub_strdup (server); if (!ret->server) { - ret->server = grub_strdup (server); - ret->port = port; - if (!ret->server) - { - grub_free (ret); - return NULL; - } + grub_free (ret); + return NULL; } ret->fs = &grub_net_fs; return ret; @@ -1751,6 +1735,138 @@ 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_len; + char *suffix; + + config_len = grub_strlen (config); + config[config_len] = '-'; + suffix = config + 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_strcpy (suffix, client_uuid); + 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; diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c index 7d90bf66e..7e659a78b 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) { @@ -207,73 +183,71 @@ 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; @@ -287,17 +261,24 @@ 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) { - 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') + { + if (src[0] == '/' && src[1] == '/') + src++; + else + *dest++ = *src++; + } + *dest = '\0'; } static grub_err_t @@ -337,9 +318,14 @@ tftp_open (struct grub_file *file, const char *filename) 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; + + /* + * 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); + rrqlen += grub_strlen (rrq) + 1; + rrq += grub_strlen (rrq) + 1; grub_strcpy (rrq, "octet"); rrqlen += grub_strlen ("octet") + 1; @@ -372,17 +358,9 @@ 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_free (data); return err; } @@ -392,7 +370,6 @@ tftp_open (struct grub_file *file, const char *filename) file); if (!data->sock) { - destroy_pq (data); grub_free (data); return grub_errno; } @@ -406,7 +383,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,7 +399,6 @@ tftp_open (struct grub_file *file, const char *filename) if (grub_errno) { grub_net_udp_close (data->sock); - destroy_pq (data); grub_free (data); return grub_errno; } @@ -466,7 +441,6 @@ tftp_close (struct grub_file *file) grub_print_error (); grub_net_udp_close (data->sock); } - destroy_pq (data); grub_free (data); return GRUB_ERR_NONE; } diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c index b0ab47d73..4dfcc3107 100644 --- a/grub-core/normal/charset.c +++ b/grub-core/normal/charset.c @@ -48,6 +48,7 @@ #include #include #include +#include #if HAVE_FONT_SOURCE #include "widthspec.h" @@ -203,7 +204,7 @@ 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; @@ -464,6 +465,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, { struct grub_unicode_combining *n; unsigned j; + grub_size_t sz; if (!haveout) continue; @@ -477,10 +479,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 +494,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; @@ -842,7 +848,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; @@ -1165,8 +1171,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++) diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index c037d5050..de03fe63b 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 (); @@ -307,12 +308,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 +359,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 +387,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 +395,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 +505,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 +612,7 @@ grub_cmdline_get (const char *prompt_translated) grub_free (kill_buf); - kill_buf = grub_malloc ((n + 1) * sizeof(grub_uint32_t)); + kill_buf = grub_calloc (n + 1, sizeof (grub_uint32_t)); if (grub_errno) { grub_print_error (); diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c index 596102848..c07100a8d 100644 --- a/grub-core/normal/completion.c +++ b/grub-core/normal/completion.c @@ -284,7 +284,8 @@ complete_file (void) /* Cut away the filename part. */ dirfile = grub_strrchr (dir, '/'); - dirfile[1] = '\0'; + if (dirfile) + dirfile[1] = '\0'; /* Iterate the directory. */ (fs->fs_dir) (dev, dir, iterate_dir, NULL); diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 1b03dfd57..c4ebe9e22 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -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); grub_enter_normal_mode (config); grub_free (config); diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c index d5e0c79a7..8397886fa 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -170,8 +170,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); @@ -624,7 +623,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; diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c index cdf3590a3..50eef918c 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)) @@ -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; @@ -1023,7 +1032,7 @@ complete (struct screen *screen, int continuous, int update) 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) { @@ -1268,7 +1277,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 +1287,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) } } - screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0])); + screen->terms = grub_calloc (screen->nterms, sizeof (screen->terms[0])); if (!screen->terms) { grub_print_error (); diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c index e22bb91f6..18240e76c 100644 --- a/grub-core/normal/menu_text.c +++ b/grub-core/normal/menu_text.c @@ -78,7 +78,7 @@ 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; @@ -211,7 +211,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; diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index a1e5c5a0d..cc8c173b6 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -264,7 +264,7 @@ grub_term_save_pos (void) FOR_ACTIVE_TERM_OUTPUTS(cur) cnt++; - ret = grub_malloc (cnt * sizeof (ret[0])); + ret = grub_calloc (cnt, sizeof (ret[0])); if (!ret) return NULL; @@ -1013,7 +1013,7 @@ 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 (); diff --git a/grub-core/osdep/aros/hostdisk.c b/grub-core/osdep/aros/hostdisk.c index 2be654ca3..3b2c9de24 100644 --- a/grub-core/osdep/aros/hostdisk.c +++ b/grub-core/osdep/aros/hostdisk.c @@ -194,7 +194,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); } diff --git a/grub-core/osdep/devmapper/hostdisk.c b/grub-core/osdep/devmapper/hostdisk.c index a697bcb4d..a8afc0c94 100644 --- a/grub-core/osdep/devmapper/hostdisk.c +++ b/grub-core/osdep/devmapper/hostdisk.c @@ -113,7 +113,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; diff --git a/grub-core/osdep/generic/blocklist.c b/grub-core/osdep/generic/blocklist.c index ea2a511b6..2d9040302 100644 --- a/grub-core/osdep/generic/blocklist.c +++ b/grub-core/osdep/generic/blocklist.c @@ -59,7 +59,7 @@ grub_install_get_blocklist (grub_device_t root_dev, grub_disk_cache_invalidate_all (); - file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | FILE_TYPE_NO_DECOMPRESS); + file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS); if (file) { if (grub_file_size (file) != core_size) @@ -116,7 +116,7 @@ grub_install_get_blocklist (grub_device_t root_dev, grub_file_t file; /* Now read the core image to determine where the sectors are. */ - file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | FILE_TYPE_NO_DECOMPRESS); + file = grub_file_open (core_path_dev, GRUB_FILE_TYPE_NONE | GRUB_FILE_TYPE_NO_DECOMPRESS); if (! file) grub_util_error ("%s", grub_errmsg); diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c index 90d92d3ad..001b818fe 100644 --- a/grub-core/osdep/linux/getroot.c +++ b/grub-core/osdep/linux/getroot.c @@ -168,7 +168,7 @@ 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++) { @@ -241,7 +241,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++) { @@ -396,7 +396,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"); @@ -921,6 +921,19 @@ grub_util_part_to_disk (const char *os_dev, struct stat *st, return path; } + /* If this is an rssd device. */ + if ((strncmp ("rssd", p, 4) == 0) && p[4] >= 'a' && p[4] <= 'z') + { + char *pp = p + 4; + while (*pp >= 'a' && *pp <= 'z') + pp++; + if (*pp) + *is_part = 1; + /* /dev/rssd[a-z]+[0-9]* */ + *pp = '\0'; + return path; + } + /* If this is a loop device */ if ((strncmp ("loop", p, 4) == 0) && p[4] >= '0' && p[4] <= '9') { diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c index 8b92f8528..da62f924e 100644 --- a/grub-core/osdep/linux/hostdisk.c +++ b/grub-core/osdep/linux/hostdisk.c @@ -366,6 +366,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. */ diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c index 65effa9f3..7d6325138 100644 --- a/grub-core/osdep/unix/config.c +++ b/grub-core/osdep/unix/config.c @@ -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/hostdisk.c b/grub-core/osdep/unix/hostdisk.c index 91150969b..3a00d7451 100644 --- a/grub-core/osdep/unix/hostdisk.c +++ b/grub-core/osdep/unix/hostdisk.c @@ -164,6 +164,9 @@ grub_util_fd_open (const char *os_dev, int flags) #ifdef O_BINARY flags |= O_BINARY; #endif +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif return open (os_dev, flags, S_IROTH | S_IRGRP | S_IRUSR | S_IWUSR); } diff --git a/grub-core/osdep/windows/getroot.c b/grub-core/osdep/windows/getroot.c index 661d95461..eada663b2 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 diff --git a/grub-core/osdep/windows/hostdisk.c b/grub-core/osdep/windows/hostdisk.c index 355100789..0be327394 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) @@ -399,7 +399,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] = '*'; diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c index e8ffd62c6..6297de632 100644 --- a/grub-core/osdep/windows/init.c +++ b/grub-core/osdep/windows/init.c @@ -161,7 +161,7 @@ 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]); diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c index 7eb53fe01..1ef86bf58 100644 --- a/grub-core/osdep/windows/platform.c +++ b/grub-core/osdep/windows/platform.c @@ -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); 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/gpt.c b/grub-core/partmap/gpt.c index 103f6796f..72a2e37cd 100644 --- a/grub-core/partmap/gpt.c +++ b/grub-core/partmap/gpt.c @@ -199,7 +199,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++) diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c index 7b8e45076..ee3f24982 100644 --- a/grub-core/partmap/msdos.c +++ b/grub-core/partmap/msdos.c @@ -337,7 +337,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++) 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 0144c5698..ce83edd4b 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -27,7 +27,6 @@ #include #include #include -#include #include /* Max digits for a char is 3 (0xFF is 255), similarly for an int it @@ -123,7 +122,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) @@ -155,7 +154,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) @@ -216,7 +215,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) @@ -554,7 +553,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; @@ -839,7 +838,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; 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..57778f881 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; } @@ -331,7 +346,7 @@ 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); diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y index 4f0ab8319..4a18ab7ba 100644 --- a/grub-core/script/parser.y +++ b/grub-core/script/parser.y @@ -279,7 +279,7 @@ function: "function" "name" $$ = state->scripts; state->scripts = 0; } - delimiters0 "{" commands1 delimiters1 "}" + newlines0 "{" commands1 delimiters1 "}" { struct grub_script *script; state->func_mem = grub_script_mem_record_stop (state, @@ -289,7 +289,8 @@ function: "function" "name" grub_script_mem_free (state->func_mem); else { script->children = state->scripts; - grub_script_function_create ($2, script); + if (!grub_script_function_create ($2, script)) + grub_script_free (script); } state->scripts = $3; diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 7b44c37b7..b7203c823 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -37,11 +37,11 @@ /* * As we don't have access to yyscanner, we cannot do much except to - * print the fatal error. + * print the fatal error and exit. */ #define YY_FATAL_ERROR(msg) \ do { \ - grub_printf (_("fatal error: %s\n"), _(msg)); \ + grub_fatal (_("fatal error: %s\n"), _(msg));\ } while (0) #define COPY(str, hint) \ diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c index f0a986eb1..597111077 100644 --- a/grub-core/term/at_keyboard.c +++ b/grub-core/term/at_keyboard.c @@ -234,7 +234,7 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) return GRUB_TERM_NO_KEY; if (! KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS))) - return -1; + return GRUB_TERM_NO_KEY; at_key = grub_inb (KEYBOARD_REG_DATA); old_led = ps2_state.led_status; diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index 4840cc59d..2f1ae85ba 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -24,6 +24,16 @@ #include #include +typedef enum { + GRUB_TEXT_MODE_UNDEFINED = -1, + GRUB_TEXT_MODE_UNAVAILABLE = 0, + GRUB_TEXT_MODE_AVAILABLE +} +grub_text_mode; + +static grub_text_mode text_mode = GRUB_TEXT_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 +76,79 @@ 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) + 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_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; + } + + grub_console_setcursor (term, 1); + 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; @@ -152,27 +227,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 = efi_call_2 (text_input->read_key_stroke, text_input, &key_data); + if (status != GRUB_EFI_SUCCESS) + return GRUB_ERR_EOF; + + key = grub_efi_translate_key (key_data.key); + } + + *key_data_ret = key_data; + *key_ret = key; + + if (consume) { + key_data.key.scan_code = 0; + key_data.key.unicode_char = 0; + } + + return GRUB_ERR_NONE; +} + static int -grub_console_getkey_ex(struct grub_term_input *term) +grub_console_getkey_ex (struct grub_term_input *term) { grub_efi_key_data_t key_data; - grub_efi_status_t status; grub_efi_uint32_t kss; + grub_err_t err; int key = -1; - grub_efi_simple_text_input_ex_interface_t *text_input = term->data; - - status = efi_call_2 (text_input->read_key_stroke, text_input, &key_data); - - if (status != GRUB_EFI_SUCCESS) + err = grub_console_read_key_stroke (term->data, &key_data, &key, 1); + if (err != GRUB_ERR_NONE || key == GRUB_TERM_NO_KEY) return GRUB_TERM_NO_KEY; kss = key_data.key_state.key_shift_state; - key = grub_efi_translate_key(key_data.key); - - if (key == GRUB_TERM_NO_KEY) - return GRUB_TERM_NO_KEY; - if (kss & GRUB_EFI_SHIFT_STATE_VALID) { if ((kss & GRUB_EFI_LEFT_SHIFT_PRESSED @@ -189,6 +294,39 @@ 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) { @@ -223,14 +361,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 || + efi_call_4 (o->query_mode, o, o->mode->mode, + &columns, &rows) != GRUB_EFI_SUCCESS) { /* Why does this fail? */ columns = 80; @@ -245,7 +384,7 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) { grub_efi_simple_text_output_interface_t *o; - if (grub_efi_is_finished) + if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) return (struct grub_term_coordinate) { 0, 0 }; o = grub_efi_system_table->con_out; @@ -253,12 +392,12 @@ 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; @@ -271,7 +410,7 @@ 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_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) return; o = grub_efi_system_table->con_out; @@ -281,60 +420,15 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused))) 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; -} - static grub_err_t grub_efi_console_output_fini (struct grub_term_output *term) { + if (text_mode != GRUB_TEXT_MODE_AVAILABLE) + return 0; + grub_console_setcursor (term, 0); grub_efi_set_text_mode (0); + text_mode = GRUB_TEXT_MODE_UNDEFINED; return 0; } @@ -342,13 +436,13 @@ static struct grub_term_input grub_console_term_input = { .name = "console", .getkey = grub_console_getkey, + .getkeystatus = grub_console_getkeystatus, .init = grub_efi_console_input_init, }; static struct grub_term_output grub_console_term_output = { .name = "console", - .init = grub_efi_console_output_init, .fini = grub_efi_console_output_fini, .putchar = grub_console_putchar, .getwh = grub_console_getwh, @@ -364,14 +458,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/serial.c b/grub-core/term/serial.c index db80b3ba0..f9271b092 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -269,7 +269,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; diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c index d317efa36..cd7200803 100644 --- a/grub-core/term/terminfo.c +++ b/grub-core/term/terminfo.c @@ -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)++; \ } @@ -602,8 +605,8 @@ grub_terminfo_getkey (struct grub_term_input *termi) return ret; } - grub_terminfo_readkey (termi, data->input_buf, - &data->npending, data->readkey); + grub_terminfo_readkey (termi, data->input_buf, &data->npending, + GRUB_TERMINFO_READKEY_MAX_LEN, data->readkey); #if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) if (data->npending == 1 && data->input_buf[0] == GRUB_TERM_ESC @@ -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; 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/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..44d081069 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); 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..7a249eb21 100644 --- a/grub-core/video/bochs.c +++ b/grub-core/video/bochs.c @@ -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..4d3195e01 100644 --- a/grub-core/video/capture.c +++ b/grub-core/video/capture.c @@ -89,7 +89,7 @@ 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; diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c index 7f9d1c2df..be446f8d2 100644 --- a/grub-core/video/efi_gop.c +++ b/grub-core/video/efi_gop.c @@ -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; } @@ -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; diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c index 044af1d20..e74d6c235 100644 --- a/grub-core/video/efi_uga.c +++ b/grub-core/video/efi_uga.c @@ -34,7 +34,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; static struct grub_efi_uga_draw_protocol *uga; -static grub_uint32_t uga_fb; +static grub_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; }; @@ -110,7 +110,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) { int i; - grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", + grub_dprintf ("video", "Display controller: %d:%d.%d\nDevice id: %x\n", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), pciid); addr += 8; @@ -129,7 +129,9 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) if (i == 5) break; - old_bar2 = grub_pci_read (addr + 4); + i++; + addr += 4; + old_bar2 = grub_pci_read (addr); } else old_bar2 = 0; @@ -138,10 +140,15 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) base64 <<= 32; base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); - grub_dprintf ("fb", "%s(%d): 0x%llx\n", + grub_dprintf ("video", "%s(%d): 0x%" PRIxGRUB_UINT64_T "\n", ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? - "VMEM" : "MMIO"), i, - (unsigned long long) base64); + "VMEM" : "MMIO"), type == GRUB_PCI_ADDR_MEM_TYPE_64 ? i - 1 : i, + base64); + +#if GRUB_CPU_SIZEOF_VOID_P == 4 + if (old_bar2) + continue; +#endif if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! ctx->found)) { @@ -149,12 +156,6 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) if (find_line_len (ctx->fb_base, ctx->line_len)) ctx->found++; } - - if (type == GRUB_PCI_ADDR_MEM_TYPE_64) - { - i++; - addr += 4; - } } } @@ -162,7 +163,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) } static int -find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) +find_framebuf (grub_uint64_t *fb_base, grub_uint32_t *line_len) { struct find_framebuf_ctx ctx = { .fb_base = fb_base, diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c index a2f639f66..0ebab6f57 100644 --- a/grub-core/video/emu/sdl.c +++ b/grub-core/video/emu/sdl.c @@ -172,7 +172,7 @@ 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; diff --git a/grub-core/video/i386/pc/vga.c b/grub-core/video/i386/pc/vga.c index 01f47112d..b2f776c99 100644 --- a/grub-core/video/i386/pc/vga.c +++ b/grub-core/video/i386/pc/vga.c @@ -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) diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c index 777e71334..0157ff742 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+"); @@ -301,15 +302,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) #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; 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.h b/include/grub/compiler.h index c9e1d7a73..8f3be3ae7 100644 --- a/include/grub/compiler.h +++ b/include/grub/compiler.h @@ -48,4 +48,12 @@ # define WARN_UNUSED_RESULT #endif +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +# define CLANG_PREREQ(maj,min) \ + ((__clang_major__ > (maj)) || \ + (__clang_major__ == (maj) && __clang_minor__ >= (min))) +#else +# define CLANG_PREREQ(maj,min) 0 +#endif + #endif /* ! GRUB_COMPILER_HEADER */ diff --git a/include/grub/crypto.h b/include/grub/crypto.h index a24e89dd9..21cd1f75a 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -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, diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 32f564ae0..e1b21e785 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -130,6 +130,9 @@ 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); diff --git a/include/grub/disk.h b/include/grub/disk.h index 316659fee..132a1bb75 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -174,6 +174,13 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; /* Return value of grub_disk_get_size() in case disk size is unknown. */ #define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL +/* 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); +} + /* This is called from the memory manager. */ void grub_disk_cache_invalidate_all (void); diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h index 576074384..1dcaa12f5 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -531,7 +531,7 @@ 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; #define GRUB_EFI_ERROR_CODE(value) \ ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) @@ -630,6 +630,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) @@ -638,13 +639,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 @@ -1295,7 +1299,7 @@ struct grub_efi_runtime_services (*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 diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 6b47373db..e90e00dc4 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -46,8 +46,7 @@ void * EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, grub_efi_uintn_t pages); void * -EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, - grub_efi_uintn_t pages); +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); @@ -83,7 +82,6 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, const grub_efi_guid_t *guid, void *data, grub_size_t datasize); -grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); int EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, const grub_efi_device_path_t *dp2); diff --git a/include/grub/efi/graphics_output.h b/include/grub/efi/graphics_output.h index 129777411..e4388127c 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; diff --git a/include/grub/efi/tpm.h b/include/grub/efi/tpm.h index 51ab02e27..ec39725c0 100644 --- a/include/grub/efi/tpm.h +++ b/include/grub/efi/tpm.h @@ -132,12 +132,14 @@ typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY EFI_TCG2_BOOT_SERVICE_CAPABILI typedef grub_efi_uint32_t TCG_PCRINDEX; typedef grub_efi_uint32_t TCG_EVENTTYPE; -typedef struct tdEFI_TCG2_EVENT_HEADER { +struct tdEFI_TCG2_EVENT_HEADER +{ grub_efi_uint32_t HeaderSize; grub_efi_uint16_t HeaderVersion; - TCG_PCRINDEX PCRIndex; - TCG_EVENTTYPE EventType; -} GRUB_PACKED EFI_TCG2_EVENT_HEADER; + TCG_PCRINDEX PCRIndex; + TCG_EVENTTYPE EventType; +} GRUB_PACKED; +typedef struct tdEFI_TCG2_EVENT_HEADER EFI_TCG2_EVENT_HEADER; struct tdEFI_TCG2_EVENT { @@ -159,7 +161,7 @@ struct grub_efi_tpm2_protocol EventLogLocation, grub_efi_physical_address_t * EventLogLastEntry, - grub_efi_boolean_t *EventLogTruncated); + grub_efi_boolean_t * EventLogTruncated); grub_efi_status_t (*hash_log_extend_event) (struct grub_efi_tpm2_protocol * this, grub_efi_uint64_t Flags, grub_efi_physical_address_t @@ -174,10 +176,10 @@ struct grub_efi_tpm2_protocol OutputParameterBlockSize, grub_efi_uint8_t * OutputParameterBlock); - grub_efi_status_t (*get_active_pcr_blanks) (struct grub_efi_tpm2_protocol * - this, - grub_efi_uint32_t * - ActivePcrBanks); + grub_efi_status_t (*get_active_pcr_banks) (struct grub_efi_tpm2_protocol * + this, + grub_efi_uint32_t * + ActivePcrBanks); grub_efi_status_t (*set_active_pcr_banks) (struct grub_efi_tpm2_protocol * this, grub_efi_uint32_t diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index ce464cfd0..ff9c48a64 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -47,6 +47,7 @@ grub_util_device_is_mapped (const char *dev); #define GRUB_HOST_PRIuLONG_LONG "llu" #define GRUB_HOST_PRIxLONG_LONG "llx" +void * EXPORT_FUNC(xcalloc) (grub_size_t nmemb, grub_size_t size) WARN_UNUSED_RESULT; void * EXPORT_FUNC(xmalloc) (grub_size_t size) WARN_UNUSED_RESULT; void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) WARN_UNUSED_RESULT; char * EXPORT_FUNC(xstrdup) (const char *str) WARN_UNUSED_RESULT; diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h index cdb6dfe8f..7a93f4329 100644 --- a/include/grub/gpt_partition.h +++ b/include/grub/gpt_partition.h @@ -21,7 +21,6 @@ #include #include -#include struct grub_gpt_part_guid { @@ -32,43 +31,24 @@ struct grub_gpt_part_guid } GRUB_PACKED; typedef struct grub_gpt_part_guid grub_gpt_part_guid_t; -/* Format the raw little-endian GUID as a newly allocated string. */ -char * grub_gpt_guid_to_str (grub_gpt_part_guid_t *guid); - - -#define GRUB_GPT_GUID_INIT(a, b, c, d1, d2, d3, d4, d5, d6, d7, d8) \ - { \ - grub_cpu_to_le32_compile_time (a), \ - grub_cpu_to_le16_compile_time (b), \ - grub_cpu_to_le16_compile_time (c), \ - { d1, d2, d3, d4, d5, d6, d7, d8 } \ +#define GRUB_GPT_PARTITION_TYPE_EMPTY \ + { 0x0, 0x0, 0x0, \ + { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } \ } -#define GRUB_GPT_PARTITION_TYPE_EMPTY \ - GRUB_GPT_GUID_INIT (0x0, 0x0, 0x0, \ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) - -#define GRUB_GPT_PARTITION_TYPE_EFI_SYSTEM \ - GRUB_GPT_GUID_INIT (0xc12a7328, 0xf81f, 0x11d2, \ - 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b) - #define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \ - GRUB_GPT_GUID_INIT (0x21686148, 0x6449, 0x6e6f, \ - 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49) + { grub_cpu_to_le32_compile_time (0x21686148), \ + grub_cpu_to_le16_compile_time (0x6449), \ + grub_cpu_to_le16_compile_time (0x6e6f), \ + { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } \ + } #define GRUB_GPT_PARTITION_TYPE_LDM \ - GRUB_GPT_GUID_INIT (0x5808c8aa, 0x7e8f, 0x42e0, \ - 0x85, 0xd2, 0xe1, 0xe9, 0x04, 0x34, 0xcf, 0xb3) - -#define GRUB_GPT_PARTITION_TYPE_USR_X86_64 \ - GRUB_GPT_GUID_INIT (0x5dfbf5f4, 0x2848, 0x4bac, \ - 0xaa, 0x5e, 0x0d, 0x9a, 0x20, 0xb7, 0x45, 0xa6) - -#define GRUB_GPT_HEADER_MAGIC \ - { 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54 } - -#define GRUB_GPT_HEADER_VERSION \ - grub_cpu_to_le32_compile_time (0x00010000U) + { grub_cpu_to_le32_compile_time (0x5808C8AAU),\ + grub_cpu_to_le16_compile_time (0x7E8F), \ + grub_cpu_to_le16_compile_time (0x42E0), \ + { 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3 } \ + } struct grub_gpt_header { @@ -77,11 +57,11 @@ struct grub_gpt_header grub_uint32_t headersize; grub_uint32_t crc32; grub_uint32_t unused1; - grub_uint64_t header_lba; - grub_uint64_t alternate_lba; + grub_uint64_t primary; + grub_uint64_t backup; grub_uint64_t start; grub_uint64_t end; - grub_gpt_part_guid_t guid; + grub_uint8_t guid[16]; grub_uint64_t partitions; grub_uint32_t maxpart; grub_uint32_t partentry_size; @@ -95,172 +75,13 @@ struct grub_gpt_partentry grub_uint64_t start; grub_uint64_t end; grub_uint64_t attrib; - grub_uint16_t name[36]; + char name[72]; } GRUB_PACKED; -enum grub_gpt_part_attr_offset -{ - /* Standard partition attribute bits defined by UEFI. */ - GRUB_GPT_PART_ATTR_OFFSET_REQUIRED = 0, - GRUB_GPT_PART_ATTR_OFFSET_NO_BLOCK_IO_PROTOCOL = 1, - GRUB_GPT_PART_ATTR_OFFSET_LEGACY_BIOS_BOOTABLE = 2, - - /* De facto standard attribute bits defined by Microsoft and reused by - * http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec */ - GRUB_GPT_PART_ATTR_OFFSET_READ_ONLY = 60, - GRUB_GPT_PART_ATTR_OFFSET_NO_AUTO = 63, - - /* Partition attributes for priority based selection, - * Currently only valid for PARTITION_TYPE_USR_X86_64. - * TRIES_LEFT and PRIORITY are 4 bit wide fields. */ - GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_PRIORITY = 48, - GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT = 52, - GRUB_GPT_PART_ATTR_OFFSET_GPTPRIO_SUCCESSFUL = 56, -}; - -/* Helpers for reading/writing partition attributes. */ -static inline grub_uint64_t -grub_gpt_entry_attribute (struct grub_gpt_partentry *entry, - enum grub_gpt_part_attr_offset offset, - unsigned int bits) -{ - grub_uint64_t attrib = grub_le_to_cpu64 (entry->attrib); - - return (attrib >> offset) & ((1ULL << bits) - 1); -} - -static inline void -grub_gpt_entry_set_attribute (struct grub_gpt_partentry *entry, - grub_uint64_t value, - enum grub_gpt_part_attr_offset offset, - unsigned int bits) -{ - grub_uint64_t attrib, mask; - - mask = (((1ULL << bits) - 1) << offset); - attrib = grub_le_to_cpu64 (entry->attrib) & ~mask; - attrib |= ((value << offset) & mask); - entry->attrib = grub_cpu_to_le64 (attrib); -} - -/* Basic GPT partmap module. */ grub_err_t grub_gpt_partition_map_iterate (grub_disk_t disk, grub_partition_iterate_hook_t hook, void *hook_data); -/* Advanced GPT library. */ - -/* Status bits for the grub_gpt.status field. */ -#define GRUB_GPT_PROTECTIVE_MBR 0x01 -#define GRUB_GPT_HYBRID_MBR 0x02 -#define GRUB_GPT_PRIMARY_HEADER_VALID 0x04 -#define GRUB_GPT_PRIMARY_ENTRIES_VALID 0x08 -#define GRUB_GPT_BACKUP_HEADER_VALID 0x10 -#define GRUB_GPT_BACKUP_ENTRIES_VALID 0x20 - -/* UEFI requires the entries table to be at least 16384 bytes for a - * total of 128 entries given the standard 128 byte entry size. */ -#define GRUB_GPT_DEFAULT_ENTRIES_SIZE 16384 -#define GRUB_GPT_DEFAULT_ENTRIES_LENGTH \ - (GRUB_GPT_DEFAULT_ENTRIES_SIZE / sizeof (struct grub_gpt_partentry)) - -struct grub_gpt -{ - /* Bit field indicating which structures on disk are valid. */ - unsigned status; - - /* Protective or hybrid MBR. */ - struct grub_msdos_partition_mbr mbr; - - /* Each of the two GPT headers. */ - struct grub_gpt_header primary; - struct grub_gpt_header backup; - - /* Only need one entries table, on disk both copies are identical. - * The on disk entry size may be larger than our partentry struct so - * the table cannot be indexed directly. */ - void *entries; - grub_size_t entries_size; - - /* Logarithm of sector size, in case GPT and disk driver disagree. */ - unsigned int log_sector_size; -}; -typedef struct grub_gpt *grub_gpt_t; - -/* Helpers for checking the gpt status field. */ -static inline int -grub_gpt_mbr_valid (grub_gpt_t gpt) -{ - return ((gpt->status & GRUB_GPT_PROTECTIVE_MBR) || - (gpt->status & GRUB_GPT_HYBRID_MBR)); -} - -static inline int -grub_gpt_primary_valid (grub_gpt_t gpt) -{ - return ((gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) && - (gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID)); -} - -static inline int -grub_gpt_backup_valid (grub_gpt_t gpt) -{ - return ((gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) && - (gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID)); -} - -static inline int -grub_gpt_both_valid (grub_gpt_t gpt) -{ - return grub_gpt_primary_valid (gpt) && grub_gpt_backup_valid (gpt); -} - -/* Translate GPT sectors to GRUB's 512 byte block addresses. */ -static inline grub_disk_addr_t -grub_gpt_sector_to_addr (grub_gpt_t gpt, grub_uint64_t sector) -{ - return (sector << (gpt->log_sector_size - GRUB_DISK_SECTOR_BITS)); -} - -/* Allocates and fills new grub_gpt structure, free with grub_gpt_free. */ -grub_gpt_t grub_gpt_read (grub_disk_t disk); - -/* Helper for indexing into the entries table. - * Returns NULL when the end of the table has been reached. */ -struct grub_gpt_partentry * grub_gpt_get_partentry (grub_gpt_t gpt, - grub_uint32_t n); - -/* Sync and update primary and backup headers if either are invalid. */ -grub_err_t grub_gpt_repair (grub_disk_t disk, grub_gpt_t gpt); - -/* Recompute checksums and revalidate everything, must be called after - * modifying any GPT data. */ -grub_err_t grub_gpt_update (grub_gpt_t gpt); - -/* Write headers and entry tables back to disk. */ -grub_err_t grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt); - -void grub_gpt_free (grub_gpt_t gpt); - -grub_err_t grub_gpt_pmbr_check (struct grub_msdos_partition_mbr *mbr); -grub_err_t grub_gpt_header_check (struct grub_gpt_header *gpt, - unsigned int log_sector_size); - - -/* Utilities for simple partition data lookups, usage is intended to - * be similar to fs->label and fs->uuid functions. */ - -/* Return the partition label of the device DEVICE in LABEL. - * The label is in a new buffer and should be freed by the caller. */ -grub_err_t grub_gpt_part_label (grub_device_t device, char **label); - -/* Return the partition uuid of the device DEVICE in UUID. - * The uuid is in a new buffer and should be freed by the caller. */ -grub_err_t grub_gpt_part_uuid (grub_device_t device, char **uuid); - -/* Return the disk uuid of the device DEVICE in UUID. - * The uuid is in a new buffer and should be freed by the caller. */ -grub_err_t grub_gpt_disk_uuid (grub_device_t device, char **uuid); #endif /* ! GRUB_GPT_PARTITION_HEADER */ diff --git a/include/grub/loader.h b/include/grub/loader.h index 7f82a499f..b20864282 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -33,6 +33,7 @@ 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), diff --git a/include/grub/misc.h b/include/grub/misc.h index ee48eb7a7..b7ca6dd58 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -243,11 +243,29 @@ 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); +/* + * 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; @@ -322,6 +340,7 @@ 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, diff --git a/include/grub/mm.h b/include/grub/mm.h index 28e2e53eb..9c38dd3ca 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -29,6 +29,7 @@ #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); @@ -48,6 +49,9 @@ extern int EXPORT_VAR(grub_mm_debug); void grub_mm_dump_free (void); void 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 +67,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/net.h b/include/grub/net.h index 65d442537..7ae4b6bd8 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -276,7 +276,6 @@ typedef struct grub_net grub_fs_t fs; int eof; int stall; - int port; } *grub_net_t; extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); @@ -455,22 +454,24 @@ struct grub_net_bootp_packet enum { - GRUB_NET_BOOTP_PAD = 0x00, - GRUB_NET_BOOTP_NETMASK = 0x01, - GRUB_NET_BOOTP_ROUTER = 0x03, - GRUB_NET_BOOTP_DNS = 0x06, - GRUB_NET_BOOTP_HOSTNAME = 0x0c, - GRUB_NET_BOOTP_DOMAIN = 0x0f, - GRUB_NET_BOOTP_ROOT_PATH = 0x11, - GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12, + GRUB_NET_BOOTP_PAD = 0, + GRUB_NET_BOOTP_NETMASK = 1, + GRUB_NET_BOOTP_ROUTER = 3, + GRUB_NET_BOOTP_DNS = 6, + GRUB_NET_BOOTP_HOSTNAME = 12, + GRUB_NET_BOOTP_DOMAIN = 15, + GRUB_NET_BOOTP_ROOT_PATH = 17, + GRUB_NET_BOOTP_EXTENSIONS_PATH = 18, GRUB_NET_DHCP_REQUESTED_IP_ADDRESS = 50, GRUB_NET_DHCP_OVERLOAD = 52, GRUB_NET_DHCP_MESSAGE_TYPE = 53, GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, + GRUB_NET_BOOTP_CLIENT_ID = 61, GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, GRUB_NET_DHCP_BOOTFILE_NAME = 67, - GRUB_NET_BOOTP_END = 0xff + GRUB_NET_BOOTP_CLIENT_UUID = 97, + GRUB_NET_BOOTP_END = 255 }; struct grub_net_network_level_interface * @@ -568,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); extern char *grub_net_default_server; diff --git a/include/grub/osdep/hostfile_aros.h b/include/grub/osdep/hostfile_aros.h index a059c0fa4..161fbb7bd 100644 --- a/include/grub/osdep/hostfile_aros.h +++ b/include/grub/osdep/hostfile_aros.h @@ -68,6 +68,12 @@ grub_util_rename (const char *from, const char *to) return rename (from, to); } +static inline ssize_t +grub_util_readlink (const char *name, char *buf, size_t bufsize) +{ + return readlink(name, buf, bufsize); +} + #define grub_util_mkdir(a) 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..17cd3aa8b 100644 --- a/include/grub/osdep/hostfile_unix.h +++ b/include/grub/osdep/hostfile_unix.h @@ -71,6 +71,12 @@ grub_util_rename (const char *from, const char *to) return rename (from, to); } +static inline ssize_t +grub_util_readlink (const char *name, char *buf, size_t bufsize) +{ + return readlink(name, buf, bufsize); +} + #define grub_util_mkdir(a) mkdir ((a), 0755) #if defined (__NetBSD__) diff --git a/include/grub/relocator.h b/include/grub/relocator.h index 24d8672d2..1b3bdd92a 100644 --- a/include/grub/relocator.h +++ b/include/grub/relocator.h @@ -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/safemath.h b/include/grub/safemath.h new file mode 100644 index 000000000..c17b89bba --- /dev/null +++ b/include/grub/safemath.h @@ -0,0 +1,37 @@ +/* + * 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 3.8. */ +#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8) + +#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) + +#else +#error gcc 5.1 or newer or clang 3.8 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/search.h b/include/grub/search.h index 7f69d25d1..d80347df3 100644 --- a/include/grub/search.h +++ b/include/grub/search.h @@ -25,11 +25,5 @@ void grub_search_fs_uuid (const char *key, const char *var, int no_floppy, char **hints, unsigned nhints); void grub_search_label (const char *key, const char *var, int no_floppy, char **hints, unsigned nhints); -void grub_search_part_uuid (const char *key, const char *var, int no_floppy, - char **hints, unsigned nhints); -void grub_search_part_label (const char *key, const char *var, int no_floppy, - char **hints, unsigned nhints); -void grub_search_disk_uuid (const char *key, const char *var, int no_floppy, - char **hints, unsigned nhints); #endif diff --git a/include/grub/smbios.h b/include/grub/smbios.h index 4b82fa845..15ec260b3 100644 --- a/include/grub/smbios.h +++ b/include/grub/smbios.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2015 Free Software Foundation, Inc. + * 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 @@ -19,6 +19,7 @@ #ifndef GRUB_SMBIOS_HEADER #define GRUB_SMBIOS_HEADER 1 +#include #include #define GRUB_SMBIOS_TYPE_END_OF_TABLE ((grub_uint8_t)127) @@ -60,9 +61,9 @@ struct grub_smbios_eps3 grub_uint64_t table_address; } GRUB_PACKED; -struct grub_smbios_eps *grub_smbios_get_eps (void); -struct grub_smbios_eps3 *grub_smbios_get_eps3 (void); -struct grub_smbios_eps *grub_machine_smbios_get_eps (void); -struct grub_smbios_eps3 *grub_machine_smbios_get_eps3 (void); +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/term.h b/include/grub/term.h index 8117e2a24..3387cb052 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -75,9 +75,11 @@ /* These are used to represent the various color states we use. */ typedef enum { + /* Used for uninitialized grub_term_color_state variables */ + GRUB_TERM_COLOR_UNDEFINED = -1, /* The color used to display all text that does not use the user defined colors below. */ - GRUB_TERM_COLOR_STANDARD, + GRUB_TERM_COLOR_STANDARD = 0, /* The user defined colors for normal text. */ GRUB_TERM_COLOR_NORMAL, /* The user defined colors for highlighted text. */ @@ -327,6 +329,8 @@ grub_term_unregister_output (grub_term_output_t term) void grub_putcode (grub_uint32_t code, struct grub_term_output *term); int EXPORT_FUNC(grub_getkey) (void); int EXPORT_FUNC(grub_getkey_noblock) (void); +int EXPORT_FUNC(grub_getkeystatus) (void); +int EXPORT_FUNC(grub_key_is_interrupt) (int key); void grub_cls (void); void EXPORT_FUNC(grub_refresh) (void); void grub_puts_terminal (const char *str, struct grub_term_output *term); diff --git a/include/grub/tpm.h b/include/grub/tpm.h index dfcbe8372..5c285cbc5 100644 --- a/include/grub/tpm.h +++ b/include/grub/tpm.h @@ -34,49 +34,6 @@ #define EV_IPL 0x0d -/* TCG_PassThroughToTPM Input Parameter Block. */ -typedef struct -{ - grub_uint16_t IPBLength; - grub_uint16_t Reserved1; - grub_uint16_t OPBLength; - grub_uint16_t Reserved2; - grub_uint8_t TPMOperandIn[1]; -} GRUB_PACKED PassThroughToTPM_InputParamBlock; - -/* TCG_PassThroughToTPM Output Parameter Block. */ -typedef struct -{ - grub_uint16_t OPBLength; - grub_uint16_t Reserved; - grub_uint8_t TPMOperandOut[1]; -} GRUB_PACKED PassThroughToTPM_OutputParamBlock; - -typedef struct -{ - grub_uint16_t tag; - grub_uint32_t paramSize; - grub_uint32_t ordinal; - grub_uint32_t pcrNum; - /* The 160 bit value representing the event to be recorded. */ - grub_uint8_t inDigest[SHA1_DIGEST_SIZE]; -} GRUB_PACKED ExtendIncoming; - -/* TPM_Extend Outgoing Operand. */ -typedef struct -{ - grub_uint16_t tag; - grub_uint32_t paramSize; - grub_uint32_t returnCode; - /* The PCR value after execution of the command. */ - grub_uint8_t outDigest[SHA1_DIGEST_SIZE]; -} GRUB_PACKED ExtendOutgoing; - grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description); -grub_err_t grub_tpm_init (void); -grub_err_t grub_tpm_execute (PassThroughToTPM_InputParamBlock *inbuf, - PassThroughToTPM_OutputParamBlock *outbuf); -grub_err_t grub_tpm_log_event (unsigned char *buf, grub_size_t size, - grub_uint8_t pcr, const char *description); #endif diff --git a/include/grub/unicode.h b/include/grub/unicode.h index a0403e91f..4de986a85 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -293,7 +293,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 +315,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, diff --git a/include/grub/verity-hash.h b/include/grub/verity-hash.h deleted file mode 100644 index 448d9aff0..000000000 --- a/include/grub/verity-hash.h +++ /dev/null @@ -1,51 +0,0 @@ -/* CoreOS verity hash */ - -#define VERITY_ARG " verity.usrhash=" -#define VERITY_ARG_LENGTH (sizeof (VERITY_ARG) - 1) -#define VERITY_HASH_LENGTH 64 -#define VERITY_CMDLINE_LENGTH ((VERITY_ARG_LENGTH)+(VERITY_HASH_LENGTH)) - -#if defined(__aarch64__) -# define VERITY_HASH_OFFSET 512 -#elif defined(__i386__) || defined(__amd64__) -# define VERITY_HASH_OFFSET 0x40 -#else -# error Unsupported arch -#endif - - -/** - * grub_pass_verity_hash - Reads the CoreOS verity hash value from a well known - * kernel image offset and adds a kernel command line argument for it. - * - * @pImage: Kernel image buffer. - * @cmdline: Kernel command line buffer. - * @cmdline_max_len: Kernel command line buffer length. - */ - -static inline void grub_pass_verity_hash(const void *pImage, - char *cmdline, - grub_size_t cmdline_max_len) -{ - const char *buf = pImage; - grub_size_t cmdline_len; - int i; - - for (i=VERITY_HASH_OFFSET; i '9') // Not a number - if (buf[i] < 'a' || buf[i] > 'f') // Not a hex letter - return; - } - - cmdline_len = grub_strlen(cmdline); - if (cmdline_len + VERITY_CMDLINE_LENGTH > cmdline_max_len) - return; - - grub_memcpy (cmdline + cmdline_len, VERITY_ARG, VERITY_ARG_LENGTH); - cmdline_len += VERITY_ARG_LENGTH; - grub_memcpy (cmdline + cmdline_len, buf + VERITY_HASH_OFFSET, - VERITY_HASH_LENGTH); - cmdline_len += VERITY_HASH_LENGTH; - cmdline[cmdline_len] = '\0'; -} diff --git a/include/grub/xen_file.h b/include/grub/xen_file.h index f8d8b19a7..658799952 100644 --- a/include/grub/xen_file.h +++ b/include/grub/xen_file.h @@ -24,9 +24,6 @@ #include grub_elf_t grub_xen_file (grub_file_t file); -grub_elf_t grub_xen_file_and_cmdline (grub_file_t file, - char *cmdline, - grub_size_t cmdline_max_len); struct grub_xen_file_info { 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/po/arabic.sed b/po/arabic.sed index b5b5db661..21dc8b6db 100644 --- a/po/arabic.sed +++ b/po/arabic.sed @@ -73,6 +73,7 @@ s,%\([0-9]*\)لد,%\1ld,g s,%\([0-9]*\)للد,%\1lld,g s,%\([0-9\.\*]*\)س,%\1s,g +s,%\([0-9\.\*]*\)م,%\1m,g s,%\([0-9]*\)لو,%\1lu,g s,%\([0-9]*\)و,%\1u,g s,%\([0-9]*\)للو,%\1llu,g diff --git a/po/cyrillic.sed b/po/cyrillic.sed index ffad0ed8c..2e3e6655d 100644 --- a/po/cyrillic.sed +++ b/po/cyrillic.sed @@ -96,6 +96,7 @@ s,%\([0-9]*\)лд,%\1ld,g s,%\([0-9]*\)ллд,%\1lld,g s,%\([0-9\.\*]*\)с,%\1s,g +s,%\([0-9\.\*]*\)м,%\1m,g s,%\([0-9]*\)лу,%\1lu,g s,%\([0-9]*\)у,%\1u,g s,%\([0-9]*\)ллу,%\1llu,g diff --git a/po/gettext-patches/0001-Support-POTFILES-shell.patch b/po/gettext-patches/0001-Support-POTFILES-shell.patch new file mode 100644 index 000000000..5a5d1ec00 --- /dev/null +++ b/po/gettext-patches/0001-Support-POTFILES-shell.patch @@ -0,0 +1,54 @@ +From d5bbd8f60aacb0f73ea5a0bde999152c467d0e78 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 1 Mar 2020 11:57:58 +0000 +Subject: [PATCH 1/4] Support POTFILES-shell + +--- + gettext-runtime/po/Makefile.in.in | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index fabdc76c9..32e9323d3 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -142,7 +142,7 @@ stamp-po: $(srcdir)/$(DOMAIN).pot + # The determination of whether the package xyz is a GNU one is based on the + # heuristic whether some file in the top level directory mentions "GNU xyz". + # If GNU 'find' is available, we avoid grepping through monster files. +-$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed ++$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell.in remove-potcdate.sed + if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ + LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \ + else \ +@@ -175,7 +175,27 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ +- esac ++ esac; \ ++ case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ ++ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ ++ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ ++ --add-comments=TRANSLATORS: @XGETTEXT_EXTRA_OPTIONS@ \ ++ --files-from=$(srcdir)/POTFILES-shell.in \ ++ --copyright-holder='$(COPYRIGHT_HOLDER)' \ ++ --msgid-bugs-address="$$msgid_bugs_address" \ ++ --join-existing --language=Shell --keyword=gettext_quoted \ ++ ;; \ ++ *) \ ++ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ ++ --add-comments=TRANSLATORS: @XGETTEXT_EXTRA_OPTIONS@ \ ++ --files-from=$(srcdir)/POTFILES-shell.in \ ++ --copyright-holder='$(COPYRIGHT_HOLDER)' \ ++ --package-name="$${package_gnu}@PACKAGE@" \ ++ --package-version='@VERSION@' \ ++ --msgid-bugs-address="$$msgid_bugs_address" \ ++ --join-existing --language=Shell --keyword=gettext_quoted \ ++ ;; \ ++ esac; \ + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ +-- +2.17.1 + diff --git a/po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch b/po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch new file mode 100644 index 000000000..2767ed65e --- /dev/null +++ b/po/gettext-patches/0002-Handle-gettext_printf-shell-function.patch @@ -0,0 +1,46 @@ +From fd17c51f2e6c87427679fbdfb5f6224ff48795db Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 1 Mar 2020 12:00:41 +0000 +Subject: [PATCH 2/4] Handle gettext_printf shell function + +Extract gettext_printf arguments. + +Run grub.d.sed over strings extracted from util/grub.d/, in order to set +c-format flags (xgettext refuses to include these itself for strings it +extracted from a shell file, but these really are c-format). +--- + gettext-runtime/po/Makefile.in.in | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index 32e9323d3..32e0c99a2 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -183,7 +183,8 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell + --files-from=$(srcdir)/POTFILES-shell.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ +- --join-existing --language=Shell --keyword=gettext_quoted \ ++ --join-existing --language=Shell \ ++ --keyword=gettext_quoted --keyword=gettext_printf \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ +@@ -193,10 +194,13 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in $(srcdir)/POTFILES-shell + --package-name="$${package_gnu}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ +- --join-existing --language=Shell --keyword=gettext_quoted \ ++ --join-existing --language=Shell \ ++ --keyword=gettext_quoted --keyword=gettext_printf \ + ;; \ + esac; \ + test ! -f $(DOMAIN).po || { \ ++ sed -f grub.d.sed < $(DOMAIN).po > $(DOMAIN).1po && \ ++ mv $(DOMAIN).1po $(DOMAIN).po; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ +-- +2.17.1 + diff --git a/po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch b/po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch new file mode 100644 index 000000000..414161133 --- /dev/null +++ b/po/gettext-patches/0003-Make-msgfmt-output-in-little-endian.patch @@ -0,0 +1,34 @@ +From 156c523e2945c9b43c5500fb93988b0dd2f08d75 Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Sun, 1 Mar 2020 12:09:25 +0000 +Subject: [PATCH 3/4] Make msgfmt output in little-endian + +GRUB expects this. +--- + gettext-runtime/po/Makefile.in.in | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index 32e0c99a2..f3ef54c39 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -84,13 +84,13 @@ CATALOGS = @CATALOGS@ + + .po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ +- $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ ++ $(MSGFMT) --endianness=little -c -o t-$@ $< && mv t-$@ $@ + + .po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ +- echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ +- cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo ++ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) --endianness=little -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ ++ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) --endianness=little -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + + .sin.sed: + sed -e '/^#/d' $< > t-$@ +-- +2.17.1 + diff --git a/po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch b/po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch new file mode 100644 index 000000000..790521d3f --- /dev/null +++ b/po/gettext-patches/0004-Use-SHELL-rather-than-bin-sh.patch @@ -0,0 +1,26 @@ +From f36f12e77798223ee7ee882c0d09e0e63db11454 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 1 Mar 2020 12:14:07 +0000 +Subject: [PATCH 4/4] Use @SHELL rather than /bin/sh + +/bin/sh might not exist. +--- + gettext-runtime/po/Makefile.in.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gettext-runtime/po/Makefile.in.in b/gettext-runtime/po/Makefile.in.in +index f3ef54c39..285a55a9d 100644 +--- a/gettext-runtime/po/Makefile.in.in ++++ b/gettext-runtime/po/Makefile.in.in +@@ -16,7 +16,7 @@ VERSION = @VERSION@ + PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + + SED = @SED@ +-SHELL = /bin/sh ++SHELL = @SHELL@ + @SET_MAKE@ + + srcdir = @srcdir@ +-- +2.17.1 + diff --git a/po/greek.sed b/po/greek.sed index 93556c386..3543f6aac 100644 --- a/po/greek.sed +++ b/po/greek.sed @@ -98,6 +98,7 @@ s,%\([0-9]*\)λδ,%\1ld,g s,%\([0-9]*\)λλδ,%\1lld,g s,%\([0-9\.\*]*\)σ,%\1s,g +s,%\([0-9\.\*]*\)μ,%\1m,g s,%\([0-9]*\)λυ,%\1lu,g s,%\([0-9]*\)υ,%\1u,g s,%\([0-9]*\)λλυ,%\1llu,g diff --git a/po/hebrew.sed b/po/hebrew.sed index a47bc6a28..9210014bc 100644 --- a/po/hebrew.sed +++ b/po/hebrew.sed @@ -81,6 +81,7 @@ s,%\([0-9]*\)לד,%\1ld,g s,%\([0-9]*\)ללד,%\1lld,g s,%\([0-9\.\*]*\)ש,%\1s,g +s,%\([0-9\.\*]*\)מ,%\1m,g s,%\([0-9]*\)לוּ,%\1lu,g s,%\([0-9]*\)וּ,%\1u,g s,%\([0-9]*\)ללוּ,%\1llu,g diff --git a/tests/gpt_unit_test.c b/tests/gpt_unit_test.c deleted file mode 100644 index 218b18697..000000000 --- a/tests/gpt_unit_test.c +++ /dev/null @@ -1,840 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2014 CoreOS, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* from gnulib */ -#include - -/* Confirm that the GPT structures conform to the sizes in the spec: - * The header size "must be greater than or equal to 92 and must be less - * than or equal to the logical block size." - * The partition entry size must be "a value of 128*(2^n) where n is an - * integer greater than or equal to zero (e.g., 128, 256, 512, etc.)." */ -verify (sizeof (struct grub_gpt_header) == 92); -verify (sizeof (struct grub_gpt_partentry) == 128); - -/* GPT section sizes. */ -#define HEADER_SIZE (sizeof (struct grub_gpt_header)) -#define HEADER_PAD (GRUB_DISK_SECTOR_SIZE - HEADER_SIZE) -#define ENTRY_SIZE (sizeof (struct grub_gpt_partentry)) -#define TABLE_ENTRIES 0x80 -#define TABLE_SIZE (TABLE_ENTRIES * ENTRY_SIZE) -#define TABLE_SECTORS (TABLE_SIZE / GRUB_DISK_SECTOR_SIZE) - -/* Double check that the table size calculation was valid. */ -verify (TABLE_SECTORS * GRUB_DISK_SECTOR_SIZE == TABLE_SIZE); - -/* GPT section locations for a 1MiB disk. */ -#define DISK_SECTORS 0x800 -#define DISK_SIZE (GRUB_DISK_SECTOR_SIZE * DISK_SECTORS) -#define PRIMARY_HEADER_SECTOR 0x1 -#define PRIMARY_TABLE_SECTOR 0x2 -#define BACKUP_HEADER_SECTOR (DISK_SECTORS - 0x1) -#define BACKUP_TABLE_SECTOR (BACKUP_HEADER_SECTOR - TABLE_SECTORS) - -#define DATA_START_SECTOR (PRIMARY_TABLE_SECTOR + TABLE_SECTORS) -#define DATA_END_SECTOR (BACKUP_TABLE_SECTOR - 0x1) -#define DATA_SECTORS (BACKUP_TABLE_SECTOR - DATA_START_SECTOR) -#define DATA_SIZE (GRUB_DISK_SECTOR_SIZE * DATA_SECTORS) - -struct test_disk -{ - struct grub_msdos_partition_mbr mbr; - - struct grub_gpt_header primary_header; - grub_uint8_t primary_header_pad[HEADER_PAD]; - struct grub_gpt_partentry primary_entries[TABLE_ENTRIES]; - - grub_uint8_t data[DATA_SIZE]; - - struct grub_gpt_partentry backup_entries[TABLE_ENTRIES]; - struct grub_gpt_header backup_header; - grub_uint8_t backup_header_pad[HEADER_PAD]; -} GRUB_PACKED; - -/* Sanity check that all the above ugly math was correct. */ -verify (sizeof (struct test_disk) == DISK_SIZE); - -struct test_data -{ - int fd; - grub_device_t dev; - struct test_disk *raw; -}; - - -/* Sample primary GPT header for a 1MB disk. */ -static const struct grub_gpt_header example_primary = { - .magic = GRUB_GPT_HEADER_MAGIC, - .version = GRUB_GPT_HEADER_VERSION, - .headersize = sizeof (struct grub_gpt_header), - .crc32 = grub_cpu_to_le32_compile_time (0xb985abe0), - .header_lba = grub_cpu_to_le64_compile_time (PRIMARY_HEADER_SECTOR), - .alternate_lba = grub_cpu_to_le64_compile_time (BACKUP_HEADER_SECTOR), - .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR), - .end = grub_cpu_to_le64_compile_time (DATA_END_SECTOR), - .guid = GRUB_GPT_GUID_INIT(0x69c131ad, 0x67d6, 0x46c6, - 0x93, 0xc4, 0x12, 0x4c, 0x75, 0x52, 0x56, 0xac), - .partitions = grub_cpu_to_le64_compile_time (PRIMARY_TABLE_SECTOR), - .maxpart = grub_cpu_to_le32_compile_time (TABLE_ENTRIES), - .partentry_size = grub_cpu_to_le32_compile_time (ENTRY_SIZE), - .partentry_crc32 = grub_cpu_to_le32_compile_time (0x074e052c), -}; - -static const struct grub_gpt_partentry example_entries[TABLE_ENTRIES] = { - { - .type = GRUB_GPT_PARTITION_TYPE_EFI_SYSTEM, - .guid = GRUB_GPT_GUID_INIT (0xa0f1792e, 0xb4ce, 0x4136, 0xbc, 0xf2, - 0x1a, 0xfc, 0x13, 0x3c, 0x28, 0x28), - .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR), - .end = grub_cpu_to_le64_compile_time (0x3f), - .attrib = 0x0, - .name = { - grub_cpu_to_le16_compile_time ('E'), - grub_cpu_to_le16_compile_time ('F'), - grub_cpu_to_le16_compile_time ('I'), - grub_cpu_to_le16_compile_time (' '), - grub_cpu_to_le16_compile_time ('S'), - grub_cpu_to_le16_compile_time ('Y'), - grub_cpu_to_le16_compile_time ('S'), - grub_cpu_to_le16_compile_time ('T'), - grub_cpu_to_le16_compile_time ('E'), - grub_cpu_to_le16_compile_time ('M'), - 0x0, - } - }, - { - .type = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT, - .guid = GRUB_GPT_GUID_INIT (0x876c898d, 0x1b40, 0x4727, 0xa1, 0x61, - 0xed, 0xf9, 0xb5, 0x48, 0x66, 0x74), - .start = grub_cpu_to_le64_compile_time (0x40), - .end = grub_cpu_to_le64_compile_time (0x7f), - .attrib = grub_cpu_to_le64_compile_time ( - 1ULL << GRUB_GPT_PART_ATTR_OFFSET_LEGACY_BIOS_BOOTABLE), - .name = { - grub_cpu_to_le16_compile_time ('B'), - grub_cpu_to_le16_compile_time ('I'), - grub_cpu_to_le16_compile_time ('O'), - grub_cpu_to_le16_compile_time ('S'), - grub_cpu_to_le16_compile_time (' '), - grub_cpu_to_le16_compile_time ('B'), - grub_cpu_to_le16_compile_time ('O'), - grub_cpu_to_le16_compile_time ('O'), - grub_cpu_to_le16_compile_time ('T'), - 0x0, - } - }, -}; - -/* And the backup header. */ -static const struct grub_gpt_header example_backup = { - .magic = GRUB_GPT_HEADER_MAGIC, - .version = GRUB_GPT_HEADER_VERSION, - .headersize = sizeof (struct grub_gpt_header), - .crc32 = grub_cpu_to_le32_compile_time (0x0af785eb), - .header_lba = grub_cpu_to_le64_compile_time (BACKUP_HEADER_SECTOR), - .alternate_lba = grub_cpu_to_le64_compile_time (PRIMARY_HEADER_SECTOR), - .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR), - .end = grub_cpu_to_le64_compile_time (DATA_END_SECTOR), - .guid = GRUB_GPT_GUID_INIT(0x69c131ad, 0x67d6, 0x46c6, - 0x93, 0xc4, 0x12, 0x4c, 0x75, 0x52, 0x56, 0xac), - .partitions = grub_cpu_to_le64_compile_time (BACKUP_TABLE_SECTOR), - .maxpart = grub_cpu_to_le32_compile_time (TABLE_ENTRIES), - .partentry_size = grub_cpu_to_le32_compile_time (ENTRY_SIZE), - .partentry_crc32 = grub_cpu_to_le32_compile_time (0x074e052c), -}; - -/* Sample protective MBR for the same 1MB disk. Note, this matches - * parted and fdisk behavior. The UEFI spec uses different values. */ -static const struct grub_msdos_partition_mbr example_pmbr = { - .entries = {{.flag = 0x00, - .start_head = 0x00, - .start_sector = 0x01, - .start_cylinder = 0x00, - .type = 0xee, - .end_head = 0xfe, - .end_sector = 0xff, - .end_cylinder = 0xff, - .start = grub_cpu_to_le32_compile_time (0x1), - .length = grub_cpu_to_le32_compile_time (DISK_SECTORS - 0x1), - }}, - .signature = grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE), -}; - -/* If errors are left in grub's error stack things can get confused. */ -static void -assert_error_stack_empty (void) -{ - do - { - grub_test_assert (grub_errno == GRUB_ERR_NONE, - "error on stack: %s", grub_errmsg); - } - while (grub_error_pop ()); -} - -static grub_err_t -execute_command2 (const char *name, const char *arg1, const char *arg2) -{ - grub_command_t cmd; - grub_err_t err; - char *argv[2]; - - cmd = grub_command_find (name); - if (!cmd) - grub_fatal ("can't find command %s", name); - - argv[0] = strdup (arg1); - argv[1] = strdup (arg2); - err = (cmd->func) (cmd, 2, argv); - free (argv[0]); - free (argv[1]); - - return err; -} - -static void -sync_disk (struct test_data *data) -{ - if (msync (data->raw, DISK_SIZE, MS_SYNC | MS_INVALIDATE) < 0) - grub_fatal ("Syncing disk failed: %s", strerror (errno)); - - grub_disk_cache_invalidate_all (); -} - -static void -reset_disk (struct test_data *data) -{ - memset (data->raw, 0, DISK_SIZE); - - /* Initialize image with valid example tables. */ - memcpy (&data->raw->mbr, &example_pmbr, sizeof (data->raw->mbr)); - memcpy (&data->raw->primary_header, &example_primary, - sizeof (data->raw->primary_header)); - memcpy (&data->raw->primary_entries, &example_entries, - sizeof (data->raw->primary_entries)); - memcpy (&data->raw->backup_entries, &example_entries, - sizeof (data->raw->backup_entries)); - memcpy (&data->raw->backup_header, &example_backup, - sizeof (data->raw->backup_header)); - - sync_disk (data); -} - -static void -open_disk (struct test_data *data) -{ - const char *loop = "loop0"; - char template[] = "/tmp/grub_gpt_test.XXXXXX"; - char host[sizeof ("(host)") + sizeof (template)]; - - data->fd = mkstemp (template); - if (data->fd < 0) - grub_fatal ("Creating %s failed: %s", template, strerror (errno)); - - if (ftruncate (data->fd, DISK_SIZE) < 0) - { - int err = errno; - unlink (template); - grub_fatal ("Resizing %s failed: %s", template, strerror (err)); - } - - data->raw = mmap (NULL, DISK_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, data->fd, 0); - if (data->raw == MAP_FAILED) - { - int err = errno; - unlink (template); - grub_fatal ("Maping %s failed: %s", template, strerror (err)); - } - - snprintf (host, sizeof (host), "(host)%s", template); - if (execute_command2 ("loopback", loop, host) != GRUB_ERR_NONE) - { - unlink (template); - grub_fatal ("loopback %s %s failed: %s", loop, host, grub_errmsg); - } - - if (unlink (template) < 0) - grub_fatal ("Unlinking %s failed: %s", template, strerror (errno)); - - reset_disk (data); - - data->dev = grub_device_open (loop); - if (!data->dev) - grub_fatal ("Opening %s failed: %s", loop, grub_errmsg); -} - -static void -close_disk (struct test_data *data) -{ - char *loop; - - assert_error_stack_empty (); - - if (munmap (data->raw, DISK_SIZE) || close (data->fd)) - grub_fatal ("Closing disk image failed: %s", strerror (errno)); - - loop = strdup (data->dev->disk->name); - grub_test_assert (grub_device_close (data->dev) == GRUB_ERR_NONE, - "Closing disk device failed: %s", grub_errmsg); - - grub_test_assert (execute_command2 ("loopback", "-d", loop) == - GRUB_ERR_NONE, "loopback -d %s failed: %s", loop, - grub_errmsg); - - free (loop); -} - -static grub_gpt_t -read_disk (struct test_data *data) -{ - grub_gpt_t gpt; - - gpt = grub_gpt_read (data->dev->disk); - if (gpt == NULL) - grub_fatal ("grub_gpt_read failed: %s", grub_errmsg); - - return gpt; -} - -static void -pmbr_test (void) -{ - struct grub_msdos_partition_mbr mbr; - - memset (&mbr, 0, sizeof (mbr)); - - /* Empty is invalid. */ - grub_gpt_pmbr_check (&mbr); - grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - /* A table without a protective partition is invalid. */ - mbr.signature = grub_cpu_to_le16_compile_time (GRUB_PC_PARTITION_SIGNATURE); - grub_gpt_pmbr_check (&mbr); - grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - /* A table with a protective type is ok. */ - memcpy (&mbr, &example_pmbr, sizeof (mbr)); - grub_gpt_pmbr_check (&mbr); - grub_test_assert (grub_errno == GRUB_ERR_NONE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; -} - -static void -header_test (void) -{ - struct grub_gpt_header primary, backup; - - /* Example headers should be valid. */ - memcpy (&primary, &example_primary, sizeof (primary)); - grub_gpt_header_check (&primary, GRUB_DISK_SECTOR_BITS); - grub_test_assert (grub_errno == GRUB_ERR_NONE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - memcpy (&backup, &example_backup, sizeof (backup)); - grub_gpt_header_check (&backup, GRUB_DISK_SECTOR_BITS); - grub_test_assert (grub_errno == GRUB_ERR_NONE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - /* Twiddle the GUID to invalidate the CRC. */ - primary.guid.data1 = 0; - grub_gpt_header_check (&primary, GRUB_DISK_SECTOR_BITS); - grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - backup.guid.data1 = 0; - grub_gpt_header_check (&backup, GRUB_DISK_SECTOR_BITS); - grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; -} - -static void -read_valid_test (void) -{ - struct test_data data; - grub_gpt_t gpt; - - open_disk (&data); - gpt = read_disk (&data); - grub_test_assert (gpt->status == (GRUB_GPT_PROTECTIVE_MBR | - GRUB_GPT_PRIMARY_HEADER_VALID | - GRUB_GPT_PRIMARY_ENTRIES_VALID | - GRUB_GPT_BACKUP_HEADER_VALID | - GRUB_GPT_BACKUP_ENTRIES_VALID), - "unexpected status: 0x%02x", gpt->status); - grub_gpt_free (gpt); - close_disk (&data); -} - -static void -read_invalid_entries_test (void) -{ - struct test_data data; - grub_gpt_t gpt; - - open_disk (&data); - - /* Corrupt the first entry in both tables. */ - memset (&data.raw->primary_entries[0], 0x55, - sizeof (data.raw->primary_entries[0])); - memset (&data.raw->backup_entries[0], 0x55, - sizeof (data.raw->backup_entries[0])); - sync_disk (&data); - - gpt = grub_gpt_read (data.dev->disk); - grub_test_assert (gpt == NULL, "no error reported for corrupt entries"); - grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - close_disk (&data); -} - -static void -read_fallback_test (void) -{ - struct test_data data; - grub_gpt_t gpt; - - open_disk (&data); - - /* Corrupt the primary header. */ - memset (&data.raw->primary_header.guid, 0x55, - sizeof (data.raw->primary_header.guid)); - sync_disk (&data); - gpt = read_disk (&data); - grub_test_assert ((gpt->status & GRUB_GPT_PRIMARY_HEADER_VALID) == 0, - "unreported corrupt primary header"); - grub_gpt_free (gpt); - reset_disk (&data); - - /* Corrupt the backup header. */ - memset (&data.raw->backup_header.guid, 0x55, - sizeof (data.raw->backup_header.guid)); - sync_disk (&data); - gpt = read_disk (&data); - grub_test_assert ((gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) == 0, - "unreported corrupt backup header"); - grub_gpt_free (gpt); - reset_disk (&data); - - /* Corrupt the primary entry table. */ - memset (&data.raw->primary_entries[0], 0x55, - sizeof (data.raw->primary_entries[0])); - sync_disk (&data); - gpt = read_disk (&data); - grub_test_assert ((gpt->status & GRUB_GPT_PRIMARY_ENTRIES_VALID) == 0, - "unreported corrupt primary entries table"); - grub_gpt_free (gpt); - reset_disk (&data); - - /* Corrupt the backup entry table. */ - memset (&data.raw->backup_entries[0], 0x55, - sizeof (data.raw->backup_entries[0])); - sync_disk (&data); - gpt = read_disk (&data); - grub_test_assert ((gpt->status & GRUB_GPT_BACKUP_ENTRIES_VALID) == 0, - "unreported corrupt backup entries table"); - grub_gpt_free (gpt); - reset_disk (&data); - - /* If primary is corrupt and disk size is unknown fallback fails. */ - memset (&data.raw->primary_header.guid, 0x55, - sizeof (data.raw->primary_header.guid)); - sync_disk (&data); - data.dev->disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; - gpt = grub_gpt_read (data.dev->disk); - grub_test_assert (gpt == NULL, "no error reported"); - grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - close_disk (&data); -} - -static void -repair_test (void) -{ - struct test_data data; - grub_gpt_t gpt; - - open_disk (&data); - - /* Erase/Repair primary. */ - memset (&data.raw->primary_header, 0, sizeof (data.raw->primary_header)); - sync_disk (&data); - gpt = read_disk (&data); - grub_gpt_repair (data.dev->disk, gpt); - grub_test_assert (grub_errno == GRUB_ERR_NONE, - "repair failed: %s", grub_errmsg); - if (memcmp (&gpt->primary, &example_primary, sizeof (gpt->primary))) - { - printf ("Invalid restored primary header:\n"); - hexdump (16, (char*)&gpt->primary, sizeof (gpt->primary)); - printf ("Expected primary header:\n"); - hexdump (16, (char*)&example_primary, sizeof (example_primary)); - grub_test_assert (0, "repair did not restore primary header"); - } - grub_gpt_free (gpt); - reset_disk (&data); - - /* Erase/Repair backup. */ - memset (&data.raw->backup_header, 0, sizeof (data.raw->backup_header)); - sync_disk (&data); - gpt = read_disk (&data); - grub_gpt_repair (data.dev->disk, gpt); - grub_test_assert (grub_errno == GRUB_ERR_NONE, - "repair failed: %s", grub_errmsg); - if (memcmp (&gpt->backup, &example_backup, sizeof (gpt->backup))) - { - printf ("Invalid restored backup header:\n"); - hexdump (16, (char*)&gpt->backup, sizeof (gpt->backup)); - printf ("Expected backup header:\n"); - hexdump (16, (char*)&example_backup, sizeof (example_backup)); - grub_test_assert (0, "repair did not restore backup header"); - } - grub_gpt_free (gpt); - reset_disk (&data); - - close_disk (&data); -} - -/* Finding/reading/writing the backup GPT may be difficult if the OS and - * BIOS report different sizes for the same disk. We need to gracefully - * recognize this and avoid causing trouble for the OS. */ -static void -weird_disk_size_test (void) -{ - struct test_data data; - grub_gpt_t gpt; - - open_disk (&data); - - /* Chop off 65536 bytes (128 512B sectors) which may happen when the - * BIOS thinks you are using a software RAID system that reserves that - * area for metadata when in fact you are not and using the bare disk. */ - grub_test_assert(data.dev->disk->total_sectors == DISK_SECTORS, - "unexpected disk size: 0x%llx", - (unsigned long long) data.dev->disk->total_sectors); - data.dev->disk->total_sectors -= 128; - - gpt = read_disk (&data); - assert_error_stack_empty (); - /* Reading the alternate_lba should have been blocked and reading - * the (new) end of disk should have found no useful data. */ - grub_test_assert ((gpt->status & GRUB_GPT_BACKUP_HEADER_VALID) == 0, - "unreported missing backup header"); - - /* We should be able to reconstruct the backup header and the location - * of the backup should remain unchanged, trusting the GPT data over - * what the BIOS is telling us. Further changes are left to the OS. */ - grub_gpt_repair (data.dev->disk, gpt); - grub_test_assert (grub_errno == GRUB_ERR_NONE, - "repair failed: %s", grub_errmsg); - grub_test_assert (memcmp (&gpt->primary, &example_primary, - sizeof (gpt->primary)) == 0, - "repair corrupted primary header"); - - grub_gpt_free (gpt); - close_disk (&data); -} - -static void -iterate_partitions_test (void) -{ - struct test_data data; - struct grub_gpt_partentry *p; - grub_gpt_t gpt; - grub_uint32_t n; - - open_disk (&data); - gpt = read_disk (&data); - - for (n = 0; (p = grub_gpt_get_partentry (gpt, n)) != NULL; n++) - grub_test_assert (memcmp (p, &example_entries[n], sizeof (*p)) == 0, - "unexpected partition %d data", n); - - grub_test_assert (n == TABLE_ENTRIES, "unexpected partition limit: %d", n); - - grub_gpt_free (gpt); - close_disk (&data); -} - -static void -large_partitions_test (void) -{ - struct test_data data; - struct grub_gpt_partentry *p; - grub_gpt_t gpt; - grub_uint32_t n; - - open_disk (&data); - - /* Double the entry size, cut the number of entries in half. */ - data.raw->primary_header.maxpart = - data.raw->backup_header.maxpart = - grub_cpu_to_le32_compile_time (TABLE_ENTRIES/2); - data.raw->primary_header.partentry_size = - data.raw->backup_header.partentry_size = - grub_cpu_to_le32_compile_time (ENTRY_SIZE*2); - data.raw->primary_header.partentry_crc32 = - data.raw->backup_header.partentry_crc32 = - grub_cpu_to_le32_compile_time (0xf2c45af8); - data.raw->primary_header.crc32 = grub_cpu_to_le32_compile_time (0xde00cc8f); - data.raw->backup_header.crc32 = grub_cpu_to_le32_compile_time (0x6d72e284); - - memset (&data.raw->primary_entries, 0, - sizeof (data.raw->primary_entries)); - for (n = 0; n < TABLE_ENTRIES/2; n++) - memcpy (&data.raw->primary_entries[n*2], &example_entries[n], - sizeof (data.raw->primary_entries[0])); - memcpy (&data.raw->backup_entries, &data.raw->primary_entries, - sizeof (data.raw->backup_entries)); - - sync_disk(&data); - gpt = read_disk (&data); - - for (n = 0; (p = grub_gpt_get_partentry (gpt, n)) != NULL; n++) - grub_test_assert (memcmp (p, &example_entries[n], sizeof (*p)) == 0, - "unexpected partition %d data", n); - - grub_test_assert (n == TABLE_ENTRIES/2, "unexpected partition limit: %d", n); - - grub_gpt_free (gpt); - - /* Editing memory beyond the entry structure should still change the crc. */ - data.raw->primary_entries[1].attrib = 0xff; - - sync_disk(&data); - gpt = read_disk (&data); - grub_test_assert (gpt->status == (GRUB_GPT_PROTECTIVE_MBR | - GRUB_GPT_PRIMARY_HEADER_VALID | - GRUB_GPT_BACKUP_HEADER_VALID | - GRUB_GPT_BACKUP_ENTRIES_VALID), - "unexpected status: 0x%02x", gpt->status); - grub_gpt_free (gpt); - - close_disk (&data); -} - -static void -invalid_partsize_test (void) -{ - struct grub_gpt_header header = { - .magic = GRUB_GPT_HEADER_MAGIC, - .version = GRUB_GPT_HEADER_VERSION, - .headersize = sizeof (struct grub_gpt_header), - .crc32 = grub_cpu_to_le32_compile_time (0x1ff2a054), - .header_lba = grub_cpu_to_le64_compile_time (PRIMARY_HEADER_SECTOR), - .alternate_lba = grub_cpu_to_le64_compile_time (BACKUP_HEADER_SECTOR), - .start = grub_cpu_to_le64_compile_time (DATA_START_SECTOR), - .end = grub_cpu_to_le64_compile_time (DATA_END_SECTOR), - .guid = GRUB_GPT_GUID_INIT(0x69c131ad, 0x67d6, 0x46c6, - 0x93, 0xc4, 0x12, 0x4c, 0x75, 0x52, 0x56, 0xac), - .partitions = grub_cpu_to_le64_compile_time (PRIMARY_TABLE_SECTOR), - .maxpart = grub_cpu_to_le32_compile_time (TABLE_ENTRIES), - /* Triple the entry size, which is not valid. */ - .partentry_size = grub_cpu_to_le32_compile_time (ENTRY_SIZE*3), - .partentry_crc32 = grub_cpu_to_le32_compile_time (0x074e052c), - }; - - grub_gpt_header_check(&header, GRUB_DISK_SECTOR_BITS); - grub_test_assert (grub_errno == GRUB_ERR_BAD_PART_TABLE, - "unexpected error: %s", grub_errmsg); - grub_test_assert (strcmp(grub_errmsg, "invalid GPT entry size") == 0, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; -} - -static void -search_part_label_test (void) -{ - struct test_data data; - const char *test_result; - char *expected_result; - - open_disk (&data); - - expected_result = grub_xasprintf ("%s,gpt1", data.dev->disk->name); - grub_env_unset ("test_result"); - grub_search_part_label ("EFI SYSTEM", "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result && strcmp (test_result, expected_result) == 0, - "wrong device: %s (%s)", test_result, expected_result); - grub_free (expected_result); - - expected_result = grub_xasprintf ("%s,gpt2", data.dev->disk->name); - grub_env_unset ("test_result"); - grub_search_part_label ("BIOS BOOT", "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result && strcmp (test_result, expected_result) == 0, - "wrong device: %s (%s)", test_result, expected_result); - grub_free (expected_result); - - grub_env_unset ("test_result"); - grub_search_part_label ("bogus name", "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result == NULL, - "unexpected device: %s", test_result); - grub_test_assert (grub_errno == GRUB_ERR_FILE_NOT_FOUND, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - close_disk (&data); -} - -static void -search_part_uuid_test (void) -{ - struct test_data data; - const char gpt1_uuid[] = "A0F1792E-B4CE-4136-BCF2-1AFC133C2828"; - const char gpt2_uuid[] = "876c898d-1b40-4727-a161-edf9b5486674"; - const char bogus_uuid[] = "1534c928-c50e-4866-9daf-6a9fd7918a76"; - const char *test_result; - char *expected_result; - - open_disk (&data); - - expected_result = grub_xasprintf ("%s,gpt1", data.dev->disk->name); - grub_env_unset ("test_result"); - grub_search_part_uuid (gpt1_uuid, "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result && strcmp (test_result, expected_result) == 0, - "wrong device: %s (%s)", test_result, expected_result); - grub_free (expected_result); - - expected_result = grub_xasprintf ("%s,gpt2", data.dev->disk->name); - grub_env_unset ("test_result"); - grub_search_part_uuid (gpt2_uuid, "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result && strcmp (test_result, expected_result) == 0, - "wrong device: %s (%s)", test_result, expected_result); - grub_free (expected_result); - - grub_env_unset ("test_result"); - grub_search_part_uuid (bogus_uuid, "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result == NULL, - "unexpected device: %s", test_result); - grub_test_assert (grub_errno == GRUB_ERR_FILE_NOT_FOUND, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - close_disk (&data); -} - -static void -search_disk_uuid_test (void) -{ - struct test_data data; - const char disk_uuid[] = "69c131ad-67d6-46c6-93c4-124c755256ac"; - const char bogus_uuid[] = "1534c928-c50e-4866-9daf-6a9fd7918a76"; - const char *test_result; - char *expected_result; - - open_disk (&data); - - expected_result = grub_xasprintf ("%s", data.dev->disk->name); - grub_env_unset ("test_result"); - grub_search_disk_uuid (disk_uuid, "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result && strcmp (test_result, expected_result) == 0, - "wrong device: %s (%s)", test_result, expected_result); - grub_free (expected_result); - - grub_env_unset ("test_result"); - grub_search_disk_uuid (bogus_uuid, "test_result", 0, NULL, 0); - test_result = grub_env_get ("test_result"); - grub_test_assert (test_result == NULL, - "unexpected device: %s", test_result); - grub_test_assert (grub_errno == GRUB_ERR_FILE_NOT_FOUND, - "unexpected error: %s", grub_errmsg); - grub_errno = GRUB_ERR_NONE; - - close_disk (&data); -} - -void -grub_unit_test_init (void) -{ - grub_init_all (); - grub_hostfs_init (); - grub_host_init (); - grub_test_register ("gpt_pmbr_test", pmbr_test); - grub_test_register ("gpt_header_test", header_test); - grub_test_register ("gpt_read_valid_test", read_valid_test); - grub_test_register ("gpt_read_invalid_test", read_invalid_entries_test); - grub_test_register ("gpt_read_fallback_test", read_fallback_test); - grub_test_register ("gpt_repair_test", repair_test); - grub_test_register ("gpt_iterate_partitions_test", iterate_partitions_test); - grub_test_register ("gpt_large_partitions_test", large_partitions_test); - grub_test_register ("gpt_invalid_partsize_test", invalid_partsize_test); - grub_test_register ("gpt_weird_disk_size_test", weird_disk_size_test); - grub_test_register ("gpt_search_part_label_test", search_part_label_test); - grub_test_register ("gpt_search_uuid_test", search_part_uuid_test); - grub_test_register ("gpt_search_disk_uuid_test", search_disk_uuid_test); -} - -void -grub_unit_test_fini (void) -{ - grub_test_unregister ("gpt_pmbr_test"); - grub_test_unregister ("gpt_header_test"); - grub_test_unregister ("gpt_read_valid_test"); - grub_test_unregister ("gpt_read_invalid_test"); - grub_test_unregister ("gpt_read_fallback_test"); - grub_test_unregister ("gpt_repair_test"); - grub_test_unregister ("gpt_iterate_partitions_test"); - grub_test_unregister ("gpt_large_partitions_test"); - grub_test_unregister ("gpt_invalid_partsize_test"); - grub_test_unregister ("gpt_weird_disk_size_test"); - grub_test_unregister ("gpt_search_part_label_test"); - grub_test_unregister ("gpt_search_part_uuid_test"); - grub_test_unregister ("gpt_search_disk_uuid_test"); - grub_fini_all (); -} diff --git a/tests/gptprio_test.in b/tests/gptprio_test.in deleted file mode 100644 index c5cf0f3b7..000000000 --- a/tests/gptprio_test.in +++ /dev/null @@ -1,207 +0,0 @@ -#! /bin/bash -set -e - -# Copyright (C) 2010 Free Software Foundation, Inc. -# Copyright (C) 2014 CoreOS, Inc. -# -# GRUB is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# GRUB is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GRUB. If not, see . - -sgdisk=sgdisk -grubshell=@builddir@/grub-shell - -if ! which "${sgdisk}" >/dev/null 2>&1; then - echo "sgdisk not installed; cannot test gptprio." - exit 77 -fi - -. "@builddir@/grub-core/modinfo.sh" - -case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in - mips-qemu_mips | mipsel-qemu_mips | i386-qemu | i386-multiboot | i386-coreboot | mipsel-loongson) - disk=ata0 - ;; - 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 - ;; - 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 - ;; - i386-ieee1275) - disk=ieee1275/d - # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label. - exit 0 - ;; - mips-arc) - # FIXME: ARC firmware has bugs which prevent it from accessing hard disk w/o dvh disklabel. - exit 0 ;; - mipsel-arc) - disk=arc/scsi0/disk0/rdisk0 - ;; - *) - disk=hd0 - ;; -esac -img1="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -trap "rm -f '${img1}'" EXIT - -prio_type="5dfbf5f4-2848-4bac-aa5e-0d9a20b745a6" -declare -a prio_uuid -prio_uuid[2]="9b003904-d006-4ab3-97f1-73f547b7af1a" -prio_uuid[3]="1aa5a658-5b02-414d-9b71-f7e6c151f0cd" -prio_uuid[4]="8aa0240d-98af-42b0-b32a-ccbe0572d62b" - -create_disk_image () { - size=$1 - rm -f "${img1}" - dd if=/dev/zero of="${img1}" bs=512 count=1 seek=$((size - 1)) status=none - ${sgdisk} \ - -n 1:0:+1 -c 1:ESP -t 1:ef00 \ - -n 2:0:+1 -c 2:A -t 2:"${prio_type}" -u 2:"${prio_uuid[2]}" \ - -n 3:0:+1 -c 3:B -t 3:"${prio_type}" -u 3:"${prio_uuid[3]}" \ - -n 4:0:+1 -c 4:C -t 4:"${prio_type}" -u 4:"${prio_uuid[4]}" \ - "${img1}" >/dev/null -} - -wipe_disk_area () { - sector=$1 - size=$2 - dd if=/dev/zero of="${img1}" bs=512 count=${size} seek=${sector} conv=notrunc status=none -} - -is_zero () { - sector=$1 - size=$2 - cmp -s -i $((sector * 512)) -n $((size * 512)) /dev/zero "${img1}" -} - -check_is_zero () { - sector=$1 - size=$2 - if ! is_zero "$@"; then - echo "$size sector(s) starting at $sector should be all zero" - exit 1 - fi -} - -check_not_zero () { - sector=$1 - size=$2 - if is_zero "$@"; then - echo "$size sector(s) starting at $sector should not be all zero" - exit 1 - fi -} - -fmt_prio () { - priority=$(( ( $1 & 15 ) << 48 )) - tries=$(( ( $2 & 15 ) << 52 )) - success=$(( ( $3 & 1 ) << 56 )) - printf %016x $(( priority | tries | success )) -} - -set_prio () { - part="$1" - attr=$(fmt_prio $2 $3 $4) - ${sgdisk} -A "${part}:=:${attr}" "${img1}" >/dev/null -} - -check_prio () { - part="$1" - expect=$(fmt_prio $2 $3 $4) - result=$(LANG=C ${sgdisk} -i "${part}" "${img1}" 2>&1 \ - | awk '/^Attribute flags: / {print $3}') - if [[ "${expect}" != "${result}" ]]; then - echo "Partition ${part} has attributes ${result:-??}, not ${expect}" - exit 1 - fi -} - -run_next() { - "${grubshell}" --disk="${img1}" --modules=gptprio <. - -parted=parted -grubshell=@builddir@/grub-shell - -. "@builddir@/grub-core/modinfo.sh" - -case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in - mips-qemu_mips | mipsel-qemu_mips | i386-qemu | i386-multiboot | i386-coreboot | mipsel-loongson) - disk=ata0 - ;; - 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 - ;; - 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 - ;; - i386-ieee1275) - disk=ieee1275/d - # FIXME: QEMU firmware has bugs which prevent it from accessing hard disk w/o recognised label. - exit 0 - ;; - mips-arc) - # FIXME: ARC firmware has bugs which prevent it from accessing hard disk w/o dvh disklabel. - exit 0 ;; - mipsel-arc) - disk=arc/scsi0/disk0/rdisk0 - ;; - *) - disk=hd0 - ;; -esac -img1="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -img2="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 -trap "rm -f '${img1}' '${img2}'" EXIT - -create_disk_image () { - size=$1 - rm -f "${img1}" - dd if=/dev/zero of="${img1}" bs=512 count=1 seek=$((size - 1)) status=none - ${parted} -a none -s "${img1}" mklabel gpt - cp "${img1}" "${img2}" -} - -wipe_disk_area () { - sector=$1 - size=$2 - dd if=/dev/zero of="${img2}" bs=512 count=${size} seek=${sector} conv=notrunc status=none -} - -do_repair () { - output="`echo "gptrepair ($disk)" | "${grubshell}" --disk="${img2}"`" - if echo "${output}" | grep ^error; then - return 1 - fi - if echo "${output}" | grep -v GPT; then - echo "Unexpected output ${output}" - return 1 - fi - echo "${output}" -} - -echo "Nothing to repair:" -create_disk_image 100 -do_repair -cmp "${img1}" "${img2}" -echo - -echo "Repair primary (MBR left intact)" -create_disk_image 100 -wipe_disk_area 1 1 -do_repair -cmp "${img1}" "${img2}" -echo - -echo "Repair backup" -create_disk_image 100 -wipe_disk_area 99 1 -do_repair -cmp "${img1}" "${img2}" -echo diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in index 147d946d2..bfc425e1f 100644 --- a/tests/util/grub-fs-tester.in +++ b/tests/util/grub-fs-tester.in @@ -600,7 +600,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do GENERATED=n LODEVICES= MOUNTDEVICE= - + case x"$fs" in x"tarfs" | x"cpio_"*| x"ziso9660" | x"romfs" | x"squash4_"*\ | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet \ @@ -796,7 +796,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do MOUNTFS=ext2 "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; xf2fs) - "mkfs.f2fs" -l "$FSLABEL" -q "${LODEVICES[0]}" ;; + "mkfs.f2fs" -l "$FSLABEL" -q "${MOUNTDEVICE}" ;; xnilfs2) "mkfs.nilfs2" -L "$FSLABEL" -b $BLKSIZE -q "${MOUNTDEVICE}" ;; xext2_old) diff --git a/util/editenv.c b/util/editenv.c index eb2d0c03a..c532b046f 100644 --- a/util/editenv.c +++ b/util/editenv.c @@ -28,15 +28,23 @@ #include #include +#if !defined(_WIN32) +#include +#endif #define DEFAULT_ENVBLK_SIZE 1024 +#define GRUB_ENVBLK_MESSAGE "# WARNING: Do not edit this file by tools other than "PACKAGE"-editenv!!!\n" void grub_util_create_envblk_file (const char *name) { FILE *fp; - char *buf; - char *namenew; + char *buf, *pbuf, *namenew; +#if !defined(_WIN32) + ssize_t size = 1; + char *rename_target = xstrdup (name); + int rc; +#endif buf = xmalloc (DEFAULT_ENVBLK_SIZE); @@ -46,9 +54,13 @@ grub_util_create_envblk_file (const char *name) grub_util_error (_("cannot open `%s': %s"), namenew, strerror (errno)); - memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); - memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', - DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); + pbuf = buf; + memcpy (pbuf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); + pbuf += sizeof (GRUB_ENVBLK_SIGNATURE) - 1; + memcpy (pbuf, GRUB_ENVBLK_MESSAGE, sizeof (GRUB_ENVBLK_MESSAGE) - 1); + pbuf += sizeof (GRUB_ENVBLK_MESSAGE) - 1; + memset (pbuf , '#', + DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) - sizeof (GRUB_ENVBLK_MESSAGE) + 2); if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE) grub_util_error (_("cannot write to `%s': %s"), namenew, @@ -60,7 +72,64 @@ grub_util_create_envblk_file (const char *name) free (buf); fclose (fp); +#if defined(_WIN32) if (grub_util_rename (namenew, name) < 0) grub_util_error (_("cannot rename the file %s to %s"), namenew, name); +#else + while (1) + { + char *linkbuf; + ssize_t retsize; + + linkbuf = xmalloc (size + 1); + retsize = grub_util_readlink (rename_target, linkbuf, size); + if (retsize < 0 && (errno == ENOENT || errno == EINVAL)) + { + free (linkbuf); + break; + } + else if (retsize < 0) + { + free (linkbuf); + grub_util_error (_("cannot rename the file %s to %s: %m"), namenew, name); + } + 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: %m"), namenew, name); +#endif + free (namenew); } diff --git a/util/getroot.c b/util/getroot.c index 847406fba..a5eaa64fd 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -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++) { diff --git a/util/grub-file.c b/util/grub-file.c index 50c18b683..b2e7dd69f 100644 --- a/util/grub-file.c +++ b/util/grub-file.c @@ -54,7 +54,7 @@ main (int argc, char *argv[]) grub_util_host_init (&argc, &argv); - argv2 = xmalloc (argc * sizeof (argv2[0])); + argv2 = xcalloc (argc, sizeof (argv2[0])); if (argc == 2 && strcmp (argv[1], "--version") == 0) { diff --git a/util/grub-fstest.c b/util/grub-fstest.c index f14e02d97..838656420 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -538,7 +538,7 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; static error_t argp_parser (int key, char *arg, struct argp_state *state) { - char *p; + const char *p; switch (key) { @@ -650,7 +650,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; @@ -734,7 +734,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-install-common.c b/util/grub-install-common.c index ca0ac612a..277eaf4e2 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -286,7 +286,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++) { @@ -598,7 +598,7 @@ copy_all (const char *srcd, grub_util_fd_closedir (d); } -#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) +#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) static const char * get_localedir (void) { @@ -659,7 +659,7 @@ static void grub_install_copy_nls(const char *src __attribute__ ((unused)), const char *dst __attribute__ ((unused))) { -#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) +#if (defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) char *dst_locale; dst_locale = grub_util_path_concat (2, dst, "locale"); diff --git a/util/grub-install.c b/util/grub-install.c index 8a55ad4b8..a35a2e2e8 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -324,6 +324,14 @@ get_default_platform (void) return "arm64-efi"; #elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) return grub_install_get_default_x86_platform (); +#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 @@ -626,7 +634,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)) { @@ -1260,7 +1268,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++) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 9f477ff05..d3e879b8e 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 } @@ -158,6 +158,15 @@ if test -f ${sysconfdir}/default/grub ; then . ${sysconfdir}/default/grub fi +if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then + if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then + GRUB_DISABLE_LINUX_UUID="true" + fi + if [ -z "${GRUB_DISABLE_LINUX_PARTUUID}" ]; then + GRUB_DISABLE_LINUX_PARTUUID="true" + fi +fi + # XXX: should this be deprecated at some point? if [ "x${GRUB_TERMINAL}" != "x" ] ; then GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}" @@ -224,6 +233,7 @@ export GRUB_DEFAULT \ GRUB_TERMINAL_INPUT \ GRUB_TERMINAL_OUTPUT \ GRUB_SERIAL_COMMAND \ + GRUB_DISABLE_UUID \ GRUB_DISABLE_LINUX_UUID \ GRUB_DISABLE_LINUX_PARTUUID \ GRUB_DISABLE_RECOVERY \ @@ -287,7 +297,8 @@ 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} + cat ${grub_cfg}.new > ${grub_cfg} + rm -f ${grub_cfg}.new fi fi diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 0f801cab3..301d1ac22 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' diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index bc087c2b5..00f49ccaa 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -463,7 +463,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc 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); @@ -1232,8 +1232,7 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, grub_uint32_t *t32 = (grub_uint32_t *) target; grub_uint16_t *t16 = (grub_uint16_t *) target; grub_uint8_t *t8 = (grub_uint8_t *) target; - grub_int64_t off = (long)sym_addr - target_section_addr - offset - - image_target->vaddr_offset; + grub_int64_t off; /* * Instructions and instruction encoding are documented in the RISC-V @@ -1243,6 +1242,7 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, */ sym_addr += addend; + off = sym_addr - target_section_addr - offset - image_target->vaddr_offset; switch (ELF_R_TYPE (info)) { @@ -2294,10 +2294,8 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path, + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize); smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); - smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections); - memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections); - smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections); - memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections); + smd.addrs = xcalloc (smd.num_sections, sizeof (*smd.addrs)); + smd.vaddrs = xcalloc (smd.num_sections, sizeof (*smd.vaddrs)); SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target); diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index ce2cbc4f1..51831027f 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -441,8 +441,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 */ diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c index 4907d44c0..edf309717 100644 --- a/util/grub-mkstandalone.c +++ b/util/grub-mkstandalone.c @@ -296,7 +296,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); diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c index 0d4084a10..11331294f 100644 --- a/util/grub-pe2elf.c +++ b/util/grub-pe2elf.c @@ -100,9 +100,9 @@ write_section_data (FILE* fp, const char *name, char *image, char *pe_strtab = (image + pe_chdr->symtab_offset + pe_chdr->num_symbols * sizeof (struct grub_pe32_symbol)); - section_map = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (int)); + section_map = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (int)); section_map[0] = 0; - shdr = xmalloc ((2 * pe_chdr->num_sections + 5) * sizeof (shdr[0])); + shdr = xcalloc (2 * pe_chdr->num_sections + 5, sizeof (shdr[0])); idx = 1; idx_reloc = pe_chdr->num_sections + 1; @@ -233,7 +233,7 @@ write_reloc_section (FILE* fp, const char *name, char *image, pe_sec = pe_shdr + shdr[i].sh_link; pe_rel = (struct grub_pe32_reloc *) (image + pe_sec->relocations_offset); - rel = (elf_reloc_t *) xmalloc (pe_sec->num_relocations * sizeof (elf_reloc_t)); + rel = (elf_reloc_t *) xcalloc (pe_sec->num_relocations, sizeof (elf_reloc_t)); num_rels = 0; modified = 0; @@ -365,12 +365,10 @@ write_symbol_table (FILE* fp, const char *name, char *image, pe_symtab = (struct grub_pe32_symbol *) (image + pe_chdr->symtab_offset); pe_strtab = (char *) (pe_symtab + pe_chdr->num_symbols); - symtab = (Elf_Sym *) xmalloc ((pe_chdr->num_symbols + 1) * - sizeof (Elf_Sym)); - memset (symtab, 0, (pe_chdr->num_symbols + 1) * sizeof (Elf_Sym)); + symtab = (Elf_Sym *) xcalloc (pe_chdr->num_symbols + 1, sizeof (Elf_Sym)); num_syms = 1; - symtab_map = (int *) xmalloc (pe_chdr->num_symbols * sizeof (int)); + symtab_map = (int *) xcalloc (pe_chdr->num_symbols, sizeof (int)); for (i = 0; i < (int) pe_chdr->num_symbols; i += pe_symtab->num_aux + 1, pe_symtab += pe_symtab->num_aux + 1) diff --git a/util/grub-probe.c b/util/grub-probe.c index 81d27eead..cbe6ed94c 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -361,8 +361,8 @@ probe (const char *path, char **device_names, char delim) grub_util_pull_device (*curdev); ndev++; } - - drives_names = xmalloc (sizeof (drives_names[0]) * (ndev + 1)); + + drives_names = xcalloc (ndev + 1, sizeof (drives_names[0])); for (curdev = device_names, curdrive = drives_names; *curdev; curdev++, curdrive++) diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 59a9a48a2..3663d360e 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -156,7 +156,15 @@ is_top_level=true while [ "x$kernels" != "x" ] ; do kernel=`version_find_latest $kernels` - 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 hurd_entry "$kernel" simple submenu_indentation="$grub_tab" diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 9d8e8fd85..199b20e16 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -214,7 +214,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" diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 4532266be..e8b01c0d0 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -261,7 +261,15 @@ while [ "x$list" != "x" ] ; do fi fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then linux_entry "${OS}" "${version}" simple \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in index 874f59969..dc0cd1b17 100644 --- a/util/grub.d/10_netbsd.in +++ b/util/grub.d/10_netbsd.in @@ -157,7 +157,15 @@ for k in /netbsd $(ls -t /netbsd?* 2>/dev/null) ; do gettext_printf "Found NetBSD kernel: %s\n" "$k" >&2 - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then netbsd_entry "knetbsd" "$k" simple "${GRUB_CMDLINE_NETBSD_DEFAULT}" submenu_indentation="$grub_tab" diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index 96179ea61..3b1f47049 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -88,6 +88,11 @@ esac title_correction_code= linux_entry () +{ + linux_entry_xsm "$@" false + linux_entry_xsm "$@" true +} +linux_entry_xsm () { os="$1" version="$2" @@ -95,6 +100,18 @@ linux_entry () type="$4" args="$5" xen_args="$6" + xsm="$7" + # If user wants to enable XSM support, make sure there's + # corresponding policy file. + if ${xsm} ; then + xenpolicy="xenpolicy-$xen_version" + if test ! -e "${xen_dirname}/${xenpolicy}" ; then + return + fi + xen_args="$xen_args flask=enforcing" + xen_version="$(gettext_printf "%s (XSM enabled)" "$xen_version")" + # 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 @@ -146,6 +163,13 @@ EOF sed "s/^/$submenu_indentation/" << EOF echo '$(echo "$message" | grub_quote)' ${module_loader} --nounzip $(echo $initrd_path) +EOF + fi + if test -n "${xenpolicy}" ; then + message="$(gettext_printf "Loading XSM policy ...")" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' + ${module_loader} ${rel_dirname}/${xenpolicy} EOF fi sed "s/^/$submenu_indentation/" << EOF @@ -173,10 +197,14 @@ if [ "x${linux_list}" = "x" ] ; then exit 0 fi -file_is_not_sym () { +file_is_not_xen_garbage () { case "$1" in */xen-syms-*) return 1;; + */xenpolicy-*) + return 1;; + */*.config) + return 1;; *) return 0;; esac @@ -184,7 +212,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= @@ -288,7 +316,15 @@ while [ "x${xen_list}" != "x" ] ; do fi fi - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + # The GRUB_DISABLE_SUBMENU option used to be different than others since it was + # mentioned in the documentation that has to be set to 'y' instead of 'true' to + # enable it. This caused a lot of confusion to users that set the option to 'y', + # 'yes' or 'true'. This was fixed but all of these values must be supported now. + if [ "x${GRUB_DISABLE_SUBMENU}" = xyes ] || [ "x${GRUB_DISABLE_SUBMENU}" = xy ]; then + GRUB_DISABLE_SUBMENU="true" + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then linux_entry "${OS}" "${version}" "${xen_version}" simple \ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}" diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 515a68c7a..1b91c102f 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -30,7 +30,7 @@ if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then 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 @@ -234,7 +234,15 @@ EOF prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | grub_add_tab)" 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 cat << EOF menuentry '$(echo "$OS $onstr" | grub_quote)' $CLASS --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-simple-$boot_device_id' { EOF diff --git a/util/grub.d/30_uefi-firmware.in b/util/grub.d/30_uefi-firmware.in new file mode 100644 index 000000000..d344d3883 --- /dev/null +++ b/util/grub.d/30_uefi-firmware.in @@ -0,0 +1,44 @@ +#! /bin/sh +set -e + +# grub-mkconfig helper script. +# 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 . + +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR="@localedir@" + +. "$pkgdatadir/grub-mkconfig_lib" + +EFI_VARS_DIR=/sys/firmware/efi/efivars +EFI_GLOBAL_VARIABLE=8be4df61-93ca-11d2-aa0d-00e098032b8c +OS_INDICATIONS="$EFI_VARS_DIR/OsIndicationsSupported-$EFI_GLOBAL_VARIABLE" + +if [ -e "$OS_INDICATIONS" ] && \ + [ "$(( $(printf 0x%x \'"$(cat $OS_INDICATIONS | cut -b5)"\') & 1 ))" = 1 ]; then + LABEL="UEFI Firmware Settings" + + gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2 + + cat << EOF +menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' { + fwsetup +} +EOF +fi 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 <> 4); +#endif +#ifdef GRUB_SETUP_SPARC64 + bl.gpt_offset = 0; #endif bl.last_length = 0; @@ -730,7 +733,6 @@ unable_to_embed: #ifdef GRUB_SETUP_SPARC64 { grub_partition_t container = root_dev->disk->partition; - bl.gpt_offset = 0; if (grub_strstr (container->partmap->name, "gpt")) bl.gpt_offset = grub_partition_get_start (container);