diff --git a/ChangeLog b/ChangeLog index aee611641..75439bbb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,286 @@ +2013-11-25 Vladimir Serbinenko + + * grub-core/osdep/unix/platform.c (get_ofpathname): Trim ending newline. + Don't rely on PATH_MAX. + +2013-11-25 Vladimir Serbinenko + + * grub-core/genmoddep.awk: Use more portable && rather than and. + +2013-11-24 Vladimir Serbinenko + + * grub-core/kern/i386/pc/startup.S [__APPLE__]: Create _edata by placing + an object after data. While it doesn't seem right solution, it + works well enough and OSX isn't main compilation platform. + +2013-11-24 Vladimir Serbinenko + + * gentpl.py: Add -ed2016 in order to make objconv accept our binary. + While it doesn't seem right solution, it works well enough and + OSX isn't main compilation platform. + +2013-11-24 Vladimir Serbinenko + + * configure.ac: Add -static to LDFLAGS when using apple linker to + prevent it from pulling in dynamic linker. + +2013-11-24 Vladimir Serbinenko + + Apple assembly doesn't handle symbol arithmetic well. So define an + offset symbol in boot.S and use it. + +2013-11-24 Vladimir Serbinenko + + Apple assembly doesn't handle symbol arithmetic well. So instead + of getting addres of kernel_sector + 4 define kernel_sector_high. + It also makes code more readable. + +2013-11-24 Vladimir Serbinenko + + With Apple assembly in .macro environvemnt you have to use $$ instead + of $. So introduce new preprocessor macro MACRO_DOLLAR(x) which expands + to $$x on Apple and to $x on everything else. + +2013-11-24 Vladimir Serbinenko + + * grub-core/Makefile.am: Use correct TARGET_OBJCONV rather than + OBJCONV. + +2013-11-24 Vladimir Serbinenko + + * grub-core/gdb/i386/machdep.S: Use xorl %eax, %eax on both Apple + and non-Apple. This instruction is shorter and faster, + so no reason not to use it on both. + +2013-11-24 Vladimir Serbinenko + + * grub-core/lib/reed_solomon.c: Use section _text, _text rather than + .text when compiling for Apple. + +2013-11-24 Vladimir Serbinenko + + * grub-core/term/arc/console.c: Add missing cast to silence warning. + +2013-11-24 Vladimir Serbinenko + + * grub-core/boot/i386/pc/boot.S: Fix floppy probe. Due to missing + %dx restore the probe worked on non-existant drive. Reorganize the + code a little bit to free 2 bytes necessary for push/pop. + +2013-11-23 Vladimir Serbinenko + + * grub-core/kern/mips/arc/init.c (grub_machine_get_bootlocation): + Add missing cast to silence warning. + +2013-11-23 Keshav Padram Amburay + + * util/grub-install.c (update_nvram): Support --no-nvram flag + for EFI targets. + +2013-11-23 Vladimir Serbinenko + + * INSTALL: Add note about sparc64/ia64 with clang (unsupported). + +2013-11-23 Vladimir Serbinenko + + * util/garbage-gen.c: Add missing include of sys/time.h. + +2013-11-23 Vladimir Serbinenko + + Don't add -mflush-func if it's not supported by compiler. + +2013-11-23 Vladimir Serbinenko + + Move common BIOS/coreboot memory map declarations to + include/grub/i386/memory_raw.h and eliminate duplicate declarations. + +2013-11-22 Andrey Borzenkov + + * Makefile.am: Add util/garbage-gen.c to EXTRA_DIST. + +2013-11-22 Vladimir Serbinenko + + * INSTALL: Document why older clang versions aren't appropriate. + +2013-11-22 Vladimir Serbinenko + + * INSTALL: Document about clang for mips. + +2013-11-22 Vladimir Serbinenko + + * grub-core/lib/libgcrypt/mpi/longlong.h: Use C version with mips + clang. + +2013-11-22 Vladimir Serbinenko + + Add *-xen to the list of grub-install-common platforms. + +2013-11-22 Vladimir Serbinenko + + * configure.ac: Do not enforce -mcmodel=large. It's not necessarry with + 3 last commits. + +2013-11-22 Vladimir Serbinenko + + * grub-core/kern/xen/init.c: Do not map more pages than we can address. + +2013-11-22 Vladimir Serbinenko + + * grub-core/kern/efi/mm.c: Limit allocations to 2GiB when not compiling + with -mcmodel=large. + +2013-11-22 Vladimir Serbinenko + + * grub-core/kern/x86_64/dl.c (grub_arch_dl_relocate_symbols): Add + range-checking for 32-bit quantities. + +2013-11-22 Vladimir Serbinenko + + * configure.ac: Compile with -fPIC when compiling with clang on + mips. + +2013-11-22 Vladimir Serbinenko + + * configure.ac: Add -no-integrated-as on mips(el) to TARGET_CCASFLAGS + when compiling with clang. + +2013-11-22 Vladimir Serbinenko + + clang emits calls to abort () under some unknown conditions. + Export abort () when compiling with clang. + +2013-11-22 Vladimir Serbinenko + + * docs/grub-dev.texi: Document stack and heap sizes. + +2013-11-22 Vladimir Serbinenko + + * include/grub/i386/pc/memory.h: Decrease + GRUB_MEMORY_MACHINE_SCRATCH_SIZE and increase + GRUB_MEMORY_MACHINE_PROT_STACK_SIZE. + The binary doesn't change (checked). It's more to better reflect actual + usage. + +2013-11-22 Vladimir Serbinenko + + * grub-core/disk/i386/pc/biosdisk.c (grub_biosdisk_open): Ensure + at compile time that enough of scratch size is available. + +2013-11-22 Vladimir Serbinenko + + * grub-core/kern/x86_64/efi/callwrap.S: Fix stack alignment. + Previously we misaligned stack by 8 in startup.S and compensated + for it in callwrap.S. According to ABI docs (EFI and sysv amd64) + right behaviour is to align stack in startup.S and keep it aligned + in callwrap.S. startup.S part was committed few commits before. This + takes care of callwrap.S. + Reported by: Gary Lin. + +2013-11-22 Vladimir Serbinenko + + * grub-core/boot/mips/startup_raw.S: Handle the case of gap between + .data and .bss. May happen if compiler and assembly use different + alignment. + +2013-11-22 Vladimir Serbinenko + + On MIPS handle got16 relocations to local symbols in an ABI-compliant + way. + +2013-11-22 Vladimir Serbinenko + + Add support for a new magic symbol _gp_disp on mips to handle PIC + binaries. + +2013-11-22 Vladimir Serbinenko + + Use $t9 for indirect calls from asm to C as PIC ABI requires. + +2013-11-22 Vladimir Serbinenko + + Remove -march=mips3 from TARGET_CCASFLAGS as it creates linking problem + when rest of GRUB is compiled for hisher stepping. Instead use + .set mips3/.set mips1 around cache and sync opcodes. + +2013-11-21 Vladimir Serbinenko + + Unify GOT/trampoline handling between PPC, MIPS and IA64 as they + do essentially the same thing, do it in similar way. + +2013-11-21 Colin Watson + + * util/grub-mkrescue.c (main): If a source directory is not + specified, read platform-specific files from subdirectories of + pkglibdir, not pkgdatadir. + +2013-11-21 Colin Watson + + * grub-core/normal/progress.c: Remove unused file. + +2013-11-20 Vladimir Serbinenko + + * grub-core/lib/crypto.c (grub_crypto_hash): Remove variable length + array. + +2013-11-20 Vladimir Serbinenko + + * util/grub-mkconfig.in: Say explicit "grub configuration" rather + than grub.cfg. + +2013-11-20 Vladimir Serbinenko + + * coreboot.cfg: Add missing file. + +2013-11-19 Vladimir Serbinenko + + * Makefile.am: Allow STRIP to be empty when creating windowszip. + +2013-11-19 Axel Kellermann + + * util/grub.d/30_os-prober.in: Add GRUB_OS_PROBER_SKIP_LIST to + selectively skipping systems. + +2013-11-19 Colin Watson + + * Makefile.util.def (grub-mkimage): Add + grub-core/osdep/aros/config.c to extra_dist. + * conf/Makefile.extra-dist (EXTRA_DIST): Add docs/autoiso.cfg, + docs/osdetect.cfg, grub-core/gnulib-fix-null-deref.diff, + grub-core/gnulib-fix-width.diff, grub-core/gnulib-no-abort.diff, and + grub-core/gnulib-no-gets.diff. + +2013-11-19 Vladimir Serbinenko + + Add automated filesystem checking based on scripts I've used now for + quite some time locally. Most of the test require root so they are + skipped when run without necessarry privelegies. + +2013-11-19 Colin Watson + + * util/grub-install.c (main): Adjust info messages to match + installed paths of grub-bios-setup and grub-sparc64-setup. + +2013-11-19 Colin Watson + + * util/grub-install-common.c (copy_locales): Consistently use + grub_util_get_localedir () rather than LOCALEDIR. + (grub_install_copy_files): Likewise. + +2013-11-19 Josh Triplett + + * grub-core/kern/x86_64/efi/startup.S (_start): Align the stack to a + 16-byte boundary, as required by the x86-64 ABI, before calling + grub_main. In some cases, GCC emits code that assumes this + alignment, which crashes if not aligned. The EFI firmware is also + entitled to assume that stack alignment without checking. + +2013-11-18 Josh Triplett + + * grub-core/mmap/efi/mmap.c (grub_mmap_register): Round up/down to + 4k page boundaries as expected by firmware rather than 1k + boundaries. + (grub_mmap_malign_and_register): Likewise. + 2013-11-18 Vladimir Serbinenko * tests/grub_func_test.in: Decrease RAM size to 512M. With less diff --git a/INSTALL b/INSTALL index 39718ecde..e81a095e9 100644 --- a/INSTALL +++ b/INSTALL @@ -15,8 +15,18 @@ configuring the GRUB. Note: older versions may work but support is limited 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 3.3 or later works for mips(el) + earlier versions fail to generate .reginfo and hence gprel relocations + fail. Note: clang 3.4 or later works for powerpc + earlier versions suffer from vacopy bug (#15286) + Note: clang has no support for generating 64-bit sparc code and hence you + can't compile GRUB for sparc64 with clang + 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 diff --git a/Makefile.am b/Makefile.am index 506325693..1a69e2e9d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -70,6 +70,11 @@ build-grub-mkfont: util/grub-mkfont.c grub-core/unidata.c grub-core/kern/emu/mis $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-mkfont\" $^ $(build_freetype_cflags) $(build_freetype_libs) CLEANFILES += build-grub-mkfont +garbage-gen: util/garbage-gen.c + $(BUILD_CC) -o $@ $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $^ +CLEANFILES += garbage-gen +EXTRA_DIST += util/garbage-gen.c + build-grub-gen-asciih: util/grub-gen-asciih.c $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror CLEANFILES += build-grub-gen-asciih @@ -406,7 +411,8 @@ windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA) test -d $(windowsdir)/themes || mkdir $(windowsdir)/themes test -d $(windowsdir)/themes/starfield || mkdir $(windowsdir)/themes/starfield for x in $(PROGRAMS); do \ - $(STRIP) $$x -o $(windowsdir)/$$x; \ + if [ x$(STRIP) != x ]; then $(STRIP) $$x -o $(windowsdir)/$$x; \ + else cp -fp $$x $(windowsdir)/$$x; fi; \ done for x in $(pkgdata_DATA); do \ cp -fp $$x $(windowsdir)/$$x; \ diff --git a/Makefile.util.def b/Makefile.util.def index b17c89bc5..d8c12d54f 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -174,6 +174,7 @@ program = { common = grub-core/kern/emu/argp_common.c; common = grub-core/osdep/init.c; common = grub-core/osdep/config.c; + extra_dist = grub-core/osdep/aros/config.c; extra_dist = grub-core/osdep/windows/config.c; extra_dist = grub-core/osdep/unix/config.c; common = util/config.c; @@ -682,6 +683,127 @@ script = { installdir = noinst; }; +script = { + name = grub-fs-tester; + common = tests/util/grub-fs-tester.in; + installdir = noinst; + dependencies = garbage-gen; +}; + +script = { + testcase; + name = ext234_test; + common = tests/ext234_test.in; +}; + +script = { + testcase; + name = squashfs_test; + common = tests/squashfs_test.in; +}; + +script = { + testcase; + name = iso9660_test; + common = tests/iso9660_test.in; +}; + +script = { + testcase; + name = hfsplus_test; + common = tests/hfsplus_test.in; +}; + +script = { + testcase; + name = ntfs_test; + common = tests/ntfs_test.in; +}; + +script = { + testcase; + name = reiserfs_test; + common = tests/reiserfs_test.in; +}; + +script = { + testcase; + name = fat_test; + common = tests/fat_test.in; +}; + +script = { + testcase; + name = minixfs_test; + common = tests/minixfs_test.in; +}; + +script = { + testcase; + name = xfs_test; + common = tests/xfs_test.in; +}; + +script = { + testcase; + name = nilfs2_test; + common = tests/nilfs2_test.in; +}; + +script = { + testcase; + name = romfs_test; + common = tests/romfs_test.in; +}; + +script = { + testcase; + name = exfat_test; + common = tests/exfat_test.in; +}; + +script = { + testcase; + name = tar_test; + common = tests/tar_test.in; +}; + +script = { + testcase; + name = udf_test; + common = tests/udf_test.in; +}; + +script = { + testcase; + name = hfs_test; + common = tests/hfs_test.in; +}; + +script = { + testcase; + name = jfs_test; + common = tests/jfs_test.in; +}; + +script = { + testcase; + name = btrfs_test; + common = tests/btrfs_test.in; +}; + +script = { + testcase; + name = zfs_test; + common = tests/zfs_test.in; +}; + +script = { + testcase; + name = cpio_test; + common = tests/cpio_test.in; +}; + script = { testcase; name = example_scripted_test; diff --git a/conf/Makefile.common b/conf/Makefile.common index 866998a15..34aa4a748 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -10,10 +10,6 @@ if COND_mips_loongson CFLAGS_PLATFORM += -mexplicit-relocs CPPFLAGS_PLATFORM = -DUSE_ASCII_FALLBACK endif -if COND_mips - CFLAGS_PLATFORM += -mflush-func=grub_red_herring - CCASFLAGS_PLATFORM = -march=mips3 -endif if COND_sparc64_ieee1275 CFLAGS_PLATFORM += -mno-app-regs LDFLAGS_PLATFORM = -Wl,-melf64_sparc -mno-relax diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index bf52487f8..72b00c043 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -12,7 +12,9 @@ EXTRA_DIST += util/import_gcry.py EXTRA_DIST += util/import_unicode.py EXTRA_DIST += docs/man +EXTRA_DIST += docs/autoiso.cfg EXTRA_DIST += docs/grub.cfg +EXTRA_DIST += docs/osdetect.cfg EXTRA_DIST += conf/i386-pc-cygwin-img-ld.sc @@ -26,6 +28,11 @@ EXTRA_DIST += grub-core/gensymlist.sh EXTRA_DIST += grub-core/genemuinit.sh EXTRA_DIST += grub-core/genemuinitheader.sh +EXTRA_DIST += grub-core/gnulib-fix-null-deref.diff +EXTRA_DIST += grub-core/gnulib-fix-width.diff +EXTRA_DIST += grub-core/gnulib-no-abort.diff +EXTRA_DIST += grub-core/gnulib-no-gets.diff + EXTRA_DIST += grub-core/lib/libgcrypt EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') @@ -103,3 +110,4 @@ EXTRA_DIST += grub-core/osdep/windows/sleep.c EXTRA_DIST += tests/dfly-mbr-mbexample.mbr.img.gz EXTRA_DIST += tests/dfly-mbr-mbexample.dfly.img.gz +EXTRA_DIST += coreboot.cfg diff --git a/configure.ac b/configure.ac index b7af65c70..ffe98b51f 100644 --- a/configure.ac +++ b/configure.ac @@ -492,7 +492,11 @@ AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang] # on x86 clang doesn't support .code16 # on arm clang doesn't support .arch directive -if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 || test "x$target_cpu" = xarm ); then +# on mips clang doesn't support privilegied instructions, doubleword store/load +# and crashes with hand-written assembly +if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 \ + || test "x$target_cpu" = xx86_64 || test "x$target_cpu" = xarm \ + || test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ); then TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as" fi @@ -522,6 +526,21 @@ if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3" fi +# on mips redirect cache flushing function to non-existant one. +if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then + AC_CACHE_CHECK([whether -mflush-func=grub_red_herring works], [grub_cv_cc_mflush_func], [ + CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mflush_func=yes], + [grub_cv_cc_mflush_func=no]) + ]) + + if test "x$grub_cv_cc_mflush_func" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring" + fi +fi + + # Force no alignment to save space on i386. if test "x$target_cpu" = xi386; then AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ @@ -660,8 +679,8 @@ if test x"$target_cpu" = xi386 || test x"$target_cpu" = xx86_64; then if test x${target_cpu} != xi386 && test x$format = x${target_cpu}pe; then continue fi - CFLAGS="$TARGET_CFLAGS -static" - LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib" + CFLAGS="$TARGET_CFLAGS" + LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib -static" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ asm (".globl start; start:"); asm (".globl _start; _start:"); @@ -729,9 +748,7 @@ if test "$target_cpu" = x86_64; then [grub_cv_cc_mcmodel=yes], [grub_cv_cc_mcmodel=no]) ]) - if test "x$grub_cv_cc_mcmodel" = xno; then - AC_MSG_ERROR([-mcmodel=large not supported. Upgrade your gcc.]) - else + if test "x$grub_cv_cc_mcmodel" = xyes; then TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" fi fi @@ -769,10 +786,17 @@ CFLAGS="$TARGET_CFLAGS" # Position independent executable. grub_CHECK_PIC -[# Need that, because some distributions ship compilers that include -# `-fPIC' in the default specs. -if [ x"$pic_possible" = xyes ]; then - TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC" +[# On most platforms we don't want PIC as it only makes relocations harder +# and code less efficient. On mips we want to have one got table per module +# and reload $gp in every function. +# GCC implements it using symbol __gnu_local_gp in non-PIC as well. +# However with clang we need PIC for this reloading to happen. +# Since default varies across dictributions use either -fPIC or -fno-PIC +# explicitly. +if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel ) && test "x$grub_cv_cc_target_clang" = xyes ; then + TARGET_CFLAGS="$TARGET_CFLAGS -fPIC" +elif [ x"$pic_possible" = xyes ]; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC" fi] CFLAGS="$TARGET_CFLAGS" @@ -807,7 +831,7 @@ fi # Set them to their new values for the tests below. CC="$TARGET_CC" if test "x$TARGET_APPLE_LINKER" = x1 ; then -CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" +CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" else CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error" fi @@ -833,7 +857,7 @@ fi AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x) if test "x$TARGET_APPLE_LINKER" = x1 ; then -CFLAGS="$TARGET_CFLAGS -nostdlib" +CFLAGS="$TARGET_CFLAGS -nostdlib -static" else CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100" fi diff --git a/coreboot.cfg b/coreboot.cfg new file mode 100644 index 000000000..188090d3a --- /dev/null +++ b/coreboot.cfg @@ -0,0 +1,3 @@ +if test -f (cbfsdisk)/etc/grub.cfg; then + source (cbfsdisk)/etc/grub.cfg +fi diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi index 401f455a3..ff79e51b0 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -79,6 +79,7 @@ This edition documents version @value{VERSION}. * Contributing Changes:: * Porting:: * Error Handling:: +* Stack and heap size:: * BIOS port memory map:: * Video Subsystem:: * PFF2 Font File Format:: @@ -906,6 +907,69 @@ if (grub_errno != GRUB_ERR_NONE) grub_error_pop (); @end example +@node Stack and heap size +@chapter Stack and heap size + +On emu stack and heap are just normal host OS stack and heap. Stack is typically +8 MiB although it's OS-dependent. + +On i386-pc, i386-coreboot, i386-qemu and i386-multiboot the stack is 60KiB. +All available space between 1MiB and 4GiB marks is part of heap. + +On *-xen stack is 4MiB. If compiled for x86-64 with GCC 4.4 or later adressable +space is unlimited. When compiled for x86-64 with older GCC version adressable +space is limited to 2GiB. When compiling for i386 adressable space is limited +to 4GiB. All adressable pages except the ones for stack, GRUB binary, special +pages and page table are in the heap. + +On *-efi GRUB uses same stack as EFI. If compiled for x86-64 with GCC 4.4 or +later adressable space is unlimited. When compiled for x86-64 with older GCC +version adressable space is limited to 2GiB. For all other platforms adressable +space is limited to 4GiB. GRUB allocates pages from EFI for its heap, at most +1.6 GiB. + +On i386-ieee1275 and powerpc-ieee1275 GRUB uses same stack as IEEE1275. +It allocates at most 32MiB for its heap. + +On sparc64-ieee1275 stack is 256KiB and heap is 2MiB. + +On mips(el)-qemu_mips and mipsel-loongson stack is 2MiB (everything below +GRUB image) and everything above GRUB image (from 2MiB + kernel size) +until 256MiB is part of heap. + +On mips-arc stack is 2MiB (everything below GRUB image) and everything above +GRUB image(from 2MiB + kernel size) until 128MiB is part of heap. + +On mipsel-arc stack is 2MiB (everything below GRUB image which is not part +of ARC) and everything above GRUB image (from 7MiB + kernel size) +until 256MiB is part of heap. + +On arm-uboot stack is 256KiB and heap is 2MiB. + +In short: + +@multitable @columnfractions .15 .25 .5 +@headitem Platform @tab Stack @tab Heap +@item emu @tab 8 MiB @tab ? +@item i386-pc @tab 60 KiB @tab < 4 GiB +@item i386-coreboot @tab 60 KiB @tab < 4 GiB +@item i386-multiboot @tab 60 KiB @tab < 4 GiB +@item i386-qemu @tab 60 KiB @tab < 4 GiB +@item *-efi @tab ? @tab < 1.6 GiB +@item i386-ieee1275 @tab ? @tab < 32 MiB +@item powerpc-ieee1275 @tab ? @tab < 32 MiB +@item sparc64-ieee1275 @tab 256KiB @tab 2 MiB +@item arm-uboot @tab 256KiB @tab 2 MiB +@item mips(el)-qemu_mips @tab 2MiB @tab 253 MiB +@item mipsel-loongson @tab 2MiB @tab 253 MiB +@item mips-arc @tab 2MiB @tab 125 MiB +@item mipsel-arc @tab 2MiB @tab 248 MiB +@item x86_64-xen (GCC >= 4.4) @tab 4MiB @tab unlimited +@item x86_64-xen (GCC < 4.4) @tab 4MiB @tab < 2GiB +@item i386-xen @tab 4MiB @tab < 4GiB +@end multitable + + @node BIOS port memory map @chapter BIOS port memory map @c By Yoshinori K Okuji @@ -917,9 +981,8 @@ grub_error_pop (); @item ? @tab 0x2000 - 1 @tab Real mode stack @item 0x7C00 @tab 0x7D00 - 1 @tab Boot sector @item 0x8000 @tab ? @tab GRUB kernel -@item 0x68000 @tab 0x78000 - 1 @tab Disk buffer +@item 0x68000 @tab 0x71000 - 1 @tab Disk buffer @item ? @tab 0x80000 - 1 @tab Protected mode stack -@item 0x80000 @tab ? @tab Heap @item ? @tab 0xA0000 - 1 @tab Extended BIOS Data Area @item 0xA0000 @tab 0xC0000 - 1 @tab Video RAM @item 0xC0000 @tab 0x100000 - 1 @tab BIOS diff --git a/docs/grub.texi b/docs/grub.texi index de72d0cce..6aee292f0 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1451,6 +1451,10 @@ Normally, @command{grub-mkconfig} will try to use the external systems installed on the same system and generate appropriate menu entries for them. Set this option to @samp{true} to disable this. +@item GRUB_OS_PROBER_SKIP_LIST +List of space-separated FS UUIDs of filesystems to be ignored from os-prober +output. For efi chainloaders it's @@ + @item GRUB_DISABLE_SUBMENU Normally, @command{grub-mkconfig} will generate top level menu entry for the kernel with highest version number and put all other found kernels diff --git a/gentpl.py b/gentpl.py index 19fab42e2..61becea20 100644 --- a/gentpl.py +++ b/gentpl.py @@ -433,7 +433,7 @@ def kernel(platform): else cp $< $@; fi""", """if test x$(TARGET_APPLE_LINKER) = x1; then \ $(TARGET_STRIP) -S -x $(""" + cname() + """) -o $@.bin $<; \ - $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $@.bin $@; \ + $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \ else """ + "$(TARGET_STRIP) $(" + cname() + "_STRIPFLAGS) -o $@ $<; \ fi""")) return r @@ -542,8 +542,8 @@ def script(platform): r += "[+ IF mansection +]" + manpage("grub-mkconfig_lib") + "[+ ENDIF +]" r += "[+ ENDIF +]" - r += rule("[+ name +]", "$(top_builddir)/config.status " + platform_sources(platform), """ -(skip=1; for x in $^; do if [ $$skip = 1 ]; then skip=0; else cat "$$x"; fi; done) | $(top_builddir)/config.status --file=$@:- + r += rule("[+ name +]", "$(top_builddir)/config.status " + platform_sources(platform) + platform_dependencies(platform), """ +(for x in """ + platform_sources(platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- chmod a+x [+ name +] """) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index ec76ca0e1..7159d426a 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -396,7 +396,7 @@ efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) -rm -f $@; \ if test "x$(TARGET_APPLE_LINKER)" = x1; then \ $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -O2 -c -o $@.bin $< || exit 1; \ - $(OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \ + $(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \ rm -f $@.bin; \ else \ $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -O2 -c -o $@ $< || exit 1; \ @@ -423,7 +423,7 @@ efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF) if test "x$(TARGET_APPLE_LINKER)" = x1; then \ rm -f $@.bin; \ $(TARGET_CC) -m64 -Wl,-r -nostdlib -o $@.bin $^ || exit 1; \ - $(OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \ + $(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \ rm -f $@.bin; \ else \ $(TARGET_CC) -m64 -Wl,-melf_x86_64 -nostdlib -Wl,-r -o $@ $^ || exit 1; \ diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S index c0880c6b8..b4975e2d0 100644 --- a/grub-core/boot/i386/pc/boot.S +++ b/grub-core/boot/i386/pc/boot.S @@ -31,27 +31,32 @@ .macro floppy part_start: -probe_values: +LOCAL(probe_values): .byte 36, 18, 15, 9, 0 LOCAL(floppy_probe): + pushw %dx /* * Perform floppy probe. */ - - movw $probe_values - 1, %si +#ifdef __APPLE__ + LOCAL(probe_values_minus_one) = LOCAL(probe_values) - 1 + movw MACRO_DOLLAR(LOCAL(probe_values_minus_one)), %si +#else + movw MACRO_DOLLAR(LOCAL(probe_values)) - 1, %si +#endif LOCAL(probe_loop): /* reset floppy controller INT 13h AH=0 */ xorw %ax, %ax - int $0x13 + int MACRO_DOLLAR(0x13) incw %si movb (%si), %cl /* if number of sectors is 0, display error and die */ - cmpb $0, %cl - jne 1f + testb %cl, %cl + jnz 1f /* * Floppy disk probe failure. @@ -64,20 +69,20 @@ fd_probe_error_string: .asciz "Floppy" 1: /* perform read */ - movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx + movw MACRO_DOLLAR(GRUB_BOOT_MACHINE_BUFFER_SEG), %bx movw %bx, %es xorw %bx, %bx - movw $0x201, %ax - movb $0, %ch - movb $0, %dh - int $0x13 + movw MACRO_DOLLAR(0x201), %ax + movb MACRO_DOLLAR(0), %ch + movb MACRO_DOLLAR(0), %dh + int MACRO_DOLLAR(0x13) /* if error, jump to "LOCAL(probe_loop)" */ jc LOCAL(probe_loop) /* %cl is already the correct value! */ - movb $1, %dh - movb $79, %ch + movb MACRO_DOLLAR(1), %dh + movb MACRO_DOLLAR(79), %ch jmp LOCAL(final_init) .endm @@ -180,7 +185,9 @@ kernel_address: #ifndef HYBRID_BOOT . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR kernel_sector: - .long 1, 0 + .long 1 +kernel_sector_high: + .long 0 #endif . = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE @@ -285,7 +292,7 @@ lba_mode: /* the absolute address */ movl kernel_sector, %ebx movl %ebx, 8(%si) - movl kernel_sector + 4, %ebx + movl kernel_sector_high, %ebx movl %ebx, 12(%si) /* the segment of buffer address */ @@ -318,11 +325,12 @@ LOCAL(chs_mode): int $0x13 jnc LOCAL(final_init) + popw %dx /* * The call failed, so maybe use the floppy probe instead. */ - testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl - jz LOCAL(floppy_probe) + testb %dl, %dl + jnb LOCAL(floppy_probe) /* Nope, we definitely have a hard disk, and we're screwed. */ ERR(hd_probe_error_string) @@ -353,7 +361,7 @@ LOCAL(final_init): setup_sectors: /* load logical sector start (top half) */ - movl kernel_sector + 4, %eax + movl kernel_sector_high, %eax orl %eax, %eax jnz LOCAL(geometry_error) @@ -505,7 +513,9 @@ LOCAL(message): #ifdef HYBRID_BOOT . = _start + 0x1b0 kernel_sector: - .long 1, 0 + .long 1 +kernel_sector_high: + .long 0 #endif . = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC nt_magic: diff --git a/grub-core/boot/i386/qemu/boot.S b/grub-core/boot/i386/qemu/boot.S index ebbfe8828..d99e2dde4 100644 --- a/grub-core/boot/i386/qemu/boot.S +++ b/grub-core/boot/i386/qemu/boot.S @@ -18,7 +18,6 @@ #include #include -#include #include #include #include diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S index 606197624..29e93c17e 100644 --- a/grub-core/boot/mips/startup_raw.S +++ b/grub-core/boot/mips/startup_raw.S @@ -27,6 +27,7 @@ .extern __bss_start .extern _end +.extern _edata .globl __start, _start, start .set noreorder @@ -248,8 +249,9 @@ cmdlinedone: #include "../../kern/mips/cache_flush.S" /* Decompress the payload. */ - lui $a0, %hi(__bss_start) - addiu $a0, $a0, %lo(__bss_start) + lui $a0, %hi(_edata) + addiu $a0, $a0, %lo(_edata) + lui $t0, %hi(base) addiu $t0, $t0, %lo(base) subu $a0, $a0, $t0 @@ -265,16 +267,16 @@ cmdlinedone: */ move $s6, $a3 - lui $t0, %hi(EXT_C(grub_decompress_core)) - addiu $t0, $t0, %lo(EXT_C(grub_decompress_core)) + lui $t9, %hi(EXT_C(grub_decompress_core)) + addiu $t9, $t9, %lo(EXT_C(grub_decompress_core)) #ifdef GRUB_MACHINE_ARC lui $sp, %hi(_start - 512) - jalr $t0 + jalr $t9 addiu $sp, $sp, %lo(_start - 512) #else lui $sp, %hi(_start - 256) - jalr $t0 + jalr $t9 addiu $sp, $sp, %lo(_start - 256) #endif move $a0, $s1 @@ -287,3 +289,11 @@ cmdlinedone: jr $t1 nop + /* Ensure that .data section is created. In code we suppose that _edata + is first location not in decompressor image. Strictly speaking it's + _edata only when .data is present and _etext otherwise. But checking + for .data presence would cost more in code than it is to ensure that + .data is created. + */ + .data + .long 0 diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c index 7458c7a0f..1689539cd 100644 --- a/grub-core/disk/i386/pc/biosdisk.c +++ b/grub-core/disk/i386/pc/biosdisk.c @@ -426,6 +426,10 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) disk->total_sectors = total_sectors; /* Limit the max to 0x7f because of Phoenix EDD. */ disk->max_agglomerate = 0x7f >> GRUB_DISK_CACHE_BITS; + COMPILE_TIME_ASSERT ((0x7f >> GRUB_DISK_CACHE_BITS + << (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS)) + + sizeof (struct grub_biosdisk_dap) + < GRUB_MEMORY_MACHINE_SCRATCH_SIZE); disk->data = data; diff --git a/grub-core/gdb/i386/machdep.S b/grub-core/gdb/i386/machdep.S index 1615b0c9f..f96d2b9c4 100644 --- a/grub-core/gdb/i386/machdep.S +++ b/grub-core/gdb/i386/machdep.S @@ -71,11 +71,7 @@ VARIABLE(grub_gdb_stack) #define REG \reg #define NDX \ndx #endif -#ifdef __APPLE__ xorl %eax, %eax -#else - movl $0, %eax -#endif movw REG, EXT_C(grub_gdb_regs)+(NDX * 4) movw %ax, EXT_C(grub_gdb_regs)+(NDX * 4 + 2) movl EXT_C(grub_gdb_regs)+(EAX * 4), %eax @@ -190,11 +186,7 @@ VARIABLE(grub_gdb_stack) .text 1: .if EC -#ifdef __APPLE__ - add $$4, %esp -#else - add $4, %esp -#endif + add MACRO_DOLLAR(4), %esp .endif save_context diff --git a/grub-core/genmoddep.awk b/grub-core/genmoddep.awk index 9ffea7309..2e6af05a7 100644 --- a/grub-core/genmoddep.awk +++ b/grub-core/genmoddep.awk @@ -23,7 +23,7 @@ BEGIN { } else if ($1 == "undefined") { if ($3 in symtab) modtab[$2] = modtab[$2] " " symtab[$3]; - else if ($3 != "__gnu_local_gp") { + else if ($3 != "__gnu_local_gp" && $3 != "_gp_disp") { printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr"; error++; } diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index ccbd5bac4..1d6841479 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -229,9 +229,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) unsigned i; Elf_Shdr *s; grub_size_t tsize = 0, talign = 1; -#if defined (__ia64__) || defined (__powerpc__) +#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) grub_size_t tramp; grub_size_t got; + grub_err_t err; #endif char *ptr; @@ -244,10 +245,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) talign = s->sh_addralign; } -#if defined (__ia64__) || defined (__powerpc__) - grub_arch_dl_get_tramp_got_size (e, &tramp, &got); - tramp *= GRUB_ARCH_DL_TRAMP_SIZE; - got *= sizeof (grub_uint64_t); +#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) + err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got); + if (err) + return err; tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) talign = GRUB_ARCH_DL_TRAMP_ALIGN; @@ -313,7 +314,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->segment = seg; } } -#if defined (__ia64__) || defined (__powerpc__) +#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); mod->tramp = ptr; ptr += tramp; diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index 1409b5da9..6e9dace91 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -32,6 +32,12 @@ #define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) #define PAGES_TO_BYTES(pages) ((pages) << 12) +#if defined (__code_model_large__) || !defined (__x86_64__) +#define MAX_USABLE_ADDRESS 0xffffffff +#else +#define MAX_USABLE_ADDRESS 0x7fffffff +#endif + /* The size of a memory map obtained from the firmware. This must be a multiplier of 4KB. */ #define MEMORY_MAP_SIZE 0x3000 @@ -58,7 +64,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address, #if 1 /* Limit the memory access to less than 4GB for 32-bit platforms. */ - if (address > 0xffffffff) + if (address > MAX_USABLE_ADDRESS) return 0; #endif @@ -66,7 +72,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address, if (address == 0) { type = GRUB_EFI_ALLOCATE_MAX_ADDRESS; - address = 0xffffffff; + address = MAX_USABLE_ADDRESS; } else type = GRUB_EFI_ALLOCATE_ADDRESS; @@ -86,7 +92,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address, { /* Uggh, the address 0 was allocated... This is too annoying, so reallocate another one. */ - address = 0xffffffff; + address = MAX_USABLE_ADDRESS; status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address); grub_efi_free_pages (0, pages); if (status != GRUB_EFI_SUCCESS) @@ -319,7 +325,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY #if 1 - && desc->physical_start <= 0xffffffff + && desc->physical_start <= MAX_USABLE_ADDRESS #endif && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 && desc->num_pages != 0) @@ -337,9 +343,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, #if 1 if (BYTES_TO_PAGES (filtered_desc->physical_start) + filtered_desc->num_pages - > BYTES_TO_PAGES (0x100000000LL)) + > BYTES_TO_PAGES (MAX_USABLE_ADDRESS+1LL)) filtered_desc->num_pages - = (BYTES_TO_PAGES (0x100000000LL) + = (BYTES_TO_PAGES (MAX_USABLE_ADDRESS+1LL) - BYTES_TO_PAGES (filtered_desc->physical_start)); #endif diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 97d59fd32..8034c637b 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -46,7 +46,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) return GRUB_ERR_BAD_MODULE; } -#if defined (__ia64__) || defined (__powerpc__) +#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), grub_size_t *tramp, grub_size_t *got) { diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index dc2c62a25..eb3dd9460 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -17,8 +17,6 @@ */ #include -/* For stack parameters. */ -#include #include #include #include diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c index 2319adf12..3c8160aab 100644 --- a/grub-core/kern/i386/pc/init.c +++ b/grub-core/kern/i386/pc/init.c @@ -161,13 +161,13 @@ mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size, void *data __attribute__ ((unused))) { /* Avoid the lower memory. */ - if (addr < 0x100000) + if (addr < GRUB_MEMORY_MACHINE_UPPER_START) { - if (size <= 0x100000 - addr) + if (size <= GRUB_MEMORY_MACHINE_UPPER_START - addr) return 0; - size -= 0x100000 - addr; - addr = 0x100000; + size -= GRUB_MEMORY_MACHINE_UPPER_START - addr; + addr = GRUB_MEMORY_MACHINE_UPPER_START; } /* Ignore >4GB. */ diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index 0761807ed..3d47d1e4f 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -19,7 +19,6 @@ #include #include -#include #include #include diff --git a/grub-core/kern/i386/realmode.S b/grub-core/kern/i386/realmode.S index 6403b9699..541cedc87 100644 --- a/grub-core/kern/i386/realmode.S +++ b/grub-core/kern/i386/realmode.S @@ -16,7 +16,7 @@ * along with GRUB. If not, see . */ -#include +#include /* * Note: These functions defined in this file may be called from C. @@ -196,8 +196,6 @@ protcseg: * along with GRUB. If not, see . */ -#include - prot_to_real: /* just in case, set GDT */ lgdt gdtdesc diff --git a/grub-core/kern/ia64/dl_helper.c b/grub-core/kern/ia64/dl_helper.c index e2209ca0a..515e323ad 100644 --- a/grub-core/kern/ia64/dl_helper.c +++ b/grub-core/kern/ia64/dl_helper.c @@ -170,7 +170,7 @@ grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr) grub_memcpy (tr->jump, jump, sizeof (tr->jump)); } -void +grub_err_t grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got) { @@ -187,7 +187,7 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, break; if (i == grub_le_to_cpu16 (e->e_shnum)) - return; + return GRUB_ERR_NONE; for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff)); i < grub_le_to_cpu16 (e->e_shnum); @@ -211,7 +211,9 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, break; } } - *tramp = cntt; - *got = cntg; + *tramp = cntt * sizeof (struct grub_ia64_trampoline); + *got = cntg * sizeof (grub_uint64_t); + + return GRUB_ERR_NONE; } diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c index cb6c22848..b4f50e496 100644 --- a/grub-core/kern/mips/arc/init.c +++ b/grub-core/kern/mips/arc/init.c @@ -396,8 +396,8 @@ grub_machine_get_bootlocation (char **device, char **path) const char *syspart = 0; if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length - >= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1) - - (char *) GRUB_ARC_FIRMWARE_VECTOR) + >= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1) + - (char *) GRUB_ARC_FIRMWARE_VECTOR) && GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable) syspart = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("SystemPartition"); if (!syspart) diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S index 141c030e9..cca4b30fe 100644 --- a/grub-core/kern/mips/cache.S +++ b/grub-core/kern/mips/cache.S @@ -20,11 +20,11 @@ FUNCTION (grub_arch_sync_dma_caches) move $t0, $t2 subu $t1, $t3, $t2 1: - cache 1, 0($t0) + cache_op 1, 0($t0) #ifdef GRUB_MACHINE_MIPS_LOONGSON - cache 1, 1($t0) - cache 1, 2($t0) - cache 1, 3($t0) + cache_op 1, 1($t0) + cache_op 1, 2($t0) + cache_op 1, 3($t0) addiu $t1, $t1, -0x20 bne $t1, $zero, 1b @@ -34,36 +34,36 @@ FUNCTION (grub_arch_sync_dma_caches) bne $t1, $zero, 1b addiu $t0, $t0, 0x4 #endif - sync + sync_op move $t0, $t2 subu $t1, $t3, $t2 2: #ifdef GRUB_MACHINE_MIPS_LOONGSON - cache 0, 0($t0) + cache_op 0, 0($t0) addiu $t1, $t1, -0x20 bne $t1, $zero, 2b addiu $t0, $t0, 0x20 #else - cache 0, 0($t0) + cache_op 0, 0($t0) addiu $t1, $t1, -4 bne $t1, $zero, 2b addiu $t0, $t0, 0x4 #endif - sync + sync_op move $t0, $t2 subu $t1, $t3, $t2 2: #ifdef GRUB_MACHINE_MIPS_LOONGSON - cache 23, 0($t0) + cache_op 23, 0($t0) addiu $t1, $t1, -0x20 bne $t1, $zero, 2b addiu $t0, $t0, 0x20 #else - cache 23, 0($t0) + cache_op 23, 0($t0) addiu $t1, $t1, -0x4 bne $t1, $zero, 2b addiu $t0, $t0, 0x4 #endif - sync + sync_op jr $ra \ No newline at end of file diff --git a/grub-core/kern/mips/cache_flush.S b/grub-core/kern/mips/cache_flush.S index a5435cf51..89961a0f7 100644 --- a/grub-core/kern/mips/cache_flush.S +++ b/grub-core/kern/mips/cache_flush.S @@ -1,3 +1,17 @@ +#ifndef CACHE_OP_DEFINED +#define CACHE_OP_DEFINED 1 + .macro cache_op op addr + .set mips3 + cache \op, \addr + .set mips1 + .endm + .macro sync_op + .set mips3 + sync + .set mips1 + .endm +#endif + move $t2, $a0 addu $t3, $a0, $a1 srl $t2, $t2, 5 @@ -8,12 +22,12 @@ move $t0, $t2 subu $t1, $t3, $t2 1: - cache 1, 0($t0) + cache_op 1, 0($t0) /* All four ways. */ #ifdef GRUB_MACHINE_MIPS_LOONGSON - cache 1, 1($t0) - cache 1, 2($t0) - cache 1, 3($t0) + cache_op 1, 1($t0) + cache_op 1, 2($t0) + cache_op 1, 3($t0) addiu $t1, $t1, -0x20 bne $t1, $zero, 1b addiu $t0, $t0, 0x20 @@ -23,11 +37,11 @@ bne $t1, $zero, 1b addiu $t0, $t0, 0x4 #endif - sync + sync_op move $t0, $t2 subu $t1, $t3, $t2 2: - cache 0, 0($t0) + cache_op 0, 0($t0) #ifdef GRUB_MACHINE_MIPS_LOONGSON addiu $t1, $t1, -0x20 bne $t1, $zero, 2b @@ -37,4 +51,4 @@ bne $t1, $zero, 2b addiu $t0, $t0, 0x4 #endif - sync + sync_op diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c index ee65c9d18..b97510a1e 100644 --- a/grub-core/kern/mips/dl.c +++ b/grub-core/kern/mips/dl.c @@ -27,6 +27,7 @@ /* Dummy __gnu_local_gp. Resolved by linker. */ static char __gnu_local_gp_dummy; +static char _gp_disp_dummy; /* Check if EHDR is a valid ELF header. */ grub_err_t @@ -51,6 +52,58 @@ grub_arch_dl_check_header (void *ehdr) #pragma GCC diagnostic ignored "-Wcast-align" +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +{ + const Elf_Ehdr *e = ehdr; + const Elf_Shdr *s; + unsigned i; + /* FIXME: suboptimal. */ + grub_size_t gp_size = 0; + + *tramp = 0; + *got = 0; + + /* Find a symbol table. */ + for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) + if (s->sh_type == SHT_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); + + for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) + if (s->sh_type == SHT_REL) + { + const Elf_Rel *rel, *max; + + for (rel = (const Elf_Rel *) ((const char *) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + switch (ELF_R_TYPE (rel->r_info)) + { + case R_MIPS_GOT16: + case R_MIPS_CALL16: + case R_MIPS_GPREL32: + gp_size += 4; + break; + } + } + + if (gp_size > 0x08000) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n"); + + *got = gp_size; + + return GRUB_ERR_NONE; +} + /* Relocate symbols. */ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) @@ -59,7 +112,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Shdr *s; Elf_Word entsize; unsigned i; - grub_size_t gp_size = 0; /* FIXME: suboptimal. */ grub_uint32_t *gp, *gpptr; grub_uint32_t gp0; @@ -88,43 +140,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5]; - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_REL) - { - grub_dl_segment_t seg; - - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) - { - Elf_Rel *rel, *max; - - for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - switch (ELF_R_TYPE (rel->r_info)) - { - case R_MIPS_GOT16: - case R_MIPS_CALL16: - case R_MIPS_GPREL32: - gp_size += 4; - break; - } - } - } - - if (gp_size > 0x08000) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n"); - - gpptr = gp = grub_malloc (gp_size); - if (!gp) - return grub_errno; + gpptr = gp = mod->got; for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); i < e->e_shnum; @@ -149,6 +165,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) { grub_uint8_t *addr; Elf_Sym *sym; + grub_uint32_t sym_value; if (seg->size < rel->r_offset) return grub_error (GRUB_ERR_BAD_MODULE, @@ -157,9 +174,17 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset); sym = (Elf_Sym *) ((char *) mod->symtab + entsize * ELF_R_SYM (rel->r_info)); - if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy) - sym->st_value = (grub_addr_t) gp; - + sym_value = sym->st_value; + if (sym_value == (grub_addr_t) &__gnu_local_gp_dummy) + sym_value = (grub_addr_t) gp; + else if (sym_value == (grub_addr_t) &_gp_disp_dummy) + { + sym_value = (grub_addr_t) gp - (grub_addr_t) addr; + if (ELF_R_TYPE (rel->r_info) == R_MIPS_LO16) + /* ABI mandates +4 even if partner lui doesn't + immediately precede addiu. */ + sym_value += 4; + } switch (ELF_R_TYPE (rel->r_info)) { case R_MIPS_HI16: @@ -175,7 +200,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) treated as signed. Hence add 0x8000 to compensate. */ value = (*(grub_uint16_t *) addr << 16) - + sym->st_value + 0x8000; + + sym_value + 0x8000; for (rel2 = rel + 1; rel2 < max; rel2++) if (ELF_R_SYM (rel2->r_info) == ELF_R_SYM (rel->r_info) @@ -196,13 +221,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) #ifdef GRUB_CPU_WORDS_BIGENDIAN addr += 2; #endif - *(grub_uint16_t *) addr += (sym->st_value) & 0xffff; + *(grub_uint16_t *) addr += sym_value & 0xffff; break; case R_MIPS_32: - *(grub_uint32_t *) addr += sym->st_value; + *(grub_uint32_t *) addr += sym_value; break; case R_MIPS_GPREL32: - *(grub_uint32_t *) addr = sym->st_value + *(grub_uint32_t *) addr = sym_value + *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp; break; @@ -212,7 +237,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) grub_uint32_t raw; raw = (*(grub_uint32_t *) addr) & 0x3ffffff; value = raw << 2; - value += sym->st_value; + value += sym_value; raw = (value >> 2) & 0x3ffffff; *(grub_uint32_t *) addr = @@ -220,12 +245,36 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) } break; case R_MIPS_GOT16: + if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) + { + Elf_Rel *rel2; + /* Handle partner lo16 relocation. Lower part is + treated as signed. Hence add 0x8000 to compensate. + */ + sym_value += (*(grub_uint16_t *) addr << 16) + + 0x8000; + for (rel2 = rel + 1; rel2 < max; rel2++) + if (ELF_R_SYM (rel2->r_info) + == ELF_R_SYM (rel->r_info) + && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16) + { + sym_value += *(grub_int16_t *) + ((char *) seg->addr + rel2->r_offset +#ifdef GRUB_CPU_WORDS_BIGENDIAN + + 2 +#endif + ); + break; + } + sym_value &= 0xffff0000; + *(grub_uint16_t *) addr = 0; + } case R_MIPS_CALL16: /* FIXME: reuse*/ #ifdef GRUB_CPU_WORDS_BIGENDIAN addr += 2; #endif - *gpptr = sym->st_value + *(grub_uint16_t *) addr; + *gpptr = sym_value + *(grub_uint16_t *) addr; *(grub_uint16_t *) addr = sizeof (grub_uint32_t) * (gpptr - gp); gpptr++; @@ -234,7 +283,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) break; default: { - grub_free (gp); return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("relocation 0x%x is not implemented yet"), ELF_R_TYPE (rel->r_info)); @@ -252,5 +300,6 @@ void grub_arch_dl_init_linker (void) { grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0, 0); + grub_dl_register_symbol ("_gp_disp", &_gp_disp_dummy, 0, 0); } diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 35a11bcf8..709a91afa 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -116,10 +116,10 @@ bsscont: bne $t3, $0, bsscont nop - lui $t1, %hi(grub_main) - addiu $t1, %lo(grub_main) + lui $t9, %hi(grub_main) + addiu $t9, %lo(grub_main) lui $sp, %hi(GRUB_MACHINE_MEMORY_STACK_HIGH) - jr $t1 + jr $t9 addiu $sp, $sp, %lo(GRUB_MACHINE_MEMORY_STACK_HIGH) diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index f61ff00c1..695777ccc 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -1220,6 +1220,15 @@ grub_abort (void) grub_exit (); } +#if defined (__clang__) && !defined (GRUB_UTIL) +/* clang emits references to abort(). */ +void __attribute__ ((noreturn)) +abort (void) +{ + grub_abort (); +} +#endif + void grub_fatal (const char *fmt, ...) { diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c index 8f77b6547..e87423438 100644 --- a/grub-core/kern/powerpc/dl.c +++ b/grub-core/kern/powerpc/dl.c @@ -38,9 +38,26 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_NONE; } +/* For low-endian reverse lis and addr_high as well as ori and addr_low. */ +struct trampoline +{ + grub_uint32_t lis; + grub_uint32_t ori; + grub_uint32_t mtctr; + grub_uint32_t bctr; +}; + +static const struct trampoline trampoline_template = + { + 0x3d800000, + 0x618c0000, + 0x7d8903a6, + 0x4e800420, + }; + #pragma GCC diagnostic ignored "-Wcast-align" -void +grub_err_t grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got) { @@ -59,7 +76,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, break; if (i == e->e_shnum) - return; + return GRUB_ERR_NONE; for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); i < e->e_shnum; @@ -77,26 +94,11 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, } - return; + *tramp *= sizeof (struct trampoline); + + return GRUB_ERR_NONE; } -/* For low-endian reverse lis and addr_high as well as ori and addr_low. */ -struct trampoline -{ - grub_uint32_t lis; - grub_uint32_t ori; - grub_uint32_t mtctr; - grub_uint32_t bctr; -}; - -static const struct trampoline trampoline_template = - { - 0x3d800000, - 0x618c0000, - 0x7d8903a6, - 0x4e800420, - }; - /* Relocate symbols. */ grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) @@ -167,8 +169,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) if (delta << 6 >> 6 != delta) { - COMPILE_TIME_ASSERT (sizeof (struct trampoline) - == GRUB_ARCH_DL_TRAMP_SIZE); grub_memcpy (tptr, &trampoline_template, sizeof (*tptr)); delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr; diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c index 65f09ef53..17c121544 100644 --- a/grub-core/kern/x86_64/dl.c +++ b/grub-core/kern/x86_64/dl.c @@ -100,14 +100,32 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) break; case R_X86_64_PC32: - *addr32 += rel->r_addend + sym->st_value - - (Elf64_Xword) seg->addr - rel->r_offset; + { + grub_int64_t value; + value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value - + (Elf64_Xword) seg->addr - rel->r_offset; + if (value != (grub_int32_t) value) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); + *addr32 = value; + } break; case R_X86_64_32: + { + grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value; + if (value != (grub_uint32_t) value) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); + *addr32 = value; + } + break; case R_X86_64_32S: - *addr32 += rel->r_addend + sym->st_value; - break; + { + grub_int64_t value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value; + if (value != (grub_int32_t) value) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); + *addr32 = value; + } + break; default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, diff --git a/grub-core/kern/x86_64/efi/callwrap.S b/grub-core/kern/x86_64/efi/callwrap.S index 2df95dda1..1337fd9fc 100644 --- a/grub-core/kern/x86_64/efi/callwrap.S +++ b/grub-core/kern/x86_64/efi/callwrap.S @@ -36,94 +36,94 @@ .text FUNCTION(efi_wrap_0) - subq $48, %rsp + subq $40, %rsp call *%rdi - addq $48, %rsp + addq $40, %rsp ret FUNCTION(efi_wrap_1) - subq $48, %rsp + subq $40, %rsp mov %rsi, %rcx call *%rdi - addq $48, %rsp + addq $40, %rsp ret FUNCTION(efi_wrap_2) - subq $48, %rsp + subq $40, %rsp mov %rsi, %rcx call *%rdi - addq $48, %rsp + addq $40, %rsp ret FUNCTION(efi_wrap_3) - subq $48, %rsp + subq $40, %rsp mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $48, %rsp + addq $40, %rsp ret FUNCTION(efi_wrap_4) - subq $48, %rsp + subq $40, %rsp mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $48, %rsp + addq $40, %rsp ret FUNCTION(efi_wrap_5) - subq $48, %rsp + subq $40, %rsp mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $48, %rsp + addq $40, %rsp ret FUNCTION(efi_wrap_6) - subq $64, %rsp - mov 64+8(%rsp), %rax + subq $56, %rsp + mov 56+8(%rsp), %rax mov %rax, 40(%rsp) mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $64, %rsp + addq $56, %rsp ret FUNCTION(efi_wrap_7) - subq $96, %rsp - mov 96+16(%rsp), %rax + subq $88, %rsp + mov 88+16(%rsp), %rax mov %rax, 48(%rsp) - mov 96+8(%rsp), %rax + mov 88+8(%rsp), %rax mov %rax, 40(%rsp) mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $96, %rsp + addq $88, %rsp ret FUNCTION(efi_wrap_10) - subq $96, %rsp - mov 96+40(%rsp), %rax + subq $88, %rsp + mov 88+40(%rsp), %rax mov %rax, 72(%rsp) - mov 96+32(%rsp), %rax + mov 88+32(%rsp), %rax mov %rax, 64(%rsp) - mov 96+24(%rsp), %rax + mov 88+24(%rsp), %rax mov %rax, 56(%rsp) - mov 96+16(%rsp), %rax + mov 88+16(%rsp), %rax mov %rax, 48(%rsp) - mov 96+8(%rsp), %rax + mov 88+8(%rsp), %rax mov %rax, 40(%rsp) mov %r9, 32(%rsp) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx call *%rdi - addq $96, %rsp + addq $88, %rsp ret diff --git a/grub-core/kern/x86_64/efi/startup.S b/grub-core/kern/x86_64/efi/startup.S index f86f01969..9357e5c5d 100644 --- a/grub-core/kern/x86_64/efi/startup.S +++ b/grub-core/kern/x86_64/efi/startup.S @@ -30,6 +30,6 @@ _start: movq %rcx, EXT_C(grub_efi_image_handle)(%rip) movq %rdx, EXT_C(grub_efi_system_table)(%rip) + andq $~0xf, %rsp call EXT_C(grub_main) - ret - + /* Doesn't return. */ diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c index ab74543d1..1d8eaec1a 100644 --- a/grub-core/kern/xen/init.c +++ b/grub-core/kern/xen/init.c @@ -341,6 +341,14 @@ page2offset (grub_uint64_t page) return page << 12; } +#if defined (__x86_64__) && defined (__code_model_large__) +#define MAX_TOTAL_PAGES (1LL << (64 - 12)) +#elif defined (__x86_64__) +#define MAX_TOTAL_PAGES (1LL << (31 - 12)) +#else +#define MAX_TOTAL_PAGES (1LL << (32 - 12)) +#endif + static void map_all_pages (void) { @@ -355,6 +363,9 @@ map_all_pages (void) grub_size_t n_unusable_pages = 0; struct mmu_update m2p_updates[2 * MAX_N_UNUSABLE_PAGES]; + if (total_pages > MAX_TOTAL_PAGES - 4) + total_pages = MAX_TOTAL_PAGES - 4; + grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver)); gnttab_setver.version = 2; diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c index e31afb745..b7c997499 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -125,7 +125,10 @@ void grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in, grub_size_t inlen) { - grub_uint8_t ctx[hash->contextsize]; + GRUB_PROPERLY_ALIGNED_ARRAY (ctx, GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE); + + if (hash->contextsize > sizeof (ctx)) + grub_fatal ("Too large md context"); hash->init (&ctx); hash->write (&ctx, in, inlen); hash->final (&ctx); diff --git a/grub-core/lib/libgcrypt/mpi/longlong.h b/grub-core/lib/libgcrypt/mpi/longlong.h index 8c8260e51..6f8dda7df 100644 --- a/grub-core/lib/libgcrypt/mpi/longlong.h +++ b/grub-core/lib/libgcrypt/mpi/longlong.h @@ -749,7 +749,7 @@ extern USItype __udiv_qrnnd (); ************** MIPS ***************** ***************************************/ #if defined (__mips__) && W_TYPE_SIZE == 32 -#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +#if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) #define umul_ppmm(w1, w0, u, v) \ do { \ UDItype _r; \ diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c index ab1b4e59e..7263cbc04 100644 --- a/grub-core/lib/reed_solomon.c +++ b/grub-core/lib/reed_solomon.c @@ -69,16 +69,23 @@ typedef grub_uint8_t gf_single_t; #define GF_POLYNOMIAL 0x1d #define GF_INVERT2 0x8e #if defined (STANDALONE) && !defined (TEST) -static gf_single_t * const gf_powx __attribute__ ((section(".text"))) = (void *) 0x100000; -static gf_single_t * const gf_powx_inv __attribute__ ((section(".text"))) = (void *) 0x100200; -static int *const chosenstat __attribute__ ((section(".text"))) = (void *) 0x100300; -static gf_single_t *const sigma __attribute__ ((section(".text"))) = (void *) 0x100700; -static gf_single_t *const errpot __attribute__ ((section(".text"))) = (void *) 0x100800; -static int *const errpos __attribute__ ((section(".text"))) = (void *) 0x100900; -static gf_single_t *const sy __attribute__ ((section(".text"))) = (void *) 0x100d00; -static gf_single_t *const mstat __attribute__ ((section(".text"))) = (void *) 0x100e00; -static gf_single_t *const errvals __attribute__ ((section(".text"))) = (void *) 0x100f00; -static gf_single_t *const eqstat __attribute__ ((section(".text"))) = (void *) 0x101000; + +#ifdef __APPLE__ +#define ATTRIBUTE_TEXT __attribute__ ((section("_text,_text"))) +#else +#define ATTRIBUTE_TEXT __attribute__ ((section(".text"))) +#endif + +static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000; +static gf_single_t * const gf_powx_inv ATTRIBUTE_TEXT = (void *) 0x100200; +static int *const chosenstat ATTRIBUTE_TEXT = (void *) 0x100300; +static gf_single_t *const sigma ATTRIBUTE_TEXT = (void *) 0x100700; +static gf_single_t *const errpot ATTRIBUTE_TEXT = (void *) 0x100800; +static int *const errpos ATTRIBUTE_TEXT = (void *) 0x100900; +static gf_single_t *const sy ATTRIBUTE_TEXT = (void *) 0x100d00; +static gf_single_t *const mstat ATTRIBUTE_TEXT = (void *) 0x100e00; +static gf_single_t *const errvals ATTRIBUTE_TEXT = (void *) 0x100f00; +static gf_single_t *const eqstat ATTRIBUTE_TEXT = (void *) 0x101000; /* Next available address: (void *) 0x112000. */ #else diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c index 4f17c8b53..a77efe81d 100644 --- a/grub-core/mmap/efi/mmap.c +++ b/grub-core/mmap/efi/mmap.c @@ -184,8 +184,8 @@ grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type) return 0; b = grub_efi_system_table->boot_services; - address = start & (~0x3ffULL); - pages = (end - address + 0x3ff) >> 12; + address = start & (~0xfffULL); + pages = (end - address + 0xfff) >> 12; status = efi_call_2 (b->free_pages, address, pages); if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND) { @@ -263,7 +263,7 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)), atype = GRUB_EFI_ALLOCATE_ANY_PAGES; #endif - pages = (size + 0x3ff) >> 12; + pages = (size + 0xfff) >> 12; status = efi_call_4 (b->allocate_pages, atype, make_efi_memtype (type), pages, &address); if (status != GRUB_EFI_SUCCESS) diff --git a/grub-core/normal/progress.c b/grub-core/normal/progress.c deleted file mode 100644 index 77a64b1bb..000000000 --- a/grub-core/normal/progress.c +++ /dev/null @@ -1,21 +0,0 @@ - -static void -grub_file_progress_hook_real (grub_disk_addr_t sector, - unsigned offset, unsigned length, - void *data) -{ - grub_file_t file = data; - file->progress_offset += length; - show_progress (file->progress_offset, file->size); -} - - -GRUB_MOD_INIT (progress) -{ - grub_file_progress_hook = grub_file_progress_hook_real; -} - -GRUB_MOD_FINI (progress) -{ - grub_file_progress_hook = 0; -} diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c index 65c93f150..dc296c98b 100644 --- a/grub-core/osdep/unix/platform.c +++ b/grub-core/osdep/unix/platform.c @@ -31,11 +31,11 @@ static char * get_ofpathname (const char *dev) { - char *ret = xmalloc (2 * PATH_MAX); - char *end = ret + 2 * PATH_MAX - 1; + size_t alloced = 4096; + char *ret = xmalloc (alloced); + size_t offset = 0; int fd; pid_t pid; - char *ptr = ret; pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd); if (!pid) @@ -45,13 +45,29 @@ get_ofpathname (const char *dev) if (!fp) goto fail; - while (!feof (fp) && ptr < end) + while (!feof (fp)) { size_t r; - r = fread (ptr, 1, end - ptr, fp); - ptr += r; + if (alloced == offset) + { + alloced *= 2; + ret = xrealloc (ret, alloced); + } + r = fread (ret + offset, 1, alloced - offset, fp); + offset += r; } + if (offset > 0 && ret[offset - 1] == '\n') + offset--; + if (offset > 0 && ret[offset - 1] == '\r') + offset--; + if (alloced == offset) + { + alloced++; + ret = xrealloc (ret, alloced); + } + ret[offset] = '\0'; + fclose (fp); return ret; diff --git a/grub-core/term/arc/console.c b/grub-core/term/arc/console.c index 330a9f7ee..c944ffc2d 100644 --- a/grub-core/term/arc/console.c +++ b/grub-core/term/arc/console.c @@ -114,8 +114,8 @@ check_is_serial (void) isn't critical. */ if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length - >= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1) - - (char *) GRUB_ARC_FIRMWARE_VECTOR) + >= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1) + - (char *) GRUB_ARC_FIRMWARE_VECTOR) && GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable) consout = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("ConsoleOut"); if (!consout) @@ -136,8 +136,8 @@ set_console_dimensions (void) } if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length - >= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus + 1) - - (char *) GRUB_ARC_FIRMWARE_VECTOR) + >= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus + 1) + - (char *) GRUB_ARC_FIRMWARE_VECTOR) && GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus) info = GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus (GRUB_ARC_STDOUT); if (info) diff --git a/include/grub/crypto.h b/include/grub/crypto.h index d7ba697c6..3739c6a4b 100644 --- a/include/grub/crypto.h +++ b/include/grub/crypto.h @@ -88,6 +88,7 @@ enum gcry_cipher_modes /* Don't rely on this. Check! */ #define GRUB_CRYPTO_MAX_MDLEN 64 #define GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE 16 +#define GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE 256 /* Type for the cipher_setkey function. */ typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c, diff --git a/include/grub/dl.h b/include/grub/dl.h index 3dc88c75c..11fc77568 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -179,7 +179,7 @@ struct grub_dl Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); -#if defined (__ia64__) || defined (__powerpc__) +#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) void *got; void *tramp; #endif @@ -243,23 +243,21 @@ void grub_arch_dl_init_linker (void); #define GRUB_IA64_DL_TRAMP_SIZE 48 #define GRUB_IA64_DL_GOT_ALIGN 16 -void +grub_err_t grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #if defined (__ia64__) #define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN #define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN -#define GRUB_ARCH_DL_TRAMP_SIZE GRUB_IA64_DL_TRAMP_SIZE #define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size #else -void +grub_err_t grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #endif -#ifdef __powerpc__ -#define GRUB_ARCH_DL_TRAMP_SIZE 16 +#if defined (__powerpc__) || defined (__mips__) #define GRUB_ARCH_DL_TRAMP_ALIGN 4 #define GRUB_ARCH_DL_GOT_ALIGN 4 #endif diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h index 2859b1d7c..1501772ac 100644 --- a/include/grub/i386/coreboot/memory.h +++ b/include/grub/i386/coreboot/memory.h @@ -28,14 +28,8 @@ #include #endif -#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 -#define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) -#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE 0x10000 - -#define GRUB_MEMORY_MACHINE_LOWER_USABLE 0x9fc00 /* 640 kiB - 1 kiB */ - -#define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */ -#define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START +#include +#include #ifndef ASM_FILE diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h index 582226eed..c9b13288f 100644 --- a/include/grub/i386/memory.h +++ b/include/grub/i386/memory.h @@ -28,6 +28,9 @@ #define GRUB_MEMORY_CPU_AMD64_MSR 0xc0000080 #define GRUB_MEMORY_CPU_AMD64_MSR_ON 0x00000100 +#define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */ +#define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START + #ifndef ASM_FILE #define GRUB_MMAP_MALLOC_LOW 1 diff --git a/include/grub/i386/memory_raw.h b/include/grub/i386/memory_raw.h new file mode 100644 index 000000000..1292ba7db --- /dev/null +++ b/include/grub/i386/memory_raw.h @@ -0,0 +1,58 @@ +/* memory_raw.h - describe the memory map on qemu/coreboot/multiboot/pc */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007,2008,2009,2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_CPU_RAW_HEADER +#define GRUB_MEMORY_CPU_RAW_HEADER 1 + +/* The scratch buffer used in real mode code. */ +#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 +#define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) +#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE 0x9000 + +/* The real mode stack. */ +#define GRUB_MEMORY_MACHINE_REAL_STACK (0x2000 - 0x10) + +/* The size of the protect mode stack. */ +#define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE 0xf000 + +/* The protected mode stack. */ +#define GRUB_MEMORY_MACHINE_PROT_STACK \ + (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \ + + GRUB_MEMORY_MACHINE_PROT_STACK_SIZE - 0x10) + +/* The memory area where GRUB uses its own purpose. This part is not added + into free memory for dynamic allocations. */ +#define GRUB_MEMORY_MACHINE_RESERVED_START \ + GRUB_MEMORY_MACHINE_SCRATCH_ADDR +#define GRUB_MEMORY_MACHINE_RESERVED_END \ + (GRUB_MEMORY_MACHINE_PROT_STACK + 0x10) + +/* The code segment of the protected mode. */ +#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 + +/* The data segment of the protected mode. */ +#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG 0x10 + +/* The code segment of the pseudo real mode. */ +#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG 0x18 + +/* The data segment of the pseudo real mode. */ +#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG 0x20 + +#endif diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 401c837fa..d0c5c202e 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -28,32 +28,10 @@ #endif #include +#include #include -/* The scratch buffer used in real mode code. */ -#define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 -#define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) -#define GRUB_MEMORY_MACHINE_SCRATCH_SIZE 0x10000 - -/* The real mode stack. */ -#define GRUB_MEMORY_MACHINE_REAL_STACK (0x2000 - 0x10) - -/* The size of the protect mode stack. */ -#define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE 0x8000 - -/* The protected mode stack. */ -#define GRUB_MEMORY_MACHINE_PROT_STACK \ - (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \ - + GRUB_MEMORY_MACHINE_PROT_STACK_SIZE - 0x10) - -/* The memory area where GRUB uses its own purpose. This part is not added - into free memory for dynamic allocations. */ -#define GRUB_MEMORY_MACHINE_RESERVED_START \ - GRUB_MEMORY_MACHINE_SCRATCH_ADDR -#define GRUB_MEMORY_MACHINE_RESERVED_END \ - (GRUB_MEMORY_MACHINE_PROT_STACK + 0x10) - /* The area where GRUB is decompressed at early startup. */ #define GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR 0x100000 @@ -63,18 +41,6 @@ /* The address where another boot loader is loaded. */ #define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 -/* The code segment of the protected mode. */ -#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 - -/* The data segment of the protected mode. */ -#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG 0x10 - -/* The code segment of the pseudo real mode. */ -#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG 0x18 - -/* The data segment of the pseudo real mode. */ -#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG 0x20 - #define GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR 0x400 #ifndef ASM_FILE diff --git a/include/grub/i386/qemu/memory.h b/include/grub/i386/qemu/memory.h index f152cd782..8dd6f7c8c 100644 --- a/include/grub/i386/qemu/memory.h +++ b/include/grub/i386/qemu/memory.h @@ -1,36 +1 @@ -/* memory.h - describe the memory map */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef _GRUB_MEMORY_MACHINE_HEADER -#define _GRUB_MEMORY_MACHINE_HEADER 1 - -#include #include - -#ifndef ASM_FILE -#include -#include -#endif - -#define GRUB_MEMORY_MACHINE_LOWER_USABLE 0x9fc00 /* 640 kiB - 1 kiB */ - -#define GRUB_MEMORY_MACHINE_UPPER_START 0x100000 /* 1 MiB */ -#define GRUB_MEMORY_MACHINE_LOWER_SIZE GRUB_MEMORY_MACHINE_UPPER_START - -#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */ diff --git a/include/grub/misc.h b/include/grub/misc.h index 3d7147797..d80da3349 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -421,6 +421,10 @@ void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); void grub_reboot (void) __attribute__ ((noreturn)); #endif +#if defined (__clang__) && !defined (GRUB_UTIL) +void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void); +#endif + #ifdef GRUB_MACHINE_PCBIOS /* Halt the system, using APM if possible. If NO_APM is true, don't * use APM even if it is available. */ diff --git a/include/grub/symbol.h b/include/grub/symbol.h index 89883a362..ed19f70db 100644 --- a/include/grub/symbol.h +++ b/include/grub/symbol.h @@ -27,6 +27,12 @@ /* Add an underscore to a C symbol in assembler code if needed. */ #ifndef GRUB_UTIL +#ifdef __APPLE__ +#define MACRO_DOLLAR(x) $$ ## x +#else +#define MACRO_DOLLAR(x) $ ## x +#endif + #if HAVE_ASM_USCORE #ifdef ASM_FILE # define EXT_C(sym) _ ## sym diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 0aead0a8a..744e2f4e8 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -87,6 +87,8 @@ enum grub_install_plat GRUB_INSTALL_PLATFORM_ARM_EFI, GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_I386_XEN, + GRUB_INSTALL_PLATFORM_X86_64_XEN, GRUB_INSTALL_PLATFORM_ARM64_EFI, GRUB_INSTALL_PLATFORM_MAX }; diff --git a/tests/btrfs_test.in b/tests/btrfs_test.in new file mode 100644 index 000000000..c55d9477f --- /dev/null +++ b/tests/btrfs_test.in @@ -0,0 +1,24 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.btrfs >/dev/null 2>&1; then + echo "mkfs.btrfs not installed; cannot test btrfs." + exit 77 +fi + +"@builddir@/grub-fs-tester" btrfs +"@builddir@/grub-fs-tester" btrfs_zlib +"@builddir@/grub-fs-tester" btrfs_lzo +"@builddir@/grub-fs-tester" btrfs_raid0 +"@builddir@/grub-fs-tester" btrfs_raid1 +"@builddir@/grub-fs-tester" btrfs_single +"@builddir@/grub-fs-tester" btrfs_raid10 diff --git a/tests/cpio_test.in b/tests/cpio_test.in new file mode 100644 index 000000000..0b09db549 --- /dev/null +++ b/tests/cpio_test.in @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +if ! which cpio >/dev/null 2>&1; then + echo "cpio not installed; cannot test cpio." + exit 77 +fi + +"@builddir@/grub-fs-tester" cpio_bin +"@builddir@/grub-fs-tester" cpio_odc +"@builddir@/grub-fs-tester" cpio_newc +"@builddir@/grub-fs-tester" cpio_crc +"@builddir@/grub-fs-tester" cpio_ustar +"@builddir@/grub-fs-tester" cpio_hpbin +"@builddir@/grub-fs-tester" cpio_hpodc diff --git a/tests/exfat_test.in b/tests/exfat_test.in new file mode 100644 index 000000000..fc1a0fe5e --- /dev/null +++ b/tests/exfat_test.in @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.exfat >/dev/null 2>&1; then + echo "mkfs.exfat not installed; cannot test exFAT." + exit 77 +fi + +"@builddir@/grub-fs-tester" exfat diff --git a/tests/ext234_test.in b/tests/ext234_test.in new file mode 100644 index 000000000..8910b716f --- /dev/null +++ b/tests/ext234_test.in @@ -0,0 +1,31 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.ext2 >/dev/null 2>&1; then + echo "mkfs.ext2 not installed; cannot test ext2." + exit 77 +fi + +if ! which mkfs.ext3 >/dev/null 2>&1; then + echo "mkfs.ext3 not installed; cannot test ext3." + exit 77 +fi + +if ! which mkfs.ext4 >/dev/null 2>&1; then + echo "mkfs.ext4 not installed; cannot test ext4." + exit 77 +fi + +"@builddir@/grub-fs-tester" ext2_old +"@builddir@/grub-fs-tester" ext2 +"@builddir@/grub-fs-tester" ext3 +"@builddir@/grub-fs-tester" ext4 diff --git a/tests/fat_test.in b/tests/fat_test.in new file mode 100644 index 000000000..1d132b517 --- /dev/null +++ b/tests/fat_test.in @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.vfat >/dev/null 2>&1; then + echo "mkfs.vfat not installed; cannot test FAT." + exit 77 +fi + +"@builddir@/grub-fs-tester" vfat16a +"@builddir@/grub-fs-tester" vfat12a +"@builddir@/grub-fs-tester" vfat12 +"@builddir@/grub-fs-tester" vfat16 +"@builddir@/grub-fs-tester" vfat32 diff --git a/tests/hfs_test.in b/tests/hfs_test.in new file mode 100644 index 000000000..e3e88f190 --- /dev/null +++ b/tests/hfs_test.in @@ -0,0 +1,23 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.hfs >/dev/null 2>&1; then + echo "mkfs.hfs not installed; cannot test HFS." + exit 77 +fi + +if ! modprobe mac-roman; then + echo "no mac-roman support; cannot test HFS." + exit 77 +fi + +"@builddir@/grub-fs-tester" hfs diff --git a/tests/hfsplus_test.in b/tests/hfsplus_test.in new file mode 100644 index 000000000..f947c4a44 --- /dev/null +++ b/tests/hfsplus_test.in @@ -0,0 +1,20 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.hfsplus >/dev/null 2>&1; then + echo "mkfs.hfsplus not installed; cannot test hfsplus." + exit 77 +fi + +"@builddir@/grub-fs-tester" hfsplus +"@builddir@/grub-fs-tester" hfsplus_casesens +"@builddir@/grub-fs-tester" hfsplus_wrap diff --git a/tests/iso9660_test.in b/tests/iso9660_test.in new file mode 100644 index 000000000..fdcc9e124 --- /dev/null +++ b/tests/iso9660_test.in @@ -0,0 +1,15 @@ +#!/bin/sh + +set -e + +if ! which xorriso >/dev/null 2>&1; then + echo "xorriso not installed; cannot test iso9660." + exit 77 +fi + +"@builddir@/grub-fs-tester" joliet +"@builddir@/grub-fs-tester" rockridge +"@builddir@/grub-fs-tester" rockridge_joliet +"@builddir@/grub-fs-tester" joliet_1999 +"@builddir@/grub-fs-tester" rockridge_1999 +"@builddir@/grub-fs-tester" rockridge_joliet_1999 \ No newline at end of file diff --git a/tests/jfs_test.in b/tests/jfs_test.in new file mode 100644 index 000000000..c2e5ecedd --- /dev/null +++ b/tests/jfs_test.in @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.jfs >/dev/null 2>&1; then + echo "mkfs.jfs not installed; cannot test JFS." + exit 77 +fi + +"@builddir@/grub-fs-tester" jfs diff --git a/tests/minixfs_test.in b/tests/minixfs_test.in new file mode 100644 index 000000000..8075ba890 --- /dev/null +++ b/tests/minixfs_test.in @@ -0,0 +1,25 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.minix >/dev/null 2>&1; then + echo "mkfs.minix not installed; cannot test minixfs." + exit 77 +fi + +if ! mkfs.minix -h | grep -- -v > /dev/null; then + echo "mkfs.minix doesn't support minix3fs; cannot test minix*fs." + exit 77 +fi + +"@builddir@/grub-fs-tester" minix +"@builddir@/grub-fs-tester" minix2 +"@builddir@/grub-fs-tester" minix3 diff --git a/tests/nilfs2_test.in b/tests/nilfs2_test.in new file mode 100644 index 000000000..780b60ec1 --- /dev/null +++ b/tests/nilfs2_test.in @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.nilfs2 >/dev/null 2>&1; then + echo "mkfs.nilfs2 not installed; cannot test nilfs2." + exit 77 +fi + +"@builddir@/grub-fs-tester" nilfs2 diff --git a/tests/ntfs_test.in b/tests/ntfs_test.in new file mode 100644 index 000000000..6bf09e691 --- /dev/null +++ b/tests/ntfs_test.in @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.ntfs >/dev/null 2>&1; then + echo "mkfs.ntfs not installed; cannot test ntfs." + exit 77 +fi + +"@builddir@/grub-fs-tester" ntfs +"@builddir@/grub-fs-tester" ntfscomp \ No newline at end of file diff --git a/tests/reiserfs_test.in b/tests/reiserfs_test.in new file mode 100644 index 000000000..678efe7b3 --- /dev/null +++ b/tests/reiserfs_test.in @@ -0,0 +1,20 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.reiserfs >/dev/null 2>&1; then + echo "mkfs.reiserfs not installed; cannot test reiserfs." + exit 77 +fi + +"@builddir@/grub-fs-tester" reiserfs +"@builddir@/grub-fs-tester" reiserfs_old + diff --git a/tests/romfs_test.in b/tests/romfs_test.in new file mode 100644 index 000000000..83e09315a --- /dev/null +++ b/tests/romfs_test.in @@ -0,0 +1,10 @@ +#!/bin/sh + +set -e + +if ! which genromfs >/dev/null 2>&1; then + echo "genromfs not installed; cannot test romfs." + exit 77 +fi + +"@builddir@/grub-fs-tester" romfs diff --git a/tests/squashfs_test.in b/tests/squashfs_test.in new file mode 100644 index 000000000..ec34e0108 --- /dev/null +++ b/tests/squashfs_test.in @@ -0,0 +1,12 @@ +#!/bin/sh + +set -e + +if ! which mksquashfs >/dev/null 2>&1; then + echo "mksquashfs not installed; cannot test squashfs." + exit 77 +fi + +"@builddir@/grub-fs-tester" squash4_gzip +"@builddir@/grub-fs-tester" squash4_xz +"@builddir@/grub-fs-tester" squash4_lzo diff --git a/tests/tar_test.in b/tests/tar_test.in new file mode 100644 index 000000000..46ba3bce2 --- /dev/null +++ b/tests/tar_test.in @@ -0,0 +1,10 @@ +#!/bin/sh + +set -e + +if ! which tar >/dev/null 2>&1; then + echo "tar not installed; cannot test tar." + exit 77 +fi + +"@builddir@/grub-fs-tester" tarfs diff --git a/tests/udf_test.in b/tests/udf_test.in new file mode 100644 index 000000000..fe244e2bd --- /dev/null +++ b/tests/udf_test.in @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkudffs >/dev/null 2>&1; then + echo "mkudffs not installed; cannot test UDF." + exit 77 +fi + +"@builddir@/grub-fs-tester" udf + diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in new file mode 100644 index 000000000..9e8aa08cf --- /dev/null +++ b/tests/util/grub-fs-tester.in @@ -0,0 +1,1427 @@ +#!/bin/bash + +set -e + +fs="$1" + +GRUBFSTEST="@builddir@/grub-fstest" + +tempdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + +# This wrapper is to ease insertion of valgrind or time statistics +run_it () { + "$GRUBFSTEST" "$@" +} + +run_grubfstest () { + run_it -c $NEED_IMAGES_N "${NEED_IMAGES[@]}" "$@" +} + +# OS LIMITATION: GNU/Linux has no AFS support, so we use a premade image and a reference tar file. I.a. no multiblocksize test + +MINLOGSECSIZE=9 +MAXLOGSECSIZE=9 +case x"$fs" in + xntfs*) + MINLOGSECSIZE=8 + MAXLOGSECSIZE=12;; + xvfat*|xmsdos*) + MINLOGSECSIZE=9 + # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096 + MAXLOGSECSIZE=12;; + xext*) + MINLOGSECSIZE=8 + MAXLOGSECSIZE=12;; + xbtrfs*) + MINLOGSECSIZE=8 + # OS LIMITATION: It could go up to 32768 but Linux rejects sector sizes > 4096 + MAXLOGSECSIZE=12;; + xxfs) + MINLOGSECSIZE=9 + # OS LIMITATION: GNU/Linux doesn't accept > 4096 + MAXLOGSECSIZE=12;; + xzfs*) + # OS LIMITATION: zfs-fuse hangs when creating zpool with sectors <=256B. + MINLOGSECSIZE=9 + # OS LIMITATION: zfs-fuse fails with >= 32K sectors. + # OS limitation: zfs-fuse always uses ashift=9 with loop devices + MAXLOGSECSIZE=9;; +esac +for ((LOGSECSIZE=MINLOGSECSIZE;LOGSECSIZE<=MAXLOGSECSIZE;LOGSECSIZE=LOGSECSIZE + 1)); do + SECSIZE="$((1 << LOGSECSIZE))" + MINBLKSIZE=512 + MAXBLKSIZE=512 + BLKSTEP=0 + case x"$fs" in + xntfs*) + MINBLKSIZE=$SECSIZE + MAXBLKSIZE=65536 + if [ x"$SECSIZE" = x256 ]; then + MINBLKSIZE=512 + MAXBLKSIZE=32768 + fi + ;; + xvfat* | xmsdos*) + MINBLKSIZE=$SECSIZE + MAXBLKSIZE=$((128*SECSIZE)) + ;; + xexfat*) + MINBLKSIZE=$SECSIZE + # It could go further but it requires more and more space + MAXBLKSIZE=8286208 + ;; + xhfs) + MINBLKSIZE=512 + # OS LIMITATION: should be 1048576 but linux hangs on unmnount with + # >= 524288 + MAXBLKSIZE=262144 + ;; + xhfsplus | xhfsplus_casesens | xhfsplus_wrap) + MINBLKSIZE=512 + MAXBLKSIZE=1048576 + ;; + xnilfs2) + MINBLKSIZE=1024 + MAXBLKSIZE=4096 + ;; + xsfs*) + MINBLKSIZE=512 + MAXBLKSIZE=4096 + ;; + xaffs | xaffs_intl) + MINBLKSIZE=512 + MAXBLKSIZE=4096 + ;; + xreiserfs*) + MINBLKSIZE=512 + # OS LIMITATION: 8192 isn't supported. + MAXBLKSIZE=4096 + ;; + x"mdraid"*) + MINBLKSIZE=4096 + # OS LIMITATION: Linux oopses with >=32768K + MAXBLKSIZE=$((16384*1024)) + ;; + x"lvm_raid4" | x"lvm_raid5" | x"lvm_raid6") + # OS LIMITATION: Linux crashes with less than 16384 + MINBLKSIZE=16384 + # Could go further but what's the point? + MAXBLKSIZE=$((65536*1024)) + ;; + x"lvm_mirrorall") + MINBLKSIZE=2048 + # Could go further but what's the point? + MAXBLKSIZE=$((65536*1024)) + ;; + x"lvm_mirror1") + MINBLKSIZE=4096 + # Could go further but what's the point? + MAXBLKSIZE=$((65536*1024)) + ;; + x"lvm_stripe") + MINBLKSIZE=4096 + # Could go further but what's the point? + MAXBLKSIZE=$((65536*1024)) + ;; + x"lvm"*) + MINBLKSIZE=1024 + # Could go further but what's the point? + MAXBLKSIZE=$((65536*1024)) + ;; + xext*) + MINBLKSIZE=1024 + if [ $MINBLKSIZE -lt $SECSIZE ]; then + MINBLKSIZE=$SECSIZE + fi + MAXBLKSIZE=4096 + ;; + xsquash*) + MINBLKSIZE=4096 + MAXBLKSIZE=1048576;; + xxfs) + MINBLKSIZE=$SECSIZE + # OS Limitation: GNU/Linux doesn't accept > 4096 + MAXBLKSIZE=4096;; + xudf) + MINBLKSIZE=1024 + MAXBLKSIZE=4096;; + xbfs) + MINBLKSIZE=1024 + MAXBLKSIZE=8192;; + xufs*) + MINBLKSIZE=4096 + # OS Limitation: Linux rejects 65536 blocks. + MAXBLKSIZE=32768;; + xminix3) + # OS LIMITATION: Linux rejects non-power-of-two blocks. + # OS LIMITATION: Linux rejects > 4096. + MINBLKSIZE=1024 + MAXBLKSIZE=4096;; + esac + for ((BLKSIZE=MINBLKSIZE;BLKSIZE<=MAXBLKSIZE;BLKSIZE=BLKSTEP?BLKSIZE+BLKSTEP:2*BLKSIZE)); do + MAXDEVICES=1 + MINDEVICES=1 + export fs + case x"$fs" in + x"zfs_raidz" | x"zfs_stripe" | x"zfs_mirror" | xbtrfs_raid0 \ + | xbtrfs_raid1 | x"mdraid"*"_raid4" | x"mdraid"*"_raid5" \ + | x"mdraid"*"_linear" \ + | x"mdraid"*"_raid10" | xlvm_mirror1 | xlvm_mirrorall) + MINDEVICES=2 + MAXDEVICES=7 + ;; + xbtrfs_raid10) + MINDEVICES=4 + MAXDEVICES=7 + ;; + x"zfs_raidz2"| xlvm_raid5 | xlvm_raid4) + MINDEVICES=3 + MAXDEVICES=7;; + x"zfs_raidz3" | x"mdraid"*"_raid6") + MINDEVICES=4 + MAXDEVICES=7;; + xlvm_raid6) + MINDEVICES=5 + MAXDEVICES=7;; + x"mdraid"*"_raid0" | x"mdraid"*"_raid1" | x"lvm" | xlvm_stripe) + MINDEVICES=1 + MAXDEVICES=7;; + esac + + for ((NDEVICES=MINDEVICES; NDEVICES <= MAXDEVICES; NDEVICES++)); do + export NDEVICES + unset FSIMAGES + for ((i=0; i < NDEVICES; i++)); do + FSIMAGES[i]="${tempdir}/${fs}_${SECSIZE}_${BLKSIZE}_${NDEVICES}_$i.img" + done + export FSIMAGES + unset NEED_IMAGES; + + case x$fs in + # RAID 1 has to work with even one device of the set. + xzfs_mirror | x"mdraid"*"_raid1" | xlvm_mirrorall) + NEED_IMAGES_N=1;; + # Degrade raidz by removing 3 devices + xzfs_raidz3) + NEED_IMAGES_N=$((NDEVICES-3));; + # Degrade raidz by removing 2 devices + xzfs_raidz2 | x"mdraid"*"_raid6" | x"lvm_raid6") + NEED_IMAGES_N=$((NDEVICES-2));; + # Degrade raidz and btrfs RAID1 by removing one device + xbtrfs_raid1 | xbtrfs_raid10 | xzfs_raidz | x"mdraid"*"_raid4" \ + | x"mdraid"*"_raid5" | x"mdraid"*"_raid10" | xlvm_mirror1 \ + | x"lvm_raid4" | x"lvm_raid5") + NEED_IMAGES_N=$((NDEVICES-1));; + *) + NEED_IMAGES_N=$NDEVICES;; + esac + for ((i=0;i < NEED_IMAGES_N; i++)); do + NEED_IMAGES[i]="${FSIMAGES[i]}"; + done + export NEED_IMAGES_N + export NEED_IMAGES + + MNTPOINTRO="${tempdir}/${fs}_ro" + MNTPOINTRW="${tempdir}/${fs}_rw" + MOUNTOPTS="" + MOUNTFS="$fs" + MASTER="${tempdir}/master" + FSLABEL="grub_;/testé莭莽茝😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfewceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoirefoireoifoijfoirereoireoivoioirevoinvoinreoinvnoieoinreoinveoinveoinreoinvoineoinoinoineoinernoiveoinvreoiioewdioewoirvnoireoivfoirewfewoifoijewoijfoijewfoijfewoijoijoijoijoijoijoijfew" + CFILESN=1 + if test -f /usr/share/dict/american-english; then + CFILESSRC[0]="/usr/share/dict/american-english" + else + CFILESSRC[0]="/usr/share/dict/linux.words" + fi + case x"$fs" in + # FS LIMITATION: 8.3 names + xmsdos*) + CFILES[0]="american.eng";; + xiso9660) + CFILES[0]="american_english";; + *) + CFILES[0]="american-english";; + esac + # OS LIMITATION: Limited by NAME_MAX (usually 255) in GNU/Linux + LONGNAME="qwertzuiopasdfghjklyxcvbnm1234567890qwertzuiopasdfghjklyxcvbnm1234567890oiewqfiewioqoiqoiurqruewqoiuwoieoiiuewqroreqiufieiuwrnureweriuvceoiroiewqoiricdsalkcndsakfirefoiwqeoircorejwoijfreoijojoiewjfwnfcoirenfoirefnreoifenoiwfnoirewoifoiwqwoieqfrqwioerijewr" + rm -rf "$MASTER" + + case x"$fs" in + # FS LIMITATION: HFS+ label is at most 255 UTF-16 chars + # OS LIMITATION: Linux HFS+ tools check UTF-8 length and don't + # handle out-of-BMP characters + x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap") + FSLABEL="grub_;/testé䏌䐓䏕киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoifoiq" + ;; + # FS LIMITATION: btrfs label is at most 255 UTF-8 chars + x"btrfs"*) + FSLABEL="grub_;/testé莭莽😁киритi urewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvnirewnivrewiuvcrewvnuewvrrrewniuerwreiuviurewiuviurewnuvewnvrenurnunuvrevuurerejiremvreijnvcreivire nverivnreivrevnureiorfnfrvoeoiroireoireoifrefoieroifoireoif";; + + # FS LIMITATION: exfat is at most 15 UTF-16 chars + x"exfat") + FSLABEL="géт ;/莭莽😁кир";; + # FS LIMITATION: ntfs label is at most ?? UTF-16 chars + x"ntfs"*) + FSLABEL="grub_;/testéтi u莭😁茝кириrewfceniuewruevrewnuuireurevueurnievrewfnerfcnevirivinrewvniwnivrewiuvcrewvnuewvrrrewniureifiuewifjiww";; + # FS LIMITATION: nilfs2 label is at most 80 UTF-8 characters + x"nilfs2") + FSLABEL="grub_;/testéтi u😁莽茝кириrewfceniuewruevrewnuuireurevueurnievrewfne";; + # FS LIMITATION: afs and iso9660 label is at most 32 UTF-8 characters + x"afs" | xiso9660 | xrockridge | xrockridge_joliet\ + | xiso9660_1999 | xrockridge_1999 | xrockridge_joliet_1999) + FSLABEL="gr_;/é莭莽😁кирит u";; + # FS LIMITATION: bfs label is at most 32 UTF-8 characters + # OS LIMITATION: bfs label can't contain ; or / + x"bfs") + FSLABEL="grub_é莭莽😁кирит u";; + # FS LIMITATION: Joliet label is at most 16 UTF-16 characters + # OS LIMITATION: xorriso doesn't handle out-of-BMP characters + xjoliet | xjoliet_1999) + FSLABEL="g;/_é䏌䐓䏕䎛䎾䏴кит u" + #FSLABEL="g;/_é莭莽😁кит u" + ;; + # FS LIMITATION: reiserfs, extN and jfs label is at most 16 UTF-8 characters + x"reiserfs_old" | x"reiserfs" | x"ext2" | xext2_old | x"ext3" | x"ext4" | x"lvm"* | x"mdraid"* | x"jfs" | x"jfs_caseins") + FSLABEL="g;/éт 莭😁";; + # FS LIMITATION: No underscore, space, semicolon, slash or international characters in UFS* in label. Limited to 32 UTF-8 characters + x"ufs1" | x"ufs1_sun" | x"ufs2") + FSLABEL="grubtest""ieurrucnenreeiurueurewf";; + # FS LIMITATION: XFS label is at most 12 UTF-8 characters + x"xfs") + FSLABEL="géт 😁к";; + # FS LIMITATION: FAT labels limited to 11 characters, no international characters or lowercase + x"vfat"* | xmsdos*) + FSLABEL="GRUBTEST ;_";; + # FS LIMITATION: AFFS is latin1. At most 29 characters + x"affs" | xaffs_intl) + FSLABEL="grub_tt? #*w;/e£@¡¤½¾{[]}<>.,";; + # FS LIMITATION: SFS is latin1. At most 30 characters + x"sfs"*) + FSLABEL="GRUB tt öäüé;/àèç åø¿ª©þð׫»µ¬";; + # FS LIMITATION: HFS is Mac-Roman. At most 27 characters + x"hfs") + FSLABEL="grub_t;/estéàèèéie fiucnree";; + # FS LIMITATION: UDF label is either up to 127 latin1 characters or 63 UTF-16 ones + # OS LIMITATION: Linux UDF tools force ASCII label ... + x"udf") + FSLABEL="grub_;/testurewfceniuewruevrewnuuireurevueurnievr";; + # FS LIMITATION: ZFS doesn't accept non-ASCII in label + # FIXME: since this is used as a path component for mount it's very limited in length + xzfs_* | xzfs) + FSLABEL="grub_testieufiue r";; + esac + case x"$fs" in + xmdraid*) + DISKSIZE=314572800;; + xlvm*) + LVMBLKMUL=$(((5800 * 1048576) / (8 * BLKSIZE * NDEVICES))) + DISKSIZE=$((8*BLKSIZE*LVMBLKMUL));; + # FS LIMITATION: some fs have disk size limit + x"vfat12" | xmsdos12) + DISKSIZE=$((4000*BLKSIZE));; + x"vfat12a" | xmsdos12a) + if [ $BLKSIZE -ge 2048 ]; then + DISKSIZE=$((2500*BLKSIZE)) + else + DISKSIZE=$((3000*BLKSIZE)) + fi + if [ $DISKSIZE -gt $((60000*SECSIZE)) ]; then + DISKSIZE=$((60000*SECSIZE)) + fi;; + x"vfat16" | xmsdos16) + DISKSIZE=$((65000*BLKSIZE));; + x"vfat16a" | xmsdos16a) + DISKSIZE=$((60000*SECSIZE)) + ;; + *) + DISKSIZE=10737418240;; + esac + + if [ $DISKSIZE -ge $(((5800/NDEVICES)*1048576)) ]; then + DISKSIZE=$(((5800/NDEVICES)*1048576)) + fi + + case x"$fs" in + xvfat* | xmsdos* | xexfat* | xhfs | xhfsplus | xhfsplus_wrap | xaffs \ + | xaffs_intl | xjfs_caseins | xsfs_caseins \ + | xzfs_caseins | xiso9660) + CASESENS=n;; + *) + CASESENS=y;; + esac + + BIGBLOCKCNT=$((5000 * 1048576)) + case x"$fs" in + # FS LIMITATION: small filesystems + x"vfat12" | xmsdos12) + if [ $BLKSIZE -le 4096 ]; then + BIGBLOCKCNT=0 + elif [ $BLKSIZE = 8192 ]; then + BIGBLOCKCNT=1500000 + else + BIGBLOCKCNT=$((2000*BLKSIZE)) + fi + ;; + x"vfat12a" | xmsdos12a) + if [ $BLKSIZE -le 4096 ] || [ $((128*SECSIZE)) = $BLKSIZE ]; then + BIGBLOCKCNT=0 + else + BIGBLOCKCNT=700000 + fi;; + x"vfat16a" | xmsdos16a) + if [ $((128*SECSIZE)) = $BLKSIZE ]; then + BIGBLOCKCNT=0 + else + BIGBLOCKCNT=$((2500*SECSIZE)) + fi + ;; + x"vfat16" | xmsdos16) + BIGBLOCKCNT=$((25000 * BLKSIZE)) + if [ $BIGBLOCKCNT -gt $((16#ffffffff)) ]; then + BIGBLOCKCNT=$((16#ffffffff)) + fi + ;; + x"minix") + BIGBLOCKCNT=30000000;; + + xexfat) + # Big blocks waste really a lot of space. + # Not much is left. + if [ $BLKSIZE = 2097152 ]; then + BIGBLOCKCNT=4500000000 + fi + if [ $BLKSIZE = 4194304 ]; then + BIGBLOCKCNT=3500000000 + fi + ;; + # FS LIMITATION: romfs image is limited to 4G. + x"romfs") + BIGBLOCKCNT=$((4000 * 1048576));; + # FS LIMITATION: These FS have uint32 as file size field + x"vfat"* | xmsdos* | x"cpio_crc" | x"cpio_newc" | x"cpio_bin" | x"cpio_hpbin" | xsfs*) + BIGBLOCKCNT=$((16#ffffffff));; + # FS LIMITATION: These FS have int32 as file size field + # FIXME: not so sure about AFFS + # OS LIMITATION: minix2/minix3 could be formatted in a way to permit more. + x"minix3" | x"minix2" | x"hfs"| x"affs" | xaffs_intl | xreiserfs_old | xext2_old) + BIGBLOCKCNT=$((16#7fffffff));; + + # FS LIMITATION: redundant storage + # We have only limited space. Mirroring multiplies it very effectively. + xmdraid* | xlvm* | xzfs_mirror | xbtrfs_raid1) + BIGBLOCKCNT=$((100 * 1048576));; + # We already test the FS for big files separately. Save some time here. + x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*) + BIGBLOCKCNT=$((100 * 1048576));; + + # OS LIMITATION: bfs_fuse bugs beyond that + xbfs) + BIGBLOCKCNT=$((800 * 1048576));; + esac + + NOSYMLINK=n + case x"$fs" in + # FS LIMITATION: no symlinks on FAT, exFAT, HFS, plain ISO9660 and Joliet + # OS LIMITATION: ntfs-3g creates interix symlinks which aren't real symlinks + x"vfat"* | xmsdos* | x"hfs" | x"exfat" | x"ntfs"* \ + | xiso9660 | xjoliet| xiso9660_1999 | xjoliet_1999) + NOSYMLINK=y;; + esac + NOHARDLINK=n + case x"$fs" in + # FS LIMITATION: no hardlinks on BFS, exfat, fat, hfs and SFS + xbfs | xexfat | x"vfat"* | xmsdos* | xhfs | xsfs | xsfs_caseins) + NOHARDLINK=y;; + # GRUB LIMITATION: no hardlink support on newc and hfs+ + xcpio_crc | xcpio_newc | xhfsplus*) + NOHARDLINK=y;; + esac + + # FS LIMITATION: some filesystems limit file name size + case x"$fs" in + x"cpio_ustar") + LONGNAME="`echo $LONGNAME |head -c 99`";; + x"hfs") + LONGNAME="`echo $LONGNAME |head -c 31`";; + x"minix" | x"minix2" | x"affs" | xaffs_intl | xiso9660) + LONGNAME="`echo $LONGNAME |head -c 30`";; + x"sfs"*) + LONGNAME="`echo $LONGNAME |head -c 105`";; + x"minix3") + LONGNAME="`echo $LONGNAME |head -c 60`";; + x"udf") + LONGNAME="`echo $LONGNAME |head -c 192`";; + # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999 + xjoliet | xjoliet_1999) + LONGNAME="`echo $LONGNAME |head -c 103`";; + xiso9660_1999) + LONGNAME="`echo $LONGNAME |head -c 207`";; + # FS LIMITATION: 8.3 + xmsdos*) + LONGNAME="qwertzui.opa";; + esac + NOFILETIME=n + NOFSTIME=n + case x"$fs" in + # FIXME: Not sure about BtrFS, NTFS, JFS, AFS, UDF and SFS. Check it. + # FS LIMITATION: as far as I know those FS don't store their last modification date. + x"jfs_caseins" | x"jfs" | x"xfs"| x"btrfs"* | x"reiserfs_old" | x"reiserfs" \ + | x"bfs" | x"afs" \ + | x"tarfs" | x"cpio_"* | x"minix" | x"minix2" \ + | x"minix3" | x"ntfs"* | x"udf" | x"sfs"*) + NOFSTIME=y;; + # OS LIMITATION: Linux doesn't update fstime. + # OS LIMITATION: Linux apparently uses localtime instead of UTC + xhfs) + NOFILETIME=y; NOFSTIME=y;; + # GRUB LIMITATION: FAT and exFAT use localtime. Unusable for GRUB + x"vfat"* | x"msdos"* | x"exfat") + NOFILETIME=y; NOFSTIME=y;; + # FS LIMITATION: romfs has no timestamps. + x"romfs") + NOFILETIME=y; NOFSTIME=y;; + esac + + NOFSLABEL=n + case x"$fs" in + # FS LIMITATION: these filesystems have no label. + x"cpio_"* | x"tarfs" | x"squash4_"* | x"minix" | x"minix2" \ + | x"minix3" | xreiserfs_old) + NOFSLABEL=y;; + esac + + PDIRCOMPNUM=220 + PDIR2COMPNUM=220 + + case x$fs in + # OS LIMITATION: bfs_fuse bugs beyond that + xbfs) + PDIRCOMPNUM=10 + PDIR2COMPNUM=10;; + # OS LIMITATION: Linux supports only inline symlinks + xudf) + if [ $BLKSIZE = 1024 ]; then + PDIR2COMPNUM=113 + fi ;; + # FS LIMITATION: at most 255 on path length + # FS LIMITATION: at most 100 on symlink length + xcpio_ustar) + PDIRCOMPNUM=85 + PDIR2COMPNUM=30;; + # OS LIMITATION: Linux supports only symlink at most one block long on reiserfs + xreiserfs | xreiserfs_old) + if [ $BLKSIZE = 512 ]; then + PDIR2COMPNUM=114 + fi ;; + # FS LIMITATION: SFS assumes that symlink + # with header fit in one block. + # FIXME: not sure about it. + xsfs | xsfs_caseins) + if [ $BLKSIZE = 512 ]; then + PDIR2COMPNUM=147 + fi ;; + # FS LIMITATION: AFFS assumes that symlink + # with rather larger header fit in one block. + # FIXME: not sure about it. + xaffs | xaffs_intl) + if [ $BLKSIZE = 512 ]; then + PDIR2COMPNUM=97 + fi ;; + esac + + + PDIR="" + # OS LIMITATION: Limited by PATH_MAX (usually 1024) + for ((i=0;i /dev/null + LODEVICES[i]=`losetup -f` + losetup "${LODEVICES[i]}" "${FSIMAGES[i]}" + done ;; + esac + + MOUNTDEVICE="${LODEVICES[0]}" + case x"$fs" in + x"afs") + ;; + x"btrfs") + "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${LODEVICES[0]}" ;; + x"btrfs_zlib" | x"btrfs_lzo") + "mkfs.btrfs" -s $SECSIZE -L "$FSLABEL" "${LODEVICES[0]}" + MOUNTOPTS="compress=${fs/btrfs_/}," + MOUNTFS="btrfs" + ;; + x"btrfs_raid0") + "mkfs.btrfs" -s $SECSIZE -d raid0 -m raid0 -L "$FSLABEL" "${LODEVICES[@]}" + MOUNTFS="btrfs" + ;; + x"btrfs_raid1") + "mkfs.btrfs" -s $SECSIZE -d raid1 -m raid1 -L "$FSLABEL" "${LODEVICES[@]}" + MOUNTFS="btrfs" + ;; + x"btrfs_raid10") + "mkfs.btrfs" -s $SECSIZE -d raid10 -m raid10 -L "$FSLABEL" "${LODEVICES[@]}" + MOUNTFS="btrfs" + ;; + x"btrfs_single") + "mkfs.btrfs" -s $SECSIZE -d single -L "$FSLABEL" "${LODEVICES[@]}" + MOUNTFS="btrfs" + ;; + x"exfat") + "mkfs.$fs" -s $((BLKSIZE/512)) -n "$FSLABEL" "${LODEVICES[0]}" + MOUNTOPTS="iocharset=utf8," + MOUNTFS="exfat-fuse";; + x"minix") + "mkfs.minix" "${LODEVICES[0]}" + ;; + # mkfs.hfs and mkfs.hfsplus don't fill UUID. + x"hfsplus") + "mkfs.hfsplus" -b $BLKSIZE -v "$FSLABEL" "${LODEVICES[0]}" + dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#468)) conv=notrunc count=8 ;; + x"hfsplus_wrap") + "mkfs.hfsplus" -w -b $BLKSIZE -v "$FSLABEL" "${LODEVICES[0]}" + dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#468)) conv=notrunc count=8 + MOUNTFS="hfsplus";; + x"hfsplus_casesens") + "mkfs.hfsplus" -s -b $BLKSIZE -v "$FSLABEL" "${LODEVICES[0]}" + dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#468)) conv=notrunc count=8 + MOUNTFS="hfsplus";; + x"hfs") + "mkfs.hfs" -b $BLKSIZE -v "`echo $FSLABEL |recode utf8..macroman`" -h "${LODEVICES[0]}" + dd if=/dev/urandom of="${LODEVICES[0]}" bs=1 seek=$((16#474)) conv=notrunc count=8 + MOUNTOPTS="iocharset=utf8,codepage=macroman," + ;; + x"vfat"*|xmsdos*) + BITS="${fs/vfat/}" + BITS="${BITS/msdos/}" + if [ "x${BITS:2:1}" = xa ]; then + A=-A + else + A= + fi + "mkfs.vfat" -a $A -S $SECSIZE -s $((BLKSIZE/SECSIZE)) -F "${BITS:0:2}" -n "$FSLABEL" "${LODEVICES[0]}" + MOUNTOPTS="iocharset=utf8,codepage=437," + MOUNTFS="$(echo "$fs"|sed 's,[0-9]*a\?$,,')";; + x"minix2") + "mkfs.minix" -v "${LODEVICES[0]}" + MOUNTFS="minix";; + x"minix3") + "mkfs.minix" -B $BLKSIZE -3 "${LODEVICES[0]}" + MOUNTFS="minix";; + x"ntfs"*) + "mkfs.ntfs" -s "$SECSIZE" -c "$BLKSIZE" -L "$FSLABEL" -Q -q "${LODEVICES[0]}" + MOUNTOPTS="iocharset=utf8,compression," + MOUNTFS="ntfs-3g";; + x"udf") + "/usr/bin/mkudffs" -b $BLKSIZE --utf8 --lvid="$FSLABEL" "${LODEVICES[0]}" + MOUNTOPTS="iocharset=utf8,bs=$BLKSIZE,";; + x"ufs2") + "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 2 "${LODEVICES[0]}" + MOUNTOPTS="ufstype=ufs2," + MOUNTFS="ufs";; + x"ufs1") + "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${LODEVICES[0]}" + MOUNTOPTS="ufstype=44bsd," + MOUNTFS="ufs";; + x"ufs1_sun") + "mkfs.ufs" -b $BLKSIZE -L "$FSLABEL" -O 1 "${LODEVICES[0]}" + MOUNTOPTS="ufstype=sun," + MOUNTFS="ufs";; + x"zfs") + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[0]}" + sleep 1 + "zfs" create "$FSLABEL"/"grub fs" + sleep 1;; + x"zfs_caseins") + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[0]}" + sleep 1 + "zfs" create -o casesensitivity=insensitive "$FSLABEL"/"grub fs" + sleep 1;; + x"zfs_lzjb" | xzfs_gzip | xzfs_zle) + "zpool" create -O compression=${fs/zfs_/} -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[0]}" + sleep 1 + "zfs" create -o compression=${fs/zfs_/} "$FSLABEL"/"grub fs" + sleep 1;; + x"zfs_raidz") + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz1 "${LODEVICES[@]}" + sleep 1 + "zfs" create "$FSLABEL"/"grub fs" + sleep 1;; + x"zfs_raidz2") + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz2 "${LODEVICES[@]}" + sleep 1 + "zfs" create "$FSLABEL"/"grub fs" + sleep 1;; + x"zfs_raidz3") + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" raidz3 "${LODEVICES[@]}" + sleep 1 + "zfs" create "$FSLABEL"/"grub fs" + sleep 1;; + x"zfs_mirror") + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" mirror "${LODEVICES[@]}" + sleep 1 + "zfs" create "$FSLABEL"/"grub fs" + sleep 1;; + x"zfs_stripe") + "zpool" create -R "$MNTPOINTRW" "$FSLABEL" "${LODEVICES[@]}" + sleep 1 + "zfs" create "$FSLABEL"/"grub fs" + sleep 1;; + x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"*) + INSTDEVICE=/dev/null;; + x"reiserfs") + "mkfs.reiserfs" --format=3.6 -b $BLKSIZE -l "$FSLABEL" -q "${LODEVICES[0]}" ;; + x"reiserfs_old") + "mkfs.reiserfs" --format=3.5 -b $BLKSIZE -l "$FSLABEL" -q "${LODEVICES[0]}" + MOUNTFS=reiserfs;; + x"jfs") + "mkfs.jfs" -L "$FSLABEL" -q "${LODEVICES[0]}" + MOUNTOPTS="iocharset=utf8,";; + x"jfs_caseins") + "mkfs.jfs" -O -L "$FSLABEL" -q "${LODEVICES[0]}" + MOUNTFS=jfs + MOUNTOPTS="iocharset=utf8,";; + x"mdraid"*) + mdadm -C --chunk=$((BLKSIZE/1024)) --force -e "${fs:6:1}.${fs:7:1}" "/dev/md/${fs}_${NDEVICES}" --level="${fs:13}" --raid-devices="$NDEVICES" "${LODEVICES[@]}" + MOUNTDEVICE="/dev/md/${fs}_${NDEVICES}" + MOUNTFS=ext2 + "mkfs.ext2" -L "$FSLABEL" -q "${MOUNTDEVICE}" ;; + x"lvm"*) + for ((i=0;i^{_}[]\`|~." + case x"$fs" in + + # FS LIMITATION: AFFS and SFS don't accept : + xsfs*) + NASTYFILE=".?*\\!\"#%@\$%&'()+ ,-.;<=>^{_}[]\`|~.";; + # FS LIMITATION: AFFS is limited in file name length (30) + x"affs" | xaffs_intl) + NASTYFILE=".?*\\!\"#@\$'()+ ,-;<=>^{_}[]\`|~.";; + # FS LIMITATION: hfs, minix and minix2 are limited in file name length (30 or 31) + x"hfs" | x"minix" | x"minix2") + NASTYFILE=".?*\\!\"#@\$&'()+ ,-:;<=>{}[]\`|~.";; + # FS LIMITATION: FAT doesn't accept ?, *, \, ", :, <, >, | + # FS LIMITATION: FAT discards dots at the end. + x"vfat"* | x"exfat") + NASTYFILE=".!#%@\$%&'()+ ,-.;=^{_}[]\`~";; + # FS LIMITATION: 8.3 limitations apply + x"msdos"*) + NASTYFILE="!#%@\$%&.;=^";; + # FS LIMITATION: No ' ', '*', '/', ':', ';', '?', '\\' in joliet + # GRUB LIMITATION: GRUB prefers Joliet over ISO9660:1999 + xjoliet | xjoliet_1999) + NASTYFILE=".!\"#%@\$%&'()+,-.<=>^{_}[]\`|~.";; + # FS LIMITATION: iso9660 accepts only [0-9A-Z_]*, 32 characters at most + xiso9660) + NASTYFILE="0123456789_acefghijknopqrvwxyz";; + esac + + case x"$fs" in + # FS LIMITATION: HFS, AFFS and SFS use legacy codepage (mac-roman or latin1) + x"sfs"* | x"hfs" | x"affs" | xaffs_intl) + IFILE="éàèüöäëñ" + ISYM="ëñéüöäàè" + ;; + # FS LIMITATION: filename length limitation. + x"minix" | x"minix2") + IFILE="éàèüö😁ñкиΕλκά" + ISYM="Ελκάкиéà😁öäëñ" + ;; + xminix3) + IFILE="éàèüöäëñкирица莭茝Ελλικά😁😜😒" + ISYM="Ελλικά😁😜😒莭茝кирицаéàèüöäëñ";; + # GRUB LIMITATION: HFS+ uses NFD. GRUB doesn't handle NF conversion. + # OS LIMITATION: Linux doesn't handle out-of-BMP characters for UTF-16 + x"hfsplus" | x"hfsplus_casesens" | x"hfsplus_wrap") + IFILE="éàèüöäëñкирилица䏌䐓䏕Ελληνικα̍䏌䐓䏕" + ISYM="Ελληνικα̍кирилица䏌䐓䏕éàèüöäëñ䏌䐓䏕" + ;; + # GRUB LIMITATION: On case-insensitive ZFS isn't supported with non-uppercase characters + xzfs_caseins) + IFILE="ÉÀÈÜÖÄËÑКИРИЛИЦА莭莽茝ΕΛΛΗΝΙΚΆ😁😜😒" + ISYM="ΕΛΛΗΝΙΚΆКИРИЛИЦА😁😜😒ÉÀÈÜÖÄËÑ莭莽茝";; + # FS LIMITATION: 8.3 CP437 + x"msdos"*) + IFILE="éàèüöäëñ.éàè" + ;; + # FS LIMITATION: iso9660 is ASCII-only. + x"iso9660") + IFILE="abcdefghijkmmnop" + ;; + # OS LIMITATION: Linux doesn't handle out-of-BMP characters for UTF-16 + # OS LIMITATION: xorriso doesn't handle out-of-BMP characters + xjoliet | xjoliet_1999 | x"vfat"* | x"jfs"* | x"udf"*) + IFILE="éàèüöäëñкирилица䏌䐓䏕Ελληνικά䏌䐓䏕" + ISYM="Ελληνικάкирилица䏌䐓䏕éàèüöäëñ䏌䐓䏕";; + *) + IFILE="éàèüöäëñкирилица莭莽茝Ελληνικά😁😜😒" + ISYM="Ελληνικάкирилица😁😜😒éàèüöäëñ莭莽茝";; + esac + BIGFILE="big.img" + BASESYM="sym" + BASEHARD="hard" + SSYM="///sdir////ssym" + USYM="///sdir////usym" + LONGSYM="longsym" + PSYM="psym" + OSDIR="" + GRUBDEVICE=loop0 + case x"$fs" in + xmdraid*) + GRUBDEVICE="mduuid/`mdadm --detail --export $MOUNTDEVICE | grep MD_UUID=|sed 's,MD_UUID=,,g;s,:,,g'`";; + xlvm*) + GRUBDEVICE="lvm/grub_test-testvol";; + esac + GRUBDIR="($GRUBDEVICE)" + case x"$fs" in + x"zfs"*) + OSDIR="grub fs/" + GRUBDIR="($GRUBDEVICE)/grub fs@";; + x"tarfs" | x"cpio_"* | x"iso9660" | xjoliet | xrockridge | xrockridge_joliet | x"iso9660_1999" | xjoliet_1999 | xrockridge_1999 | xrockridge_joliet_1999 | x"ziso9660" | x"romfs" | x"squash4_"* | xafs) + ;; + *) + if ! mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRW" -o ${MOUNTOPTS}${SELINUXOPTS}rw ; then + echo "MOUNT FAILED." + for ((i=0; i < NDEVICES; i++)); do + while ! losetup -d "${LODEVICES[i]}"; do + sleep 1 + done + rm "${FSIMAGES[i]}" + done + exit 1; + fi + ;; + esac + case x"$fs" in + # FS LIMITATION: redundant storage + xmdraid* | xlvm*) + BLOCKCNT=1048576;; + x"zfs_raid"* | x"zfs_stripe"* | x"zfs_mirror"* | x"btrfs_raid"*) + BLOCKCNT=1048576;; + + # FS LIMITATION: small filesystems + x"vfat16a" | x"msdos16a") + BLOCKCNT=65536;; + x"vfat12a" | xmsdos12a) + BLOCKCNT=32768;; + xminix) + BLOCKCNT=2621440;; + xvfat16 | xmsdos16) + if [ $BLKSIZE = 512 ] || [ $BLKSIZE = 1024 ]; then + BLOCKCNT=1048576 + else + BLOCKCNT=5242880 + fi + ;; + xvfat12 | xmsdos12) + BLOCKCNT=$((100*BLKSIZE)) + if [ $BLOCKCNT -gt 5242880 ]; then + BLOCKCNT=5242880; + fi + ;; + *) + BLOCKCNT=5242880;; + esac + case x"$fs" in + x"ntfscomp") + setfattr -h -v 0x00000800 -n system.ntfs_attrib_be "$MNTPOINTRW/$OSDIR";; + esac + # OS LIMITATION: No AFS support under GNU/Linux + mkdir "$MNTPOINTRW/$OSDIR/sdir" + mkdir -p "$MNTPOINTRW/$OSDIR/$PDIR" + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/sdir/2.img" + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$BASEFILE" + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$NASTYFILE" + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$IFILE" + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$LONGNAME" + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/$PDIR/$PFIL" + if [ $PDIR != $PDIR2 ]; then + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/${PDIR2}/$PFIL" + fi + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/CaSe" + if [ x$CASESENS = xy ]; then + "@builddir@"/garbage-gen $BLOCKCNT > "$MNTPOINTRW/$OSDIR/cAsE" + fi + if (test x$fs = xvfat12a || test x$fs = xmsdos12a) && test x$BLKSIZE = x131072; then + # With this config there isn't enough space for full copy. + # Copy as much as we can + cp "${CFILESSRC[0]}" "$MNTPOINTRW/$OSDIR/${CFILES[0]}" &> /dev/null; + else + for ((i=0;i<$CFILESN;i++)); do + cp "${CFILESSRC[i]}" "$MNTPOINTRW/$OSDIR/${CFILES[i]}"; + done + fi + + if [ x$NOSYMLINK != xy ]; then + ln -s "$BASEFILE" "$MNTPOINTRW/$OSDIR/$BASESYM" + ln -s "2.img" "$MNTPOINTRW/$OSDIR/$SSYM" + ln -s "../1.img" "$MNTPOINTRW/$OSDIR/$USYM" + ln -s "$LONGNAME" "$MNTPOINTRW/$OSDIR/$LONGSYM" + ln -s "${PDIR2}/$PFIL" "$MNTPOINTRW/$OSDIR/$PSYM" + ln -s "$IFILE" "$MNTPOINTRW/$OSDIR/$ISYM" + fi + if [ x$NOHARDLINK != xy ]; then + ln "$MNTPOINTRW/$OSDIR/$BASEFILE" "$MNTPOINTRW/$OSDIR/$BASEHARD" + fi + + case x"$fs" in + x"afs") + ;; + x"zfs"*) + while ! zpool export "$FSLABEL" ; do + sleep 1; + done + sleep 2 + ;; + x"tarfs") + (cd "$MASTER"; tar cf "${FSIMAGES[0]}" .) ;; + x"cpio_"*) + (cd "$MASTER"; find . | cpio -o -H "${fs/cpio_/}" > "${FSIMAGES[0]}" ) ;; + x"ziso9660") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + xorriso -compliance rec_mtime -set_filter_r --zisofs -- -zisofs default -as mkisofs -iso-level 3 -graft-points -R -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" -- -set_filter_r --zisofs -- -zisofs default -add /="$MASTER" ;; + x"iso9660") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"joliet") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"rockridge") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"rockridge_joliet") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 3 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"iso9660_1999") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"joliet_1999") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge off -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"rockridge_1999") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"rockridge_joliet_1999") + FSUUID=$(date -u +%Y-%m-%d-%H-%M-%S-00); + /usr/local/bin/xorriso --rockridge on -compliance rec_mtime -as mkisofs -iso-level 4 -graft-points -J -joliet-long -V "$FSLABEL" --modification-date=$(echo ${FSUUID} | sed 's/-//g;') -o "${FSIMAGES[0]}" /="$MASTER" ;; + x"romfs") + genromfs -V "$FSLABEL" -f "${FSIMAGES[0]}" -d "$MASTER" ;; + xsquash4_*) + echo mksquashfs "$MASTER" "${FSIMAGES[0]}" -comp "${fs/squash4_/}" -b $BLKSIZE + mksquashfs "$MASTER" "${FSIMAGES[0]}" -comp "${fs/squash4_/}" -b $BLKSIZE ;; + x"bfs") + sleep 1 + fusermount -u "$MNTPOINTRW" + ;; + xlvm*) + sleep 1 + for ((try=0;try < 20; try++)); do + if umount "$MNTPOINTRW" ; then + break; + fi + sleep 1; + done + sleep 1 + vgchange -a n grub_test + ;; + xmdraid*) + sleep 1 + for ((try=0;try < 20; try++)); do + if umount "$MNTPOINTRW" ; then + break; + fi + sleep 1; + done + sleep 1 + mdadm --stop /dev/md/"${fs}_$NDEVICES" + ;; + *) + sleep 1 + for ((try=0;try < 20; try++)); do + if umount "$MNTPOINTRW" ; then + break; + fi + sleep 1; + done + ;; + esac + sleep 1 + + case x"$fs" in + x"zfs"*) + "zpool" import -d /dev -R "$MNTPOINTRO" "$FSLABEL" + ;; + x"tarfs") + ;; + x"cpio_"*) + ;; + x"ziso9660") + ;; + xiso9660 | xrockridge | xjoliet | xrockridge_joliet) + ;; + xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) + ;; + x"romfs") + ;; + xsquash4_*) + ;; + xlvm*) + vgchange -a y grub_test + sleep 1 + mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;; + xmdraid*) + mdadm --assemble /dev/md/"${fs}_$NDEVICES" "${LODEVICES[@]}" + sleep 1 + mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;; + *) + mount -t "$MOUNTFS" "${MOUNTDEVICE}" "$MNTPOINTRO" -o ${MOUNTOPTS}${SELINUXOPTS}ro ;; + esac + + run_grubfstest ls -- -la + case x"$fs" in + x"zfs"*) + LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/grub fs@/");; + *) + LSROUT=$(run_grubfstest ls -- -la "($GRUBDEVICE)/");; + esac + if echo "$LSROUT" | grep -F " $BASEFILE" | grep "$BLOCKCNT" > /dev/null; then + : + else + echo LIST FAIL + echo "$LSROUT" + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + exit 1 + fi + + if echo "$LSROUT" | grep -F " $NASTYFILE" | grep "$BLOCKCNT"> /dev/null; then + : + else + echo NLIST FAIL + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -lA "$MNTPOINTRO" + exit 1 + fi + + if echo "$LSROUT" | grep -F " $IFILE" | grep "$BLOCKCNT"> /dev/null; then + : + else + echo ILIST FAIL + echo "$LSROUT" + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + exit 1 + fi + + if echo "$LSROUT" | grep -F " $LONGNAME" | grep "$BLOCKCNT"> /dev/null; then + : + else + echo LONG LIST FAIL + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + exit 1 + fi + + if [ x$NOFILETIME != xy ]; then + filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$BASEFILE"|awk '{print $6; }') + if echo "$LSROUT" | grep -F "$filtime $BASEFILE" > /dev/null; then + : + else + echo TIME FAIL + echo "$LSROUT" + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + exit 1 + fi + + filtime=$(TZ=UTC ls --time-style=+%Y%m%d%H%M%S -l -d "$MNTPOINTRO/$OSDIR/$LONGNAME"|awk '{print $6; }') + if echo "$LSROUT" | grep -F "$filtime $LONGNAME" > /dev/null; then + : + else + echo LONG TIME FAIL + echo "$LSROUT" + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO" + exit 1 + fi + fi + + case x"$fs" in + x"zfs"*) + LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/////sdir");; + *) + LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/////sdir");; + esac + if echo "$LSROUT" | grep -F " 2.img" | grep $BLOCKCNT > /dev/null; then + : + else + echo SLIST FAIL + echo "$LSROUT" + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/sdir" + exit 1 + fi + + case x"$fs" in + x"zfs"*) + LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/grub fs@/$PDIR");; + *) + LSROUT=$(run_grubfstest ls -- -l "($GRUBDEVICE)/$PDIR");; + esac + if echo "$LSROUT" | grep -F " p.img" | grep $BLOCKCNT > /dev/null; then + : + else + echo PLIST FAIL + echo "$LSROUT" + TZ=UTC ls --time-style=+%Y%m%d%H%M%S.%N -l "$MNTPOINTRO/$PDIR" + exit 1 + fi + + LSOUT=`run_grubfstest ls -- -l "($GRUBDEVICE)"` + if [ x"$NOFSLABEL" = xy ]; then + : + elif echo "$LSOUT" | grep -F "Label \`$FSLABEL'" > /dev/null; then + : + else + echo LABEL FAIL + echo "$LSOUT" + blkid "${MOUNTDEVICE}" + exit 1 + fi + + # Inconsistencies between GRUB and blkid. + case x"$fs" in + x"iso9660" | x"ziso9660" | xrockridge | xjoliet | xrockridge_joliet | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) ;; + x"zfs"*) + for ((i=0;i /dev/null; then + : + else + echo UUID FAIL + echo "$FSUUID" + echo "$LSOUT" + blkid "${LODEVICES[0]}" + exit 1 + fi + ;; + esac + + case x$fs in + xiso9660 | xziso9660 | xrockridge | xjoliet | xrockridge_joliet | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) + FSTIME="$(date -d "$(echo ${FSUUID} | awk -F - '{ print $1"-"$2"-"$3" "$4":"$5":"$6 ;}')" '+%Y-%m-%d %H:%M:%S')";; + *) + FSTIME="$(TZ=UTC ls --time-style="+%Y-%m-%d_%H:%M:%S" -l -d "${FSIMAGES[0]}"|awk '{print $6; }'|sed 's,_, ,g')";; + esac + # With some abstractions like mdraid it may take up to 2 seconds for the data to reach the disks after it was flushed by FS in these tests. + FSTIMEM1="$(date -d "$FSTIME UTC -1 second" -u "+%Y-%m-%d %H:%M:%S")" + FSTIMEM2="$(date -d "$FSTIME UTC -2 second" -u "+%Y-%m-%d %H:%M:%S")" + + if [ x$NOFSTIME = xy ]; then + : + elif echo "$LSOUT" | grep -F 'Last modification time '"$FSTIME" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM1" > /dev/null || echo "$LSOUT" | grep -F 'Last modification time '"$FSTIMEM2" > /dev/null; then + : + else + echo FSTIME FAIL + echo "$FSTIME" + echo "$LSOUT" + exit 1 + fi + + if [ x$NOHARDLINK != xy ]; then + if run_grubfstest cmp "$GRUBDIR/$BASEHARD" "$MNTPOINTRO/$OSDIR/$BASEFILE" ; then + : + else + echo HARDLINK FAIL + exit 1 + fi + fi + + if [ x$NOSYMLINK != xy ]; then + if run_grubfstest cmp "$GRUBDIR/$BASESYM" "$MNTPOINTRO/$OSDIR/$BASEFILE" ; then + : + else + echo SYMLINK FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$LONGSYM" "$MNTPOINTRO/$OSDIR/$LONGNAME" ; then + : + else + echo LONG SYMLINK FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$ISYM" "$MNTPOINTRO/$OSDIR/$IFILE" ; then + : + else + echo INTL SYMLINK FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$SSYM" "$MNTPOINTRO/$OSDIR/////sdir/////2.img" ; then + : + else + echo SDIR SYMLINK FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$USYM" "$MNTPOINTRO/$OSDIR/1.img" ; then + : + else + echo SDIR SYMLINK FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$PSYM" "$MNTPOINTRO/$OSDIR/${PDIR2}/$PFIL" ; then + : + else + echo PATH LONG SYMLINK FAIL + exit 1 + fi + fi + + if run_grubfstest cmp "$GRUBDIR/$BASEFILE" "$MNTPOINTRO/$OSDIR/$BASEFILE" ; then + : + else + echo READ FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$NASTYFILE" "$MNTPOINTRO/$OSDIR/$NASTYFILE" ; then + : + else + echo NREAD FAIL + exit 1 + fi + # Reference archive contains original name + if run_grubfstest cmp "$GRUBDIR/$LONGNAME" "$MNTPOINTRO/$OSDIR/$LONGNAME" ; then + : + else + echo LONG NAME READ FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/////sdir/////2.img" "$MNTPOINTRO/$OSDIR/sdir/2.img" ; then + : + else + echo LONG NAME READ FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$IFILE" "$MNTPOINTRO/$OSDIR/$IFILE" ; then + : + else + echo IREAD FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/$PDIR/$PFIL" "$MNTPOINTRO/$OSDIR/$PDIR/$PFIL" ; then + : + else + echo PREAD FAIL + echo cmp "$GRUBDIR/$PDIR/$PFIL" "$MNTPOINTRO/$OSDIR/$PDIR/$PFIL" + exit 1 + fi + ok=true + for ((i=0;i<$CFILESN;i++)); do + if ! run_grubfstest cmp "$GRUBDIR/${CFILES[i]}" "$MNTPOINTRO/$OSDIR/${CFILES[i]}" ; then + ok=false; + fi + done + if test x$ok = xtrue; then + : + else + echo CREAD FAIL + exit 1 + fi + + if [ x$CASESENS = xy ]; then + if run_grubfstest cmp "$GRUBDIR/CaSe" "$MNTPOINTRO/$OSDIR/CaSe" ; then + : + else + echo CASE1 READ FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/cAsE" "$MNTPOINTRO/$OSDIR/cAsE" ; then + : + else + exit 1 + fi + if cmp "$MNTPOINTRO/$OSDIR/cAsE" "$MNTPOINTRO/$OSDIR/CaSe" > /dev/null ; then + exit 1 + fi + if test x$ok = xtrue; then + : + else + echo CASE READ FAIL + exit 1 + fi + else + # OS LIMITATION: Linux make FAT (partially) case-sensitive... + # ISO9660 is generated and master doesn't change + case x$fs in + xiso9660 | xvfat*) + CASEX=CaSe;; + *) + CASEX=cAsE;; + esac + if run_grubfstest cmp "$GRUBDIR/CaSe" "$MNTPOINTRO/$OSDIR/${CASEX}" ; then + : + else + echo CASE1 READ FAIL + exit 1 + fi + if run_grubfstest cmp "$GRUBDIR/cAsE" "$MNTPOINTRO/$OSDIR/CaSe" ; then + : + else + echo CASE2 READ FAIL + exit 1 + fi + if ! cmp "$MNTPOINTRO/$OSDIR/CaSe" "$MNTPOINTRO/$OSDIR/${CASEX}" > /dev/null ; then + echo CASE CMP READ FAIL + exit 1 + fi + if test x$ok = xtrue; then + : + else + echo CASE READ FAIL + exit 1 + fi + fi + + case x"$fs" in + x"zfs"*) + while ! zpool export "$FSLABEL" ; do + sleep 1; + done + sleep 5;; + x"tarfs" | x"cpio_"* | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | xiso9660 | xiso9660_1999 | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) + rm -rf "$MNTPOINTRW";; + x"afs") + rm -rf "$MNTPOINTRO" + ;; + *) + sleep 1 + umount "$MNTPOINTRO" || true + umount "$MNTPOINTRW" || true + esac + sleep 1 + case x"$fs" in + xmdraid*) + mdadm --stop /dev/md/"${fs}_$NDEVICES" + sleep 1 + ;; + xlvm*) + vgchange -a n grub_test + sleep 1 + ;; + esac + for ((i=0; i < NDEVICES; i++)); do + case x"$fs" in + x"tarfs" | x"cpio_"* | x"iso9660" | xrockridge | xjoliet | xrockridge_joliet | x"ziso9660" | x"romfs" | x"squash4_"* | x"iso9660_1999" | xrockridge_1999 | xjoliet_1999 | xrockridge_joliet_1999) ;; + *) + while ! losetup -d "${LODEVICES[i]}"; do + sleep 1 + done;; + esac + rm "${FSIMAGES[i]}" + done + if [ x"$fs" = x"zfs" ]; then + rmdir "$MNTPOINTRW"/"grub fs" || true + rmdir "$MNTPOINTRO"/"grub fs" || true + fi + rm -rf "$MNTPOINTRW" || true + rm -rf "$MNTPOINTRO" || true + done + done +done diff --git a/tests/xfs_test.in b/tests/xfs_test.in new file mode 100644 index 000000000..173b1cfe6 --- /dev/null +++ b/tests/xfs_test.in @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which mkfs.xfs >/dev/null 2>&1; then + echo "mkfs.xfs not installed; cannot test xfs." + exit 77 +fi + + +"@builddir@/grub-fs-tester" xfs diff --git a/tests/zfs_test.in b/tests/zfs_test.in new file mode 100644 index 000000000..047120e47 --- /dev/null +++ b/tests/zfs_test.in @@ -0,0 +1,27 @@ +#!/bin/sh + +set -e + +if [ "x$EUID" = "x" ] ; then + EUID=`id -u` +fi + +if [ "$EUID" != 0 ] ; then + exit 77 +fi + +if ! which zpool >/dev/null 2>&1; then + echo "zpool not installed; cannot test zfs." + exit 77 +fi + +"@builddir@/grub-fs-tester" zfs +"@builddir@/grub-fs-tester" zfs_lzjb +"@builddir@/grub-fs-tester" zfs_gzip +"@builddir@/grub-fs-tester" zfs_zle +"@builddir@/grub-fs-tester" zfs_raidz3 +"@builddir@/grub-fs-tester" zfs_raidz2 +"@builddir@/grub-fs-tester" zfs_raidz +"@builddir@/grub-fs-tester" zfs_mirror +"@builddir@/grub-fs-tester" zfs_stripe +"@builddir@/grub-fs-tester" zfs_caseins diff --git a/util/garbage-gen.c b/util/garbage-gen.c new file mode 100644 index 000000000..ccba1bf1c --- /dev/null +++ b/util/garbage-gen.c @@ -0,0 +1,67 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* Standard random generator is slow. For FS testing we need just some + garbage files, we don't need them to be high-quality random. + */ + +#include +#include +#include +#include + +static unsigned long long buffer[1048576]; + +int +main (int argc, char **argv) +{ + unsigned long long high = 0, low = 1; + unsigned long i, j; + unsigned long long cnt = strtoull (argv[1], 0, 0); + struct timeval tv; + gettimeofday (&tv, NULL); + high = tv.tv_sec; + low = tv.tv_usec; + if (!high) + high = 1; + if (!low) + low = 2; + + for (j = 0; j < (cnt + sizeof (buffer) - 1) / sizeof (buffer); j++) + { + for (i = 0; i < sizeof (buffer) / sizeof (buffer[0]); i += 2) + { + int c1 = 0, c2 = 0; + buffer[i] = low; + buffer[i+1] = high; + if (low & (1ULL << 63)) + c1 = 1; + low <<= 1; + if (high & (1ULL << 63)) + c2 = 1; + high = (high << 1) | c1; + if (c2) + low ^= 0x87; + } + if (sizeof (buffer) < cnt - sizeof (buffer) * j) + fwrite (buffer, 1, sizeof (buffer), stdout); + else + fwrite (buffer, 1, cnt - sizeof (buffer) * j, stdout); + } + return 0; +} diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 1a903a66d..633e5292d 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -558,7 +558,7 @@ copy_locales (const char *dstd) grub_util_fd_dirent_t de; const char *locale_dir = grub_util_get_localedir (); - d = grub_util_fd_opendir (LOCALEDIR); + d = grub_util_fd_opendir (locale_dir); if (!d) { grub_util_warn (_("cannot open directory `%s': %s"), @@ -597,6 +597,8 @@ static struct [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, + [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, @@ -707,6 +709,8 @@ grub_install_copy_files (const char *src, } else { + const char *locale_dir = grub_util_get_localedir (); + for (i = 0; i < install_locales.n_entries; i++) { char *srcf = grub_util_path_concat_ext (3, src, @@ -724,7 +728,7 @@ grub_install_copy_files (const char *src, } free (srcf); srcf = grub_util_path_concat_ext (4, - LOCALEDIR, + locale_dir, install_locales.entries[i], "LC_MESSAGES", PACKAGE, diff --git a/util/grub-install.c b/util/grub-install.c index d9cde51d1..2d6ef757a 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -233,7 +233,7 @@ static struct argp_option options[] = { "This option is only available on BIOS target."), 2}, {"no-nvram", OPTION_NO_NVRAM, 0, 0, N_("don't update the `boot-device' NVRAM variable. " - "This option is only available on IEEE1275 targets."), 2}, + "This option is only available on EFI and IEEE1275 targets."), 2}, {"skip-fs-probe",'s',0, 0, N_("do not probe for filesystems in DEVICE"), 0}, {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0, @@ -418,6 +418,9 @@ have_bootdev (enum grub_install_plat pl) case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: return 0; /* pacify warning. */ @@ -758,6 +761,8 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: case GRUB_INSTALL_PLATFORM_MIPS_ARC: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: break; case GRUB_INSTALL_PLATFORM_I386_QEMU: @@ -798,6 +803,8 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: free (install_device); install_device = NULL; break; @@ -1217,6 +1224,8 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPS_ARC: case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance")); break; /* pacify warning. */ @@ -1304,6 +1313,8 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: case GRUB_INSTALL_PLATFORM_I386_IEEE1275: case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: core_name = "core.elf"; snprintf (mkimage_target, sizeof (mkimage_target), "%s-%s", @@ -1395,6 +1406,8 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_QEMU: case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: break; /* pacify warning. */ case GRUB_INSTALL_PLATFORM_MAX: @@ -1414,7 +1427,7 @@ main (int argc, char *argv[]) "boot.img"); grub_install_copy_file (boot_img_src, boot_img, 1); - grub_util_info ("%sgrub_bios_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + grub_util_info ("%sgrub-bios-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", install_bootsector ? "" : "NOT RUNNING: ", allow_floppy ? "--allow-floppy " : "", verbosity ? "--verbose " : "", @@ -1440,7 +1453,7 @@ main (int argc, char *argv[]) "boot.img"); grub_install_copy_file (boot_img_src, boot_img, 1); - grub_util_info ("%sgrub_sparc_setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + grub_util_info ("%sgrub-sparc64-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", install_bootsector ? "" : "NOT RUNNING: ", allow_floppy ? "--allow-floppy " : "", verbosity ? "--verbose " : "", @@ -1525,7 +1538,7 @@ main (int argc, char *argv[]) grub_install_copy_file (imgfile, dst, 1); free (dst); } - if (!removable) + if (!removable && update_nvram) { char * efidir_disk; int efidir_part; @@ -1552,6 +1565,8 @@ main (int argc, char *argv[]) case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: case GRUB_INSTALL_PLATFORM_ARM_UBOOT: case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: grub_util_warn ("%s", _("WARNING: no platform-specific install was performed")); break; diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index db58ab930..ba1d4ef35 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -216,6 +216,7 @@ export GRUB_DEFAULT \ GRUB_SAVEDEFAULT \ GRUB_ENABLE_CRYPTODISK \ GRUB_BADRAM \ + GRUB_OS_PROBER_SKIP_LIST \ GRUB_DISABLE_SUBMENU if test "x${grub_cfg}" != "x"; then @@ -224,7 +225,7 @@ if test "x${grub_cfg}" != "x"; then exec > "${grub_cfg}.new" umask $oldumask fi -gettext "Generating grub.cfg ..." >&2 +gettext "Generating grub configuration file ..." >&2 echo >&2 cat << EOF diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index b88e9b980..5240fe2aa 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -1376,7 +1376,6 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, *kernel_sz = ALIGN_UP (*kernel_sz, 16); grub_ia64_dl_get_tramp_got_size (e, &tramp, &got); - tramp *= sizeof (struct grub_ia64_trampoline); ia64_toff = *kernel_sz; *kernel_sz += ALIGN_UP (tramp, 16); @@ -1387,7 +1386,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, *kernel_sz += 16 * ia64jmpnum; ia64_got_off = *kernel_sz; - *kernel_sz += ALIGN_UP (got * sizeof (grub_uint64_t), 16); + *kernel_sz += ALIGN_UP (got, 16); } #endif diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index 6b7239846..7a76bc37a 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -396,11 +396,12 @@ main (int argc, char *argv[]) if (!grub_install_source_directory) { + const char *pkglibdir = grub_util_get_pkglibdir (); enum grub_install_plat plat; for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) { - char *platdir = grub_util_path_concat (2, pkgdatadir, + char *platdir = grub_util_path_concat (2, pkglibdir, grub_install_get_platform_name (plat)); if (!grub_util_is_directory (platdir)) diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 502faeaa8..3d1b93893 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -112,6 +112,18 @@ for OS in ${OSPROBED} ; do LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`" BOOT="`echo ${OS} | cut -d ':' -f 4`" + UUID="`grub-probe --target=fs_uuid --device ${DEVICE%@*}`" + EXPUUID="$UUID" + + if [ x"${DEVICE#*@}" != x ] ; then + EXPUUID="${EXPUUID}@${DEVICE#*@}" + fi + + if [ "x${GRUB_OS_PROBER_SKIP_LIST}" != "x" -a "x`echo ${GRUB_OS_PROBER_SKIP_LIST} | grep -i -e '\b'${EXPUUID}'\b'`" != "x" ] ; then + echo "Skipped ${LONGNAME} on ${DEVICE} by user request." >&2 + continue + fi + BTRFS="`echo ${OS} | cut -d ':' -f 5`" if [ "x$BTRFS" = "xbtrfs" ]; then BTRFSuuid="`echo ${OS} | cut -d ':' -f 6`" @@ -265,7 +277,7 @@ EOF echo "$title_correction_code" ;; macosx) - OSXUUID="`${grub_probe} --target=fs_uuid --device ${DEVICE} 2> /dev/null`" + OSXUUID="${UUID}" osx_entry xnu_kernel 32 osx_entry xnu_kernel64 64 ;; diff --git a/util/import_gcry.py b/util/import_gcry.py index a197b3141..1319a8ca8 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -137,11 +137,13 @@ for cipher_file in cipher_files: ciphernames = [] mdnames = [] + mdctxsizes = [] pknames = [] hold = False skip = 0 skip2 = False ismd = False + mdarg = 0 ispk = False iscipher = False iscryptostart = False @@ -174,6 +176,11 @@ for cipher_file in cipher_files: sg = s.groups()[0] cryptolist.write (("%s: %s\n") % (sg, modname)) iscryptostart = False + if ismd: + spl = line.split (",") + if mdarg + len (spl) > 9 and mdarg <= 9 and ("sizeof" in spl[9-mdarg]): + mdctxsizes.append (spl[9-mdarg].lstrip ().rstrip()) + mdarg = mdarg + len (spl) - 1 if ismd or iscipher or ispk: if not re.search (" *};", line) is None: if not iscomma: @@ -189,6 +196,7 @@ for cipher_file in cipher_files: fw.write (" .blocksize = %s\n" % mdblocksizes [mdname]) ismd = False + mdarg = 0 iscipher = False ispk = False iscomma = not re.search (",$", line) is None @@ -283,6 +291,7 @@ for cipher_file in cipher_files: mdname = re.match("[a-zA-Z0-9_]*",mdname).group () mdnames.append (mdname) ismd = True + mdarg = 0 iscryptostart = True m = re.match ("static const char \*selftest.*;$", line) if not m is None: @@ -423,6 +432,8 @@ for cipher_file in cipher_files: chmsg = "Register cipher %s" % ciphername chlognew = "%s\n %s" % (chlognew, chmsg) fw.write (" grub_cipher_register (&%s);\n" % ciphername) + for ctxsize in mdctxsizes: + fw.write (" COMPILE_TIME_ASSERT(%s <= GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE);\n" % ctxsize) for mdname in mdnames: chmsg = "Register digest %s" % mdname chlognew = "%s\n %s" % (chlognew, chmsg)